Merge branch 'dev/11/fp3/security-aosp-rvc-release' into int/11/fp3

* dev/11/fp3/security-aosp-rvc-release:
  Canonicalise path before extracting relative path

Change-Id: Ic9b9583758d6d0b37eb7779dbc31bce37a1cb0ba
diff --git a/jni/FuseDaemon.cpp b/jni/FuseDaemon.cpp
index e927fd1..52ac5f7 100644
--- a/jni/FuseDaemon.cpp
+++ b/jni/FuseDaemon.cpp
@@ -427,10 +427,14 @@
         // invalidate node_name if different case
         // Note that we invalidate async otherwise we will deadlock the kernel
         if (name != node->GetName()) {
-            std::thread t([=]() {
-                fuse_inval(fuse->se, fuse->ToInode(parent), fuse->ToInode(node), node->GetName(),
-                           path);
-            });
+            // Make copies of the node name and path so we're not attempting to acquire
+            // any node locks from the invalidation thread. Depending on timing, we may end
+            // up invalidating the wrong inode but that shouldn't result in correctness issues.
+            const fuse_ino_t parent_ino = fuse->ToInode(parent);
+            const fuse_ino_t child_ino = fuse->ToInode(node);
+            const std::string& node_name = node->GetName();
+
+            std::thread t([=]() { fuse_inval(fuse->se, parent_ino, child_ino, node_name, path); });
             t.detach();
         }
     }
@@ -1485,7 +1489,7 @@
         return;
     }
     const string path = node->BuildPath();
-    if (!is_app_accessible_path(fuse->mp, path, req->ctx.uid)) {
+    if (path != "/storage/emulated" && !is_app_accessible_path(fuse->mp, path, req->ctx.uid)) {
         fuse_reply_err(req, ENOENT);
         return;
     }
@@ -1509,6 +1513,13 @@
     bool for_write = mask & W_OK;
     bool is_directory = S_ISDIR(stat.st_mode);
     if (is_directory) {
+        if (path == "/storage/emulated" && mask == X_OK) {
+            // Special case for this path: apps should be allowed to enter it,
+            // but not list directory contents (which would be user numbers).
+            int res = access(path.c_str(), X_OK);
+            fuse_reply_err(req, res ? errno : 0);
+            return;
+        }
         status = fuse->mp->IsOpendirAllowed(path, req->ctx.uid, for_write);
     } else {
         if (mask & X_OK) {
diff --git a/jni/node-inl.h b/jni/node-inl.h
index d6ad0ad..364a327 100644
--- a/jni/node-inl.h
+++ b/jni/node-inl.h
@@ -19,12 +19,16 @@
 
 #include <android-base/logging.h>
 
+#include <cstdint>
+#include <limits>
 #include <list>
 #include <memory>
 #include <mutex>
+#include <set>
 #include <sstream>
 #include <string>
 #include <unordered_set>
+#include <utility>
 #include <vector>
 
 #include "libfuse_jni/ReaddirHelper.h"
@@ -175,14 +179,18 @@
     node* LookupChildByName(const std::string& name, bool acquire) const {
         std::lock_guard<std::recursive_mutex> guard(*lock_);
 
-        const char* name_char = name.c_str();
-        for (node* child : children_) {
-            const std::string& child_name = child->GetName();
-            if (!strcasecmp(name_char, child_name.c_str()) && !child->deleted_) {
+        // 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_) {
                 if (acquire) {
                     child->Acquire();
                 }
-
                 return child;
             }
         }
@@ -201,10 +209,41 @@
     void Rename(const std::string& name, node* new_parent) {
         std::lock_guard<std::recursive_mutex> guard(*lock_);
 
-        name_ = name;
         if (new_parent != parent_) {
             RemoveFromParent();
+            name_ = name;
             AddToParent(new_parent);
+            return;
+        }
+
+        // Changing name_ will change the expected position of this node in parent's set of
+        // children. Consider following scenario:
+        // 1. This node: "b"; parent's set: {"a", "b", "c"}
+        // 2. Rename("b", "d")
+        //
+        // After rename, parent's set should become: {"a", "b", "d"}, but if we simply change the
+        // name it will be {"a", "d", "b"}, which violates properties of the set.
+        //
+        // To make sure that parent's set is always valid, changing name is 3 steps procedure:
+        // 1. Remove this node from parent's set.
+        // 2  Change the name.
+        // 3. Add it back to the set.
+        // Rename of node without changing its parent. Still need to remove and re-add it to make
+        // sure lookup index is correct.
+        if (name_ != name) {
+            // If this is a root node, simply rename it.
+            if (parent_ == nullptr) {
+                name_ = name;
+                return;
+            }
+
+            auto it = parent_->children_.find(this);
+            CHECK(it != parent_->children_.end());
+            parent_->children_.erase(it);
+
+            name_ = name;
+
+            parent_->children_.insert(this);
         }
     }
 
@@ -299,7 +338,7 @@
         CHECK(parent != nullptr);
 
         parent_ = parent;
-        parent_->children_.push_back(this);
+        parent_->children_.insert(this);
 
         // TODO(narayan, zezeozue): It's unclear why we need to call Acquire on the
         // parent node when we're adding a child to it.
@@ -311,16 +350,55 @@
         std::lock_guard<std::recursive_mutex> guard(*lock_);
 
         if (parent_ != nullptr) {
-            std::list<node*>& children = parent_->children_;
-            std::list<node*>::iterator it = std::find(children.begin(), children.end(), this);
+            auto it = parent_->children_.find(this);
+            CHECK(it != parent_->children_.end());
+            parent_->children_.erase(it);
 
-            CHECK(it != children.end());
-            children.erase(it);
             parent_->Release(1);
             parent_ = nullptr;
         }
     }
 
+    // A custom heterogeneous comparator used for set of this node's children_ to speed up child
+    // node by name lookups.
+    //
+    // This comparator treats node* as pair (node->name_, node): two nodes* are first
+    // compared by their name using case-insenstive comparison function. If their names are equal,
+    // then pointers are compared as integers.
+    //
+    // See LookupChildByName function to see how this comparator is used.
+    //
+    // Note that it's important to first compare by name_, since it will make all nodes with same
+    // name (compared using strcasecmp) together, which allows LookupChildByName function to find
+    // range of the candidate nodes by issuing two binary searches.
+    struct NodeCompare {
+        using is_transparent = void;
+
+        bool operator()(const node* lhs, const node* rhs) const {
+            int cmp = strcasecmp(lhs->name_.c_str(), rhs->name_.c_str());
+            if (cmp != 0) {
+                return cmp < 0;
+            }
+            return reinterpret_cast<uintptr_t>(lhs) < reinterpret_cast<uintptr_t>(rhs);
+        }
+
+        bool operator()(const node* lhs, const std::pair<std::string, uintptr_t>& rhs) const {
+            int cmp = strcasecmp(lhs->name_.c_str(), rhs.first.c_str());
+            if (cmp != 0) {
+                return cmp < 0;
+            }
+            return reinterpret_cast<uintptr_t>(lhs) < rhs.second;
+        }
+
+        bool operator()(const std::pair<std::string, uintptr_t>& lhs, const node* rhs) const {
+            int cmp = strcasecmp(lhs.first.c_str(), rhs->name_.c_str());
+            if (cmp != 0) {
+                return cmp < 0;
+            }
+            return lhs.second < reinterpret_cast<uintptr_t>(rhs);
+        }
+    };
+
     // A helper function to recursively construct the absolute path of a given node.
     // If |safe| is true, builds a PII safe path instead
     void BuildPathForNodeRecursive(bool safe, const node* node, std::stringstream* path) const;
@@ -329,9 +407,9 @@
     std::string name_;
     // The reference count for this node. Guarded by |lock_|.
     uint32_t refcount_;
-    // List of children of this node. All of them contain a back reference
+    // Set of children of this node. All of them contain a back reference
     // to their parent. Guarded by |lock_|.
-    std::list<node*> children_;
+    std::set<node*, NodeCompare> children_;
     // Containing directory for this node. Guarded by |lock_|.
     node* parent_;
     // List of file handles associated with this node. Guarded by |lock_|.
diff --git a/jni/node_test.cpp b/jni/node_test.cpp
index 098bb28..357cea8 100644
--- a/jni/node_test.cpp
+++ b/jni/node_test.cpp
@@ -3,6 +3,7 @@
 #include "node-inl.h"
 
 #include <algorithm>
+#include <limits>
 #include <memory>
 #include <mutex>
 
@@ -33,6 +34,9 @@
     unique_node_ptr CreateNode(node* parent, const std::string& path) {
         return unique_node_ptr(node::Create(parent, path, &lock_, &tracker_), &NodeTest::destroy);
     }
+
+    // Expose NodeCompare for testing.
+    node::NodeCompare cmp;
 };
 
 TEST_F(NodeTest, TestCreate) {
@@ -239,3 +243,78 @@
     ASSERT_EQ(mixed_child.get(), lower_child);
     ASSERT_EQ(mixed_child.get(), upper_child);
 }
+
+TEST_F(NodeTest, RenameSameNameSameParent) {
+    unique_node_ptr parent = CreateNode(nullptr, "/path1");
+    unique_node_ptr child = CreateNode(parent.get(), "subdir");
+
+    ASSERT_EQ(child.get(), parent->LookupChildByName("SuBdIr", false /* acquire */));
+    ASSERT_EQ(2, GetRefCount(parent.get()));
+
+    child->Rename("subdir", parent.get());
+
+    ASSERT_EQ(child.get(), parent->LookupChildByName("SuBdIr", false /* acquire */));
+    ASSERT_EQ(2, GetRefCount(parent.get()));
+}
+
+TEST_F(NodeTest, RenameRoot) {
+    unique_node_ptr root = CreateNode(nullptr, "/root");
+    ASSERT_EQ(1, GetRefCount(root.get()));
+
+    root->Rename("/i-am-root!", nullptr);
+
+    ASSERT_EQ("/i-am-root!", root->GetName());
+    ASSERT_EQ(1, GetRefCount(root.get()));
+}
+
+TEST_F(NodeTest, NodeCompareDefinesLinearOrder) {
+    unique_node_ptr node_a = CreateNode(nullptr, "a");
+    unique_node_ptr node_b = CreateNode(nullptr, "B");
+    unique_node_ptr node_c = CreateNode(nullptr, "c");
+
+    ASSERT_FALSE(cmp.operator()(node_a.get(), node_a.get()));
+    ASSERT_FALSE(cmp.operator()(node_b.get(), node_b.get()));
+    ASSERT_FALSE(cmp.operator()(node_c.get(), node_c.get()));
+
+    auto check_fn = [&](const node* lhs_node, const node* rhs_node) {
+        ASSERT_TRUE(cmp.operator()(lhs_node, rhs_node));
+        ASSERT_FALSE(cmp.operator()(rhs_node, lhs_node));
+    };
+
+    check_fn(node_a.get(), node_b.get());
+    check_fn(node_b.get(), node_c.get());
+    check_fn(node_a.get(), node_c.get());
+
+    // ("A", 0) < node_a < ("a", max_uintptr_t) < node_b
+    ASSERT_TRUE(cmp.operator()(std::make_pair("A", 0), node_a.get()));
+    ASSERT_TRUE(cmp.operator()(node_a.get(),
+                               std::make_pair("A", std::numeric_limits<uintptr_t>::max())));
+    ASSERT_TRUE(cmp.operator()(std::make_pair("A", std::numeric_limits<uintptr_t>::max()),
+                               node_b.get()));
+}
+
+TEST_F(NodeTest, LookupChildByName_ChildrenWithSameName) {
+    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 bar1 = CreateNode(parent.get(), "BAR");
+    unique_node_ptr bar2 = CreateNode(parent.get(), "bar");
+    unique_node_ptr baz1 = CreateNode(parent.get(), "baZ");
+    unique_node_ptr baz2 = CreateNode(parent.get(), "Baz");
+
+    auto test_fn = [&](const std::string& name, node* first, node* second) {
+        auto node1 = parent->LookupChildByName(name, false /* acquire */);
+        ASSERT_EQ(std::min(first, second), node1);
+        node1->SetDeleted();
+
+        auto node2 = parent->LookupChildByName(name, false /* acquire */);
+        ASSERT_EQ(std::max(first, second), node2);
+        node2->SetDeleted();
+
+        ASSERT_EQ(nullptr, parent->LookupChildByName(name, false /* acquire */));
+    };
+
+    test_fn("foo", foo1.get(), foo2.get());
+    test_fn("bAr", bar1.get(), bar2.get());
+    test_fn("BaZ", baz1.get(), baz2.get());
+}
diff --git a/legacy/src/com/android/providers/media/LegacyMediaProvider.java b/legacy/src/com/android/providers/media/LegacyMediaProvider.java
index 6e152d4..e921155 100644
--- a/legacy/src/com/android/providers/media/LegacyMediaProvider.java
+++ b/legacy/src/com/android/providers/media/LegacyMediaProvider.java
@@ -26,6 +26,7 @@
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.OperationApplicationException;
+import android.content.UriMatcher;
 import android.content.pm.ProviderInfo;
 import android.database.Cursor;
 import android.net.Uri;
@@ -99,9 +100,10 @@
     @Override
     public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
             String sortOrder) {
+        final String appendedSelection = getAppendedSelection(selection, uri);
         final DatabaseHelper helper = getDatabaseForUri(uri);
         return helper.runWithoutTransaction((db) -> {
-            return db.query("files", projection, selection, selectionArgs,
+            return db.query(getTableName(uri), projection, appendedSelection, selectionArgs,
                     null, null, sortOrder);
         });
     }
@@ -151,7 +153,7 @@
 
         final DatabaseHelper helper = getDatabaseForUri(uri);
         final long id = helper.runWithTransaction((db) -> {
-            return db.insert("files", null, values);
+            return db.insert(getTableName(uri), null, values);
         });
         return ContentUris.withAppendedId(uri, id);
     }
@@ -166,6 +168,48 @@
         throw new UnsupportedOperationException();
     }
 
+    private static final int AUDIO_PLAYLISTS_ID_MEMBERS = 112;
+    private static final int FILES_ID = 701;
+    private static final UriMatcher BASIC_URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
+    static {
+        final UriMatcher basicUriMatcher = BASIC_URI_MATCHER;
+        basicUriMatcher.addURI(MediaStore.AUTHORITY_LEGACY, "*/audio/playlists/#/members",
+                AUDIO_PLAYLISTS_ID_MEMBERS);
+        basicUriMatcher.addURI(MediaStore.AUTHORITY_LEGACY, "*/file/#", FILES_ID);
+    };
+
+    private static String getAppendedSelection(String selection, Uri uri) {
+        String whereClause = "";
+        final int match = BASIC_URI_MATCHER.match(uri);
+        switch (match) {
+            case AUDIO_PLAYLISTS_ID_MEMBERS:
+                whereClause = "playlist_id=" + uri.getPathSegments().get(3);
+                break;
+            case FILES_ID:
+                whereClause = "_id=" + uri.getPathSegments().get(2);
+                break;
+            default:
+                // No additional whereClause required
+        }
+        if (selection == null || selection.isEmpty()) {
+            return whereClause;
+        } else if (whereClause.isEmpty()) {
+            return selection;
+        } else {
+            return  whereClause + " AND " + selection;
+        }
+    }
+
+    private static String getTableName(Uri uri) {
+        final int playlistMatch = BASIC_URI_MATCHER.match(uri);
+        if (playlistMatch == AUDIO_PLAYLISTS_ID_MEMBERS) {
+            return "audio_playlists_map";
+        } else {
+            // Return the "files" table by default for all other Uris.
+            return "files";
+        }
+    }
+
     @Override
     public Bundle call(String authority, String method, String arg, Bundle extras) {
         switch (method) {
diff --git a/res/drawable/ic_warning.xml b/res/drawable/ic_delete.xml
similarity index 82%
rename from res/drawable/ic_warning.xml
rename to res/drawable/ic_delete.xml
index 2163203..333cb63 100644
--- a/res/drawable/ic_warning.xml
+++ b/res/drawable/ic_delete.xml
@@ -20,6 +20,6 @@
         android:viewportHeight="24"
         android:viewportWidth="24">
     <path
-        android:fillColor="#1A73E8"
-        android:pathData="M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z" />
+        android:fillColor="@color/clear_cache_icon_color"
+        android:pathData="M15 4V3H9v1H4v2h1v13c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V6h1V4h-5zm2 15H7V6h10v13zM9 8h2v9H9zm4 0h2v9h-2z" />
 </vector>
\ No newline at end of file
diff --git a/res/drawable/ic_warning.xml b/res/drawable/thumb_clip_gradient.xml
similarity index 64%
copy from res/drawable/ic_warning.xml
copy to res/drawable/thumb_clip_gradient.xml
index 2163203..d94b0c2 100644
--- a/res/drawable/ic_warning.xml
+++ b/res/drawable/thumb_clip_gradient.xml
@@ -14,12 +14,8 @@
      limitations under the License.
 -->
 
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportHeight="24"
-        android:viewportWidth="24">
-    <path
-        android:fillColor="#1A73E8"
-        android:pathData="M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z" />
-</vector>
\ No newline at end of file
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+        android:shape="rectangle">
+    <solid android:color="@color/thumb_more_tint"/>
+    <corners android:radius="4dp" />
+</shape>
diff --git a/res/layout/cache_clearing_dialog.xml b/res/layout/cache_clearing_dialog.xml
index 06f97b8..bf5a60b 100644
--- a/res/layout/cache_clearing_dialog.xml
+++ b/res/layout/cache_clearing_dialog.xml
@@ -20,15 +20,18 @@
         android:theme="@style/CacheClearingAlertDialogTheme"
         android:paddingStart="?android:attr/dialogPreferredPadding"
         android:paddingEnd="?android:attr/dialogPreferredPadding"
+        android:paddingTop="@dimen/dialog_space"
+        android:paddingBottom="10dp"
         android:orientation="vertical">
     <ImageView
         android:adjustViewBounds="true"
+        android:id="@+id/dialog_icon"
         android:layout_gravity="bottom|center_horizontal"
         android:layout_width="24dp"
         android:layout_height="24dp"
-        android:layout_marginTop="20dp"
+        android:layout_marginBottom="7dp"
         android:scaleType="fitCenter"
-        android:src="@drawable/ic_warning"
+        android:src="@drawable/ic_delete"
         android:contentDescription="@null"/>
 
     <TextView
diff --git a/res/layout/permission_body.xml b/res/layout/permission_body.xml
index 6282c7c..0fb4ece 100644
--- a/res/layout/permission_body.xml
+++ b/res/layout/permission_body.xml
@@ -61,8 +61,13 @@
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
                 android:background="@drawable/thumb_clip"
-                android:scaleType="centerCrop"
-                android:tint="@color/thumb_more_tint" />
+                android:scaleType="centerCrop"/>
+            <View
+                android:id="@+id/thumb_more_gradient"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:background="@drawable/thumb_clip_gradient"
+                android:visibility="gone"/>
             <TextView
                 android:id="@+id/thumb_more_text"
                 android:layout_width="match_parent"
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 99778ca..09a1296 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Vee tydelike programlêers uit?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"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 f8400b6..1a62bf5 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -37,9 +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="4672878017407595782">"ጊዜያዊ የመተግበሪያ ፋይሎች ይጽዱ?"</string>
+    <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>
     <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 dd3b567..c5d7cea 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -45,9 +45,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="4672878017407595782">"هل تريد محو ملفات التطبيق المؤقتة؟"</string>
+    <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>
     <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 d6c697e..35449a8 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/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">"Images"</string>
     <string name="root_videos" msgid="8792703517064649453">"ভিডিঅ\'সমূহ"</string>
     <string name="root_audio" msgid="3505830755201326018">"অডিঅ’"</string>
     <string name="root_documents" msgid="3829103301363849237">"নথিপত্র"</string>
@@ -37,9 +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="4672878017407595782">"অস্থায়ী এপ্‌ ফাইলসমূহ মচিবনে?"</string>
+    <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>
     <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 4a278d7..a8d2ab3 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Müvəqqəti tətbiq faylları silinsin?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Müvəqqəti tətbiq fayllarını silin"</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 6a9a757..9756151 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -39,9 +39,10 @@
       <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="4672878017407595782">"Želite li da obrišete privremene datoteke aplikacija?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Obrišite 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 78175e3..58bffee 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -41,9 +41,10 @@
       <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="4672878017407595782">"Ачысціць часовыя файлы праграм?"</string>
+    <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>
     <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 c52ece9..b576228 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -37,9 +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="4672878017407595782">"Да се изчистят ли временните файлове на приложенията?"</string>
+    <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>
     <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 9f27ed3..4b02f68 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/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">"Images"</string>
     <string name="root_videos" msgid="8792703517064649453">"ভিডিও"</string>
     <string name="root_audio" msgid="3505830755201326018">"অডিও"</string>
     <string name="root_documents" msgid="3829103301363849237">"ডকুমেন্ট"</string>
@@ -37,9 +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="4672878017407595782">"অস্থায়ী অ্যাপ ফাইল মুছে দিতে চান?"</string>
+    <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>
     <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 e40f5f7..9f89481 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -39,9 +39,10 @@
       <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="4672878017407595782">"Obrisati privremene fajlove aplikacija?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Brisanje privremenih fajlova 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 1a0069b..184a9b9 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Vols esborrar els fitxers temporals d\'aplicacions?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Esborra 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 e4c1bc0..3fa3e40 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -41,9 +41,10 @@
       <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="4672878017407595782">"Vymazat dočasné soubory aplikací?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Vymazání dočasných souborů 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 074233c..96ee522 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Vil du rydde midlertidige appfiler?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Ryd 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 1dbc776..8b19ff5 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Temporäre App-Dateien löschen?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"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 970e877..7045ca0 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -37,9 +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="4672878017407595782">"Να διαγραφούν τα προσωρινά αρχεία εφαρμογών;"</string>
+    <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>
     <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 9f91376..1205a7e 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Clear temporary app files?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"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 9f91376..1205a7e 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Clear temporary app files?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"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 9f91376..1205a7e 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Clear temporary app files?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"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 9f91376..1205a7e 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Clear temporary app files?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"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 78226b4..18ba860 100644
--- a/res/values-en-rXC/strings.xml
+++ b/res/values-en-rXC/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‎‏‏‎‎‏‎‏‏‎‎‏‎‏‏‏‎‎‏‏‎‎‏‎‎‎‎‎‏‎‎‏‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‎‏‏‎‎Clear temporary app files?‎‏‎‎‏‎"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‏‎‎‏‏‎‎‏‎‎‎‏‏‏‎‏‎‏‎‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎‎‎‎‎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 9ca1b9b..e2ffe99 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"¿Deseas borrar archivos temporales de apps?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Borra 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 7d54c38..7d0ee18 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"¿Borrar archivos temporales de aplicaciones?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Borrar archivos de aplicaciones temporales"</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 fd66592..1dbfc5c 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Kas soovite rakenduse ajutised failid kustutada?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Rakenduse ajutiste failide kustutamine"</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 28a6d4f..982a7c8 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Aplikazioen aldi baterako fitxategiak garbitu nahi dituzu?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Garbitu aplikazioen aldi baterako fitxategiak"</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 622792d..fc0d11e 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,11 +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="4672878017407595782">"فایل‌های موقت برنامه پاک شوند؟"</string>
+    <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>
     <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 142b960..39517ba 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Poistetaanko väliaikaisia sovellustiedostoja?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Poista 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 74e490d..021ba70 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Effacer les fichiers temporaires des applications?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"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 beace75..7b0d694 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Effacer les fichiers d\'application temporaires ?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"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">
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 05a69de..93e281d 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Queres borrar os ficheiros temporais da aplicación?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Borrar os ficheiros temporais das aplicacións"</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 232fea0..d7cc37d 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -21,8 +21,8 @@
     <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_videos" msgid="8792703517064649453">"વિડિઓઝ"</string>
+    <string name="root_images" msgid="5861633549189045666">"Images"</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>
@@ -37,9 +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="4672878017407595782">"ઍપની બધી અસ્થાયી ફાઇલોને સાફ કરીએ?"</string>
+    <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>
     <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 2442f74..3937bd2 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -37,9 +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="4672878017407595782">"ऐप्लिकेशन से जुड़ी, कुछ समय तक रहने वाली फ़ाइलें मिटाना चाहते हैं?"</string>
+    <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>
     <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-hr/strings.xml b/res/values-hr/strings.xml
index 1025609..6b4abd9 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -39,9 +39,10 @@
       <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="4672878017407595782">"Želite li izbrisati privremene datoteke aplikacija?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Brisanje privremenih datoteka 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 89c12f5..1e39499 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Törli az ideiglenes alkalmazásfájlokat?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Ideiglenes alkalmazásfájlok törlése"</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 81f1fc4..862e27a 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -37,9 +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="4672878017407595782">"Ջնջե՞լ հավելվածի լրացուցիչ ֆայլերը"</string>
+    <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>
     <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 c5f0532..42406d7 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Hapus file aplikasi sementara?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Menghapus 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 7c03eef..fb7daa3 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Hreinsa tímabundnar forritaskrár?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"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 e8d291a..9b5d598 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Cancellare i file temporanei delle app?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Cancellare 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 2238a61..d078c28 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -19,7 +19,7 @@
     <string name="uid_label" msgid="8421971615411294156">"מדיה"</string>
     <string name="storage_description" msgid="4081716890357580107">"אחסון מקומי"</string>
     <string name="app_label" msgid="9035307001052716210">"אחסון מדיה"</string>
-    <string name="artist_label" msgid="8105600993099120273">"אמן"</string>
+    <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>
@@ -41,9 +41,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="4672878017407595782">"לנקות קובצי אפליקציה זמניים?"</string>
+    <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>
     <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 b7b0c5b..a7795b9 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -37,9 +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="4672878017407595782">"アプリの一時ファイルを削除しますか?"</string>
+    <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>
     <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 b1d0b87..420e846 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -37,9 +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="4672878017407595782">"გასუფთავდეს აპის დროებითი ფაილები?"</string>
+    <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>
     <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 161809b..1b899b2 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -37,9 +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="4672878017407595782">"Қолданбаның уақытша файлдарын өшіру керек пе?"</string>
+    <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>
     <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 a87025e..b4a930f 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -37,9 +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="4672878017407595782">"សម្អាត​ឯកសារ​កម្មវិធី​បណ្ដោះអាសន្ន​ឬ?"</string>
+    <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>
     <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 1896b5f..99c1788 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/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">"Images"</string>
     <string name="root_videos" msgid="8792703517064649453">"ವೀಡಿಯೊಗಳು"</string>
     <string name="root_audio" msgid="3505830755201326018">"ಆಡಿಯೊ"</string>
     <string name="root_documents" msgid="3829103301363849237">"ಡಾಕ್ಯುಮೆಂಟ್‌ಗಳು"</string>
@@ -37,9 +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="4672878017407595782">"ತಾತ್ಕಾಲಿಕ ಆ್ಯಪ್ ಫೈಲ್‌ಗಳನ್ನು ತೆರವುಗೊಳಿಸಬೇಕೇ?"</string>
+    <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>
     <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 43c798f..97fa4ec 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -37,9 +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="4672878017407595782">"임시 앱 파일을 삭제하시겠습니까?"</string>
+    <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>
     <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 38642b0..6198dba 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -37,9 +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="4672878017407595782">"Колдонмодогу убактылуу файлдарды өчүрөсүзбү?"</string>
+    <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>
     <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 f14e1c3..568d20a 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -37,9 +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="4672878017407595782">"ລຶບລ້າງໄຟລ໌ແອັບຊົ່ວຄາວບໍ?"</string>
+    <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>
     <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 5cf0dad..4190c0f 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -41,9 +41,10 @@
       <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="4672878017407595782">"Išvalyti laikinus programų failus?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Laikinų programų failų išvalymas"</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 af20087..7bc296f 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -39,9 +39,10 @@
       <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="4672878017407595782">"Vai notīrīt lietotņu pagaidu failus?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Lietotņu pagaidu failu notīrīšana"</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 8683cbd..9dd0bf3 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -37,9 +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="4672878017407595782">"Да се избришат привремените датотеки на апликацијата?"</string>
+    <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>
     <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 9150998..d505748 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/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">"Images"</string>
     <string name="root_videos" msgid="8792703517064649453">"വീഡിയോകൾ"</string>
     <string name="root_audio" msgid="3505830755201326018">"ഓഡിയോ"</string>
     <string name="root_documents" msgid="3829103301363849237">"ഡോക്യുമെന്റുകൾ"</string>
@@ -37,9 +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="4672878017407595782">"താൽക്കാലികമായ ആപ്പ് ഫയലുകൾ മായ്ക്കണോ?"</string>
+    <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>
     <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 c1153cf..8c7a39b 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -37,9 +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="4672878017407595782">"Аппын түр зуурын файлуудыг арилгах уу?"</string>
+    <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>
     <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 da22d60..b110be3 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/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">"Images"</string>
     <string name="root_videos" msgid="8792703517064649453">"व्हिडिओ"</string>
     <string name="root_audio" msgid="3505830755201326018">"ऑडिओ"</string>
     <string name="root_documents" msgid="3829103301363849237">"दस्तऐवज"</string>
@@ -37,9 +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="4672878017407595782">"तात्पुरत्या अ‍ॅप फाइल काढून टाकायच्या आहेत का?"</string>
+    <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>
     <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 8e703b6..067cc43 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Kosongkan fail apl sementara?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"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 ee0c757..ab3766c 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -37,9 +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="4672878017407595782">"ယာယီအက်ပ်ဖိုင်များ ရှင်းထုတ်မလား။"</string>
+    <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>
     <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 25a2710..35fd892 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Vil du slette midlertidige appfiler?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Slett 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 835a9be..0735ae7 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -37,9 +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="4672878017407595782">"अनुप्रयोगका अस्थायी फाइलहरू मेटाउने हो?"</string>
+    <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>
     <string name="allow" msgid="8885707816848569619">"अनुमति दिनुहोस्"</string>
     <string name="deny" msgid="6040983710442068936">"अस्वीकार गर्नुहोस्"</string>
     <plurals name="permission_write_audio" formatted="false" msgid="8914759422381305478">
@@ -51,8 +52,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>
@@ -67,8 +68,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>
@@ -83,8 +84,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>
@@ -99,8 +100,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-night/colors.xml b/res/values-night/colors.xml
index 56d8417..1478eb2 100644
--- a/res/values-night/colors.xml
+++ b/res/values-night/colors.xml
@@ -16,5 +16,6 @@
   -->
 
 <resources>
-    <color name="thumb_gray_color">#3c4043</color>
+    <color name="thumb_gray_color">#3C4043</color>
+    <color name="clear_cache_icon_color">#DADCE0</color>
 </resources>
diff --git a/res/values-night/styles.xml b/res/values-night/styles.xml
new file mode 100644
index 0000000..9b4da23
--- /dev/null
+++ b/res/values-night/styles.xml
@@ -0,0 +1,38 @@
+<?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.
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <style name="PickerDialogTheme"
+           parent="@android:style/Theme.DeviceDefault.Dialog.Alert">
+        <item name="android:windowNoTitle">true</item>
+    </style>
+
+    <style name="AlertDialogTheme"
+           parent="@android:style/Theme.DeviceDefault.Dialog.Alert"/>
+
+    <style name="CacheClearingAlertDialogTheme"
+           parent="@android:style/Theme.DeviceDefault.Dialog.Alert">
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowContentOverlay">@null</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowIsFloating">true</item>
+        <item name="android:backgroundDimEnabled">true</item>
+        <item name="android:alertDialogTheme">@style/AlertDialogTheme</item>
+    </style>
+
+</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 18803cc..d685675 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">"Toestemming vereist om dit item aan te passen of te verwijderen."</string>
+    <string name="permission_required" msgid="1460820436132943754">"Rechten 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,9 +37,10 @@
       <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="4672878017407595782">"Tijdelijke app-bestanden wissen?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"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 1554b52..5ea6ea3 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/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">"Images"</string>
     <string name="root_videos" msgid="8792703517064649453">"ଭିଡିଓ"</string>
     <string name="root_audio" msgid="3505830755201326018">"ଅଡିଓ"</string>
     <string name="root_documents" msgid="3829103301363849237">"ଡକ୍ୟୁମେଣ୍ଟଗୁଡ଼ିକ"</string>
@@ -37,9 +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="4672878017407595782">"ଅସ୍ଥାୟୀ ଆପ୍ ଫାଇଲଗୁଡ଼ିକୁ ଖାଲି କରିବେ?"</string>
+    <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>
     <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-pa/strings.xml b/res/values-pa/strings.xml
index c598bda..cb5e9b4 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -37,9 +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="4672878017407595782">"ਕੀ ਅਸਥਾਈ ਐਪ ਫ਼ਾਈਲਾਂ ਨੂੰ ਕਲੀਅਰ ਕਰਨਾ ਹੈ?"</string>
+    <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>
     <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 b4a3897..ea4a8ce 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -41,9 +41,10 @@
       <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="4672878017407595782">"Usunąć tymczasowe pliki aplikacji?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Usuwanie tymczasowych plików 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 042ceef..d0ff6d6 100644
--- a/res/values-pt-rBR/strings.xml
+++ b/res/values-pt-rBR/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Limpar arquivos temporários de apps?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"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 6d0cb80..27c1cb0 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Pretende limpar os ficheiros temporários da app?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Limpe ficheiros de apps temporários"</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">
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 042ceef..d0ff6d6 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Limpar arquivos temporários de apps?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"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 77e8db2..8df20b8 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -39,9 +39,10 @@
       <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="4672878017407595782">"Ștergeți fișierele temporare ale aplicațiilor?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Ș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 c423cdb..d7a1aaa 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -41,9 +41,10 @@
       <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="4672878017407595782">"Удалить временные файлы приложения?"</string>
+    <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>
     <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 cc7435c..ad22297 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -37,9 +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="4672878017407595782">"තාවකාලික යෙදුම් ගොනු හිස් කරන්නද?"</string>
+    <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>
     <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 b9d6a81..359ba24 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -41,9 +41,10 @@
       <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="4672878017407595782">"Chcete vymazať dočasné súbory aplikácie?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Vymazanie dočasných súborov aplikácií"</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 2d8bb2b..ff63498 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -41,9 +41,10 @@
       <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="4672878017407595782">"Želite izbrisati začasne datoteke aplikacij?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Brisanje začasnih datotek 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 25c1f56..1e90f35 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Të pastrohen skedarët e përkohshëm të aplikacioneve?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Pastro 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 c1e3bd8..079f9aa 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -39,9 +39,10 @@
       <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="4672878017407595782">"Желите ли да обришете привремене датотеке апликација?"</string>
+    <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>
     <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 c19d34f..b0b990c 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Vill du ta bort tillfälliga appfiler?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Rensa 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 a3b2dc8..4917e30 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Ungependa kufuta faili za muda za programu?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Futa 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 c2b05ac..f13588a 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/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">"Images"</string>
     <string name="root_videos" msgid="8792703517064649453">"வீடியோக்கள்"</string>
     <string name="root_audio" msgid="3505830755201326018">"ஆடியோ"</string>
     <string name="root_documents" msgid="3829103301363849237">"ஆவணங்கள்"</string>
@@ -37,9 +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="4672878017407595782">"தற்காலிக ஆப்ஸ் ஃபைல்களை அழிக்கவா?"</string>
+    <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>
     <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-te/strings.xml b/res/values-te/strings.xml
index 24b12ea..30c0faa 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -37,9 +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="4672878017407595782">"తాత్కాలిక యాప్ ఫైల్‌లను తొలగించాలా?"</string>
+    <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>
     <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-th/strings.xml b/res/values-th/strings.xml
index e3ed08a..db76bee 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -37,9 +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="4672878017407595782">"ล้างไฟล์แอปชั่วคราวใช่ไหม"</string>
+    <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>
     <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 6502f43..79452b3 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"I-clear ang mga pansamantalang file ng app?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"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 831946e..669eac9 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Geçici uygulama dosyaları temizlensin mi?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Geçici uygulama dosyalarını temizleyin"</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 a50fd45..281c8b2 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -41,9 +41,10 @@
       <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="4672878017407595782">"Видалити тимчасові файли додатків?"</string>
+    <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>
     <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 fd7e14c..ad6cdf1 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -37,9 +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="4672878017407595782">"ایپ کی عارضی فائلز کو صاف کریں؟"</string>
+    <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>
     <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 982651f..0dcad99 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Ilovaga oid vaqtincha fayllar tozalansinmi?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"Ilovaga oid vaqtincha fayllarni tozalash"</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 5a4ee8c..d0cbec7 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Xóa tệp ứng dụng tạm thời?"</string>
+    <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_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 6d4c467..6cd41f7 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -37,9 +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="4672878017407595782">"要清除临时应用文件吗?"</string>
+    <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>
     <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 ffc74ce..3243f9b 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -37,9 +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="4672878017407595782">"要清除應用程式暫存檔案嗎?"</string>
+    <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>
     <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 f19f715..1a37210 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -37,9 +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="4672878017407595782">"要清除應用程式暫存檔案嗎?"</string>
+    <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>
     <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 2fe5245..e2f528d 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -37,9 +37,10 @@
       <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="4672878017407595782">"Sula amafayela ohlelo lokusebenza wesikhashana?"</string>
+    <string name="cache_clearing_dialog_title" msgid="8907893815183913664">"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/res/values/colors.xml b/res/values/colors.xml
index 28f31ee..ed0c6c2 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -15,5 +15,6 @@
 -->
 
 <resources>
-    <color name="thumb_gray_color">#1f000000</color>
+    <color name="thumb_gray_color">#1F000000</color>
+    <color name="clear_cache_icon_color">#5F6368</color>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 840135e..c3bdf8f 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -18,4 +18,5 @@
     <dimen name="permission_dialog_width">320dp</dimen>
     <dimen name="permission_thumb_size">64dp</dimen>
     <dimen name="permission_thumb_margin">6dp</dimen>
+    <dimen name="dialog_space">20dp</dimen>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 96c086d..d6171ca 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -62,7 +62,7 @@
     </plurals>
 
     <!-- Cache clearing permission dialog warning title. [CHAR LIMIT=NONE] -->
-    <string name="cache_clearing_dialog_title">Clear temporary app files?</string>
+    <string name="cache_clearing_dialog_title">Clear temporary app files</string>
 
     <!-- Cache clearing permission dialog warning text. [CHAR LIMIT=NONE] -->
     <string name="cache_clearing_dialog_text"><xliff:g id="app_seeking_permission" example="File manager">%s</xliff:g> would like to clear some temporary files. This may result in an increased usage of battery or cellular data.</string>
@@ -70,6 +70,9 @@
     <!-- Cache clearing in progress title. [CHAR LIMIT=NONE] -->
     <string name="cache_clearing_in_progress_title">Clearing temporary app files\u2026</string>
 
+    <!--  Cache clearing permission dialog Clear button text. [CHAR LIMIT=30] -->
+    <string name="clear">Clear</string>
+
     <!-- Allow dialog action text. [CHAR LIMIT=30] -->
     <string name="allow">Allow</string>
 
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 322ba66..5f1e662 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -16,15 +16,16 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
 
-    <style name="PickerDialogTheme" parent="@*android:style/Theme.DeviceDefault.Settings.Dialog">
+    <style name="PickerDialogTheme"
+           parent="@android:style/Theme.DeviceDefault.Light.Dialog.Alert">
         <item name="android:windowNoTitle">true</item>
     </style>
 
     <style name="AlertDialogTheme"
-      parent="@*android:style/Theme.DeviceDefault.Dialog.Alert.DayNight" />
+           parent="@android:style/Theme.DeviceDefault.Light.Dialog.Alert"/>
 
     <style name="CacheClearingAlertDialogTheme"
-           parent="@*android:style/Theme.DeviceDefault.Dialog.Alert.DayNight">
+           parent="@android:style/Theme.DeviceDefault.Light.Dialog.Alert">
         <item name="android:windowIsTranslucent">true</item>
         <item name="android:windowBackground">@android:color/transparent</item>
         <item name="android:windowContentOverlay">@null</item>
@@ -41,6 +42,7 @@
         <item name="android:gravity">center</item>
         <item name="android:textColor">?android:attr/textColorPrimary</item>
         <item name="android:textSize">16sp</item>
+        <item name="android:textStyle">bold</item>
     </style>
 
     <style name="PermissionAlertDialogTitle"
diff --git a/src/com/android/providers/media/CacheClearingActivity.java b/src/com/android/providers/media/CacheClearingActivity.java
index d65a4a2..e3aff15 100644
--- a/src/com/android/providers/media/CacheClearingActivity.java
+++ b/src/com/android/providers/media/CacheClearingActivity.java
@@ -25,6 +25,7 @@
 import android.graphics.Typeface;
 import android.os.AsyncTask;
 import android.os.Bundle;
+import android.os.Handler;
 import android.text.BidiFormatter;
 import android.text.SpannableString;
 import android.text.TextPaint;
@@ -43,6 +44,7 @@
     private static final String TAG = "CacheClearingActivity";
     private static final float MAX_APP_NAME_SIZE_PX = 500f;
     private static final float TEXT_SIZE = 42f;
+    private static final Long LEAST_SHOW_PROGRESS_TIME_MS = 300L;
 
     private AlertDialog mActionDialog;
     private Dialog mLoadingDialog;
@@ -102,11 +104,14 @@
     }
 
     private class CacheClearingTask extends AsyncTask<Void, Void, Integer> {
+        private long mStartTime;
+
         @Override
         protected void onPreExecute() {
             dismissDialogs(mActionDialog);
             createLoadingDialog();
             mLoadingDialog.show();
+            mStartTime = System.currentTimeMillis();
         }
 
         @Override
@@ -118,13 +123,25 @@
         protected void onPostExecute(Integer result) {
             // We take the convention of not using primitive wrapper pretty seriously
             int status = result.intValue();
-            dismissDialogs(mLoadingDialog);
+
             if (result == 0) {
                 setResult(RESULT_OK);
             } else {
                 setResult(status);
             }
-            finish();
+
+            // Don't dismiss the progress dialog too quick, it will cause bad UX.
+            final long duration = System.currentTimeMillis() - mStartTime;
+            if (duration > LEAST_SHOW_PROGRESS_TIME_MS) {
+                dismissDialogs(mLoadingDialog);
+                finish();
+            } else {
+                Handler handler = new Handler(getMainLooper());
+                handler.postDelayed(() -> {
+                    dismissDialogs(mLoadingDialog);
+                    finish();
+                }, LEAST_SHOW_PROGRESS_TIME_MS - duration);
+            }
         }
     }
 
@@ -132,12 +149,19 @@
         final CharSequence dialogTitle = getString(R.string.cache_clearing_in_progress_title);
         final View dialogTitleView = View.inflate(this, R.layout.cache_clearing_dialog, null);
         final TextView titleText = dialogTitleView.findViewById(R.id.dialog_title);
+        final ProgressBar progressBar = new ProgressBar(CacheClearingActivity.this);
+        final int padding = getResources().getDimensionPixelOffset(R.dimen.dialog_space);
+
+        progressBar.setIndeterminate(true);
+        progressBar.setPadding(0, padding / 2, 0, padding);
         titleText.setText(dialogTitle);
         mLoadingDialog = new AlertDialog.Builder(this)
                 .setCustomTitle(dialogTitleView)
-                .setView(new ProgressBar(CacheClearingActivity.this))
+                .setView(progressBar)
                 .setCancelable(false)
                 .create();
+
+        dialogTitleView.findViewById(R.id.dialog_icon).setVisibility(View.GONE);
         mLoadingDialog.create();
         setDialogOverlaySettings(mActionDialog);
     }
@@ -149,16 +173,7 @@
         final String unsanitizedAppName = TextUtils.ellipsize(appLabel,
                 paint, MAX_APP_NAME_SIZE_PX, TextUtils.TruncateAt.END).toString();
         final String appName = BidiFormatter.getInstance().unicodeWrap(unsanitizedAppName);
-
         final String actionText = getString(R.string.cache_clearing_dialog_text, appName);
-        final SpannableString message = new SpannableString(actionText);
-
-        int appNameIndex = actionText.indexOf(appName);
-        if (appNameIndex >= 0) {
-            message.setSpan(new StyleSpan(Typeface.BOLD),
-                    appNameIndex, appNameIndex + appName.length(), 0);
-        }
-
         final CharSequence dialogTitle = getString(R.string.cache_clearing_dialog_title);
 
         final View dialogTitleView = View.inflate(this, R.layout.cache_clearing_dialog, null);
@@ -166,9 +181,9 @@
         titleText.setText(dialogTitle);
         mActionDialog = new AlertDialog.Builder(this)
                 .setCustomTitle(dialogTitleView)
-                .setMessage(message)
-                .setPositiveButton(R.string.allow, this)
-                .setNegativeButton(R.string.deny, this)
+                .setMessage(actionText)
+                .setPositiveButton(R.string.clear, this)
+                .setNegativeButton(android.R.string.cancel, this)
                 .setCancelable(false)
                 .create();
 
diff --git a/src/com/android/providers/media/DatabaseHelper.java b/src/com/android/providers/media/DatabaseHelper.java
index 84ed540..d48726b 100644
--- a/src/com/android/providers/media/DatabaseHelper.java
+++ b/src/com/android/providers/media/DatabaseHelper.java
@@ -160,7 +160,7 @@
             @Nullable Class<? extends Annotation> columnAnnotation,
             @Nullable OnSchemaChangeListener schemaListener,
             @Nullable OnFilesChangeListener filesListener,
-            @Nullable OnLegacyMigrationListener migrationListener,
+            @NonNull OnLegacyMigrationListener migrationListener,
             @Nullable UnaryOperator<String> idGenerator) {
         this(context, name, getDatabaseVersion(context), internal, earlyUpgrade, legacyProvider,
                 columnAnnotation, schemaListener, filesListener, migrationListener, idGenerator);
@@ -171,7 +171,7 @@
             @Nullable Class<? extends Annotation> columnAnnotation,
             @Nullable OnSchemaChangeListener schemaListener,
             @Nullable OnFilesChangeListener filesListener,
-            @Nullable OnLegacyMigrationListener migrationListener,
+            @NonNull OnLegacyMigrationListener migrationListener,
             @Nullable UnaryOperator<String> idGenerator) {
         super(context, name, null, version);
         mContext = context;
@@ -1009,7 +1009,7 @@
                 + ", COUNT(DISTINCT album_id) AS " + Audio.Artists.NUMBER_OF_ALBUMS
                 + ", COUNT(DISTINCT _id) AS " + Audio.Artists.NUMBER_OF_TRACKS
                 + " FROM audio"
-                + " WHERE volume_name IN " + filterVolumeNames
+                + " WHERE is_music=1 AND volume_name IN " + filterVolumeNames
                 + " GROUP BY artist_id");
 
         db.execSQL("CREATE VIEW audio_albums AS SELECT "
@@ -1026,7 +1026,7 @@
                 + ", MAX(year) AS " + Audio.Albums.LAST_YEAR
                 + ", NULL AS " + Audio.Albums.ALBUM_ART
                 + " FROM audio"
-                + " WHERE volume_name IN " + filterVolumeNames
+                + " WHERE is_music=1 AND volume_name IN " + filterVolumeNames
                 + " GROUP BY album_id");
 
         db.execSQL("CREATE VIEW audio_genres AS SELECT "
@@ -1290,6 +1290,11 @@
         db.execSQL("ALTER TABLE files ADD COLUMN xmp BLOB DEFAULT NULL;");
     }
 
+    private static void updateAudioAlbumId(SQLiteDatabase db, boolean internal) {
+        // We change the logic for generating album id, rescan all audio files
+        db.execSQL("UPDATE files SET date_modified=0 WHERE media_type=2;");
+    }
+
     private static void recomputeDataValues(SQLiteDatabase db, boolean internal) {
         try (Cursor c = db.query("files", new String[] { FileColumns._ID, FileColumns.DATA },
                 null, null, null, null, null, null)) {
@@ -1345,7 +1350,7 @@
     static final int VERSION_O = 800;
     static final int VERSION_P = 900;
     static final int VERSION_Q = 1023;
-    static final int VERSION_R = 1114;
+    static final int VERSION_R = 1115;
     static final int VERSION_LATEST = VERSION_R;
 
     /**
@@ -1488,6 +1493,9 @@
             if (fromVersion < 1114) {
                 // Empty version bump to ensure triggers are recreated
             }
+            if (fromVersion < 1115) {
+                updateAudioAlbumId(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 9bb8198..4797457 100644
--- a/src/com/android/providers/media/LocalCallingIdentity.java
+++ b/src/com/android/providers/media/LocalCallingIdentity.java
@@ -37,6 +37,7 @@
 import static com.android.providers.media.util.PermissionUtils.checkPermissionWriteImages;
 import static com.android.providers.media.util.PermissionUtils.checkPermissionWriteStorage;
 import static com.android.providers.media.util.PermissionUtils.checkPermissionWriteVideo;
+import static com.android.providers.media.util.PermissionUtils.checkWriteImagesOrVideoAppOps;
 
 import android.annotation.Nullable;
 import android.app.AppOpsManager;
@@ -216,6 +217,8 @@
     public static final int PERMISSION_WRITE_VIDEO = 1 << 20;
     public static final int PERMISSION_WRITE_IMAGES = 1 << 21;
 
+    public static final int PERMISSION_IS_SYSTEM_GALLERY = 1 <<22;
+
     /**
      * Explicitly checks **only** for INSTALL_PACKAGES runtime permission.
      */
@@ -290,6 +293,9 @@
             case PERMISSION_WRITE_IMAGES:
                 return checkPermissionWriteImages(
                         context, pid, uid, getPackageName(), attributionTag);
+            case PERMISSION_IS_SYSTEM_GALLERY:
+                return checkWriteImagesOrVideoAppOps(
+                        context, uid, getPackageName(), attributionTag);
             case PERMISSION_INSTALL_PACKAGES:
                 return checkPermissionInstallPackages(
                         context, pid, uid, getPackageName(), attributionTag);
diff --git a/src/com/android/providers/media/MediaDocumentsProvider.java b/src/com/android/providers/media/MediaDocumentsProvider.java
index f26716d..5121a45 100644
--- a/src/com/android/providers/media/MediaDocumentsProvider.java
+++ b/src/com/android/providers/media/MediaDocumentsProvider.java
@@ -939,7 +939,7 @@
                 if (mimeTypes == null || !shouldFilterMimeType || matchedMimeTypes.size() > 0) {
                     final Pair<String, String[]> selectionPair = buildSearchSelection(displayName,
                             matchedMimeTypes.toArray(new String[0]), lastModifiedAfter,
-                            fileSizeOver, AudioColumns.TITLE, AudioColumns.MIME_TYPE,
+                            fileSizeOver, AudioColumns.DISPLAY_NAME, AudioColumns.MIME_TYPE,
                             AudioColumns.DATE_MODIFIED, AudioColumns.SIZE);
 
                     cursor = resolver.query(Audio.Media.EXTERNAL_CONTENT_URI, SongQuery.PROJECTION,
diff --git a/src/com/android/providers/media/MediaProvider.java b/src/com/android/providers/media/MediaProvider.java
index 5bc77d0..7db1e6d 100644
--- a/src/com/android/providers/media/MediaProvider.java
+++ b/src/com/android/providers/media/MediaProvider.java
@@ -47,6 +47,7 @@
 import static com.android.providers.media.LocalCallingIdentity.PERMISSION_IS_REDACTION_NEEDED;
 import static com.android.providers.media.LocalCallingIdentity.PERMISSION_IS_SELF;
 import static com.android.providers.media.LocalCallingIdentity.PERMISSION_IS_SHELL;
+import static com.android.providers.media.LocalCallingIdentity.PERMISSION_IS_SYSTEM_GALLERY;
 import static com.android.providers.media.LocalCallingIdentity.PERMISSION_READ_AUDIO;
 import static com.android.providers.media.LocalCallingIdentity.PERMISSION_READ_IMAGES;
 import static com.android.providers.media.LocalCallingIdentity.PERMISSION_READ_VIDEO;
@@ -57,6 +58,7 @@
 import static com.android.providers.media.scan.MediaScanner.REASON_DEMAND;
 import static com.android.providers.media.scan.MediaScanner.REASON_IDLE;
 import static com.android.providers.media.util.DatabaseUtils.bindList;
+import static com.android.providers.media.util.FileUtils.DEFAULT_FOLDER_NAMES;
 import static com.android.providers.media.util.FileUtils.PATTERN_PENDING_FILEPATH_FOR_SQL;
 import static com.android.providers.media.util.FileUtils.extractDisplayName;
 import static com.android.providers.media.util.FileUtils.extractFileName;
@@ -703,7 +705,9 @@
         return null;
     };
 
-    private final OnLegacyMigrationListener mMigrationListener = new OnLegacyMigrationListener() {
+    /** {@hide} */
+    public static final OnLegacyMigrationListener MIGRATION_LISTENER =
+            new OnLegacyMigrationListener() {
         @Override
         public void onStarted(ContentProviderClient client, String volumeName) {
             MediaStore.startLegacyMigration(ContentResolver.wrap(client), volumeName);
@@ -770,29 +774,6 @@
         }
     }
 
-    private static final String[] sDefaultFolderNames = {
-            Environment.DIRECTORY_MUSIC,
-            Environment.DIRECTORY_PODCASTS,
-            Environment.DIRECTORY_RINGTONES,
-            Environment.DIRECTORY_ALARMS,
-            Environment.DIRECTORY_NOTIFICATIONS,
-            Environment.DIRECTORY_PICTURES,
-            Environment.DIRECTORY_MOVIES,
-            Environment.DIRECTORY_DOWNLOADS,
-            Environment.DIRECTORY_DCIM,
-            Environment.DIRECTORY_AUDIOBOOKS,
-            Environment.DIRECTORY_DOCUMENTS,
-    };
-
-    private static boolean isDefaultDirectoryName(@Nullable String dirName) {
-        for (String defaultDirName : sDefaultFolderNames) {
-            if (defaultDirName.equals(dirName)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     /**
      * Ensure that default folders are created on mounted primary storage
      * devices. We only do this once per volume so we don't annoy the user if
@@ -817,7 +798,7 @@
             final SharedPreferences prefs = PreferenceManager
                     .getDefaultSharedPreferences(getContext());
             if (prefs.getInt(key, 0) == 0) {
-                for (String folderName : sDefaultFolderNames) {
+                for (String folderName : DEFAULT_FOLDER_NAMES) {
                     final File folder = new File(vol.getDirectory(), folderName);
                     if (!folder.exists()) {
                         folder.mkdirs();
@@ -904,10 +885,10 @@
 
         mInternalDatabase = new DatabaseHelper(context, INTERNAL_DATABASE_NAME,
                 true, false, false, Column.class,
-                Metrics::logSchemaChange, mFilesListener, mMigrationListener, mIdGenerator);
+                Metrics::logSchemaChange, mFilesListener, MIGRATION_LISTENER, mIdGenerator);
         mExternalDatabase = new DatabaseHelper(context, EXTERNAL_DATABASE_NAME,
                 false, false, false, Column.class,
-                Metrics::logSchemaChange, mFilesListener, mMigrationListener, mIdGenerator);
+                Metrics::logSchemaChange, mFilesListener, MIGRATION_LISTENER, mIdGenerator);
 
         final IntentFilter packageFilter = new IntentFilter();
         packageFilter.setPriority(10);
@@ -1223,18 +1204,39 @@
 
     @VisibleForTesting
     static void computeAudioKeyValues(ContentValues values) {
-        computeAudioKeyValue(values,
-                AudioColumns.TITLE, AudioColumns.TITLE_KEY, null);
-        computeAudioKeyValue(values,
-                AudioColumns.ALBUM, AudioColumns.ALBUM_KEY, AudioColumns.ALBUM_ID);
-        computeAudioKeyValue(values,
-                AudioColumns.ARTIST, AudioColumns.ARTIST_KEY, AudioColumns.ARTIST_ID);
-        computeAudioKeyValue(values,
-                AudioColumns.GENRE, AudioColumns.GENRE_KEY, AudioColumns.GENRE_ID);
+        computeAudioKeyValue(values, AudioColumns.TITLE, AudioColumns.TITLE_KEY, /* focusId */
+                null, /* hashValue */ 0);
+        computeAudioKeyValue(values, AudioColumns.ARTIST, AudioColumns.ARTIST_KEY,
+                AudioColumns.ARTIST_ID, /* hashValue */ 0);
+        computeAudioKeyValue(values, AudioColumns.GENRE, AudioColumns.GENRE_KEY,
+                AudioColumns.GENRE_ID, /* hashValue */ 0);
+        computeAudioAlbumKeyValue(values);
+    }
+
+    /**
+     * To distinguish same-named albums, we append a hash. The hash is
+     * based on the "album artist" tag if present, otherwise on the path of
+     * the parent directory of the audio file.
+     */
+    private static void computeAudioAlbumKeyValue(ContentValues values) {
+        int hashCode = 0;
+
+        final String albumArtist = values.getAsString(MediaColumns.ALBUM_ARTIST);
+        if (!TextUtils.isEmpty(albumArtist)) {
+            hashCode = albumArtist.hashCode();
+        } else {
+            final String path = values.getAsString(MediaColumns.DATA);
+            if (!TextUtils.isEmpty(path)) {
+                hashCode = path.substring(0, path.lastIndexOf('/')).hashCode();
+            }
+        }
+
+        computeAudioKeyValue(values, AudioColumns.ALBUM, AudioColumns.ALBUM_KEY,
+                AudioColumns.ALBUM_ID, hashCode);
     }
 
     private static void computeAudioKeyValue(@NonNull ContentValues values, @NonNull String focus,
-            @Nullable String focusKey, @Nullable String focusId) {
+            @Nullable String focusKey, @Nullable String focusId, int hashValue) {
         if (focusKey != null) values.remove(focusKey);
         if (focusId != null) values.remove(focusId);
 
@@ -1250,8 +1252,8 @@
         if (focusId != null) {
             // Many apps break if we generate negative IDs, so trim off the
             // highest bit to ensure we're always unsigned
-            final long id = Hashing.farmHashFingerprint64()
-                    .hashString(key, StandardCharsets.UTF_8).asLong() & ~(1L << 63);
+            final long id = Hashing.farmHashFingerprint64().hashString(key + hashValue,
+                    StandardCharsets.UTF_8).asLong() & ~(1L << 63);
             values.put(focusId, id);
         }
     }
@@ -1741,15 +1743,17 @@
      * Gets all files in the given {@code path} and subdirectories of the given {@code path}.
      */
     private ArrayList<String> getAllFilesForRenameDirectory(String oldPath) {
-        final String selection = MediaColumns.RELATIVE_PATH + " REGEXP '^" +
-                extractRelativePathWithDisplayName(oldPath) + "/?.*' and mime_type not like 'null'";
+        final String selection = FileColumns.DATA + " LIKE ? ESCAPE '\\'"
+                + " and mime_type not like 'null'";
+        final String[] selectionArgs = new String[] {DatabaseUtils.escapeForLike(oldPath) + "/%"};
         ArrayList<String> fileList = new ArrayList<>();
 
         final LocalCallingIdentity token = clearLocalCallingIdentity();
         try (final Cursor c = query(FileUtils.getContentUriForPath(oldPath),
-                new String[] {MediaColumns.DATA}, selection, null, null)) {
+                new String[] {MediaColumns.DATA}, selection, selectionArgs, null)) {
             while (c.moveToNext()) {
-                final String filePath = c.getString(0).replaceFirst("^" + oldPath + "/(.*)", "$1");
+                String filePath = c.getString(0);
+                filePath = filePath.replaceFirst(Pattern.quote(oldPath + "/"), "");
                 fileList.add(filePath);
             }
         } finally {
@@ -1783,13 +1787,15 @@
         }
 
         final int countAllFilesInDirectory;
-        final String selection = MediaColumns.RELATIVE_PATH + " REGEXP '^" +
-                extractRelativePathWithDisplayName(oldPath) + "/?.*' and mime_type not like 'null'";
+        final String selection = FileColumns.DATA + " LIKE ? ESCAPE '\\'"
+                + " and mime_type not like 'null'";
+        final String[] selectionArgs = new String[] {DatabaseUtils.escapeForLike(oldPath) + "/%"};
+
         final Uri uriOldPath = FileUtils.getContentUriForPath(oldPath);
 
         final LocalCallingIdentity token = clearLocalCallingIdentity();
-        try (final Cursor c = query(uriOldPath, new String[] {MediaColumns._ID}, selection, null,
-                null)) {
+        try (final Cursor c = query(uriOldPath, new String[] {MediaColumns._ID}, selection,
+                selectionArgs, null)) {
             // get actual number of files in the given directory.
             countAllFilesInDirectory = c.getCount();
         } finally {
@@ -1809,8 +1815,8 @@
 
         ArrayList<String> fileList = new ArrayList<>();
         final String[] projection = {MediaColumns.DATA, MediaColumns.MIME_TYPE};
-        try (Cursor c = qb.query(helper, projection, selection, null,
-                null, null, null, null, null)) {
+        try (Cursor c = qb.query(helper, projection, selection, selectionArgs, null, null, null,
+                null, null)) {
             // Check if the calling package has write permission to all files in the given
             // directory. If calling package has write permission to all files in the directory, the
             // query with update uri should return same number of files as previous query.
@@ -1819,7 +1825,9 @@
                         + " to rename one or more files in " + oldPath);
             }
             while(c.moveToNext()) {
-                final String filePath = c.getString(0).replaceFirst("^" + oldPath + "/(.*)", "$1");
+                String filePath = c.getString(0);
+                filePath = filePath.replaceFirst(Pattern.quote(oldPath + "/"), "");
+
                 final String mimeType = c.getString(1);
                 if (!isMimeTypeSupportedInPath(newPath + "/" + filePath, mimeType)) {
                     throw new IllegalArgumentException("Can't rename " + oldPath + "/" + filePath
@@ -2061,6 +2069,10 @@
                 return OsConstants.EPERM;
             }
 
+            if (shouldBypassDatabaseForFuse(uid)) {
+                return renameInLowerFs(oldPath, newPath);
+            }
+
             if (shouldBypassFuseRestrictions(/*forWrite*/ true, oldPath)
                     && shouldBypassFuseRestrictions(/*forWrite*/ true, newPath)) {
                 return renameUncheckedForFuse(oldPath, newPath);
@@ -2077,17 +2089,19 @@
                 // Rename not allowed on paths that can't be translated to RELATIVE_PATH.
                 Log.e(TAG, errorMessage +  "Invalid path.");
                 return OsConstants.EPERM;
-            } else if (oldRelativePath.length == 1 && TextUtils.isEmpty(oldRelativePath[0])) {
+            }
+            if (oldRelativePath.length == 1 && TextUtils.isEmpty(oldRelativePath[0])) {
                 // Allow rename of files/folders other than default directories.
                 final String displayName = extractDisplayName(oldPath);
-                for (String defaultFolder : sDefaultFolderNames) {
+                for (String defaultFolder : DEFAULT_FOLDER_NAMES) {
                     if (displayName.equals(defaultFolder)) {
                         Log.e(TAG, errorMessage + oldPath + " is a default folder."
                                 + " Renaming a default folder is not allowed.");
                         return OsConstants.EPERM;
                     }
                 }
-            } else if (newRelativePath.length == 1 && TextUtils.isEmpty(newRelativePath[0])) {
+            }
+            if (newRelativePath.length == 1 && TextUtils.isEmpty(newRelativePath[0])) {
                 Log.e(TAG, errorMessage +  newPath + " is in root folder."
                         + " Renaming a file/directory to root folder is not allowed");
                 return OsConstants.EPERM;
@@ -2150,10 +2164,13 @@
             }
 
             final int type;
+            final boolean forWrite;
             if ((modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
                 type = TYPE_UPDATE;
+                forWrite = true;
             } else {
                 type = TYPE_QUERY;
+                forWrite = false;
             }
 
             final SQLiteQueryBuilder qb = getQueryBuilder(type, table, uri, Bundle.EMPTY, null);
@@ -2163,6 +2180,24 @@
                     return PackageManager.PERMISSION_GRANTED;
                 }
             }
+
+            try {
+                if (ContentUris.parseId(uri) != -1) {
+                    return PackageManager.PERMISSION_DENIED;
+                }
+            } catch (NumberFormatException ignored) { }
+
+            // If the uri is a valid content uri and doesn't have a valid ID at the end of the uri,
+            // (i.e., uri is uri of the table not of the item/row), and app doesn't request prefix
+            // grant, we are willing to grant this uri permission since this doesn't grant them any
+            // extra access. This grant will only grant permissions on given uri, it will not grant
+            // access to db rows of the corresponding table.
+            if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) == 0) {
+                return PackageManager.PERMISSION_GRANTED;
+            }
+
+            // For prefix grant on the uri with content uri without id, we don't allow apps to
+            // grant access as they might end up granting access to all files.
         } finally {
             restoreLocalCallingIdentity(token);
         }
@@ -2572,17 +2607,17 @@
                         defaultMimeType = "audio/mpegurl";
                         defaultMediaType = FileColumns.MEDIA_TYPE_PLAYLIST;
                         defaultPrimary = Environment.DIRECTORY_MUSIC;
-                        allowedPrimary = Arrays.asList(
-                                Environment.DIRECTORY_MUSIC,
-                                Environment.DIRECTORY_MOVIES);
+                        allowedPrimary = new ArrayList<>(allowedPrimary);
+                        allowedPrimary.add(Environment.DIRECTORY_MUSIC);
+                        allowedPrimary.add(Environment.DIRECTORY_MOVIES);
                         break;
                     case FileColumns.MEDIA_TYPE_SUBTITLE:
                         defaultMimeType = "application/x-subrip";
                         defaultMediaType = FileColumns.MEDIA_TYPE_SUBTITLE;
                         defaultPrimary = Environment.DIRECTORY_MOVIES;
-                        allowedPrimary = Arrays.asList(
-                                Environment.DIRECTORY_MUSIC,
-                                Environment.DIRECTORY_MOVIES);
+                        allowedPrimary = new ArrayList<>(allowedPrimary);
+                        allowedPrimary.add(Environment.DIRECTORY_MUSIC);
+                        allowedPrimary.add(Environment.DIRECTORY_MOVIES);
                         break;
                 }
             } else if (defaultMediaType != actualMediaType) {
@@ -3078,7 +3113,11 @@
             if (isCallingPackageSelf() && values.containsKey(FileColumns.MEDIA_TYPE)) {
                 // Leave FileColumns.MEDIA_TYPE untouched if the caller is ModernMediaScanner and
                 // FileColumns.MEDIA_TYPE is already populated.
-            } else if (path != null && shouldFileBeHidden(new File(path))) {
+            } else if (isFuseThread() && path != null && shouldFileBeHidden(new File(path))) {
+                // We should only mark MEDIA_TYPE as MEDIA_TYPE_NONE for Fuse Thread.
+                // MediaProvider#insert() returns the uri by appending the "rowId" to the given
+                // uri, hence to ensure the correct working of the returned uri, we shouldn't
+                // change the MEDIA_TYPE in insert operation and let scan change it for us.
                 values.put(FileColumns.MEDIA_TYPE, FileColumns.MEDIA_TYPE_NONE);
             } else {
                 values.put(FileColumns.MEDIA_TYPE, MimeUtils.resolveMediaType(mimeType));
@@ -3367,6 +3406,9 @@
 
                 if (isCallingPackageSelf() || isCallingPackageLegacyWrite()) {
                     // Mutation allowed
+                } else if (isCallingPackageManager()) {
+                    // Apps with MANAGE_EXTERNAL_STORAGE have all files access, hence they are
+                    // allowed to insert files anywhere.
                 } else {
                     Log.w(TAG, "Ignoring mutation of  " + column + " from "
                             + getCallingPackageOrSelf());
@@ -3387,6 +3429,15 @@
             if (initialValues.containsKey(ImageColumns.LONGITUDE)) {
                 initialValues.putNull(ImageColumns.LONGITUDE);
             }
+            if (getCallingPackageTargetSdkVersion() <= Build.VERSION_CODES.Q) {
+                // These columns are removed in R.
+                if (initialValues.containsKey("primary_directory")) {
+                    initialValues.remove("primary_directory");
+                }
+                if (initialValues.containsKey("secondary_directory")) {
+                    initialValues.remove("secondary_directory");
+                }
+            }
 
             if (isCallingPackageSelf() || isCallingPackageShell()) {
                 // When media inserted by ourselves during a scan, or by the
@@ -4009,7 +4060,7 @@
             case AUDIO_ARTISTS_ID_ALBUMS: {
                 if (type == TYPE_QUERY) {
                     qb.setTables("audio_albums");
-                    qb.setProjectionMap(getProjectionMap(Audio.Artists.Albums.class));
+                    qb.setProjectionMap(getProjectionMap(Audio.Albums.class));
 
                     final String artistId = uri.getPathSegments().get(3);
                     appendWhereStandalone(qb, "artist_id=?", artistId);
@@ -5208,6 +5259,15 @@
             if (initialValues.containsKey(ImageColumns.LONGITUDE)) {
                 initialValues.putNull(ImageColumns.LONGITUDE);
             }
+            if (getCallingPackageTargetSdkVersion() <= Build.VERSION_CODES.Q) {
+                // These columns are removed in R.
+                if (initialValues.containsKey("primary_directory")) {
+                    initialValues.remove("primary_directory");
+                }
+                if (initialValues.containsKey("secondary_directory")) {
+                    initialValues.remove("secondary_directory");
+                }
+            }
         }
 
         // If we're not updating anything, then we can skip
@@ -6085,6 +6145,8 @@
             // the remote writer tried claiming an exception
             invalidateThumbnails(uri);
 
+            // Invalidate so subsequent stat(2) on the upper fs is eventually consistent
+            invalidateFuseDentry(file);
             try {
                 switch (match) {
                     case IMAGES_THUMBNAILS_ID:
@@ -6318,6 +6380,24 @@
         return !isCallingIdentitySharedPackageName(appSpecificDir);
     }
 
+    private boolean shouldBypassDatabaseForFuse(int uid) {
+        final LocalCallingIdentity token =
+                clearLocalCallingIdentity(getCachedCallingIdentityForFuse(uid));
+        try {
+            if (uid != android.os.Process.SHELL_UID && isCallingPackageManager()) {
+                return true;
+            }
+            // We bypass db operations for legacy system galleries with W_E_S (see b/167307393).
+            // Tracking a longer term solution in b/168784136.
+            if (isCallingPackageLegacyWrite() && isCallingPackageSystemGallery()) {
+                return true;
+            }
+            return false;
+        } finally {
+            restoreLocalCallingIdentity(token);
+        }
+    }
+
     /**
      * Set of Exif tags that should be considered for redaction.
      */
@@ -6746,6 +6826,10 @@
                 return OsConstants.EPERM;
             }
 
+            if (shouldBypassDatabaseForFuse(uid)) {
+                return 0;
+            }
+
             final String mimeType = MimeUtils.resolveMimeType(new File(path));
 
             if (shouldBypassFuseRestrictions(/*forWrite*/ true, path)) {
@@ -6854,6 +6938,10 @@
                 return OsConstants.ENOENT;
             }
 
+            if (shouldBypassDatabaseForFuse(uid)) {
+                return deleteFileUnchecked(path);
+            }
+
             final boolean shouldBypass = shouldBypassFuseRestrictions(/*forWrite*/ true, path);
 
             // Legacy apps that made is this far don't have the right storage permission and hence
@@ -6929,7 +7017,7 @@
             if (isTopLevelDir) {
                 // We allow creating the default top level directories only, all other operations on
                 // top level directories are not allowed.
-                if (forCreate && isDefaultDirectoryName(extractDisplayName(path))) {
+                if (forCreate && FileUtils.isDefaultDirectoryName(extractDisplayName(path))) {
                     return 0;
                 }
                 Log.e(TAG,
@@ -6994,7 +7082,7 @@
                 final boolean isTopLevelDir =
                         relativePath.length == 1 && TextUtils.isEmpty(relativePath[0]);
                 if (isTopLevelDir) {
-                    if (isDefaultDirectoryName(extractDisplayName(path))) {
+                    if (FileUtils.isDefaultDirectoryName(extractDisplayName(path))) {
                         return 0;
                     } else {
                         Log.e(TAG,
@@ -7837,6 +7925,10 @@
         return builder.build();
     }
 
+    private boolean isCallingPackageSystemGallery() {
+        return mCallingIdentity.get().hasPermission(PERMISSION_IS_SYSTEM_GALLERY);
+    }
+
     private int getCallingUidOrSelf() {
         return mCallingIdentity.get().uid;
     }
diff --git a/src/com/android/providers/media/MediaUpgradeReceiver.java b/src/com/android/providers/media/MediaUpgradeReceiver.java
index b9fba09..5864b78 100644
--- a/src/com/android/providers/media/MediaUpgradeReceiver.java
+++ b/src/com/android/providers/media/MediaUpgradeReceiver.java
@@ -67,8 +67,8 @@
                     try {
                         DatabaseHelper helper = new DatabaseHelper(
                                 context, file, MediaProvider.isInternalMediaDatabaseName(file),
-                                false, false, Column.class, Metrics::logSchemaChange, null, null,
-                                null);
+                                false, false, Column.class, Metrics::logSchemaChange, null,
+                                MediaProvider.MIGRATION_LISTENER, null);
                         helper.runWithTransaction((db) -> {
                             // Perform just enough to force database upgrade
                             return db.getVersion();
diff --git a/src/com/android/providers/media/PermissionActivity.java b/src/com/android/providers/media/PermissionActivity.java
index 1b2d0ad..6a3cced 100644
--- a/src/com/android/providers/media/PermissionActivity.java
+++ b/src/com/android/providers/media/PermissionActivity.java
@@ -41,6 +41,8 @@
 import android.graphics.ImageDecoder;
 import android.graphics.ImageDecoder.ImageInfo;
 import android.graphics.ImageDecoder.Source;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Icon;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
@@ -68,9 +70,11 @@
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.List;
 import java.util.Objects;
 import java.util.function.Predicate;
+import java.util.function.ToIntFunction;
 import java.util.stream.Collectors;
 
 /**
@@ -114,6 +118,12 @@
     private static final String DATA_IMAGE = "image";
     private static final String DATA_GENERIC = "generic";
 
+    // Use to sort the thumbnails.
+    private static final int ORDER_IMAGE = 1;
+    private static final int ORDER_VIDEO = 2;
+    private static final int ORDER_AUDIO = 3;
+    private static final int ORDER_GENERIC = 4;
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -497,6 +507,25 @@
                 }
             }
 
+            // Sort the uris in DATA_GENERIC case (Image, Video, Audio, Others)
+            if (TextUtils.equals(data, DATA_GENERIC) && uris.size() > 1) {
+                final ToIntFunction<Uri> score = (uri) -> {
+                    final LocalUriMatcher matcher = new LocalUriMatcher(MediaStore.AUTHORITY);
+                    final int match = matcher.matchUri(uri, false);
+
+                    switch (match) {
+                        case AUDIO_MEDIA_ID: return ORDER_AUDIO;
+                        case VIDEO_MEDIA_ID: return ORDER_VIDEO;
+                        case IMAGES_MEDIA_ID: return ORDER_IMAGE;
+                        default: return ORDER_GENERIC;
+                    }
+                };
+                final Comparator<Uri> bestScore = (a, b) ->
+                        score.applyAsInt(a) - score.applyAsInt(b);
+
+                uris.sort(bestScore);
+            }
+
             for (Uri uri : uris) {
                 try {
                     final Description desc = new Description(bodyView.getContext(), uri, loadFlags);
@@ -539,15 +568,23 @@
         }
 
         /**
-         * Bind dialog as a single full-bleed image.
+         * Bind dialog as a single full-bleed image. If there is no image, use
+         * the icon of Mime type instead.
          */
         private void bindAsFull(@NonNull Description result) {
             final ImageView thumbFull = bodyView.requireViewById(R.id.thumb_full);
-            result.bindFull(thumbFull);
+            if (result.full != null) {
+                result.bindFull(thumbFull);
+            } else {
+                thumbFull.setScaleType(ImageView.ScaleType.FIT_CENTER);
+                thumbFull.setBackground(new ColorDrawable(getColor(R.color.thumb_gray_color)));
+                result.bindMimeIcon(thumbFull);
+            }
         }
 
         /**
-         * Bind dialog as a list of multiple thumbnails.
+         * Bind dialog as a list of multiple thumbnails. If there is no thumbnail for some
+         * items, use the icons of the MIME type instead.
          */
         private void bindAsThumbs(@NonNull List<Description> results,
                 @NonNull List<Description> visualResults) {
@@ -564,6 +601,7 @@
                 final View thumbMoreContainer = bodyView.requireViewById(R.id.thumb_more_container);
                 final ImageView thumbMore = bodyView.requireViewById(R.id.thumb_more);
                 final TextView thumbMoreText = bodyView.requireViewById(R.id.thumb_more_text);
+                final View gradientView = bodyView.requireViewById(R.id.thumb_more_gradient);
 
                 // Since we only want three tiles displayed maximum, swap out
                 // the first tile for our "more" tile
@@ -577,6 +615,7 @@
 
                 thumbMoreText.setText(moreText);
                 thumbMoreContainer.setVisibility(View.VISIBLE);
+                gradientView.setVisibility(View.VISIBLE);
             }
 
             // Trim off extra thumbnails from the front of our list, so that we
@@ -589,7 +628,11 @@
             for (int i = 0; i < thumbs.size(); i++) {
                 final Description desc = visualResults.get(i);
                 final ImageView imageView = thumbs.get(i);
-                desc.bindThumbnail(imageView);
+                if (desc.thumbnail != null) {
+                    desc.bindThumbnail(imageView);
+                } else {
+                    desc.bindMimeIcon(imageView);
+                }
             }
         }
 
@@ -624,6 +667,7 @@
         public @Nullable CharSequence contentDescription;
         public @Nullable Bitmap thumbnail;
         public @Nullable Bitmap full;
+        public @Nullable Icon mimeIcon;
 
         public static final int LOAD_CONTENT_DESCRIPTION = 1 << 0;
         public static final int LOAD_THUMBNAIL = 1 << 1;
@@ -662,11 +706,15 @@
                 }
             } catch (IOException e) {
                 Log.w(TAG, e);
+                if (thumbnail == null && full == null) {
+                    final String mimeType = resolver.getType(uri);
+                    mimeIcon = resolver.getTypeInfo(mimeType).getIcon();
+                }
             }
         }
 
         public boolean isVisual() {
-            return thumbnail != null || full != null;
+            return thumbnail != null || full != null || mimeIcon != null;
         }
 
         public void bindThumbnail(ImageView imageView) {
@@ -683,6 +731,14 @@
             imageView.setContentDescription(contentDescription);
             imageView.setVisibility(View.VISIBLE);
         }
+
+        public void bindMimeIcon(ImageView imageView) {
+            Objects.requireNonNull(mimeIcon);
+            imageView.setImageIcon(mimeIcon);
+            imageView.setContentDescription(contentDescription);
+            imageView.setVisibility(View.VISIBLE);
+            imageView.setClipToOutline(true);
+        }
     }
 
     /**
diff --git a/src/com/android/providers/media/scan/ModernMediaScanner.java b/src/com/android/providers/media/scan/ModernMediaScanner.java
index 58e63cd..9658827 100644
--- a/src/com/android/providers/media/scan/ModernMediaScanner.java
+++ b/src/com/android/providers/media/scan/ModernMediaScanner.java
@@ -402,7 +402,7 @@
                     new String[] {pathEscapedForLike + "/%", pathEscapedForLike});
             queryArgs.putString(ContentResolver.QUERY_ARG_SQL_SORT_ORDER,
                     FileColumns._ID + " DESC");
-            queryArgs.putInt(MediaStore.QUERY_ARG_MATCH_PENDING, MediaStore.MATCH_INCLUDE);
+            queryArgs.putInt(MediaStore.QUERY_ARG_MATCH_PENDING, MediaStore.MATCH_EXCLUDE);
             queryArgs.putInt(MediaStore.QUERY_ARG_MATCH_TRASHED, MediaStore.MATCH_INCLUDE);
             queryArgs.putInt(MediaStore.QUERY_ARG_MATCH_FAVORITE, MediaStore.MATCH_INCLUDE);
 
diff --git a/src/com/android/providers/media/util/FileUtils.java b/src/com/android/providers/media/util/FileUtils.java
index 6a0496e..7bd1e4e 100644
--- a/src/com/android/providers/media/util/FileUtils.java
+++ b/src/com/android/providers/media/util/FileUtils.java
@@ -914,6 +914,21 @@
     private static final Pattern PATTERN_OBB_OR_CHILD_RELATIVE_PATH = Pattern.compile(
             "(?i)^Android/obb(?:/.*)?$");
 
+    @VisibleForTesting
+    public static final String[] DEFAULT_FOLDER_NAMES = {
+            Environment.DIRECTORY_MUSIC,
+            Environment.DIRECTORY_PODCASTS,
+            Environment.DIRECTORY_RINGTONES,
+            Environment.DIRECTORY_ALARMS,
+            Environment.DIRECTORY_NOTIFICATIONS,
+            Environment.DIRECTORY_PICTURES,
+            Environment.DIRECTORY_MOVIES,
+            Environment.DIRECTORY_DOWNLOADS,
+            Environment.DIRECTORY_DCIM,
+            Environment.DIRECTORY_DOCUMENTS,
+            Environment.DIRECTORY_AUDIOBOOKS,
+    };
+
     /**
      * Regex that matches paths for {@link MediaColumns#RELATIVE_PATH}; it
      * captures both top-level paths and sandboxed paths.
@@ -927,6 +942,9 @@
     private static final Pattern PATTERN_VOLUME_NAME = Pattern.compile(
             "(?i)^/storage/([^/]+)");
 
+    private static final String CAMERA_RELATIVE_PATH =
+            String.format("%s/%s/", Environment.DIRECTORY_DCIM, "Camera");
+
     private static @Nullable String normalizeUuid(@Nullable String fsUuid) {
         return fsUuid != null ? fsUuid.toLowerCase(Locale.ROOT) : null;
     }
@@ -1066,6 +1084,15 @@
         return relativePathSegments.length > 0 ? relativePathSegments[0] : null;
     }
 
+    public static boolean isDefaultDirectoryName(@Nullable String dirName) {
+        for (String defaultDirName : DEFAULT_FOLDER_NAMES) {
+            if (defaultDirName.equalsIgnoreCase(dirName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * Compute the value of {@link MediaColumns#DATE_EXPIRES} based on other
      * columns being modified by this operation.
@@ -1272,12 +1299,32 @@
         }
 
         final File nomedia = new File(dir, ".nomedia");
+
         // check for .nomedia presence
-        if (nomedia.exists()) {
-            Logging.logPersistent("Observed non-standard " + nomedia);
-            return true;
+        if (!nomedia.exists()) {
+            return false;
         }
-        return false;
+
+        // Handle top-level default directories. These directories should always be visible,
+        // regardless of .nomedia presence.
+        final String[] relativePath = sanitizePath(extractRelativePath(dir.getAbsolutePath()));
+        final boolean isTopLevelDir =
+                relativePath.length == 1 && TextUtils.isEmpty(relativePath[0]);
+        if (isTopLevelDir && isDefaultDirectoryName(name)) {
+            nomedia.delete();
+            return false;
+        }
+
+        // DCIM/Camera should always be visible regardless of .nomedia presence.
+        if (CAMERA_RELATIVE_PATH.equalsIgnoreCase(
+                extractRelativePathWithDisplayName(dir.getAbsolutePath()))) {
+            nomedia.delete();
+            return false;
+        }
+
+        // .nomedia is present which makes this directory as hidden directory
+        Logging.logPersistent("Observed non-standard " + nomedia);
+        return true;
     }
 
     /**
diff --git a/src/com/android/providers/media/util/PermissionUtils.java b/src/com/android/providers/media/util/PermissionUtils.java
index 4c27624..6b93b48 100644
--- a/src/com/android/providers/media/util/PermissionUtils.java
+++ b/src/com/android/providers/media/util/PermissionUtils.java
@@ -189,6 +189,20 @@
     }
 
     /**
+     * Returns {@code true} if the given package has write images or write video app op, which
+     * indicates the package is a system gallery.
+     */
+    public static boolean checkWriteImagesOrVideoAppOps(@NonNull Context context, int uid,
+            @NonNull String packageName, @Nullable String attributionTag) {
+        return checkAppOp(
+                context, OPSTR_WRITE_MEDIA_IMAGES, uid, packageName, attributionTag,
+                generateAppOpMessage(packageName, sOpDescription.get()))
+                || checkAppOp(
+                        context, OPSTR_WRITE_MEDIA_VIDEO, uid, packageName, attributionTag,
+                generateAppOpMessage(packageName, sOpDescription.get()));
+    }
+
+    /**
      * Returns {@code true} if any package for the given uid has request_install_packages app op.
      */
     public static boolean checkAppOpRequestInstallPackagesForSharedUid(@NonNull Context context,
@@ -202,26 +216,6 @@
         return false;
     }
 
-    /**
-     * Checks *only* App Ops.
-     */
-    private static boolean checkAppOp(@NonNull Context context,
-            @NonNull String op, int uid, @NonNull String packageName,
-            @Nullable String attributionTag, @Nullable String opMessage) {
-        final AppOpsManager appOps = context.getSystemService(AppOpsManager.class);
-        final int mode = appOps.noteOpNoThrow(op, uid, packageName, attributionTag, opMessage);
-        switch (mode) {
-            case AppOpsManager.MODE_ALLOWED:
-                return true;
-            case AppOpsManager.MODE_DEFAULT:
-            case AppOpsManager.MODE_IGNORED:
-            case AppOpsManager.MODE_ERRORED:
-                return false;
-            default:
-                throw new IllegalStateException(op + " has unknown mode " + mode);
-        }
-    }
-
     public static boolean checkPermissionInstallPackages(@NonNull Context context, int pid, int uid,
             @NonNull String packageName, @Nullable String attributionTag) {
         return checkPermissionForDataDelivery(context, INSTALL_PACKAGES, pid,
@@ -272,6 +266,27 @@
     }
 
     /**
+     * Checks *only* App Ops.
+     */
+    private static boolean checkAppOp(@NonNull Context context,
+            @NonNull String op, int uid, @NonNull String packageName,
+            @Nullable String attributionTag, @Nullable String opMessage) {
+        final AppOpsManager appOps = context.getSystemService(AppOpsManager.class);
+        final int mode = appOps.noteOpNoThrow(op, uid, packageName, attributionTag, opMessage);
+        switch (mode) {
+            case AppOpsManager.MODE_ALLOWED:
+                return true;
+            case AppOpsManager.MODE_DEFAULT:
+            case AppOpsManager.MODE_IGNORED:
+            case AppOpsManager.MODE_ERRORED:
+                return false;
+            default:
+                throw new IllegalStateException(op + " has unknown mode " + mode);
+        }
+    }
+
+
+    /**
      * Checks *only* App Ops, also returns true for legacy apps.
      */
     private static boolean checkAppOpAllowingLegacy(@NonNull Context context,
diff --git a/src/com/android/providers/media/util/SQLiteQueryBuilder.java b/src/com/android/providers/media/util/SQLiteQueryBuilder.java
index e95d28c..e68cb80 100644
--- a/src/com/android/providers/media/util/SQLiteQueryBuilder.java
+++ b/src/com/android/providers/media/util/SQLiteQueryBuilder.java
@@ -75,6 +75,7 @@
                     + "mov|asf|avi|divx|mpg|mpeg|mkv|webm|mk3d|mks|3gp|mpegts|ts|m2ts|m2t)");
     private static final Pattern sPattern156832140 = Pattern.compile(
             "(?i)%com\\.gopro\\.smarty%");
+    private static final Pattern sPattern158537159 = Pattern.compile("(?i)localized");
 
     private static final Pattern sCustomCollatorPattern = Pattern.compile(
             "(?i)custom_[a-zA-Z]+");
@@ -817,6 +818,7 @@
             // proper SQL string substitution
             if (sPattern154193772.matcher(token).matches()) return;
             if (sPattern156832140.matcher(token).matches()) return;
+            if (sPattern158537159.matcher(token).matches()) return;
         }
 
         throw new IllegalArgumentException("Invalid token " + token);
diff --git a/tests/client/src/com/android/providers/media/client/LegacyProviderMigrationTest.java b/tests/client/src/com/android/providers/media/client/LegacyProviderMigrationTest.java
index 0c1fc65..1a94ef1 100644
--- a/tests/client/src/com/android/providers/media/client/LegacyProviderMigrationTest.java
+++ b/tests/client/src/com/android/providers/media/client/LegacyProviderMigrationTest.java
@@ -49,6 +49,7 @@
 import android.webkit.MimeTypeMap;
 
 import androidx.annotation.NonNull;
+import androidx.test.filters.FlakyTest;
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -78,6 +79,7 @@
  * {@link MediaColumns#IS_FAVORITE} should be retained.
  */
 @RunWith(AndroidJUnit4.class)
+@FlakyTest(bugId = 176977253)
 public class LegacyProviderMigrationTest {
     private static final String TAG = "LegacyTest";
 
diff --git a/tests/client/src/com/android/providers/media/client/PerformanceTest.java b/tests/client/src/com/android/providers/media/client/PerformanceTest.java
index 1e1abe7..eff8e67 100644
--- a/tests/client/src/com/android/providers/media/client/PerformanceTest.java
+++ b/tests/client/src/com/android/providers/media/client/PerformanceTest.java
@@ -39,7 +39,6 @@
 import org.junit.runner.RunWith;
 
 import java.io.File;
-import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
@@ -367,6 +366,7 @@
     public static class CountingContentObserver extends ContentObserver {
         private final int uriCount;
         private final int flags;
+        private int accumulatedCount = 0;
 
         private final CountDownLatch latch = new CountDownLatch(1);
 
@@ -381,8 +381,19 @@
             Log.v(TAG, String.format("onChange(%b, %s, %d)",
                     selfChange, asSet(uris).toString(), flags));
 
-            if ((asSet(uris).size() == this.uriCount) && (flags == this.flags)) {
-                latch.countDown();
+            if (this.uriCount == 1) {
+                if (asSet(uris).size() == 1 && flags == this.flags) {
+                    latch.countDown();
+                }
+            } else if (flags == this.flags) {
+                // NotifyChange for bulk operations will be sent in batches.
+                final int receivedCount = asSet(uris).size();
+
+                if (receivedCount + accumulatedCount == this.uriCount) {
+                    latch.countDown();
+                } else {
+                    accumulatedCount += receivedCount;
+                }
             }
         }
 
diff --git a/tests/src/com/android/providers/media/DatabaseHelperTest.java b/tests/src/com/android/providers/media/DatabaseHelperTest.java
index d57ffe9..b2b7825 100644
--- a/tests/src/com/android/providers/media/DatabaseHelperTest.java
+++ b/tests/src/com/android/providers/media/DatabaseHelperTest.java
@@ -20,6 +20,8 @@
 
 import static com.android.providers.media.DatabaseHelper.makePristineSchema;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
@@ -42,11 +44,12 @@
 
 import com.android.providers.media.scan.MediaScannerTest.IsolatedContext;
 
+import com.google.common.collect.ImmutableSet;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.util.Arrays;
 import java.util.Set;
 
 @RunWith(AndroidJUnit4.class)
@@ -83,6 +86,7 @@
                 values.put(AudioColumns.ALBUM, "A Rush of Blood");
                 values.put(AudioColumns.ARTIST, "Coldplay");
                 values.put(AudioColumns.GENRE, "Rock");
+                values.put(AudioColumns.IS_MUSIC, true);
                 MediaProvider.computeAudioKeyValues(values);
                 db.insert("files", FileColumns.DATA, values);
             }
@@ -95,6 +99,7 @@
                 values.put(AudioColumns.ALBUM, "X&Y");
                 values.put(AudioColumns.ARTIST, "Coldplay");
                 values.put(AudioColumns.GENRE, "Alternative rock");
+                values.put(AudioColumns.IS_MUSIC, true);
                 MediaProvider.computeAudioKeyValues(values);
                 db.insert("files", FileColumns.DATA, values);
             }
@@ -107,48 +112,108 @@
                 values.put(AudioColumns.ALBUM, "All That You Can't Leave Behind");
                 values.put(AudioColumns.ARTIST, "U2");
                 values.put(AudioColumns.GENRE, "Rock");
+                values.put(AudioColumns.IS_MUSIC, true);
                 MediaProvider.computeAudioKeyValues(values);
                 db.insert("files", FileColumns.DATA, values);
             }
 
             // Confirm that raw view knows everything
-            assertEquals(asSet("Clocks", "Speed of Sound", "Beautiful Day"),
-                    queryValues(helper, "audio", "title"));
+            assertThat(queryValues(helper, "audio", "title"))
+                    .containsExactly("Clocks", "Speed of Sound", "Beautiful Day");
 
             // By default, database only knows about primary storage
-            assertEquals(asSet("Coldplay"),
-                    queryValues(helper, "audio_artists", "artist"));
-            assertEquals(asSet("A Rush of Blood"),
-                    queryValues(helper, "audio_albums", "album"));
-            assertEquals(asSet("Rock"),
-                    queryValues(helper, "audio_genres", "name"));
+            assertThat(queryValues(helper, "audio_artists", "artist"))
+                    .containsExactly("Coldplay");
+            assertThat(queryValues(helper, "audio_albums", "album"))
+                    .containsExactly("A Rush of Blood");
+            assertThat(queryValues(helper, "audio_genres", "name"))
+                    .containsExactly("Rock");
 
             // Once we broaden mounted volumes, we know a lot more
-            helper.setFilterVolumeNames(asSet(VOLUME_EXTERNAL_PRIMARY, "0000-0000"));
-            assertEquals(asSet("Coldplay", "U2"),
-                    queryValues(helper, "audio_artists", "artist"));
-            assertEquals(asSet("A Rush of Blood", "X&Y", "All That You Can't Leave Behind"),
-                    queryValues(helper, "audio_albums", "album"));
-            assertEquals(asSet("Rock", "Alternative rock"),
-                    queryValues(helper, "audio_genres", "name"));
+            helper.setFilterVolumeNames(ImmutableSet.of(VOLUME_EXTERNAL_PRIMARY, "0000-0000"));
+            assertThat(queryValues(helper, "audio_artists", "artist"))
+                    .containsExactly("Coldplay", "U2");
+            assertThat(queryValues(helper, "audio_albums", "album"))
+                    .containsExactly("A Rush of Blood", "X&Y", "All That You Can't Leave Behind");
+            assertThat(queryValues(helper, "audio_genres", "name"))
+                    .containsExactly("Rock", "Alternative rock");
 
             // And unmounting primary narrows us the other way
-            helper.setFilterVolumeNames(asSet("0000-0000"));
-            assertEquals(asSet("Coldplay", "U2"),
-                    queryValues(helper, "audio_artists", "artist"));
-            assertEquals(asSet("X&Y", "All That You Can't Leave Behind"),
-                    queryValues(helper, "audio_albums", "album"));
-            assertEquals(asSet("Rock", "Alternative rock"),
-                    queryValues(helper, "audio_genres", "name"));
+            helper.setFilterVolumeNames(ImmutableSet.of("0000-0000"));
+            assertThat(queryValues(helper, "audio_artists", "artist"))
+                    .containsExactly("Coldplay", "U2");
+            assertThat(queryValues(helper, "audio_albums", "album"))
+                    .containsExactly("X&Y", "All That You Can't Leave Behind");
+            assertThat(queryValues(helper, "audio_genres", "name"))
+                    .containsExactly("Rock", "Alternative rock");
 
             // Finally fully unmounted means nothing
-            helper.setFilterVolumeNames(asSet());
-            assertEquals(asSet(),
-                    queryValues(helper, "audio_artists", "artist"));
-            assertEquals(asSet(),
-                    queryValues(helper, "audio_albums", "album"));
-            assertEquals(asSet(),
-                    queryValues(helper, "audio_genres", "name"));
+            helper.setFilterVolumeNames(ImmutableSet.of());
+            assertThat(queryValues(helper, "audio_artists", "artist")).isEmpty();
+            assertThat(queryValues(helper, "audio_albums", "album")).isEmpty();
+            assertThat(queryValues(helper, "audio_genres", "name")).isEmpty();
+        }
+    }
+
+    @Test
+    public void testArtistsAndAlbumsIncludeOnlyMusic() throws Exception {
+        try (DatabaseHelper helper = new DatabaseHelperR(sIsolatedContext, TEST_CLEAN_DB)) {
+            SQLiteDatabase db = helper.getWritableDatabaseForTest();
+            {
+                final ContentValues values = new ContentValues();
+                values.put(FileColumns.MEDIA_TYPE, FileColumns.MEDIA_TYPE_AUDIO);
+                values.put(FileColumns.VOLUME_NAME, VOLUME_EXTERNAL_PRIMARY);
+                values.put(FileColumns.DATA, "/storage/emulated/0/Coldplay-Clocks.mp3");
+                values.put(AudioColumns.TITLE, "Clocks");
+                values.put(AudioColumns.ALBUM, "A Rush of Blood");
+                values.put(AudioColumns.ARTIST, "Coldplay");
+                values.put(AudioColumns.GENRE, "Rock");
+                values.put(AudioColumns.IS_MUSIC, true);
+                MediaProvider.computeAudioKeyValues(values);
+                db.insert("files", FileColumns.DATA, values);
+            }
+            {
+                final ContentValues values = new ContentValues();
+                values.put(FileColumns.MEDIA_TYPE, FileColumns.MEDIA_TYPE_AUDIO);
+                values.put(FileColumns.VOLUME_NAME, VOLUME_EXTERNAL_PRIMARY);
+                values.put(FileColumns.DATA, "/storage/emulated/0/My-podcast.mp3");
+                values.put(AudioColumns.TITLE, "My podcast title with false is_music");
+                values.put(AudioColumns.ALBUM, "My podcast album");
+                values.put(AudioColumns.ARTIST, "My podcast artist");
+                values.put(AudioColumns.GENRE, "Podcast");
+                values.put(AudioColumns.IS_MUSIC, false);
+                MediaProvider.computeAudioKeyValues(values);
+                db.insert("files", FileColumns.DATA, values);
+            }
+            {
+                final ContentValues values = new ContentValues();
+                values.put(FileColumns.MEDIA_TYPE, FileColumns.MEDIA_TYPE_AUDIO);
+                values.put(FileColumns.VOLUME_NAME, VOLUME_EXTERNAL_PRIMARY);
+                values.put(FileColumns.DATA, "/storage/emulated/0/My-podcast-2.mp3");
+                values.put(AudioColumns.TITLE, "My podcast title with not set is_music");
+                values.put(AudioColumns.ALBUM, "My podcast album");
+                values.put(AudioColumns.ARTIST, "My podcast artist");
+                values.put(AudioColumns.GENRE, "Podcast 2");
+                MediaProvider.computeAudioKeyValues(values);
+                db.insert("files", FileColumns.DATA, values);
+            }
+
+            // Raw view shows everything.
+            assertThat(queryValues(helper, "audio", "title"))
+                    .containsExactly(
+                            "Clocks",
+                            "My podcast title with false is_music",
+                            "My podcast title with not set is_music");
+
+            // Artists and albums show only music files.
+            assertThat(queryValues(helper, "audio_artists", "artist"))
+                    .containsExactly("Coldplay");
+            assertThat(queryValues(helper, "audio_albums", "album"))
+                    .containsExactly("A Rush of Blood");
+
+            // Genres should show all genres.
+            assertThat(queryValues(helper, "audio_genres", "name"))
+                    .containsExactly("Rock", "Podcast", "Podcast 2");
         }
     }
 
@@ -406,10 +471,6 @@
         return sql != null ? sql.replace(", ", ",") : null;
     }
 
-    private static Set<String> asSet(String... vars) {
-        return new ArraySet<>(Arrays.asList(vars));
-    }
-
     private static Set<String> queryValues(@NonNull DatabaseHelper helper, @NonNull String table,
             @NonNull String columnName) {
         try (Cursor c = helper.getWritableDatabaseForTest().query(table,
@@ -461,7 +522,8 @@
     private static class DatabaseHelperR extends DatabaseHelper {
         public DatabaseHelperR(Context context, String name) {
             super(context, name, DatabaseHelper.VERSION_R,
-                    false, false, false, Column.class, null, null, null, null);
+                    false, false, false, Column.class, null, null,
+                    MediaProvider.MIGRATION_LISTENER, null);
         }
     }
 
diff --git a/tests/src/com/android/providers/media/MediaProviderTest.java b/tests/src/com/android/providers/media/MediaProviderTest.java
index 0749e02..83b722e 100644
--- a/tests/src/com/android/providers/media/MediaProviderTest.java
+++ b/tests/src/com/android/providers/media/MediaProviderTest.java
@@ -26,6 +26,7 @@
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
@@ -47,11 +48,12 @@
 import android.os.CancellationSignal;
 import android.os.Environment;
 import android.provider.MediaStore;
+import android.provider.MediaStore.Audio.AudioColumns;
+import android.provider.MediaStore.Files.FileColumns;
 import android.provider.MediaStore.Images.ImageColumns;
 import android.provider.MediaStore.MediaColumns;
 import android.util.ArrayMap;
 import android.util.Log;
-import android.util.Pair;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
@@ -1025,6 +1027,124 @@
         }
     }
 
+    @Test
+    public void testComputeAudioKeyValues_167339595_differentAlbumIds() throws Exception {
+        // same album name, different album artists
+        final ContentValues valuesOne = new ContentValues();
+        valuesOne.put(FileColumns.MEDIA_TYPE, FileColumns.MEDIA_TYPE_AUDIO);
+        valuesOne.put(FileColumns.VOLUME_NAME, MediaStore.VOLUME_EXTERNAL_PRIMARY);
+        valuesOne.put(FileColumns.DATA, "/storage/emulated/0/Clocks.mp3");
+        valuesOne.put(AudioColumns.TITLE, "Clocks");
+        valuesOne.put(AudioColumns.ALBUM, "A Rush of Blood");
+        valuesOne.put(AudioColumns.ALBUM_ARTIST, "Coldplay");
+        valuesOne.put(AudioColumns.GENRE, "Rock");
+        valuesOne.put(AudioColumns.IS_MUSIC, true);
+
+        final ContentValues valuesTwo = new ContentValues();
+        valuesTwo.put(FileColumns.MEDIA_TYPE, FileColumns.MEDIA_TYPE_AUDIO);
+        valuesTwo.put(FileColumns.VOLUME_NAME, MediaStore.VOLUME_EXTERNAL_PRIMARY);
+        valuesTwo.put(FileColumns.DATA, "/storage/emulated/0/Sounds.mp3");
+        valuesTwo.put(AudioColumns.TITLE, "Sounds");
+        valuesTwo.put(AudioColumns.ALBUM, "A Rush of Blood");
+        valuesTwo.put(AudioColumns.ALBUM_ARTIST, "ColdplayTwo");
+        valuesTwo.put(AudioColumns.GENRE, "Alternative rock");
+        valuesTwo.put(AudioColumns.IS_MUSIC, true);
+
+        MediaProvider.computeAudioKeyValues(valuesOne);
+        final long albumIdOne = valuesOne.getAsLong(AudioColumns.ALBUM_ID);
+        MediaProvider.computeAudioKeyValues(valuesTwo);
+        final long albumIdTwo = valuesTwo.getAsLong(AudioColumns.ALBUM_ID);
+
+        assertNotEquals(albumIdOne, albumIdTwo);
+
+        // same album name, different paths, no album artists
+        final ContentValues valuesThree = new ContentValues();
+        valuesThree.put(FileColumns.MEDIA_TYPE, FileColumns.MEDIA_TYPE_AUDIO);
+        valuesThree.put(FileColumns.VOLUME_NAME, MediaStore.VOLUME_EXTERNAL_PRIMARY);
+        valuesThree.put(FileColumns.DATA, "/storage/emulated/0/Silent.mp3");
+        valuesThree.put(AudioColumns.TITLE, "Silent");
+        valuesThree.put(AudioColumns.ALBUM, "Rainbow");
+        valuesThree.put(AudioColumns.ARTIST, "Sample1");
+        valuesThree.put(AudioColumns.GENRE, "Rock");
+        valuesThree.put(AudioColumns.IS_MUSIC, true);
+
+        final ContentValues valuesFour = new ContentValues();
+        valuesFour.put(FileColumns.MEDIA_TYPE, FileColumns.MEDIA_TYPE_AUDIO);
+        valuesFour.put(FileColumns.VOLUME_NAME, MediaStore.VOLUME_EXTERNAL_PRIMARY);
+        valuesFour.put(FileColumns.DATA, "/storage/emulated/0/123456/Rainbow.mp3");
+        valuesFour.put(AudioColumns.TITLE, "Rainbow");
+        valuesFour.put(AudioColumns.ALBUM, "Rainbow");
+        valuesFour.put(AudioColumns.ARTIST, "Sample2");
+        valuesFour.put(AudioColumns.GENRE, "Alternative rock");
+        valuesFour.put(AudioColumns.IS_MUSIC, true);
+
+        MediaProvider.computeAudioKeyValues(valuesThree);
+        final long albumIdThree = valuesThree.getAsLong(AudioColumns.ALBUM_ID);
+        MediaProvider.computeAudioKeyValues(valuesFour);
+        final long albumIdFour = valuesFour.getAsLong(AudioColumns.ALBUM_ID);
+
+        assertNotEquals(albumIdThree, albumIdFour);
+    }
+
+    @Test
+    public void testComputeAudioKeyValues_167339595_sameAlbumId() throws Exception {
+        // same album name, same path, no album artists
+        final ContentValues valuesOne = new ContentValues();
+        valuesOne.put(FileColumns.MEDIA_TYPE, FileColumns.MEDIA_TYPE_AUDIO);
+        valuesOne.put(FileColumns.VOLUME_NAME, MediaStore.VOLUME_EXTERNAL_PRIMARY);
+        valuesOne.put(FileColumns.DATA, "/storage/emulated/0/Clocks.mp3");
+        valuesOne.put(AudioColumns.TITLE, "Clocks");
+        valuesOne.put(AudioColumns.ALBUM, "A Rush of Blood");
+        valuesOne.put(AudioColumns.GENRE, "Rock");
+        valuesOne.put(AudioColumns.IS_MUSIC, true);
+
+        final ContentValues valuesTwo = new ContentValues();
+        valuesTwo.put(FileColumns.MEDIA_TYPE, FileColumns.MEDIA_TYPE_AUDIO);
+        valuesTwo.put(FileColumns.VOLUME_NAME, MediaStore.VOLUME_EXTERNAL_PRIMARY);
+        valuesTwo.put(FileColumns.DATA, "/storage/emulated/0/Sounds.mp3");
+        valuesTwo.put(AudioColumns.TITLE, "Sounds");
+        valuesTwo.put(AudioColumns.ALBUM, "A Rush of Blood");
+        valuesTwo.put(AudioColumns.GENRE, "Alternative rock");
+        valuesTwo.put(AudioColumns.IS_MUSIC, true);
+
+        MediaProvider.computeAudioKeyValues(valuesOne);
+        final long albumIdOne = valuesOne.getAsLong(AudioColumns.ALBUM_ID);
+        MediaProvider.computeAudioKeyValues(valuesTwo);
+        final long albumIdTwo = valuesTwo.getAsLong(AudioColumns.ALBUM_ID);
+
+        assertEquals(albumIdOne, albumIdTwo);
+
+        // same album name, same album artists, different artists
+        final ContentValues valuesThree = new ContentValues();
+        valuesThree.put(FileColumns.MEDIA_TYPE, FileColumns.MEDIA_TYPE_AUDIO);
+        valuesThree.put(FileColumns.VOLUME_NAME, MediaStore.VOLUME_EXTERNAL_PRIMARY);
+        valuesThree.put(FileColumns.DATA, "/storage/emulated/0/Silent.mp3");
+        valuesThree.put(AudioColumns.TITLE, "Silent");
+        valuesThree.put(AudioColumns.ALBUM, "Rainbow");
+        valuesThree.put(AudioColumns.ALBUM_ARTIST, "Various Artists");
+        valuesThree.put(AudioColumns.ARTIST, "Sample1");
+        valuesThree.put(AudioColumns.GENRE, "Rock");
+        valuesThree.put(AudioColumns.IS_MUSIC, true);
+
+        final ContentValues valuesFour = new ContentValues();
+        valuesFour.put(FileColumns.MEDIA_TYPE, FileColumns.MEDIA_TYPE_AUDIO);
+        valuesFour.put(FileColumns.VOLUME_NAME, MediaStore.VOLUME_EXTERNAL_PRIMARY);
+        valuesFour.put(FileColumns.DATA, "/storage/emulated/0/Rainbow.mp3");
+        valuesFour.put(AudioColumns.TITLE, "Rainbow");
+        valuesFour.put(AudioColumns.ALBUM, "Rainbow");
+        valuesFour.put(AudioColumns.ALBUM_ARTIST, "Various Artists");
+        valuesFour.put(AudioColumns.ARTIST, "Sample2");
+        valuesFour.put(AudioColumns.GENRE, "Alternative rock");
+        valuesFour.put(AudioColumns.IS_MUSIC, true);
+
+        MediaProvider.computeAudioKeyValues(valuesThree);
+        final long albumIdThree = valuesThree.getAsLong(AudioColumns.ALBUM_ID);
+        MediaProvider.computeAudioKeyValues(valuesFour);
+        final long albumIdFour = valuesFour.getAsLong(AudioColumns.ALBUM_ID);
+
+        assertEquals(albumIdThree, albumIdFour);
+    }
+
     private static void assertRelativePathForDirectory(String directoryPath, String relativePath) {
         assertWithMessage("extractRelativePathForDirectory(" + directoryPath + ") :")
                 .that(extractRelativePathWithDisplayName(directoryPath))
diff --git a/tests/src/com/android/providers/media/scan/ModernMediaScannerTest.java b/tests/src/com/android/providers/media/scan/ModernMediaScannerTest.java
index 59ef0f2..f7bb434 100644
--- a/tests/src/com/android/providers/media/scan/ModernMediaScannerTest.java
+++ b/tests/src/com/android/providers/media/scan/ModernMediaScannerTest.java
@@ -45,18 +45,22 @@
 import static org.mockito.Mockito.when;
 
 import android.Manifest;
+import android.app.UiAutomation;
 import android.content.ContentResolver;
 import android.content.ContentUris;
+import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.media.ExifInterface;
 import android.media.MediaMetadataRetriever;
 import android.net.Uri;
+import android.os.Environment;
 import android.os.ParcelFileDescriptor;
 import android.provider.MediaStore;
 import android.provider.MediaStore.Files.FileColumns;
 import android.provider.MediaStore.MediaColumns;
+import android.util.Log;
 import android.util.Pair;
 
 import androidx.test.InstrumentationRegistry;
@@ -66,19 +70,26 @@
 import com.android.providers.media.scan.MediaScannerTest.IsolatedContext;
 import com.android.providers.media.util.FileUtils;
 
+import com.google.common.io.ByteStreams;
+
 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.FileNotFoundException;
 import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InterruptedIOException;
 import java.util.Optional;
 
 @RunWith(AndroidJUnit4.class)
 public class ModernMediaScannerTest {
     // TODO: scan directory-vs-files and confirm identical results
 
+    private static final String TAG = "ModernMediaScannerTest";
     private File mDir;
 
     private Context mIsolatedContext;
@@ -399,6 +410,41 @@
         }
     }
 
+    private void assertVisibleFolder(File dir) throws Exception {
+        final File nomediaFile = new File(dir, ".nomedia");
+
+        if (!nomediaFile.getParentFile().exists()) {
+            assertTrue(nomediaFile.getParentFile().mkdirs());
+        }
+        try {
+            if (!nomediaFile.exists()) {
+                executeShellCommand("touch " + nomediaFile.getAbsolutePath());
+                assertTrue(nomediaFile.exists());
+            }
+            assertShouldScanPathAndIsPathHidden(true, false, dir);
+        } finally {
+            executeShellCommand("rm " + nomediaFile.getAbsolutePath());
+        }
+    }
+
+    /**
+     * b/168830497: Test that default folders and Camera folder are always visible
+     */
+    @Test
+    public void testVisibleDefaultFolders() throws Exception {
+        final File root = new File("storage/emulated/0");
+
+        // Top level directories should always be visible
+        for (String dirName : FileUtils.DEFAULT_FOLDER_NAMES) {
+            final File defaultFolder = new File(root, dirName);
+            assertVisibleFolder(defaultFolder);
+        }
+
+        // DCIM/Camera should always be visible
+        final File cameraDir = new File(root, Environment.DIRECTORY_DCIM + "/" + "Camera");
+        assertVisibleFolder(cameraDir);
+    }
+
     private static void assertShouldScanDirectory(File file) {
         assertTrue(file.getAbsolutePath(), shouldScanDirectory(file));
     }
@@ -820,6 +866,31 @@
         }
     }
 
+    /**
+     * If there is a scan action between invoking {@link ContentResolver#insert} and
+     * {@link ContentResolver#openFileDescriptor}, it should not raise
+     * (@link FileNotFoundException}.
+     */
+    @Test
+    public void testScan_166063754() throws Exception {
+        Uri collection = MediaStore.Images.Media
+                .getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
+
+        ContentValues values = new ContentValues();
+        values.put(MediaStore.Images.Media.DISPLAY_NAME, mDir.getName() + "_166063754.jpg");
+        values.put(MediaStore.Images.Media.IS_PENDING, 1);
+
+        Uri uri = mIsolatedResolver.insert(collection, values);
+
+        File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
+        mModern.scanFile(dir, REASON_UNKNOWN);
+        try {
+            mIsolatedResolver.openFileDescriptor(uri, "w", null);
+        } catch (FileNotFoundException e) {
+            throw new AssertionError("Can't open uri " + uri, e);
+        }
+    }
+
     @Test
     public void testAlbumArtPattern() throws Exception {
         for (String path : new String[] {
@@ -853,4 +924,29 @@
             assertTrue(isFileAlbumArt(file));
         }
     }
+
+    /**
+     * 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));
+        }
+    }
 }
diff --git a/tests/src/com/android/providers/media/util/SQLiteQueryBuilderTest.java b/tests/src/com/android/providers/media/util/SQLiteQueryBuilderTest.java
index 9af8e5d..c8fe3bb 100644
--- a/tests/src/com/android/providers/media/util/SQLiteQueryBuilderTest.java
+++ b/tests/src/com/android/providers/media/util/SQLiteQueryBuilderTest.java
@@ -741,6 +741,25 @@
     }
 
     @Test
+    public void testStrict_158537159() {
+        final SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
+        final HashMap<String, String> map = new HashMap<>();
+        map.put("bucket_id", "bucket_id");
+        builder.setProjectionMap(map);
+        final String sortOrder = "bucket_id COLLATE LOCALIZED ASC";
+        {
+            builder.setTargetSdkVersion(Build.VERSION_CODES.Q);
+            builder.enforceStrictGrammar(null, null, null, sortOrder, null);
+        }
+        try {
+            builder.setTargetSdkVersion(Build.VERSION_CODES.R);
+            builder.enforceStrictGrammar(null, null, null, sortOrder, null);
+            fail("Expected to throw");
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    @Test
     public void testStrictCustomCollator() {
         final SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
         final HashMap<String, String> map = new HashMap<>();