summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-09-04 13:01:47 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-09-04 13:01:47 +0000
commitdcaac1d6e2ee9383e0838babfe47f5ece909324a (patch)
tree2ff12209efd2db6f49a08d34ed91ef8d4e9e38f2
parent6edd5f233a879cd8d67148d20965720ba2fe84b7 (diff)
parente530e0bc50da4811b290983c72b159a39aec6b54 (diff)
downloadMediaProvider-aml_sdk_341110080.tar.gz
Snap for 10758424 from e530e0bc50da4811b290983c72b159a39aec6b54 to mainline-sdkext-releaseaml_sdk_341110080aml_sdk_341110000
Change-Id: I8c0aa687685bf2c56612e1f2cd4418f714c3b86d
-rw-r--r--jni/FuseDaemon.cpp47
-rw-r--r--res/drawable/error_icon.xml17
-rw-r--r--res/drawable/ic_background_circle.xml20
-rw-r--r--res/drawable/picker_app_icon.xml26
-rw-r--r--res/drawable/thumbnail_favorites.xml25
-rw-r--r--res/drawable/thumbnail_videos.xml26
-rw-r--r--res/layout/error_dialog.xml47
-rw-r--r--res/layout/item_album_grid.xml10
-rw-r--r--res/values-af/strings.xml11
-rw-r--r--res/values-am/strings.xml11
-rw-r--r--res/values-ar/strings.xml13
-rw-r--r--res/values-as/strings.xml11
-rw-r--r--res/values-az/strings.xml11
-rw-r--r--res/values-b+sr+Latn/strings.xml31
-rw-r--r--res/values-be/strings.xml11
-rw-r--r--res/values-bg/strings.xml19
-rw-r--r--res/values-bn/strings.xml11
-rw-r--r--res/values-bs/strings.xml25
-rw-r--r--res/values-ca/strings.xml13
-rw-r--r--res/values-cs/strings.xml13
-rw-r--r--res/values-da/strings.xml11
-rw-r--r--res/values-de/strings.xml17
-rw-r--r--res/values-el/strings.xml13
-rw-r--r--res/values-en-rAU/strings.xml11
-rw-r--r--res/values-en-rCA/strings.xml10
-rw-r--r--res/values-en-rGB/strings.xml11
-rw-r--r--res/values-en-rIN/strings.xml11
-rw-r--r--res/values-en-rXC/strings.xml10
-rw-r--r--res/values-es-rUS/strings.xml13
-rw-r--r--res/values-es/strings.xml15
-rw-r--r--res/values-et/strings.xml23
-rw-r--r--res/values-eu/strings.xml13
-rw-r--r--res/values-fa/strings.xml15
-rw-r--r--res/values-fi/strings.xml11
-rw-r--r--res/values-fr-rCA/strings.xml11
-rw-r--r--res/values-fr/strings.xml17
-rw-r--r--res/values-gl/strings.xml11
-rw-r--r--res/values-gu/strings.xml13
-rw-r--r--res/values-hi/strings.xml17
-rw-r--r--res/values-hr/strings.xml11
-rw-r--r--res/values-hu/strings.xml11
-rw-r--r--res/values-hy/strings.xml15
-rw-r--r--res/values-in/strings.xml11
-rw-r--r--res/values-is/strings.xml13
-rw-r--r--res/values-it/strings.xml17
-rw-r--r--res/values-iw/strings.xml11
-rw-r--r--res/values-ja/strings.xml13
-rw-r--r--res/values-ka/strings.xml13
-rw-r--r--res/values-kk/strings.xml11
-rw-r--r--res/values-km/strings.xml13
-rw-r--r--res/values-kn/strings.xml21
-rw-r--r--res/values-ko/strings.xml15
-rw-r--r--res/values-ky/strings.xml15
-rw-r--r--res/values-lo/strings.xml11
-rw-r--r--res/values-lt/strings.xml11
-rw-r--r--res/values-lv/strings.xml11
-rw-r--r--res/values-mk/strings.xml21
-rw-r--r--res/values-ml/strings.xml11
-rw-r--r--res/values-mn/strings.xml15
-rw-r--r--res/values-mr/strings.xml11
-rw-r--r--res/values-ms/strings.xml11
-rw-r--r--res/values-my/strings.xml15
-rw-r--r--res/values-nb/strings.xml11
-rw-r--r--res/values-ne/strings.xml11
-rw-r--r--res/values-night-v31/styles.xml5
-rw-r--r--res/values-night/styles.xml5
-rw-r--r--res/values-nl/strings.xml11
-rw-r--r--res/values-or/strings.xml21
-rw-r--r--res/values-pa/strings.xml13
-rw-r--r--res/values-pl/strings.xml15
-rw-r--r--res/values-pt-rBR/strings.xml17
-rw-r--r--res/values-pt-rPT/strings.xml12
-rw-r--r--res/values-pt/strings.xml17
-rw-r--r--res/values-ro/strings.xml11
-rw-r--r--res/values-ru/strings.xml15
-rw-r--r--res/values-si/strings.xml11
-rw-r--r--res/values-sk/strings.xml17
-rw-r--r--res/values-sl/strings.xml11
-rw-r--r--res/values-sq/strings.xml17
-rw-r--r--res/values-sr/strings.xml31
-rw-r--r--res/values-sv/strings.xml11
-rw-r--r--res/values-sw/strings.xml21
-rw-r--r--res/values-ta/strings.xml15
-rw-r--r--res/values-te/strings.xml15
-rw-r--r--res/values-th/strings.xml11
-rw-r--r--res/values-tl/strings.xml13
-rw-r--r--res/values-tr/strings.xml11
-rw-r--r--res/values-uk/strings.xml11
-rw-r--r--res/values-ur/strings.xml11
-rw-r--r--res/values-uz/strings.xml17
-rw-r--r--res/values-v31/styles.xml5
-rw-r--r--res/values-vi/strings.xml27
-rw-r--r--res/values-zh-rCN/strings.xml23
-rw-r--r--res/values-zh-rHK/strings.xml13
-rw-r--r--res/values-zh-rTW/strings.xml11
-rw-r--r--res/values-zu/strings.xml11
-rw-r--r--res/values/attrs.xml6
-rw-r--r--res/values/dimens.xml1
-rw-r--r--res/values/strings.xml24
-rw-r--r--res/values/styles.xml20
-rw-r--r--src/com/android/providers/media/ConfigStore.java36
-rw-r--r--src/com/android/providers/media/DatabaseBackupAndRecovery.java67
-rw-r--r--src/com/android/providers/media/MediaGrants.java54
-rw-r--r--src/com/android/providers/media/MediaProvider.java35
-rw-r--r--src/com/android/providers/media/photopicker/DialogUtils.java57
-rw-r--r--src/com/android/providers/media/photopicker/PhotoPickerActivity.java61
-rw-r--r--src/com/android/providers/media/photopicker/PickerDataLayer.java157
-rw-r--r--src/com/android/providers/media/photopicker/PickerSyncController.java229
-rw-r--r--src/com/android/providers/media/photopicker/SelectedMediaPreloader.java54
-rw-r--r--src/com/android/providers/media/photopicker/data/CloudProviderQueryExtras.java25
-rw-r--r--src/com/android/providers/media/photopicker/data/ItemsProvider.java85
-rw-r--r--src/com/android/providers/media/photopicker/data/PaginationParameters.java5
-rw-r--r--src/com/android/providers/media/photopicker/data/PickerDbFacade.java143
-rw-r--r--src/com/android/providers/media/photopicker/data/Selection.java46
-rw-r--r--src/com/android/providers/media/photopicker/data/model/Category.java7
-rw-r--r--src/com/android/providers/media/photopicker/data/model/Item.java15
-rw-r--r--src/com/android/providers/media/photopicker/sync/ImmediateAlbumSyncWorker.java28
-rw-r--r--src/com/android/providers/media/photopicker/sync/ImmediateSyncWorker.java31
-rw-r--r--src/com/android/providers/media/photopicker/sync/MediaResetWorker.java203
-rw-r--r--src/com/android/providers/media/photopicker/sync/PickerSyncManager.java242
-rw-r--r--src/com/android/providers/media/photopicker/sync/PickerSyncNotificationHelper.java95
-rw-r--r--src/com/android/providers/media/photopicker/sync/ProactiveSyncWorker.java30
-rw-r--r--src/com/android/providers/media/photopicker/ui/AlbumGridHolder.java14
-rw-r--r--src/com/android/providers/media/photopicker/ui/AlbumsTabFragment.java10
-rw-r--r--src/com/android/providers/media/photopicker/ui/ImageLoader.java19
-rw-r--r--src/com/android/providers/media/photopicker/ui/PhotosTabAdapter.java6
-rw-r--r--src/com/android/providers/media/photopicker/ui/PhotosTabFragment.java42
-rw-r--r--src/com/android/providers/media/photopicker/ui/TabAdapter.java18
-rw-r--r--src/com/android/providers/media/photopicker/ui/TabFragment.java21
-rw-r--r--src/com/android/providers/media/photopicker/ui/remotepreview/RemotePreviewSession.java15
-rw-r--r--src/com/android/providers/media/photopicker/ui/settings/SettingsCloudMediaViewModel.java4
-rw-r--r--src/com/android/providers/media/photopicker/util/CloudProviderUtils.java48
-rw-r--r--src/com/android/providers/media/photopicker/viewmodel/BannerController.java56
-rw-r--r--src/com/android/providers/media/photopicker/viewmodel/BannerManager.java23
-rw-r--r--src/com/android/providers/media/photopicker/viewmodel/PickerViewModel.java96
-rw-r--r--src/com/android/providers/media/stableuris/dao/BackupIdRow.java38
-rw-r--r--tests/Android.bp7
-rw-r--r--tests/client/Android.bp1
-rw-r--r--tests/client/src/com/android/providers/media/client/ClientPlaylistTest.java3
-rw-r--r--tests/client/src/com/android/providers/media/client/PerformanceTest.java2
-rw-r--r--tests/client/src/com/android/providers/media/client/PlaylistPerformanceTest.java2
-rw-r--r--tests/client/src/com/android/providers/media/client/PublicVolumePlaylistTest.java3
-rw-r--r--tests/client/src/com/android/providers/media/client/PublicVolumeTest.java3
-rw-r--r--tests/src/com/android/providers/media/DatabaseBackupAndRecoveryTest.java13
-rw-r--r--tests/src/com/android/providers/media/IsolatedContext.java15
-rw-r--r--tests/src/com/android/providers/media/MediaGrantsTest.java42
-rw-r--r--tests/src/com/android/providers/media/PublicVolumeTest.java2
-rw-r--r--tests/src/com/android/providers/media/TestConfigStore.java43
-rw-r--r--tests/src/com/android/providers/media/TestDatabaseBackupAndRecovery.java2
-rw-r--r--tests/src/com/android/providers/media/cloudproviders/CloudProviderSecondary.java2
-rw-r--r--tests/src/com/android/providers/media/cloudproviders/FlakyCloudProvider.java36
-rw-r--r--tests/src/com/android/providers/media/photopicker/ItemsProviderTest.java90
-rw-r--r--tests/src/com/android/providers/media/photopicker/PickerDataLayerTest.java103
-rw-r--r--tests/src/com/android/providers/media/photopicker/PickerSyncControllerTest.java129
-rw-r--r--tests/src/com/android/providers/media/photopicker/data/PickerDbFacadeTest.java111
-rw-r--r--tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerActivityTest.java6
-rw-r--r--tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerBaseTest.java8
-rw-r--r--tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerTestActivity.java24
-rw-r--r--tests/src/com/android/providers/media/photopicker/espresso/ProgressBarTest.java196
-rw-r--r--tests/src/com/android/providers/media/photopicker/sync/MediaResetWorkerTest.java439
-rw-r--r--tests/src/com/android/providers/media/photopicker/sync/PickerSyncManagerTest.java263
-rw-r--r--tests/src/com/android/providers/media/photopicker/sync/SyncWorkerTestUtils.java16
-rw-r--r--tests/src/com/android/providers/media/photopicker/util/CloudProviderUtilsTest.java61
-rw-r--r--tests/src/com/android/providers/media/photopicker/viewmodel/BannerControllerTest.java98
-rw-r--r--tests/src/com/android/providers/media/photopicker/viewmodel/PickerViewModelPaginationTest.java28
-rw-r--r--tests/src/com/android/providers/media/photopicker/viewmodel/PickerViewModelTest.java4
-rw-r--r--tests/src/com/android/providers/media/stableuris/dao/BackupIdRowTest.java4
167 files changed, 4607 insertions, 750 deletions
diff --git a/jni/FuseDaemon.cpp b/jni/FuseDaemon.cpp
index a0eb54754..0a1b25f3a 100644
--- a/jni/FuseDaemon.cpp
+++ b/jni/FuseDaemon.cpp
@@ -103,7 +103,9 @@ const bool IS_OS_DEBUGABLE = android::base::GetIntProperty("ro.debuggable", 0);
// Stolen from: android_filesystem_config.h
#define AID_APP_START 10000
-constexpr size_t MAX_READ_SIZE = 128 * 1024;
+#define FUSE_MAX_MAX_PAGES 256
+
+const size_t MAX_READ_SIZE = FUSE_MAX_MAX_PAGES * getpagesize();
// Stolen from: UserHandle#getUserId
constexpr int PER_USER_RANGE = 100000;
@@ -2590,7 +2592,7 @@ std::string deriveVolumeName(const std::string& path) {
void FuseDaemon::DeleteFromLevelDb(const std::string& key) {
std::string volume_name = deriveVolumeName(key);
if (!CheckLevelDbConnection(volume_name)) {
- LOG(ERROR) << "Failure in leveldb delete in volume:" << volume_name << " for key:" << key;
+ LOG(ERROR) << "DeleteFromLevelDb: Missing leveldb connection.";
return;
}
@@ -2605,7 +2607,7 @@ void FuseDaemon::DeleteFromLevelDb(const std::string& key) {
void FuseDaemon::InsertInLevelDb(const std::string& key, const std::string& value) {
std::string volume_name = deriveVolumeName(key);
if (!CheckLevelDbConnection(volume_name)) {
- LOG(ERROR) << "Failure in leveldb insert in volume:" << volume_name << " for key:" << key;
+ LOG(ERROR) << "InsertInLevelDb: Missing leveldb connection.";
return;
}
@@ -2613,6 +2615,7 @@ void FuseDaemon::InsertInLevelDb(const std::string& key, const std::string& valu
status = fuse->level_db_connection_map[volume_name]->Put(leveldb::WriteOptions(), key, value);
if (!status.ok()) {
LOG(ERROR) << "Failure in leveldb insert for key: " << key << " in volume:" << volume_name;
+ LOG(ERROR) << status.ToString();
}
}
@@ -2623,7 +2626,7 @@ std::vector<std::string> FuseDaemon::ReadFilePathsFromLevelDb(const std::string&
std::vector<std::string> file_paths;
if (!CheckLevelDbConnection(volume_name)) {
- LOG(ERROR) << "Failure in leveldb file paths read for volume:" << volume_name;
+ LOG(ERROR) << "ReadFilePathsFromLevelDb: Missing leveldb connection.";
return file_paths;
}
@@ -2648,16 +2651,16 @@ std::string FuseDaemon::ReadBackedUpDataFromLevelDb(const std::string& filePath)
std::string data = "";
std::string volume_name = deriveVolumeName(filePath);
if (!CheckLevelDbConnection(volume_name)) {
- LOG(ERROR) << "Failure in leveldb data read for key:" << filePath;
+ LOG(ERROR) << "ReadBackedUpDataFromLevelDb: Missing leveldb connection.";
return data;
}
leveldb::Status status = fuse->level_db_connection_map[volume_name]->Get(leveldb::ReadOptions(),
filePath, &data);
- if (!status.ok()) {
- LOG(WARNING) << "Failure in leveldb read for key: " << filePath << status.ToString();
- } else {
- LOG(DEBUG) << "Read successful for key: " << filePath;
+ if (status.IsNotFound()) {
+ LOG(VERBOSE) << "Key is not found in leveldb: " << filePath << " " << status.ToString();
+ } else if (!status.ok()) {
+ LOG(WARNING) << "Failure in leveldb read for key: " << filePath << " " << status.ToString();
}
return data;
}
@@ -2665,22 +2668,26 @@ std::string FuseDaemon::ReadBackedUpDataFromLevelDb(const std::string& filePath)
std::string FuseDaemon::ReadOwnership(const std::string& key) {
// Return empty string if key not found
std::string data = "";
- if (CheckLevelDbConnection(OWNERSHIP_RELATION)) {
- leveldb::Status status = fuse->level_db_connection_map[OWNERSHIP_RELATION]->Get(
- leveldb::ReadOptions(), key, &data);
- if (!status.ok()) {
- LOG(WARNING) << "Failure in leveldb read for key: " << key << status.ToString();
- } else {
- LOG(DEBUG) << "Read successful for key: " << key;
- }
+ if (!CheckLevelDbConnection(OWNERSHIP_RELATION)) {
+ LOG(ERROR) << "ReadOwnership: Missing leveldb connection.";
+ return data;
}
+
+ leveldb::Status status = fuse->level_db_connection_map[OWNERSHIP_RELATION]->Get(
+ leveldb::ReadOptions(), key, &data);
+ if (status.IsNotFound()) {
+ LOG(VERBOSE) << "Key is not found in leveldb: " << key << " " << status.ToString();
+ } else if (!status.ok()) {
+ LOG(WARNING) << "Failure in leveldb read for key: " << key << " " << status.ToString();
+ }
+
return data;
}
void FuseDaemon::CreateOwnerIdRelation(const std::string& ownerId,
const std::string& ownerPackageIdentifier) {
if (!CheckLevelDbConnection(OWNERSHIP_RELATION)) {
- LOG(ERROR) << "Failure in leveldb insert for ownership relation.";
+ LOG(ERROR) << "CreateOwnerIdRelation: Missing leveldb connection.";
return;
}
@@ -2703,7 +2710,7 @@ void FuseDaemon::CreateOwnerIdRelation(const std::string& ownerId,
void FuseDaemon::RemoveOwnerIdRelation(const std::string& ownerId,
const std::string& ownerPackageIdentifier) {
if (!CheckLevelDbConnection(OWNERSHIP_RELATION)) {
- LOG(ERROR) << "Failure in leveldb delete for ownership relation.";
+ LOG(ERROR) << "RemoveOwnerIdRelation: Missing leveldb connection.";
return;
}
@@ -2729,7 +2736,7 @@ void FuseDaemon::RemoveOwnerIdRelation(const std::string& ownerId,
std::map<std::string, std::string> FuseDaemon::GetOwnerRelationship() {
std::map<std::string, std::string> resultMap;
if (!CheckLevelDbConnection(OWNERSHIP_RELATION)) {
- LOG(ERROR) << "Failure in leveldb read for ownership relation.";
+ LOG(ERROR) << "GetOwnerRelationship: Missing leveldb connection.";
return resultMap;
}
diff --git a/res/drawable/error_icon.xml b/res/drawable/error_icon.xml
new file mode 100644
index 000000000..e9433b758
--- /dev/null
+++ b/res/drawable/error_icon.xml
@@ -0,0 +1,17 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <group>
+ <clip-path
+ android:pathData="M0,0h24v24h-24z"/>
+ <path
+ android:pathData="M1,21L12,2L23,21H1ZM4.45,19H19.55L12,6L4.45,19ZM12,18C12.283,18
+ 12.517,17.908 12.7,17.725C12.9,17.525 13,17.283 13,17C13,16.717 12.9,16.483
+ 12.7,16.3C12.517,16.1 12.283,16 12,16C11.717,16 11.475,16.1 11.275,16.3C11.092,16.483
+ 11,16.717 11,17C11,17.283 11.092,17.525 11.275,17.725C11.475,17.908 11.717,18 12,
+ 18ZM11,15H13V10H11V15Z"
+ android:fillColor="#775A0B"/>
+ </group>
+</vector>
diff --git a/res/drawable/ic_background_circle.xml b/res/drawable/ic_background_circle.xml
new file mode 100644
index 000000000..ec6f524fc
--- /dev/null
+++ b/res/drawable/ic_background_circle.xml
@@ -0,0 +1,20 @@
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+ <solid android:color="?attr/categoryDefaultThumbnailCircleColor" />
+</shape> \ No newline at end of file
diff --git a/res/drawable/picker_app_icon.xml b/res/drawable/picker_app_icon.xml
new file mode 100644
index 000000000..9f8334423
--- /dev/null
+++ b/res/drawable/picker_app_icon.xml
@@ -0,0 +1,26 @@
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:pathData="M8,2H20C21.1,2 22,2.9 22,4V16C22,17.1 21.1,18 20,18H8C6.9,18 6,17.1 6,16V4C6,2.9 6.9,2 8,2ZM20,16V4H8V16H20ZM2,6V20C2,21.1 2.9,22 4,22H18V20H4V6H2ZM13.17,13.98L15.67,11L19,15H9L11.5,11.8L13.17,13.98Z"
+ android:fillColor="#5F6368"
+ android:fillType="evenOdd"/>
+</vector>
diff --git a/res/drawable/thumbnail_favorites.xml b/res/drawable/thumbnail_favorites.xml
new file mode 100644
index 000000000..a1a8101fe
--- /dev/null
+++ b/res/drawable/thumbnail_favorites.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:pathData="M14.81,8.62L22,9.24L16.55,13.97L18.18,21L12,17.27L5.82,21L7.46,13.97L2,9.24L9.19,8.63L12,2L14.81,8.62ZM8.24,17.67L12,15.4L15.77,17.68L14.77,13.4L18.09,10.52L13.71,10.14L12,6.1L10.3,10.13L5.92,10.51L9.24,13.39L8.24,17.67Z"
+ android:fillColor="#5B631D"
+ android:fillType="evenOdd"/>
+</vector>
diff --git a/res/drawable/thumbnail_videos.xml b/res/drawable/thumbnail_videos.xml
new file mode 100644
index 000000000..e5944d5c7
--- /dev/null
+++ b/res/drawable/thumbnail_videos.xml
@@ -0,0 +1,26 @@
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:pathData="M18,6V10.48L22,6.5V17.5L18,13.52V18C18,19.1 17.1,20 16,20H4C2.9,20 2,19.1 2,18V6C2,4.9 2.9,4 4,4H16C17.1,4 18,4.9 18,6ZM16,6H4V18H16V6Z"
+ android:fillColor="#5B631D"
+ android:fillType="evenOdd"/>
+</vector>
+
diff --git a/res/layout/error_dialog.xml b/res/layout/error_dialog.xml
new file mode 100644
index 000000000..5fa23d171
--- /dev/null
+++ b/res/layout/error_dialog.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="20dp"
+ android:gravity="center">
+ <ImageView
+ android:layout_width="34dp"
+ android:layout_height="34dp"
+ android:src="@drawable/error_icon"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginBottom="16dp"
+ android:importantForAccessibility="no"/>
+
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/dialog_error_title"
+ android:textSize="24sp"
+ android:layout_gravity="center_horizontal"
+ android:gravity="center"
+ android:textColor="?android:attr/textColorPrimary"/>
+
+ <TextView
+ android:id="@+id/message"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/dialog_error_message"
+ android:layout_marginTop="16dp"
+ android:layout_gravity="center_horizontal"
+ android:gravity="center"
+ android:textSize="16sp"
+ android:textColor="?android:attr/textColorSecondary"/>
+
+ <Button
+ android:id="@+id/okButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/dialog_button_text"
+ android:layout_marginTop="16dp"
+ android:layout_gravity="end"
+ android:textColor="?attr/pickerHighlightTextColor"
+ android:backgroundTint="?attr/pickerHighlightColor"/>
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/item_album_grid.xml b/res/layout/item_album_grid.xml
index 0e67c5740..c09beaf0e 100644
--- a/res/layout/item_album_grid.xml
+++ b/res/layout/item_album_grid.xml
@@ -38,6 +38,16 @@
android:scaleType="centerCrop"
android:contentDescription="@null"/>
+ <ImageView
+ android:id="@+id/icon_default_thumbnail"
+ android:layout_width="56dp"
+ android:layout_height="56dp"
+ android:scaleType="centerCrop"
+ android:tint="?attr/categoryDefaultThumbnailColor"
+ android:contentDescription="@null"
+ android:layout_gravity="center"
+ android:background="@drawable/ic_background_circle"
+ android:padding="16dp"/>
</com.google.android.material.card.MaterialCardView>
<TextView
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index c5a67ec51..7f2e20848 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Media"</string>
<string name="storage_description" msgid="4081716890357580107">"Plaaslike berging"</string>
<string name="app_label" msgid="9035307001052716210">"Mediaberging"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Media"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Mediakieser"</string>
<string name="artist_label" msgid="8105600993099120273">"Kunstenaar"</string>
<string name="unknown" msgid="2059049215682829375">"Onbekend"</string>
<string name="root_images" msgid="5861633549189045666">"Prente"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Kry toegang tot wolkmedia vanaf"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Geen"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Kon nie wolkmedia-app op dié tydstip verander nie."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Mediakieser"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Mediakieser"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Sinkroniseer tans media …"</string>
<string name="add" msgid="2894574044585549298">"Voeg by"</string>
<string name="deselect" msgid="4297825044827769490">"Ontkies"</string>
<string name="deselected" msgid="8488133193326208475">"Ontkies"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Gaan jou internetverbinding na en probeer weer"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Herprobeer"</string>
<string name="not_selected" msgid="2244008151669896758">"nie gekies nie"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Berei tans jou geselekteerde media voor"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> van <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> is gereed"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Gerugsteunde foto\'s word nou ingesluit"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Jy kan foto\'s van <xliff:g id="APP_NAME">%1$s</xliff:g>-rekening <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> af kies"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Kies app"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Kies rekening"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Verander rekening"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Kry tans al jou foto’s"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Laat <xliff:g id="APP_NAME_0">^1</xliff:g> toe om hierdie oudiolêer te wysig?}other{Laat <xliff:g id="APP_NAME_1">^1</xliff:g> toe om <xliff:g id="COUNT">^2</xliff:g> oudiolêers te wysig?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Wysig tans oudiolêer …}other{Wysig tans <xliff:g id="COUNT">^1</xliff:g> oudiolêers …}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Laat <xliff:g id="APP_NAME_0">^1</xliff:g> toe om hierdie video te wysig?}other{Laat <xliff:g id="APP_NAME_1">^1</xliff:g> toe om <xliff:g id="COUNT">^2</xliff:g> video\'s te wysig?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Veiligheidbeskerming"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Toestelspesifieke kodewisselingopletberigte"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Toestelspesifieke kodewisselingvordering"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Sommige foto’s kan nie laai nie"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Het dit"</string>
</resources>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 44e9b1c77..b5c3edccd 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/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="picker_app_label" msgid="4254039089502164761">"ሚዲያ"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"የሚዲያ መራጭ"</string>
<string name="artist_label" msgid="8105600993099120273">"አርቲስት"</string>
<string name="unknown" msgid="2059049215682829375">"የማይታወቅ"</string>
<string name="root_images" msgid="5861633549189045666">"ምስሎች"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"የደመና ሚዲያን ይድረሱ ከ"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"ምንም"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"በዚህ ጊዜ የደመና የሚዲያ መተግበሪያን መለወጥ አልተቻለም።"</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"የሚዲያ መራጭ"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"የሚዲያ መራጭ"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"ሚዲያ በማስመር ላይ…"</string>
<string name="add" msgid="2894574044585549298">"አክል"</string>
<string name="deselect" msgid="4297825044827769490">"አትምረጥ"</string>
<string name="deselected" msgid="8488133193326208475">"አልተመረጠም"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"የበይነመረብዎን ግንኙነት ይፈትሹ እና እንደገና ይሞክሩ"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"እንደገና ሞክር"</string>
<string name="not_selected" msgid="2244008151669896758">"አልተመረጠም"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"የእርስዎን የተመረጠ ሚዲያ በማዘጋጀት ላይ"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> ከ<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> ዝግጁ"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"ምትኬ የተቀመጠላቸው ፎቶዎች አሁን ተካትተዋል"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"ከ<xliff:g id="APP_NAME">%1$s</xliff:g> መለያ <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> ፎቶዎችን መምረጥ ይችላሉ"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"መተግበሪያ ይምረጡ"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"መለያ ይምረጡ"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"መለያ ቀይር"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"ሁሉንም ፎቶዎችዎን በማምጣት ላይ"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> ይህን ኦዲዮ ፋይል እንዲቀይር ይፈቀድለት?}one{<xliff:g id="APP_NAME_1">^1</xliff:g> <xliff:g id="COUNT">^2</xliff:g> ኦዲዮ ፋይልን እንዲቀይር ይፈቀድለት?}other{<xliff:g id="APP_NAME_1">^1</xliff:g> <xliff:g id="COUNT">^2</xliff:g> ኦዲዮ ፋይሎችን እንዲቀይር ይፈቀድለት?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{የኦዲዮ ፋይልን በመቀየር ላይ…}one{<xliff:g id="COUNT">^1</xliff:g> የኦዲዮ ፋይልን በመቀየር ላይ…}other{<xliff:g id="COUNT">^1</xliff:g> የኦዲዮ ፋይሎችን በመቀየር ላይ…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> ይህን ቪዲዮ እንዲቀይር ይፈቀድለት?}one{<xliff:g id="APP_NAME_1">^1</xliff:g> <xliff:g id="COUNT">^2</xliff:g> ቪዲዮን እንዲቀይር ይፈቀድለት?}other{<xliff:g id="APP_NAME_1">^1</xliff:g> <xliff:g id="COUNT">^2</xliff:g> ቪዲዮዎችን እንዲቀይር ይፈቀድለት?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"የደህንነት ጥበቃ"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"የቤተኛ ትራንስኮድ ማንቂያዎች"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"የቤተኛ ትራንስኮድ ሂደት"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"አንዳንድ ፎቶዎችን መጫን አይቻለም"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"ገባኝ"</string>
</resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index c8544f1e6..de14d5650 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/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="picker_app_label" msgid="4254039089502164761">"الوسائط"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"أداة اختيار الوسائط"</string>
<string name="artist_label" msgid="8105600993099120273">"الفنان"</string>
<string name="unknown" msgid="2059049215682829375">"غير معروف"</string>
<string name="root_images" msgid="5861633549189045666">"الصور"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"الوصول إلى الوسائط في السحابة الإلكترونية من"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"بلا تطبيق"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"تعذر تغيير تطبيق وسائط في السحابة الإلكترونية حاليًا"</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"أداة اختيار الوسائط"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"أداة اختيار الوسائط"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"جارٍ مزامنة الوسائط…"</string>
<string name="add" msgid="2894574044585549298">"إضافة"</string>
<string name="deselect" msgid="4297825044827769490">"إلغاء الاختيار"</string>
<string name="deselected" msgid="8488133193326208475">"تم إلغاء الاختيار"</string>
@@ -93,9 +96,10 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"يُرجى التحقّق من الاتصال بالإنترنت ثم إعادة المحاولة."</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"إعادة المحاولة"</string>
<string name="not_selected" msgid="2244008151669896758">"غير محدّد"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"جارٍ تحضير الوسائط التي تم اختيارها"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> من إجمالي <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> صورة جاهزة"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"تم الآن تضمين الصور التي تم الاحتفاظ بنسخة احتياطية منها"</string>
- <string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"يمكنك اختيار صور من حساب <xliff:g id="APP_NAME">%1$s</xliff:g> للمستخدم <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>."</string>
+ <string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"يمكنك اختيار صور من حساب \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" للمستخدم <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>."</string>
<string name="picker_banner_cloud_account_changed_title" msgid="4825058474378077327">"تم تعديل الحساب <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="picker_banner_cloud_account_changed_desc" msgid="3433218869899792497">"تم الآن تضمين الصور من <xliff:g id="USER_ACCOUNT">%1$s</xliff:g> هنا."</string>
<string name="picker_banner_cloud_choose_app_title" msgid="3165966147547974251">"اختيار تطبيق موسيقى على السحابة الإلكترونية"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"اختيار تطبيق"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"اختيار حساب"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"تبديل الحساب"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"جارٍ تحميل جميع الصور"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{هل تريد السماح لتطبيق <xliff:g id="APP_NAME_0">^1</xliff:g> بتعديل هذا الملف الصوتي؟}zero{هل تريد السماح لتطبيق <xliff:g id="APP_NAME_1">^1</xliff:g> بتعديل <xliff:g id="COUNT">^2</xliff:g> ملف صوتي؟}two{هل تريد السماح لتطبيق <xliff:g id="APP_NAME_1">^1</xliff:g> بتعديل ملفَين صوتيين (<xliff:g id="COUNT">^2</xliff:g>)؟}few{هل تريد السماح لتطبيق <xliff:g id="APP_NAME_1">^1</xliff:g> بتعديل <xliff:g id="COUNT">^2</xliff:g> ملفات صوتية؟}many{هل تريد السماح لتطبيق <xliff:g id="APP_NAME_1">^1</xliff:g> بتعديل <xliff:g id="COUNT">^2</xliff:g> ملفًا صوتيًا؟}other{هل تريد السماح لتطبيق <xliff:g id="APP_NAME_1">^1</xliff:g> بتعديل <xliff:g id="COUNT">^2</xliff:g> ملف صوتي؟}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{جارٍ تعديل ملف صوتي واحد…}zero{جارٍ تعديل <xliff:g id="COUNT">^1</xliff:g> ملف صوتي…}two{جارٍ تعديل ملفَين صوتين (<xliff:g id="COUNT">^1</xliff:g>)…}few{جارٍ تعديل <xliff:g id="COUNT">^1</xliff:g> ملفات صوتية…}many{جارٍ تعديل <xliff:g id="COUNT">^1</xliff:g> ملفًا صوتيًا…}other{جارٍ تعديل <xliff:g id="COUNT">^1</xliff:g> ملف صوتي…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{هل تريد السماح لتطبيق <xliff:g id="APP_NAME_0">^1</xliff:g> بتعديل هذا الفيديو؟}zero{هل تريد السماح لتطبيق <xliff:g id="APP_NAME_1">^1</xliff:g> بتعديل <xliff:g id="COUNT">^2</xliff:g> فيديو؟}two{هل تريد السماح لتطبيق <xliff:g id="APP_NAME_1">^1</xliff:g> بتعديل فيديوهين (<xliff:g id="COUNT">^2</xliff:g>)؟}few{هل تريد السماح لتطبيق <xliff:g id="APP_NAME_1">^1</xliff:g> بتعديل <xliff:g id="COUNT">^2</xliff:g> فيديوهات؟}many{هل تريد السماح لتطبيق <xliff:g id="APP_NAME_1">^1</xliff:g> بتعديل <xliff:g id="COUNT">^2</xliff:g> فيديو؟}other{هل تريد السماح لتطبيق <xliff:g id="APP_NAME_1">^1</xliff:g> بتعديل <xliff:g id="COUNT">^2</xliff:g> فيديو؟}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"حماية الأمن الشخصي"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"‏تنبيهات Native Transcode"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"‏مدى تقدُّم Native Transcode"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"يتعذّر تحميل بعض الصور"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"حسنًا"</string>
</resources>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index 25f559634..db0cd53fb 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/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="picker_app_label" msgid="4254039089502164761">"মিডিয়া"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"মিডিয়া বাছনিকৰ্তা"</string>
<string name="artist_label" msgid="8105600993099120273">"শিল্পী"</string>
<string name="unknown" msgid="2059049215682829375">"অজ্ঞাত"</string>
<string name="root_images" msgid="5861633549189045666">"প্ৰতিচ্ছবি"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"ইয়াৰ পৰা ক্লাউড মিডিয়া এক্সেছ কৰক"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"নাই"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"এই সময়ত ক্লাউড মিডিয়া এপ্ সলনি কৰিব নোৱাৰি"</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"মিডিয়া বাছনিকৰ্তা"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"মিডিয়া বাছনিকৰ্তা"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"মিডিয়া ছিংক কৰি থকা হৈছে…"</string>
<string name="add" msgid="2894574044585549298">"যোগ দিয়ক"</string>
<string name="deselect" msgid="4297825044827769490">"বাছনিৰ পৰা আঁতৰাওক"</string>
<string name="deselected" msgid="8488133193326208475">"বাছনিৰ পৰা আঁতৰোৱা হ’ল"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"আপোনাৰ ইণ্টাৰনেট সংযোগ পৰীক্ষা কৰক আৰু পুনৰ চেষ্টা কৰক"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"পুনৰ চেষ্টা কৰক"</string>
<string name="not_selected" msgid="2244008151669896758">"বাছনি কৰা হোৱা নাই"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"আপুনি বাছনি কৰা মিডিয়া সাজু কৰি থকা হৈছে"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> টা বস্তুৰ ভিতৰত <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> টা সাজু"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"এতিয়া বেকআপ লোৱা ফট’সমূহ অন্তৰ্ভুক্ত কৰা হৈছে"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"আপুনি <xliff:g id="APP_NAME">%1$s</xliff:g>ৰ একাউণ্টৰ <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> পৰা ফট’সমূহ বাছনি কৰিব পাৰে"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"এপ্‌ বাছনি কৰক"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"একাউণ্ট বাছনি কৰক"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"একাউণ্ট সলনি কৰক"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"আপোনাৰ আটাইবোৰ ফট’ পাই থকা হৈছে"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g>ক এই অডিঅ’ ফাইলটো সংশোধন কৰিবলৈ অনুমতি দিবনে?}one{<xliff:g id="APP_NAME_1">^1</xliff:g>ক <xliff:g id="COUNT">^2</xliff:g> টা অডিঅ’ ফাইল সংশোধন কৰিবলৈ অনুমতি দিবনে?}other{<xliff:g id="APP_NAME_1">^1</xliff:g>ক <xliff:g id="COUNT">^2</xliff:g> টা অডিঅ’ ফাইল সংশোধন কৰিবলৈ অনুমতি দিবনে?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{অডিঅ’ ফাইলটো সংশোধন কৰি থকা হৈছে…}one{<xliff:g id="COUNT">^1</xliff:g> টা অডিঅ’ ফাইল সংশোধন কৰি থকা হৈছে…}other{<xliff:g id="COUNT">^1</xliff:g> টা অডিঅ’ ফাইল সংশোধন কৰি থকা হৈছে…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g>ক এই ভিডিঅ’টো সংশোধন কৰিবলৈ অনুমতি দিবনে?}one{<xliff:g id="APP_NAME_1">^1</xliff:g>ক <xliff:g id="COUNT">^2</xliff:g> টা ভিডিঅ’ সংশোধন কৰিবলৈ অনুমতি দিবনে?}other{<xliff:g id="APP_NAME_1">^1</xliff:g>ক <xliff:g id="COUNT">^2</xliff:g> টা ভিডিঅ’ সংশোধন কৰিবলৈ অনুমতি দিবনে?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"সুৰক্ষিত নিৰাপত্তা"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"স্থানীয় ট্ৰেন্সক’ড সতৰ্কবাৰ্তা"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"স্থানীয় ট্ৰেন্সক’ড অগ্ৰগতি"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"কিছুমান ফট’ ল’ড কৰিব নোৱাৰি"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"বুজি পালোঁ"</string>
</resources>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index ff42afe61..9fa2b25d3 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Media"</string>
<string name="storage_description" msgid="4081716890357580107">"Yerli yaddaş"</string>
<string name="app_label" msgid="9035307001052716210">"Media Yaddaşı"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Media"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Media seçici"</string>
<string name="artist_label" msgid="8105600993099120273">"Sənətçi"</string>
<string name="unknown" msgid="2059049215682829375">"Naməlum"</string>
<string name="root_images" msgid="5861633549189045666">"Təsvirlər"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Bulud mediasına buradan giriş edin:"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Heç biri"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"İndi bulud media tətbiqini dəyişmək mümkün deyil."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Media seçici"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Media seçici"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Media sinxronlaşdırılır…"</string>
<string name="add" msgid="2894574044585549298">"Əlavə edin"</string>
<string name="deselect" msgid="4297825044827769490">"Seçimi ləğv edin"</string>
<string name="deselected" msgid="8488133193326208475">"Seçimi ləğv edilib"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"İnternet bağlantınızı yoxlayın və yenidən sınayın"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Yenidən cəhd edin"</string>
<string name="not_selected" msgid="2244008151669896758">"seçilməyib"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Seçilmiş media hazırlanır"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>/<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> hazırdır"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Yedəklənmiş fotolar indi daxildir"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"<xliff:g id="APP_NAME">%1$s</xliff:g> hesabından (<xliff:g id="USER_ACCOUNT">%2$s</xliff:g>) fotoları seçə bilərsiniz"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Tətbiq seçin"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Hesab seçin"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Hesabı dəyişdirin"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Bütün fotolar əldə edilir"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> tətbiqinə bu audio fayla dəyişiklik etmək icazəsi verilsin?}other{<xliff:g id="APP_NAME_1">^1</xliff:g> tətbiqinə <xliff:g id="COUNT">^2</xliff:g> audio fayla dəyişiklik etmək icazəsi verilsin?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Audio fayl dəyişdirilir…}other{<xliff:g id="COUNT">^1</xliff:g> audio fayl dəyişdirilir…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> tətbiqinə bu videoya dəyişiklik etmək icazəsi verilsin?}other{<xliff:g id="APP_NAME_1">^1</xliff:g> tətbiqinə <xliff:g id="COUNT">^2</xliff:g> videoya dəyişiklik etmək icazəsi verilsin?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Güvənlik qoruması"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Orijinal Transkod Xəbərdarlıqları"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Orijinal Transkod İrəliləyişi"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Bəzi fotolar yüklənmir"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Anladım"</string>
</resources>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index cc2d31d13..3d759fa64 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Mediji"</string>
<string name="storage_description" msgid="4081716890357580107">"Lokalni memorijski prostor"</string>
<string name="app_label" msgid="9035307001052716210">"Memorijski prostor za medije"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Mediji"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Birač medija"</string>
<string name="artist_label" msgid="8105600993099120273">"Izvođač"</string>
<string name="unknown" msgid="2059049215682829375">"Nepoznato"</string>
<string name="root_images" msgid="5861633549189045666">"Slike"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Pristupajte medijima u klaudu iz"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Ništa"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Promena aplikacije za medije u klaudu nije uspela."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Birač medija"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Birač medija"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Mediji se sinhronizuju…"</string>
<string name="add" msgid="2894574044585549298">"Dodaj"</string>
<string name="deselect" msgid="4297825044827769490">"Opozovi izbor"</string>
<string name="deselected" msgid="8488133193326208475">"Opozvan je izbor"</string>
@@ -53,8 +56,8 @@
<string name="selected" msgid="9151797369975828124">"Izabrano"</string>
<string name="select_up_to" msgid="6994294169508439957">"{count,plural, =1{Izaberite najviše <xliff:g id="COUNT_0">^1</xliff:g> stavku}one{Izaberite najviše <xliff:g id="COUNT_1">^1</xliff:g> stavku}few{Izaberite najviše <xliff:g id="COUNT_1">^1</xliff:g> stavke}other{Izaberite najviše <xliff:g id="COUNT_1">^1</xliff:g> stavki}}"</string>
<string name="recent" msgid="6694613584743207874">"Nedavno"</string>
- <string name="picker_photos_empty_message" msgid="5980619500554575558">"Nema slika niti video snimaka"</string>
- <string name="picker_album_media_empty_message" msgid="7061850698189881671">"Nema podržanih slika niti video snimaka"</string>
+ <string name="picker_photos_empty_message" msgid="5980619500554575558">"Nema slika niti videa"</string>
+ <string name="picker_album_media_empty_message" msgid="7061850698189881671">"Nema podržanih slika niti videa"</string>
<string name="picker_albums_empty_message" msgid="8341079772950966815">"Nema albuma"</string>
<string name="picker_view_selected" msgid="2266031384396143883">"Prikaži izabrano"</string>
<string name="picker_photos" msgid="7415035516411087392">"Slike"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Proverite internet vezu i probajte ponovo"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Probaj ponovo"</string>
<string name="not_selected" msgid="2244008151669896758">"nije izabrano"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Pripremaju se odabrani medijski fajlovi"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"Spremno:<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> od <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Sada su uvrštene rezervne kopije slika"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Možete da izaberete slike sa naloga <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> za <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -106,34 +110,35 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Odaberi aplikaciju"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Odaberi nalog"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Promeni nalog"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Preuzimaju se sve slike"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Želite li da dozvolite da <xliff:g id="APP_NAME_0">^1</xliff:g> izmeni ovaj audio fajl?}one{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izmeni <xliff:g id="COUNT">^2</xliff:g> audio fajl?}few{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izmeni <xliff:g id="COUNT">^2</xliff:g> audio fajla?}other{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izmeni <xliff:g id="COUNT">^2</xliff:g> audio fajlova?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Menja se audio fajl…}one{Menja se <xliff:g id="COUNT">^1</xliff:g> audio fajl…}few{Menjaju se <xliff:g id="COUNT">^1</xliff:g> audio fajla…}other{Menja se <xliff:g id="COUNT">^1</xliff:g> audio fajlova…}}"</string>
- <string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Želite li da dozvolite da <xliff:g id="APP_NAME_0">^1</xliff:g> izmeni ovaj video?}one{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izmeni <xliff:g id="COUNT">^2</xliff:g> video?}few{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izmeni <xliff:g id="COUNT">^2</xliff:g> video snimka?}other{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izmeni <xliff:g id="COUNT">^2</xliff:g> video snimaka?}}"</string>
- <string name="permission_progress_write_video" msgid="7014908418349819148">"{count,plural, =1{Menja se video…}one{Menja se <xliff:g id="COUNT">^1</xliff:g> video…}few{Menjaju se <xliff:g id="COUNT">^1</xliff:g> video snimka…}other{Menja se <xliff:g id="COUNT">^1</xliff:g> video snimaka…}}"</string>
+ <string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Želite li da dozvolite da <xliff:g id="APP_NAME_0">^1</xliff:g> izmeni ovaj video?}one{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izmeni <xliff:g id="COUNT">^2</xliff:g> video?}few{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izmeni <xliff:g id="COUNT">^2</xliff:g> video snimka?}other{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izmeni <xliff:g id="COUNT">^2</xliff:g> videa?}}"</string>
+ <string name="permission_progress_write_video" msgid="7014908418349819148">"{count,plural, =1{Menja se video…}one{Menja se <xliff:g id="COUNT">^1</xliff:g> video…}few{Menjaju se <xliff:g id="COUNT">^1</xliff:g> video snimka…}other{Menja se <xliff:g id="COUNT">^1</xliff:g> videa…}}"</string>
<string name="permission_write_image" msgid="3518991791620523786">"{count,plural, =1{Želite li da dozvolite da <xliff:g id="APP_NAME_0">^1</xliff:g> izmeni ovu sliku?}one{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izmeni <xliff:g id="COUNT">^2</xliff:g> sliku?}few{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izmeni <xliff:g id="COUNT">^2</xliff:g> slike?}other{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izmeni <xliff:g id="COUNT">^2</xliff:g> slika?}}"</string>
<string name="permission_progress_write_image" msgid="3623580315590025262">"{count,plural, =1{Menja se slika…}one{Menja se <xliff:g id="COUNT">^1</xliff:g> slika…}few{Menjaju se <xliff:g id="COUNT">^1</xliff:g> slike…}other{Menja se <xliff:g id="COUNT">^1</xliff:g> slika…}}"</string>
<string name="permission_write_generic" msgid="7431128739233656991">"{count,plural, =1{Želite li da dozvolite da <xliff:g id="APP_NAME_0">^1</xliff:g> izmeni ovu stavku?}one{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izmeni <xliff:g id="COUNT">^2</xliff:g> stavku?}few{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izmeni <xliff:g id="COUNT">^2</xliff:g> stavke?}other{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izmeni <xliff:g id="COUNT">^2</xliff:g> stavki?}}"</string>
<string name="permission_progress_write_generic" msgid="2806560971318391443">"{count,plural, =1{Menja se stavka…}one{Menja se <xliff:g id="COUNT">^1</xliff:g> stavka…}few{Menjaju se <xliff:g id="COUNT">^1</xliff:g> stavke…}other{Menja se <xliff:g id="COUNT">^1</xliff:g> stavki…}}"</string>
<string name="permission_trash_audio" msgid="6554672354767742206">"{count,plural, =1{Želite li da dozvolite da <xliff:g id="APP_NAME_0">^1</xliff:g> premesti ovaj audio fajl u otpad?}one{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> audio fajl u otpad?}few{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> audio fajla u otpad?}other{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> audio fajlova u otpad?}}"</string>
<string name="permission_progress_trash_audio" msgid="3116279868733641329">"{count,plural, =1{Audio fajl se premešta u otpad…}one{<xliff:g id="COUNT">^1</xliff:g> audio fajl se premešta u otpad…}few{<xliff:g id="COUNT">^1</xliff:g> audio fajla se premeštaju u otpad…}other{<xliff:g id="COUNT">^1</xliff:g> audio fajlova se premešta u otpad…}}"</string>
- <string name="permission_trash_video" msgid="7555850843259959642">"{count,plural, =1{Želite li da dozvolite da <xliff:g id="APP_NAME_0">^1</xliff:g> premesti ovaj video u otpad?}one{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> video u otpad?}few{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> video snimka u otpad?}other{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> video snimaka u otpad?}}"</string>
- <string name="permission_progress_trash_video" msgid="4637821778329459681">"{count,plural, =1{Video se premešta u otpad…}one{<xliff:g id="COUNT">^1</xliff:g> video se premešta u otpad…}few{<xliff:g id="COUNT">^1</xliff:g> video snimka se premeštaju u otpad…}other{<xliff:g id="COUNT">^1</xliff:g> video snimaka se premešta u otpad…}}"</string>
+ <string name="permission_trash_video" msgid="7555850843259959642">"{count,plural, =1{Želite li da dozvolite da <xliff:g id="APP_NAME_0">^1</xliff:g> premesti ovaj video u otpad?}one{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> video u otpad?}few{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> video snimka u otpad?}other{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> videa u otpad?}}"</string>
+ <string name="permission_progress_trash_video" msgid="4637821778329459681">"{count,plural, =1{Video se premešta u otpad…}one{<xliff:g id="COUNT">^1</xliff:g> video se premešta u otpad…}few{<xliff:g id="COUNT">^1</xliff:g> video snimka se premeštaju u otpad…}other{<xliff:g id="COUNT">^1</xliff:g> videa se premešta u otpad…}}"</string>
<string name="permission_trash_image" msgid="3333128084684156675">"{count,plural, =1{Želite li da dozvolite da <xliff:g id="APP_NAME_0">^1</xliff:g> premesti ovu sliku u otpad?}one{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> sliku u otpad?}few{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> slike u otpad?}other{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> slika u otpad?}}"</string>
<string name="permission_progress_trash_image" msgid="3063857679090024764">"{count,plural, =1{Slika se premešta u otpad…}one{<xliff:g id="COUNT">^1</xliff:g> slika se premešta u otpad…}few{<xliff:g id="COUNT">^1</xliff:g> slike se premeštaju u otpad…}other{<xliff:g id="COUNT">^1</xliff:g> slika se premešta u otpad…}}"</string>
<string name="permission_trash_generic" msgid="5545420534785075362">"{count,plural, =1{Želite li da dozvolite da <xliff:g id="APP_NAME_0">^1</xliff:g> premesti ovu stavku u otpad?}one{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> stavku u otpad?}few{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> stavke u otpad?}other{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> stavki u otpad?}}"</string>
<string name="permission_progress_trash_generic" msgid="7815124979717814057">"{count,plural, =1{Stavka se premešta u otpad…}one{<xliff:g id="COUNT">^1</xliff:g> stavka se premešta u otpad…}few{<xliff:g id="COUNT">^1</xliff:g> stavke se premeštaju u otpad…}other{<xliff:g id="COUNT">^1</xliff:g> stavki se premešta u otpad…}}"</string>
<string name="permission_untrash_audio" msgid="8404597563284002472">"{count,plural, =1{Želite li da dozvolite da <xliff:g id="APP_NAME_0">^1</xliff:g> premesti ovaj audio fajl iz otpada?}one{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> audio fajl iz otpada?}few{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> audio fajla iz otpada?}other{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> audio fajlova iz otpada?}}"</string>
<string name="permission_progress_untrash_audio" msgid="2775372344946464508">"{count,plural, =1{Audio fajl se premešta iz otpada…}one{<xliff:g id="COUNT">^1</xliff:g> audio fajl se premešta iz otpada…}few{<xliff:g id="COUNT">^1</xliff:g> audio fajla se premeštaju iz otpada…}other{<xliff:g id="COUNT">^1</xliff:g> audio fajlova se premešta iz otpada…}}"</string>
- <string name="permission_untrash_video" msgid="3178914827607608162">"{count,plural, =1{Želite li da dozvolite da <xliff:g id="APP_NAME_0">^1</xliff:g> premesti ovaj video iz otpada?}one{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> video iz otpada?}few{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> video snimka iz otpada?}other{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> video snimaka iz otpada?}}"</string>
- <string name="permission_progress_untrash_video" msgid="5500929409733841567">"{count,plural, =1{Video se premešta iz otpada…}one{<xliff:g id="COUNT">^1</xliff:g> video se premešta iz otpada…}few{<xliff:g id="COUNT">^1</xliff:g> video snimka se premeštaju iz otpada…}other{<xliff:g id="COUNT">^1</xliff:g> video snimaka se premešta iz otpada…}}"</string>
+ <string name="permission_untrash_video" msgid="3178914827607608162">"{count,plural, =1{Želite li da dozvolite da <xliff:g id="APP_NAME_0">^1</xliff:g> premesti ovaj video iz otpada?}one{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> video iz otpada?}few{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> video snimka iz otpada?}other{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> videa iz otpada?}}"</string>
+ <string name="permission_progress_untrash_video" msgid="5500929409733841567">"{count,plural, =1{Video se premešta iz otpada…}one{<xliff:g id="COUNT">^1</xliff:g> video se premešta iz otpada…}few{<xliff:g id="COUNT">^1</xliff:g> video snimka se premeštaju iz otpada…}other{<xliff:g id="COUNT">^1</xliff:g> videa se premešta iz otpada…}}"</string>
<string name="permission_untrash_image" msgid="3397523279351032265">"{count,plural, =1{Želite li da dozvolite da <xliff:g id="APP_NAME_0">^1</xliff:g> premesti ovu sliku iz otpada?}one{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> sliku iz otpada?}few{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> slike iz otpada?}other{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> slika iz otpada?}}"</string>
<string name="permission_progress_untrash_image" msgid="5295061520504846264">"{count,plural, =1{Slika se premešta iz otpada…}one{<xliff:g id="COUNT">^1</xliff:g> slika se premešta iz otpada…}few{<xliff:g id="COUNT">^1</xliff:g> slike se premeštaju iz otpada…}other{<xliff:g id="COUNT">^1</xliff:g> slika se premešta iz otpada…}}"</string>
<string name="permission_untrash_generic" msgid="2118366929431671046">"{count,plural, =1{Želite li da dozvolite da <xliff:g id="APP_NAME_0">^1</xliff:g> premesti ovu stavku iz otpada?}one{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> stavku iz otpada?}few{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> stavke iz otpada?}other{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> premesti <xliff:g id="COUNT">^2</xliff:g> stavki iz otpada?}}"</string>
<string name="permission_progress_untrash_generic" msgid="1489511601966842579">"{count,plural, =1{Stavka se premešta iz otpada…}one{<xliff:g id="COUNT">^1</xliff:g> stavka se premešta iz otpada…}few{<xliff:g id="COUNT">^1</xliff:g> stavke se premeštaju iz otpada…}other{<xliff:g id="COUNT">^1</xliff:g> stavki se premešta iz otpada…}}"</string>
<string name="permission_delete_audio" msgid="3326674742892796627">"{count,plural, =1{Želite li da dozvolite da <xliff:g id="APP_NAME_0">^1</xliff:g> izbriše ovaj audio fajl?}one{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izbriše <xliff:g id="COUNT">^2</xliff:g> audio fajl?}few{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izbriše <xliff:g id="COUNT">^2</xliff:g> audio fajla?}other{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izbriše <xliff:g id="COUNT">^2</xliff:g> audio fajlova?}}"</string>
<string name="permission_progress_delete_audio" msgid="1734871539021696401">"{count,plural, =1{Briše se audio fajl…}one{Briše se <xliff:g id="COUNT">^1</xliff:g> audio fajl…}few{Brišu se <xliff:g id="COUNT">^1</xliff:g> audio fajla…}other{Briše se <xliff:g id="COUNT">^1</xliff:g> audio fajlova…}}"</string>
- <string name="permission_delete_video" msgid="604024971828349279">"{count,plural, =1{Želite li da dozvolite da <xliff:g id="APP_NAME_0">^1</xliff:g> izbriše ovaj video?}one{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izbriše <xliff:g id="COUNT">^2</xliff:g> video?}few{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izbriše <xliff:g id="COUNT">^2</xliff:g> video snimka?}other{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izbriše <xliff:g id="COUNT">^2</xliff:g> video snimaka?}}"</string>
- <string name="permission_progress_delete_video" msgid="1846702435073793157">"{count,plural, =1{Briše se video…}one{Briše se <xliff:g id="COUNT">^1</xliff:g> video…}few{Brišu se <xliff:g id="COUNT">^1</xliff:g> video snimka…}other{Briše se <xliff:g id="COUNT">^1</xliff:g> video snimaka…}}"</string>
+ <string name="permission_delete_video" msgid="604024971828349279">"{count,plural, =1{Želite li da dozvolite da <xliff:g id="APP_NAME_0">^1</xliff:g> izbriše ovaj video?}one{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izbriše <xliff:g id="COUNT">^2</xliff:g> video?}few{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izbriše <xliff:g id="COUNT">^2</xliff:g> video snimka?}other{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izbriše <xliff:g id="COUNT">^2</xliff:g> videa?}}"</string>
+ <string name="permission_progress_delete_video" msgid="1846702435073793157">"{count,plural, =1{Briše se video…}one{Briše se <xliff:g id="COUNT">^1</xliff:g> video…}few{Brišu se <xliff:g id="COUNT">^1</xliff:g> video snimka…}other{Briše se <xliff:g id="COUNT">^1</xliff:g> videa…}}"</string>
<string name="permission_delete_image" msgid="3109056012794330510">"{count,plural, =1{Želite li da dozvolite da <xliff:g id="APP_NAME_0">^1</xliff:g> izbriše ovu sliku?}one{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izbriše <xliff:g id="COUNT">^2</xliff:g> sliku?}few{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izbriše <xliff:g id="COUNT">^2</xliff:g> slike?}other{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izbriše <xliff:g id="COUNT">^2</xliff:g> slika?}}"</string>
<string name="permission_progress_delete_image" msgid="8580517204901148906">"{count,plural, =1{Briše se slika…}one{Briše se <xliff:g id="COUNT">^1</xliff:g> slika…}few{Brišu se <xliff:g id="COUNT">^1</xliff:g> slike…}other{Briše se <xliff:g id="COUNT">^1</xliff:g> slika…}}"</string>
<string name="permission_delete_generic" msgid="7891939881065520271">"{count,plural, =1{Želite li da dozvolite da <xliff:g id="APP_NAME_0">^1</xliff:g> izbriše ovu stavku?}one{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izbriše <xliff:g id="COUNT">^2</xliff:g> stavku?}few{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izbriše <xliff:g id="COUNT">^2</xliff:g> stavke?}other{Želite li da dozvolite da <xliff:g id="APP_NAME_1">^1</xliff:g> izbriše <xliff:g id="COUNT">^2</xliff:g> stavki?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Sigurnosna zaštita"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Obaveštenja o osnovnom transkodiranju"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Tok osnovnog transkodiranja"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Učitavanje nekih slika nije uspelo"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Važi"</string>
</resources>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index f7f5b9713..1b71e81a3 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/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="picker_app_label" msgid="4254039089502164761">"Мультымедыя"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Сродак выбару мультымедыя"</string>
<string name="artist_label" msgid="8105600993099120273">"Выканаўца"</string>
<string name="unknown" msgid="2059049215682829375">"Невядома"</string>
<string name="root_images" msgid="5861633549189045666">"Відарысы"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Доступ да воблачных мультымедыя з:"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Няма"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Воблачныя мультымедыйныя праграмы не зменены."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Сродак выбару мультымедыя"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Сродак выбару мультымедыя"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Ідзе сінхранізацыя мультымедыя…"</string>
<string name="add" msgid="2894574044585549298">"Дадаць"</string>
<string name="deselect" msgid="4297825044827769490">"Адмяніць выбар"</string>
<string name="deselected" msgid="8488133193326208475">"Выбар скасаваны"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Праверце падключэнне да інтэрнэту і паўтарыце спробу"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Паўтарыць спробу"</string>
<string name="not_selected" msgid="2244008151669896758">"не выбраны"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Ідзе падрыхтоўка выбраных вамі медыяфайлаў"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"Гатова: <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> з <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Цяпер дададзены рэзервовыя копіі фотаздымкаў"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Вы можаце выбраць фотаздымкі з уліковага запісу <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> для праграмы \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Выбраць праграму"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Выбраць уліковы запіс"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Змяніць уліковы запіс"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Вашы фота загружаюцца"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Дазволіць праграме \"<xliff:g id="APP_NAME_0">^1</xliff:g>\" змяніць гэты аўдыяфайл?}one{Дазволіць праграме \"<xliff:g id="APP_NAME_1">^1</xliff:g>\" змяніць <xliff:g id="COUNT">^2</xliff:g> аўдыяфайл?}few{Дазволіць праграме \"<xliff:g id="APP_NAME_1">^1</xliff:g>\" змяніць <xliff:g id="COUNT">^2</xliff:g> аўдыяфайлы?}many{Дазволіць праграме \"<xliff:g id="APP_NAME_1">^1</xliff:g>\" змяніць <xliff:g id="COUNT">^2</xliff:g> аўдыяфайлаў?}other{Дазволіць праграме \"<xliff:g id="APP_NAME_1">^1</xliff:g>\" змяніць <xliff:g id="COUNT">^2</xliff:g> аўдыяфайла?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Змяняецца аўдыяфайл…}one{Змяняецца <xliff:g id="COUNT">^1</xliff:g> аўдыяфайл…}few{Змяняюцца <xliff:g id="COUNT">^1</xliff:g> аўдыяфайлы…}many{Змяняюцца <xliff:g id="COUNT">^1</xliff:g> аўдыяфайлаў…}other{Змяняюцца <xliff:g id="COUNT">^1</xliff:g> аўдыяфайла…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Дазволіць праграме \"<xliff:g id="APP_NAME_0">^1</xliff:g>\" змяніць гэта відэа?}one{Дазволіць праграме \"<xliff:g id="APP_NAME_1">^1</xliff:g>\" змяніць <xliff:g id="COUNT">^2</xliff:g> відэа?}few{Дазволіць праграме \"<xliff:g id="APP_NAME_1">^1</xliff:g>\" змяніць <xliff:g id="COUNT">^2</xliff:g> відэа?}many{Дазволіць праграме \"<xliff:g id="APP_NAME_1">^1</xliff:g>\" змяніць <xliff:g id="COUNT">^2</xliff:g> відэа?}other{Дазволіць праграме \"<xliff:g id="APP_NAME_1">^1</xliff:g>\" змяніць <xliff:g id="COUNT">^2</xliff:g> відэа?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Ахова бяспекі"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Абвесткі пра ўбудаванае перакадзіраванне"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Ход убудаванага перакадзіравання"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Некаторыя фота не ўдалося загрузіць"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"OK"</string>
</resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index dbd02206a..adb514e72 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/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="picker_app_label" msgid="4254039089502164761">"Мултимедия"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Инструмент за избор на носители"</string>
<string name="artist_label" msgid="8105600993099120273">"Изпълнител"</string>
<string name="unknown" msgid="2059049215682829375">"Неизвестно"</string>
<string name="root_images" msgid="5861633549189045666">"Изображения"</string>
@@ -39,16 +39,19 @@
<string name="allow" msgid="8885707816848569619">"Разрешаване"</string>
<string name="deny" msgid="6040983710442068936">"Отказ"</string>
<string name="picker_browse" msgid="5554477454636075934">"Преглед…"</string>
- <string name="picker_settings" msgid="6443463167344790260">"Медийно приложение в облака"</string>
+ <string name="picker_settings" msgid="6443463167344790260">"Прил. за мултимедия в облака"</string>
<string name="picker_settings_system_settings_menu_title" msgid="3055084757610063581">"Приложение за мултимедия в облака"</string>
<string name="picker_settings_title" msgid="5647700706470673258">"Приложение за мултимедия в облака"</string>
<string name="picker_settings_description" msgid="2916686824777214585">"Осъществяване на достъп до мултимедията в облака, когато приложение или уебсайт иска от вас да изберете снимки или видеоклипове"</string>
<string name="picker_settings_selection_message" msgid="245453573086488596">"Достъп до мултимедия в облака от"</string>
- <string name="picker_settings_no_provider" msgid="2582311853680058223">"Няма"</string>
+ <string name="picker_settings_no_provider" msgid="2582311853680058223">"Нищо"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Медийното приложение в облака не бе променено."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Инструмент за избор на мултимедия"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Инструмент за избор на мултимедия"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Мултимедията се синхронизира…"</string>
<string name="add" msgid="2894574044585549298">"Добавяне"</string>
<string name="deselect" msgid="4297825044827769490">"Премахване на избора"</string>
- <string name="deselected" msgid="8488133193326208475">"Неизбрано"</string>
+ <string name="deselected" msgid="8488133193326208475">"Отменен избор"</string>
<string name="select" msgid="2704765470563027689">"Избиране"</string>
<string name="selected" msgid="9151797369975828124">"Избрано"</string>
<string name="select_up_to" msgid="6994294169508439957">"{count,plural, =1{Изберете най-много <xliff:g id="COUNT_0">^1</xliff:g> елемент}other{Изберете най-много <xliff:g id="COUNT_1">^1</xliff:g> елемента}}"</string>
@@ -61,7 +64,7 @@
<string name="picker_albums" msgid="4822511902115299142">"Албуми"</string>
<string name="picker_preview" msgid="6257414886055861039">"Визуализация"</string>
<string name="picker_work_profile" msgid="2083221066869141576">"Превкл. към служ. пoтр. профил"</string>
- <string name="picker_personal_profile" msgid="639484258397758406">"Превключване към личния потребителски профил"</string>
+ <string name="picker_personal_profile" msgid="639484258397758406">"Превкл. към личния потр. профил"</string>
<string name="picker_profile_admin_title" msgid="4172022376418293777">"Блокирано от администратора ви"</string>
<string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"Достъпът до служебни данни от лично приложение не е разрешен"</string>
<string name="picker_profile_admin_msg_from_work" msgid="8048524337462790110">"Достъпът до лични данни от служебно приложение не е разрешен"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Проверете връзката си с интернет и опитайте отново"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Нов опит"</string>
<string name="not_selected" msgid="2244008151669896758">"не е избрано"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Избраната от вас мултимедия се подготвя"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"Готови: <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> от <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Снимките, за които е създадено резервно копие, вече са добавени"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Можете да избирате снимки от профила <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> в(ъв) <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Избиране на приложение"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Избиране на профил"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Промяна на профила"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Всичките ви снимки се извличат"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Да се разреши ли на <xliff:g id="APP_NAME_0">^1</xliff:g> да промени този аудиофайл?}other{Да се разреши ли на <xliff:g id="APP_NAME_1">^1</xliff:g> да промени <xliff:g id="COUNT">^2</xliff:g> аудиофайла?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Аудиофайлът се променя…}other{<xliff:g id="COUNT">^1</xliff:g> аудиофайла се променят…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Да се разреши ли на <xliff:g id="APP_NAME_0">^1</xliff:g> да промени този видеоклип?}other{Да се разреши ли на <xliff:g id="APP_NAME_1">^1</xliff:g> да промени <xliff:g id="COUNT">^2</xliff:g> видеоклипа?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Защита на безопасността"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Стандартни сигнали за прекодиране"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Стандартен прогрес при прекодиране"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Някои снимки не могат да се заредят"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Разбрах"</string>
</resources>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index 4ce4bee8a..e0ccfb3c7 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/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="picker_app_label" msgid="4254039089502164761">"মিডিয়া"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"মিডিয়া বাছাইকারি"</string>
<string name="artist_label" msgid="8105600993099120273">"শিল্পী"</string>
<string name="unknown" msgid="2059049215682829375">"অজানা"</string>
<string name="root_images" msgid="5861633549189045666">"ছবি"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"এখান থেকে ক্লাউড মিডিয়া অ্যাক্সেস করুন"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"কোনওটিই নয়"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"এই মুহূর্তে ক্লাউড মিডিয়া অ্যাপ বদল করা যায়নি।"</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"মিডিয়া বাছাইকারী"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"মিডিয়া বাছাইকারী"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"মিডিয়া সিঙ্ক করছে…"</string>
<string name="add" msgid="2894574044585549298">"যোগ করুন"</string>
<string name="deselect" msgid="4297825044827769490">"টিক চিহ্নটি সরিয়ে দিন"</string>
<string name="deselected" msgid="8488133193326208475">"টিকচিহ্ন সরিয়ে দিন"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"ইন্টারনেট কানেকশন ঠিক আছে কিনা দেখে নিয়ে আবার চেষ্টা করুন"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"আবার চেষ্টা করুন"</string>
<string name="not_selected" msgid="2244008151669896758">"বেছে নেওয়া হয়নি"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"আপনার বেছে নেওয়া মিডিয়া রেডি করা হচ্ছে"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>টির মধ্যে <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> নম্বর আইটেম রেডি আছে"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"ব্যাক-আপ নেওয়া ফটো এখন যোগ করা হয়েছে"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"আপনি <xliff:g id="APP_NAME">%1$s</xliff:g>-এর অ্যাকাউন্ট <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> থেকে ফটো বেছে নিতে পারবেন"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"অ্যাপ বেছে নিন"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"অ্যাকাউন্ট বেছে নিন"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"অ্যাকাউন্ট পরিবর্তন করুন"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"আপনার সব ফটো লোড করা হচ্ছে"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g>-কে এই অডিও ফাইল পরিবর্তন করার অনুমতি দিতে চান?}one{<xliff:g id="APP_NAME_1">^1</xliff:g>-কে <xliff:g id="COUNT">^2</xliff:g>টি অডিও ফাইল পরিবর্তন করার অনুমতি দিতে চান?}other{<xliff:g id="APP_NAME_1">^1</xliff:g>-কে <xliff:g id="COUNT">^2</xliff:g>টি অডিও ফাইল পরিবর্তন করার অনুমতি দিতে চান?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{অডিও ফাইলে পরিবর্তন করা হচ্ছে…}one{<xliff:g id="COUNT">^1</xliff:g>টি অডিও ফাইলে পরিবর্তন করা হচ্ছে…}other{<xliff:g id="COUNT">^1</xliff:g>টি অডিও ফাইলে পরিবর্তন করা হচ্ছে…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g>-কে এই ভিডিও পরিবর্তন করার অনুমতি দিতে চান?}one{<xliff:g id="APP_NAME_1">^1</xliff:g>-কে <xliff:g id="COUNT">^2</xliff:g>টি ভিডিও পরিবর্তন করার অনুমতি দিতে চান?}other{<xliff:g id="APP_NAME_1">^1</xliff:g>-কে <xliff:g id="COUNT">^2</xliff:g>টি ভিডিও পরিবর্তন করার অনুমতি দিতে চান?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"নিরাপত্তার সুরক্ষা"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"নেটিভ ট্রান্সকোড অ্যালার্ট"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"নেটিভ ট্রান্সকোড প্রোগ্রেস"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"কিছু ফটো লোড করা যাচ্ছে না"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"বুঝেছি"</string>
</resources>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 99bd07ce2..d701edd1f 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Mediji"</string>
<string name="storage_description" msgid="4081716890357580107">"Lokalna pohrana"</string>
<string name="app_label" msgid="9035307001052716210">"Medijska pohrana"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Medij"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Izbornik medijskog sadržaja"</string>
<string name="artist_label" msgid="8105600993099120273">"Umjetnik"</string>
<string name="unknown" msgid="2059049215682829375">"Nepoznato"</string>
<string name="root_images" msgid="5861633549189045666">"Slike"</string>
@@ -39,16 +39,19 @@
<string name="allow" msgid="8885707816848569619">"Dozvoli"</string>
<string name="deny" msgid="6040983710442068936">"Odbij"</string>
<string name="picker_browse" msgid="5554477454636075934">"Pregledajte…"</string>
- <string name="picker_settings" msgid="6443463167344790260">"Apl. za med. sadržaje u oblaku"</string>
- <string name="picker_settings_system_settings_menu_title" msgid="3055084757610063581">"Aplikacija za medijske sadržaje u oblaku"</string>
+ <string name="picker_settings" msgid="6443463167344790260">"Aplikacija za medije u oblaku"</string>
+ <string name="picker_settings_system_settings_menu_title" msgid="3055084757610063581">"Aplikacija za medije u oblaku"</string>
<string name="picker_settings_title" msgid="5647700706470673258">"Aplikacija za medijske sadržaje u oblaku"</string>
- <string name="picker_settings_description" msgid="2916686824777214585">"Pristupite medijima na oblaku kada vam aplikacija ili web lokacija zatraži da odaberete fotografije ili videozapise"</string>
- <string name="picker_settings_selection_message" msgid="245453573086488596">"Pristupite medijskom sadržaju u oblaku iz"</string>
+ <string name="picker_settings_description" msgid="2916686824777214585">"Pristupite medijima u oblaku kada vam aplikacija ili web lokacija zatraži da odaberete fotografije ili videozapise"</string>
+ <string name="picker_settings_selection_message" msgid="245453573086488596">"Pristupite medijima u oblaku iz oblaku iz"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Ništa"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Promjena medijske aplikacije u oblaku nije uspjela."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Izbornik medijskog sadržaja"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Izbornik medijskog sadržaja"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Sinhroniziranje medijskog sadržaja…"</string>
<string name="add" msgid="2894574044585549298">"Dodaj"</string>
<string name="deselect" msgid="4297825044827769490">"Poništi odabir"</string>
- <string name="deselected" msgid="8488133193326208475">"Odabir poništen"</string>
+ <string name="deselected" msgid="8488133193326208475">"Odabir je poništen"</string>
<string name="select" msgid="2704765470563027689">"Odaberi"</string>
<string name="selected" msgid="9151797369975828124">"Odabrano"</string>
<string name="select_up_to" msgid="6994294169508439957">"{count,plural, =1{Odaberite najviše <xliff:g id="COUNT_0">^1</xliff:g> stavku}one{Odaberite najviše <xliff:g id="COUNT_1">^1</xliff:g> stavku}few{Odaberite najviše <xliff:g id="COUNT_1">^1</xliff:g> stavke}other{Odaberite najviše <xliff:g id="COUNT_1">^1</xliff:g> stavki}}"</string>
@@ -60,8 +63,8 @@
<string name="picker_photos" msgid="7415035516411087392">"Fotografije"</string>
<string name="picker_albums" msgid="4822511902115299142">"Albumi"</string>
<string name="picker_preview" msgid="6257414886055861039">"Pregled"</string>
- <string name="picker_work_profile" msgid="2083221066869141576">"Prebacite se na radni"</string>
- <string name="picker_personal_profile" msgid="639484258397758406">"Prebacite se na lični"</string>
+ <string name="picker_work_profile" msgid="2083221066869141576">"Prebacite se na radni profil"</string>
+ <string name="picker_personal_profile" msgid="639484258397758406">"Prebacite se na lični profil profil"</string>
<string name="picker_profile_admin_title" msgid="4172022376418293777">"Blokirao je administrator"</string>
<string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"Pristupanje poslovnim podacima iz lične aplikacije nije dozvoljeno"</string>
<string name="picker_profile_admin_msg_from_work" msgid="8048524337462790110">"Pristupanje ličnim podacima iz poslovne aplikacije nije dozvoljeno"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Provjerite internetsku vezu i pokušajte ponovo"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Pokušaj ponovo"</string>
<string name="not_selected" msgid="2244008151669896758">"nije odabrano"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Pripremanje odabranih medijskih fajlova"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"Spremno: <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> od <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Sigurnosne kopije fotografija su sada uključene"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Možete odabrati fotografije s računa <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> u aplikaciji <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Odaberite aplikaciju"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Odaberite račun"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Promijenite račun"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Dohvatanje svih fotografija"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Dozvoliti da <xliff:g id="APP_NAME_0">^1</xliff:g> izmijeni ovaj audio fajl?}one{Dozvoliti da <xliff:g id="APP_NAME_1">^1</xliff:g> izmijeni <xliff:g id="COUNT">^2</xliff:g> audio fajl?}few{Dozvoliti da <xliff:g id="APP_NAME_1">^1</xliff:g> izmijeni <xliff:g id="COUNT">^2</xliff:g> audio fajla?}other{Dozvoliti da <xliff:g id="APP_NAME_1">^1</xliff:g> izmijeni <xliff:g id="COUNT">^2</xliff:g> audio fajlova?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Mijenjanje audio fajla…}one{Mijenjanje <xliff:g id="COUNT">^1</xliff:g> audio fajla…}few{Mijenjanje <xliff:g id="COUNT">^1</xliff:g> audio fajla…}other{Mijenjanje <xliff:g id="COUNT">^1</xliff:g> audio fajlova…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Dozvoliti da <xliff:g id="APP_NAME_0">^1</xliff:g> izmijeni ovaj videozapis?}one{Dozvoliti da <xliff:g id="APP_NAME_1">^1</xliff:g> izmijeni <xliff:g id="COUNT">^2</xliff:g> videozapis?}few{Dozvoliti da <xliff:g id="APP_NAME_1">^1</xliff:g> izmijeni <xliff:g id="COUNT">^2</xliff:g> videozapisa?}other{Dozvoliti da <xliff:g id="APP_NAME_1">^1</xliff:g> izmijeni <xliff:g id="COUNT">^2</xliff:g> videozapisa?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Zaštita sigurnosti"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Obavještenja o izvornom konvertiranju"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Napredak izvornog konvertiranja"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Nije moguće učitati određene fotografije"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Razumijem"</string>
</resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 34a682c6e..b99c99d0d 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Multimèdia"</string>
<string name="storage_description" msgid="4081716890357580107">"Emmagatzematge local"</string>
<string name="app_label" msgid="9035307001052716210">"Emmagatzematge multimèdia"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Contingut multimèdia"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Selector de mitjans"</string>
<string name="artist_label" msgid="8105600993099120273">"Artista"</string>
<string name="unknown" msgid="2059049215682829375">"Desconegut"</string>
<string name="root_images" msgid="5861633549189045666">"Imatges"</string>
@@ -40,12 +40,15 @@
<string name="deny" msgid="6040983710442068936">"Denega"</string>
<string name="picker_browse" msgid="5554477454636075934">"Navega…"</string>
<string name="picker_settings" msgid="6443463167344790260">"Aplicació multimèdia al núvol"</string>
- <string name="picker_settings_system_settings_menu_title" msgid="3055084757610063581">"Aplicació multimèdia al núvol"</string>
+ <string name="picker_settings_system_settings_menu_title" msgid="3055084757610063581">"App multimèdia al núvol"</string>
<string name="picker_settings_title" msgid="5647700706470673258">"Aplicació multimèdia al núvol"</string>
<string name="picker_settings_description" msgid="2916686824777214585">"Accedeix al contingut multimèdia al núvol si una aplicació o un lloc web et demana que seleccionis fotos o vídeos"</string>
<string name="picker_settings_selection_message" msgid="245453573086488596">"Accedeix al contingut multimèdia al núvol des de"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Cap"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"No s\'ha pogut canviar l\'app multimèdia al núvol."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Selector de mitjans"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Selector de mitjans"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"S\'està sincronitzant el contingut multimèdia…"</string>
<string name="add" msgid="2894574044585549298">"Afegeix"</string>
<string name="deselect" msgid="4297825044827769490">"Desselecciona"</string>
<string name="deselected" msgid="8488133193326208475">"Desseleccionat"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Comprova la connexió a Internet i torna-ho a provar"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Torna-ho a provar"</string>
<string name="not_selected" msgid="2244008151669896758">"no seleccionat"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"S\'està preparant el contingut multimèdia seleccionat"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> de <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> a punt"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Ara s\'ha inclòs la còpia de seguretat de les fotos"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Pots seleccionar fotos del compte de <xliff:g id="APP_NAME">%1$s</xliff:g> de <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Tria una aplicació"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Tria un compte"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Canvia de compte"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"S\'estan obtenint totes les teves fotos"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Vols permetre que <xliff:g id="APP_NAME_0">^1</xliff:g> modifiqui aquest fitxer d\'àudio?}many{Vols permetre que <xliff:g id="APP_NAME_1">^1</xliff:g> modifiqui <xliff:g id="COUNT">^2</xliff:g> fitxers d\'àudio?}other{Vols permetre que <xliff:g id="APP_NAME_1">^1</xliff:g> modifiqui <xliff:g id="COUNT">^2</xliff:g> fitxers d\'àudio?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{S\'està modificant el fitxer d\'àudio…}many{S\'estan modificant <xliff:g id="COUNT">^1</xliff:g> fitxers d\'àudio…}other{S\'estan modificant <xliff:g id="COUNT">^1</xliff:g> fitxers d\'àudio…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Vols permetre que <xliff:g id="APP_NAME_0">^1</xliff:g> modifiqui aquest vídeo?}many{Vols permetre que <xliff:g id="APP_NAME_1">^1</xliff:g> modifiqui <xliff:g id="COUNT">^2</xliff:g> vídeos?}other{Vols permetre que <xliff:g id="APP_NAME_1">^1</xliff:g> modifiqui <xliff:g id="COUNT">^2</xliff:g> vídeos?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Protecció de seguretat"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Alertes de transcodificació nativa"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Progrés de la transcodificació nativa"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"No es poden carregar algunes fotos"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Entesos"</string>
</resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 05f934c38..0363ca530 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Média"</string>
<string name="storage_description" msgid="4081716890357580107">"Místní úložiště"</string>
<string name="app_label" msgid="9035307001052716210">"Úložiště médií"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Média"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Nástroj pro výběr médií"</string>
<string name="artist_label" msgid="8105600993099120273">"Interpret"</string>
<string name="unknown" msgid="2059049215682829375">"Neznámý"</string>
<string name="root_images" msgid="5861633549189045666">"Obrázky"</string>
@@ -42,10 +42,13 @@
<string name="picker_settings" msgid="6443463167344790260">"Aplikace pro cloudová média"</string>
<string name="picker_settings_system_settings_menu_title" msgid="3055084757610063581">"Aplikace pro cloudová média"</string>
<string name="picker_settings_title" msgid="5647700706470673258">"Aplikace pro cloudová média"</string>
- <string name="picker_settings_description" msgid="2916686824777214585">"Když vás aplikace nebo web požádá o výběr fotografií nebo videí, přejít na vaše cloudová média"</string>
+ <string name="picker_settings_description" msgid="2916686824777214585">"Když vás aplikace nebo web požádá o výběr fotografií nebo videí, můžete přejít na svoje cloudová média"</string>
<string name="picker_settings_selection_message" msgid="245453573086488596">"Přístup ke cloudovým médiím z"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Žádný"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Aplikaci pro cloudová média nyní nelze změnit."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Nástroj pro výběr médií"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Nástroj pro výběr médií"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Synchronizace médií…"</string>
<string name="add" msgid="2894574044585549298">"Přidat"</string>
<string name="deselect" msgid="4297825044827769490">"Zrušit výběr"</string>
<string name="deselected" msgid="8488133193326208475">"Výběr zrušen"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Zkontrolujte připojení k internetu a zkuste to znovu"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Zkusit znovu"</string>
<string name="not_selected" msgid="2244008151669896758">"nevybráno"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Příprava vámi vybraných médií"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"Připraveno: <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> z <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Teď jsou zde zahrnuty zálohované fotky"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Můžete vybrat fotky z účtu <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Vybrat aplikaci"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Vybrat účet"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Změnit účet"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Načítání všech fotek"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Povolit aplikaci <xliff:g id="APP_NAME_0">^1</xliff:g> upravit tento zvukový soubor?}few{Povolit aplikaci <xliff:g id="APP_NAME_1">^1</xliff:g> upravit <xliff:g id="COUNT">^2</xliff:g> zvukové soubory?}many{Povolit aplikaci <xliff:g id="APP_NAME_1">^1</xliff:g> upravit <xliff:g id="COUNT">^2</xliff:g> zvukového souboru?}other{Povolit aplikaci <xliff:g id="APP_NAME_1">^1</xliff:g> upravit <xliff:g id="COUNT">^2</xliff:g> zvukových souborů?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Úprava zvukového souboru…}few{Úprava <xliff:g id="COUNT">^1</xliff:g> zvukových souborů…}many{Úprava <xliff:g id="COUNT">^1</xliff:g> zvukového souboru…}other{Úprava <xliff:g id="COUNT">^1</xliff:g> zvukových souborů…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Povolit aplikaci <xliff:g id="APP_NAME_0">^1</xliff:g> upravit toto video?}few{Povolit aplikaci <xliff:g id="APP_NAME_1">^1</xliff:g> upravit <xliff:g id="COUNT">^2</xliff:g> videa?}many{Povolit aplikaci <xliff:g id="APP_NAME_1">^1</xliff:g> upravit <xliff:g id="COUNT">^2</xliff:g> videa?}other{Povolit aplikaci <xliff:g id="APP_NAME_1">^1</xliff:g> upravit <xliff:g id="COUNT">^2</xliff:g> videí?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Bezpečnostní ochrana"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Upozornění na nativní překódování"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Průběh nativního překódování"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Některé fotografie nelze načíst"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Rozumím"</string>
</resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 65d3a01b1..9417aab79 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Medier"</string>
<string name="storage_description" msgid="4081716890357580107">"Lokalt lager"</string>
<string name="app_label" msgid="9035307001052716210">"Medielagring"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Mediefiler"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Medievælger"</string>
<string name="artist_label" msgid="8105600993099120273">"Kunstner"</string>
<string name="unknown" msgid="2059049215682829375">"Ukendt"</string>
<string name="root_images" msgid="5861633549189045666">"Billeder"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Få adgang til medier i skyen via"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Ingen"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Skymedieappen kunne ikke ændres"</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Medievælger"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Medievælger"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Mediet synkroniseres…"</string>
<string name="add" msgid="2894574044585549298">"Tilføj"</string>
<string name="deselect" msgid="4297825044827769490">"Fravælg"</string>
<string name="deselected" msgid="8488133193326208475">"Fravalgt"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Tjek din internetforbindelse, og prøv igen"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Prøv igen"</string>
<string name="not_selected" msgid="2244008151669896758">"ikke valgt"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Dine valgte medier gøres klar"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> af <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> er klar"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Sikkerhedskopierede billeder er nu inkluderet"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Du kan vælge billeder fra <xliff:g id="APP_NAME">%1$s</xliff:g>-kontoen <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Vælg app"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Vælg en konto"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Skift konto"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Indlæser alle dine billeder"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Vil du give <xliff:g id="APP_NAME_0">^1</xliff:g> tilladelse til at ændre denne lydfil?}one{Vil du give <xliff:g id="APP_NAME_1">^1</xliff:g> tilladelse til at ændre <xliff:g id="COUNT">^2</xliff:g> lydfil?}other{Vil du give <xliff:g id="APP_NAME_1">^1</xliff:g> tilladelse til at ændre <xliff:g id="COUNT">^2</xliff:g> lydfiler?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Ændrer lydfilen…}one{Ændrer <xliff:g id="COUNT">^1</xliff:g> lydfil…}other{Ændrer <xliff:g id="COUNT">^1</xliff:g> lydfiler…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Vil du give <xliff:g id="APP_NAME_0">^1</xliff:g> tilladelse til at ændre denne video?}one{Vil du give <xliff:g id="APP_NAME_1">^1</xliff:g> tilladelse til at ændre <xliff:g id="COUNT">^2</xliff:g> video?}other{Vil du give <xliff:g id="APP_NAME_1">^1</xliff:g> tilladelse til at ændre <xliff:g id="COUNT">^2</xliff:g> videoer?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Beskyttelse"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Underretninger om indbygget omkodning"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Status på indbygget omkodning"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Nogle billeder kan ikke indlæses"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"OK"</string>
</resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 716a0f23a..9a63210d6 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Medien"</string>
<string name="storage_description" msgid="4081716890357580107">"Lokaler Speicher"</string>
<string name="app_label" msgid="9035307001052716210">"Medienspeicher"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Medien"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Media-Auswahl"</string>
<string name="artist_label" msgid="8105600993099120273">"Interpret"</string>
<string name="unknown" msgid="2059049215682829375">"Unbekannt"</string>
<string name="root_images" msgid="5861633549189045666">"Bilder"</string>
@@ -42,10 +42,13 @@
<string name="picker_settings" msgid="6443463167344790260">"Cloud-Medien-App"</string>
<string name="picker_settings_system_settings_menu_title" msgid="3055084757610063581">"Cloud-Medien-App"</string>
<string name="picker_settings_title" msgid="5647700706470673258">"Cloud-Medien-App"</string>
- <string name="picker_settings_description" msgid="2916686824777214585">"Zugriff auf Cloudmedien, wenn dich eine App oder Website darum bittet, Fotos oder Videos auszuwählen"</string>
+ <string name="picker_settings_description" msgid="2916686824777214585">"Zugriff auf Cloud-Medien, wenn dich eine App oder Website darum bittet, Fotos oder Videos auszuwählen"</string>
<string name="picker_settings_selection_message" msgid="245453573086488596">"Zugriff auf Cloud-Medien aus"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Keine"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Ändern der Cloud-Medien-App derzeit nicht möglich."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Media-Auswahl"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Media-Auswahl"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Medien werden synchronisiert…"</string>
<string name="add" msgid="2894574044585549298">"Hinzufügen"</string>
<string name="deselect" msgid="4297825044827769490">"Auswahl aufheben"</string>
<string name="deselected" msgid="8488133193326208475">"Auswahl aufgehoben"</string>
@@ -93,19 +96,21 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Prüfe deine Internetverbindung und versuche es noch einmal"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Wiederholen"</string>
<string name="not_selected" msgid="2244008151669896758">"nicht ausgewählt"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Ausgewählte Medien werden vorbereitet"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> von <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> fertig"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Gesicherte Fotos jetzt mit berücksichtigt"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Du kannst Fotos aus dem <xliff:g id="APP_NAME">%1$s</xliff:g>-Konto <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> auswählen"</string>
<string name="picker_banner_cloud_account_changed_title" msgid="4825058474378077327">"<xliff:g id="APP_NAME">%1$s</xliff:g>-Konto aktualisiert"</string>
<string name="picker_banner_cloud_account_changed_desc" msgid="3433218869899792497">"Fotos von <xliff:g id="USER_ACCOUNT">%1$s</xliff:g> sind jetzt hier mit berücksichtigt"</string>
- <string name="picker_banner_cloud_choose_app_title" msgid="3165966147547974251">"Cloudmedien-App auswählen"</string>
- <string name="picker_banner_cloud_choose_app_desc" msgid="2359212653555524926">"Damit gesicherte Fotos hier mit berücksichtigt werden, wähle eine Cloudmedien-App in den Einstellungen aus"</string>
+ <string name="picker_banner_cloud_choose_app_title" msgid="3165966147547974251">"Cloud-Medien-App auswählen"</string>
+ <string name="picker_banner_cloud_choose_app_desc" msgid="2359212653555524926">"Damit gesicherte Fotos hier mit berücksichtigt werden, wähle eine Cloud-Medien-App in den Einstellungen aus"</string>
<string name="picker_banner_cloud_choose_account_title" msgid="5010901185639577685">"<xliff:g id="APP_NAME">%1$s</xliff:g>-Konto auswählen"</string>
<string name="picker_banner_cloud_choose_account_desc" msgid="8868134443673142712">"Damit Fotos von <xliff:g id="APP_NAME">%1$s</xliff:g> hier mit berücksichtigt werden, wähle eine Konto in der App aus"</string>
<string name="picker_banner_cloud_dismiss_button" msgid="2935903078288463882">"Schließen"</string>
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"App auswählen"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Konto auswählen"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Konto ändern"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Alle deine Fotos werden geladen"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Darf <xliff:g id="APP_NAME_0">^1</xliff:g> diese Audiodatei ändern?}other{Darf <xliff:g id="APP_NAME_1">^1</xliff:g> <xliff:g id="COUNT">^2</xliff:g> Audiodateien ändern?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Audiodatei wird geändert…}other{<xliff:g id="COUNT">^1</xliff:g> Audiodateien werden geändert…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Darf <xliff:g id="APP_NAME_0">^1</xliff:g> dieses Video ändern?}other{Darf <xliff:g id="APP_NAME_1">^1</xliff:g> <xliff:g id="COUNT">^2</xliff:g> Videos ändern?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Schutz"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Warnmeldungen bei nativer Transcodierung"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Fortschritt bei nativer Transcodierung"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Einige Fotos konnten nicht geladen werden"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Ok"</string>
</resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index a4beb6a82..f8aefdbc3 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/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="picker_app_label" msgid="4254039089502164761">"Μέσα"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Εργαλείο επιλογής μέσων"</string>
<string name="artist_label" msgid="8105600993099120273">"Καλλιτέχνης"</string>
<string name="unknown" msgid="2059049215682829375">"Άγνωστο"</string>
<string name="root_images" msgid="5861633549189045666">"Εικόνες"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Πρόσβαση σε μέσα στο cloud από"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Καμία"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Η αλλαγή της εφαρμογής μέσων cloud ήταν αδύνατη."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Εργαλείο επιλογής μέσων"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Εργαλείο επιλογής μέσων"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Συγχρονισμός μέσων…"</string>
<string name="add" msgid="2894574044585549298">"Προσθήκη"</string>
<string name="deselect" msgid="4297825044827769490">"Αποεπιλογή"</string>
<string name="deselected" msgid="8488133193326208475">"Αποεπιλέχθηκε"</string>
@@ -55,7 +58,7 @@
<string name="recent" msgid="6694613584743207874">"Πρόσφατα"</string>
<string name="picker_photos_empty_message" msgid="5980619500554575558">"Δεν υπάρχουν φωτογραφίες ή βίντεο"</string>
<string name="picker_album_media_empty_message" msgid="7061850698189881671">"Δεν υπάρχουν υποστηριζόμενες φωτογραφίες ή βίντεο"</string>
- <string name="picker_albums_empty_message" msgid="8341079772950966815">"Δεν υπάρχουν λευκώματα"</string>
+ <string name="picker_albums_empty_message" msgid="8341079772950966815">"Δεν υπάρχουν άλμπουμ"</string>
<string name="picker_view_selected" msgid="2266031384396143883">"Προβολή επιλεγμένων"</string>
<string name="picker_photos" msgid="7415035516411087392">"Φωτογραφίες"</string>
<string name="picker_albums" msgid="4822511902115299142">"Άλμπουμ"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Ελέγξτε τη σύνδεσή σας στο διαδίκτυο και δοκιμάστε ξανά"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Επανάληψη"</string>
<string name="not_selected" msgid="2244008151669896758">"μη επιλεγμένο"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Προετοιμασία των μέσων που επιλέξατε"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> από <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> έτοιμα"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Συμπεριλαμβάνονται πλέον φωτογραφίες που έχουν αντίγραφα ασφαλείας"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Μπορείτε να επιλέξετε φωτογραφίες από τον λογαριασμό <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> στην εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Επιλογή εφαρμογής"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Επιλογή λογαριασμού"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Αλλαγή λογαριασμού"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Γίνεται λήψη όλων των φωτογραφιών σας"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Να επιτραπεί στην εφαρμογή <xliff:g id="APP_NAME_0">^1</xliff:g> η τροποποίηση αυτού του αρχείου ήχου;}other{Να επιτραπεί στην εφαρμογή <xliff:g id="APP_NAME_1">^1</xliff:g> η τροποποίηση <xliff:g id="COUNT">^2</xliff:g> αρχείων ήχου;}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Τροποποίηση αρχείου ήχου…}other{Τροποποίηση <xliff:g id="COUNT">^1</xliff:g> αρχείων ήχου…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Να επιτραπεί στην εφαρμογή <xliff:g id="APP_NAME_0">^1</xliff:g> η τροποποίηση αυτού του βίντεο;}other{Να επιτραπεί στην εφαρμογή <xliff:g id="APP_NAME_1">^1</xliff:g> η τροποποίηση <xliff:g id="COUNT">^2</xliff:g> βίντεο;}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Safety Protection"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Ειδοποιήσεις εγγενούς διακωδικοποίησης"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Πρόοδος εγγενούς διακωδικοποίησης"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Δεν είναι δυνατή η φόρτωση ορισμένων φωτογραφιών"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Το κατάλαβα"</string>
</resources>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index 28f903e32..390d946cd 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Media"</string>
<string name="storage_description" msgid="4081716890357580107">"Local storage"</string>
<string name="app_label" msgid="9035307001052716210">"Media Storage"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Media"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Media picker"</string>
<string name="artist_label" msgid="8105600993099120273">"Artist"</string>
<string name="unknown" msgid="2059049215682829375">"Unknown"</string>
<string name="root_images" msgid="5861633549189045666">"Images"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Access cloud media from"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"None"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Could not change cloud media app at this time."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Media Picker"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Media Picker"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Syncing media…"</string>
<string name="add" msgid="2894574044585549298">"Add"</string>
<string name="deselect" msgid="4297825044827769490">"Deselect"</string>
<string name="deselected" msgid="8488133193326208475">"Deselected"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Please check your Internet connection and try again"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Retry"</string>
<string name="not_selected" msgid="2244008151669896758">"not selected"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Preparing your selected media"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> of <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> ready"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Backed up photos now included"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"You can select photos from <xliff:g id="APP_NAME">%1$s</xliff:g> account <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Choose app"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Choose account"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Change account"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Getting all your photos"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Allow <xliff:g id="APP_NAME_0">^1</xliff:g> to modify this audio file?}other{Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to modify <xliff:g id="COUNT">^2</xliff:g> audio files?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Modifying audio file…}other{Modifying <xliff:g id="COUNT">^1</xliff:g> audio files…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Allow <xliff:g id="APP_NAME_0">^1</xliff:g> to modify this video?}other{Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to modify <xliff:g id="COUNT">^2</xliff:g> videos?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Safety protection"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Native transcode alerts"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Native transcode progress"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Can\'t load some Photos"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Got it"</string>
</resources>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index 2a0225f8a..209bf8f0e 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Media"</string>
<string name="storage_description" msgid="4081716890357580107">"Local storage"</string>
<string name="app_label" msgid="9035307001052716210">"Media Storage"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Media"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Media picker"</string>
<string name="artist_label" msgid="8105600993099120273">"Artist"</string>
<string name="unknown" msgid="2059049215682829375">"Unknown"</string>
<string name="root_images" msgid="5861633549189045666">"Images"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Access cloud media from"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"None"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Could not change cloud media app at this time."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Media picker"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Media picker"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Syncing media…"</string>
<string name="add" msgid="2894574044585549298">"Add"</string>
<string name="deselect" msgid="4297825044827769490">"Deselect"</string>
<string name="deselected" msgid="8488133193326208475">"Deselected"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Check your internet connection and try again"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Retry"</string>
<string name="not_selected" msgid="2244008151669896758">"not selected"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Preparing your selected media"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> of <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> ready"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Backed up photos now included"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"You can select photos from <xliff:g id="APP_NAME">%1$s</xliff:g> account <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Choose app"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Choose account"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Change account"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Getting all your photos"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Allow <xliff:g id="APP_NAME_0">^1</xliff:g> to modify this audio file?}other{Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to modify <xliff:g id="COUNT">^2</xliff:g> audio files?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Modifying audio file…}other{Modifying <xliff:g id="COUNT">^1</xliff:g> audio files…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Allow <xliff:g id="APP_NAME_0">^1</xliff:g> to modify this video?}other{Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to modify <xliff:g id="COUNT">^2</xliff:g> videos?}}"</string>
@@ -149,4 +154,7 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Safety protection"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Native Transcode Alerts"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Native Transcode Progress"</string>
+ <string name="dialog_error_message" msgid="5120432204743681606">"Try again later. Your photos will be available once the issue is resolved."</string>
+ <string name="dialog_error_title" msgid="636349284077820636">"Can\'t load some Photos"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Got it"</string>
</resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 28f903e32..390d946cd 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Media"</string>
<string name="storage_description" msgid="4081716890357580107">"Local storage"</string>
<string name="app_label" msgid="9035307001052716210">"Media Storage"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Media"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Media picker"</string>
<string name="artist_label" msgid="8105600993099120273">"Artist"</string>
<string name="unknown" msgid="2059049215682829375">"Unknown"</string>
<string name="root_images" msgid="5861633549189045666">"Images"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Access cloud media from"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"None"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Could not change cloud media app at this time."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Media Picker"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Media Picker"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Syncing media…"</string>
<string name="add" msgid="2894574044585549298">"Add"</string>
<string name="deselect" msgid="4297825044827769490">"Deselect"</string>
<string name="deselected" msgid="8488133193326208475">"Deselected"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Please check your Internet connection and try again"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Retry"</string>
<string name="not_selected" msgid="2244008151669896758">"not selected"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Preparing your selected media"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> of <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> ready"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Backed up photos now included"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"You can select photos from <xliff:g id="APP_NAME">%1$s</xliff:g> account <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Choose app"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Choose account"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Change account"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Getting all your photos"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Allow <xliff:g id="APP_NAME_0">^1</xliff:g> to modify this audio file?}other{Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to modify <xliff:g id="COUNT">^2</xliff:g> audio files?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Modifying audio file…}other{Modifying <xliff:g id="COUNT">^1</xliff:g> audio files…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Allow <xliff:g id="APP_NAME_0">^1</xliff:g> to modify this video?}other{Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to modify <xliff:g id="COUNT">^2</xliff:g> videos?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Safety protection"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Native transcode alerts"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Native transcode progress"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Can\'t load some Photos"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Got it"</string>
</resources>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 28f903e32..390d946cd 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Media"</string>
<string name="storage_description" msgid="4081716890357580107">"Local storage"</string>
<string name="app_label" msgid="9035307001052716210">"Media Storage"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Media"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Media picker"</string>
<string name="artist_label" msgid="8105600993099120273">"Artist"</string>
<string name="unknown" msgid="2059049215682829375">"Unknown"</string>
<string name="root_images" msgid="5861633549189045666">"Images"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Access cloud media from"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"None"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Could not change cloud media app at this time."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Media Picker"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Media Picker"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Syncing media…"</string>
<string name="add" msgid="2894574044585549298">"Add"</string>
<string name="deselect" msgid="4297825044827769490">"Deselect"</string>
<string name="deselected" msgid="8488133193326208475">"Deselected"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Please check your Internet connection and try again"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Retry"</string>
<string name="not_selected" msgid="2244008151669896758">"not selected"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Preparing your selected media"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> of <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> ready"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Backed up photos now included"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"You can select photos from <xliff:g id="APP_NAME">%1$s</xliff:g> account <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Choose app"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Choose account"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Change account"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Getting all your photos"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Allow <xliff:g id="APP_NAME_0">^1</xliff:g> to modify this audio file?}other{Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to modify <xliff:g id="COUNT">^2</xliff:g> audio files?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Modifying audio file…}other{Modifying <xliff:g id="COUNT">^1</xliff:g> audio files…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Allow <xliff:g id="APP_NAME_0">^1</xliff:g> to modify this video?}other{Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to modify <xliff:g id="COUNT">^2</xliff:g> videos?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Safety protection"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Native transcode alerts"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Native transcode progress"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Can\'t load some Photos"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Got it"</string>
</resources>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
index bb86af760..938928f33 100644
--- a/res/values-en-rXC/strings.xml
+++ b/res/values-en-rXC/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‎‎‏‏‎‏‏‎‏‎‏‎‎‏‎‎‎‎‎‎‎‎‏‏‎‏‎‎‎‎‎‎‏‏‎‏‎‎‏‏‏‏‏‏‎‎‏‏‎‎‎Media‎‏‎‎‏‎"</string>
<string name="storage_description" msgid="4081716890357580107">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‎‏‎‏‎‎‏‎‏‎‏‏‏‏‏‎‎‎‏‎‏‏‎‎‏‎‏‏‎‏‏‏‏‎‎‏‏‏‎‎‎‎‎‏‎‏‎‎‏‎‏‏‎Local storage‎‏‎‎‏‎"</string>
<string name="app_label" msgid="9035307001052716210">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‎‎‏‎‏‏‎‎‎‏‏‎‏‏‏‎‎‏‎‏‏‎‎‏‎‎Media Storage‎‏‎‎‏‎"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‎‎‏‎‏‏‎‎‎‏‎‎‎‎‎‎‎‏‏‎‏‎‏‎‏‏‎‎‏‏‎‎‏‏‏‎‎‎‏‎‏‏‏‎‎‎‏‏‎‎‏‎Media‎‏‎‎‏‎"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‏‎‏‏‏‎‎‎‎‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎Media picker‎‏‎‎‏‎"</string>
<string name="artist_label" msgid="8105600993099120273">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‎‎‏‎‏‎‎‎‎‏‏‎‏‏‎‎‏‎‏‏‏‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎Artist‎‏‎‎‏‎"</string>
<string name="unknown" msgid="2059049215682829375">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‎‎‏‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‏‎‎‎‏‏‎‎‏‏‏‏‎‏‎‎‏‎‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‎Unknown‎‏‎‎‏‎"</string>
<string name="root_images" msgid="5861633549189045666">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎‏‎‏‎‎‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‎‎‏‏‎‏‏‏‎‏‏‎‏‎‎‎‏‎‎Images‎‏‎‎‏‎"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‏‏‎‏‎‎‎‎‎‎‎‎‏‏‎‏‎‏‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‏‎‏‎‏‏‏‎‏‎‏‎‎‎‎‎‎‏‎‏‎‎‎Access cloud media from‎‏‎‎‏‎"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‏‎‏‏‎‎‎‏‏‎‏‏‎‏‏‏‏‎‎‏‏‎‎‎‎‎‎‎‏‏‏‏‎‎‎‎‏‎‏‎‏‏‏‏‏‎‏‏‎‏‏‏‏‎None‎‏‎‎‏‎"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‏‎‏‏‎‏‎‎‏‏‎‏‏‏‎‏‏‎‏‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‏‎‏‎‎‏‏‎‎‏‎‎‎‎‎‎‏‏‎‏‎Could not change cloud media app at this time.‎‏‎‎‏‎"</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‎‏‎‎‏‎‏‎‎‏‎‏‎‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‏‏‎‏‎‏‎‎‎‏‎‎‎‏‏‎‎‏‎Media picker‎‏‎‎‏‎"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‎‎‏‎‏‎‎‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‎‎‏‎‎‏‏‏‎‎Media picker‎‏‎‎‏‎"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‎‏‏‎‎‏‎‎‎‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‏‎‎Syncing media…‎‏‎‎‏‎"</string>
<string name="add" msgid="2894574044585549298">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‎‏‎‏‏‏‎‎‏‎‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‏‏‎‏‏‏‏‏‎‎‏‎‎Add‎‏‎‎‏‎"</string>
<string name="deselect" msgid="4297825044827769490">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‎‏‏‎‏‏‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‏‎‏‎‏‎‎‏‎‎‏‎‎Deselect‎‏‎‎‏‎"</string>
<string name="deselected" msgid="8488133193326208475">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‏‏‏‏‏‎‏‎‎‎‎‎‏‎‏‎‏‎‏‏‎‏‎‎‏‎‎‏‏‎‏‎‎‏‎‎‏‎‎‏‎‏‏‏‎‏‏‎‏‏‎Deselected‎‏‎‎‏‎"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‎‏‎‎‏‏‏‎‏‎‏‎‏‎‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‎‎‏‏‏‏‎‏‎Check your internet connection and try again‎‏‎‎‏‎"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‎‏‎‎‏‏‎‏‎‏‎‎‎‎‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎‏‎‏‏‎‏‎‎‏‏‎‎‎‎‎Retry‎‏‎‎‏‎"</string>
<string name="not_selected" msgid="2244008151669896758">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‎‏‎‎‎‏‏‎‎‎‎‏‏‎‎‏‎‏‎‎‎‏‎‏‎‏‏‏‎‏‎‏‏‏‎‏‏‎‎‎‏‏‎‏‏‎‎not selected‎‏‎‎‏‎"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎‎‏‎‎‎‎‏‏‎‏‏‏‏‎‏‎‏‏‎‏‎‎‏‎‎‎‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‎‏‏‏‏‎‎‏‎‏‏‏‎Preparing your selected media‎‏‎‎‏‎"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‏‏‏‏‏‎‏‎‎‏‎‏‎‏‎‎‏‎‎‏‎‏‎‎‎‎‏‏‎‏‎‎‎‎‎‎‏‎‎‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g>‎‏‎‎‏‏‏‎ of ‎‏‎‎‏‏‎<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>‎‏‎‎‏‏‏‎ ready‎‏‎‎‏‎"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‎‏‎‏‏‎‎‏‎‎‏‏‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‏‎‏‎‏‏‎Backed up photos now included‎‏‎‎‏‎"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‎‎‏‎‏‎‏‎‏‎‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‎‏‎‏‏‏‎You can select photos from ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ account ‎‏‎‎‏‏‎<xliff:g id="USER_ACCOUNT">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‏‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‏‏‎‏‎‎‏‏‎‎‎‎‎‏‏‎‏‏‎‎‏‎‏‏‏‎Choose app‎‏‎‎‏‎"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‎‏‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‎‎‏‏‏‎‏‎‎‎‏‎‎‎‏‏‏‏‎Choose account‎‏‎‎‏‎"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‎‎‎‏‎‎‎‏‏‎‏‏‎‎‎‎‎‏‎‎‏‏‏‎‎‎‏‎‎‏‎‏‏‎‏‎‏‎‎Change account‎‏‎‎‏‎"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‎‎‎‎‎‎‎‏‎‏‏‏‎‎‎‏‏‏‏‎‎‎‏‏‎‎‏‎‎‏‏‎‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‎‎‏‎‏‎Getting all your photos‎‏‎‎‏‎"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‏‏‎‏‏‎‎‏‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‎‎‏‎‎‏‎‏‏‏‎‎‏‎Allow ‎‏‎‎‏‏‎<xliff:g id="APP_NAME_0">^1</xliff:g>‎‏‎‎‏‏‏‎ to modify this audio file?‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‏‏‎‏‏‎‎‏‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‎‎‏‎‎‏‎‏‏‏‎‎‏‎Allow ‎‏‎‎‏‏‎<xliff:g id="APP_NAME_1">^1</xliff:g>‎‏‎‎‏‏‏‎ to modify ‎‏‎‎‏‏‎<xliff:g id="COUNT">^2</xliff:g>‎‏‎‎‏‏‏‎ audio files?‎‏‎‎‏‎}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‎‏‏‎‎‏‎‏‎‎‏‎‏‎‎‎‎‎‎‎‏‏‎‏‏‏‎‏‎‎‏‏‏‎‏‏‏‎‏‎‎‎‎‏‏‏‎‎‎‎‎‎‏‎Modifying audio file…‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‎‏‏‎‎‏‎‏‎‎‏‎‏‎‎‎‎‎‎‎‏‏‎‏‏‏‎‏‎‎‏‏‏‎‏‏‏‎‏‎‎‎‎‏‏‏‎‎‎‎‎‎‏‎Modifying ‎‏‎‎‏‏‎<xliff:g id="COUNT">^1</xliff:g>‎‏‎‎‏‏‏‎ audio files…‎‏‎‎‏‎}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‏‏‏‎‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‎‎‏‏‎‎‎‏‏‎‎‏‎‏‏‎‏‎Allow ‎‏‎‎‏‏‎<xliff:g id="APP_NAME_0">^1</xliff:g>‎‏‎‎‏‏‏‎ to modify this video?‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‏‏‏‎‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‎‎‏‏‎‎‎‏‏‎‎‏‎‏‏‎‏‎Allow ‎‏‎‎‏‏‎<xliff:g id="APP_NAME_1">^1</xliff:g>‎‏‎‎‏‏‏‎ to modify ‎‏‎‎‏‏‎<xliff:g id="COUNT">^2</xliff:g>‎‏‎‎‏‏‏‎ videos?‎‏‎‎‏‎}}"</string>
@@ -149,4 +154,7 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎‎‏‏‎‏‏‎‎‏‏‏‎Safety protection‎‏‎‎‏‎"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‎‏‎‏‏‏‎‎‏‏‏‏‎‎‏‎‎‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‎‏‏‏‎‏‎‏‎‎‎‏‏‏‎‏‎‏‏‏‏‎‎Native Transcode Alerts‎‏‎‎‏‎"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎‏‎‏‏‎‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‎‏‎‏‎‏‎‏‎‏‎‎‏‏‎Native Transcode Progress‎‏‎‎‏‎"</string>
+ <string name="dialog_error_message" msgid="5120432204743681606">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎‎‎‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‎‏‎‎‎‏‏‎‎Try again later. Your photos will be available once the issue is resolved.‎‏‎‎‏‎"</string>
+ <string name="dialog_error_title" msgid="636349284077820636">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‎‏‎‎‎‏‎‎‏‏‎‏‎‏‏‎‎‏‏‎‏‎‎‎‏‎‎‎‎‏‎‏‏‎‏‎‏‏‎‏‏‏‎‎‎Can\'t load some Photos‎‏‎‎‏‎"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‏‏‏‏‏‎‏‎‎‏‏‏‎‏‎‏‎‏‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‏‏‎‎‎‎Got it‎‏‎‎‏‎"</string>
</resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 791a94443..90be78bd5 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Multimedia"</string>
<string name="storage_description" msgid="4081716890357580107">"Almacenamiento local"</string>
<string name="app_label" msgid="9035307001052716210">"Almacenamiento multimedia"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Multimedia"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Selector de medios"</string>
<string name="artist_label" msgid="8105600993099120273">"Artista"</string>
<string name="unknown" msgid="2059049215682829375">"Desconocido"</string>
<string name="root_images" msgid="5861633549189045666">"Imágenes"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Accede a los medios en la nube desde"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Ninguna"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"No se pudo cambiar la app de música en la nube."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Selector de medios"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Selector de medios"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Sincronizando contenido multimedia…"</string>
<string name="add" msgid="2894574044585549298">"Agregar"</string>
<string name="deselect" msgid="4297825044827769490">"Anular la selección"</string>
<string name="deselected" msgid="8488133193326208475">"Sin seleccionar"</string>
@@ -93,9 +96,10 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Revisa la conexión a Internet y vuelve a intentarlo"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Reintentar"</string>
<string name="not_selected" msgid="2244008151669896758">"sin seleccionar"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Preparando el contenido multimedia seleccionado"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> de <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> listos"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Ahora se incluyen las fotos con copia de seguridad"</string>
- <string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Puedes seleccionar fotos de <xliff:g id="APP_NAME">%1$s</xliff:g> desde la cuenta de <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
+ <string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Puedes seleccionar imágenes de <xliff:g id="APP_NAME">%1$s</xliff:g> desde la cuenta de <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
<string name="picker_banner_cloud_account_changed_title" msgid="4825058474378077327">"Se actualizó la cuenta de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="picker_banner_cloud_account_changed_desc" msgid="3433218869899792497">"Ahora se incluyen aquí las fotos de <xliff:g id="USER_ACCOUNT">%1$s</xliff:g>"</string>
<string name="picker_banner_cloud_choose_app_title" msgid="3165966147547974251">"Elige una app multimedia en la nube"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Elegir una app"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Elegir cuenta"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Cambiar cuenta"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Obteniendo todas tus fotos"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{¿Deseas permitir que <xliff:g id="APP_NAME_0">^1</xliff:g> modifique este archivo de audio?}many{¿Deseas permitir que <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> archivos de audio?}other{¿Deseas permitir que <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> archivos de audio?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Modificando el archivo de audio…}many{Modificando <xliff:g id="COUNT">^1</xliff:g> archivos de audio…}other{Modificando <xliff:g id="COUNT">^1</xliff:g> archivos de audio…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{¿Deseas permitir que <xliff:g id="APP_NAME_0">^1</xliff:g> modifique este video?}many{¿Deseas permitir que <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> videos?}other{¿Deseas permitir que <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> videos?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Protección de seguridad"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Native Transcode Alerts"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Native Transcode Progress"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Se produjo un error durante la carga de algunas fotos"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Entendido"</string>
</resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 241897de5..64349b44a 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Multimedia"</string>
<string name="storage_description" msgid="4081716890357580107">"Almacenamiento local"</string>
<string name="app_label" msgid="9035307001052716210">"Almacenamiento multimedia"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Multimedia"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Selector de medios"</string>
<string name="artist_label" msgid="8105600993099120273">"Artista"</string>
<string name="unknown" msgid="2059049215682829375">"Desconocido"</string>
<string name="root_images" msgid="5861633549189045666">"Imágenes"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Accede al contenido multimedia en la nube desde"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Ninguna"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"No se puede cambiar la app multimedia en la nube."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Selector de medios"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Selector de medios"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Sincronizando contenido multimedia…"</string>
<string name="add" msgid="2894574044585549298">"Añadir"</string>
<string name="deselect" msgid="4297825044827769490">"Desmarcar"</string>
<string name="deselected" msgid="8488133193326208475">"Desmarcado"</string>
@@ -60,8 +63,8 @@
<string name="picker_photos" msgid="7415035516411087392">"Fotos"</string>
<string name="picker_albums" msgid="4822511902115299142">"Álbumes"</string>
<string name="picker_preview" msgid="6257414886055861039">"Vista previa"</string>
- <string name="picker_work_profile" msgid="2083221066869141576">"Cambiar al de trabajo"</string>
- <string name="picker_personal_profile" msgid="639484258397758406">"Cambiar al personal"</string>
+ <string name="picker_work_profile" msgid="2083221066869141576">"Cambiar a perfil de trabajo"</string>
+ <string name="picker_personal_profile" msgid="639484258397758406">"Cambiar a perfil personal"</string>
<string name="picker_profile_admin_title" msgid="4172022376418293777">"Bloqueado por tu administrador"</string>
<string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"No se puede acceder a datos de trabajo desde una aplicación personal"</string>
<string name="picker_profile_admin_msg_from_work" msgid="8048524337462790110">"No se puede acceder a datos personales desde una aplicación de trabajo"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Comprueba tu conexión a Internet y vuelve a intentarlo"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Reintentar"</string>
<string name="not_selected" msgid="2244008151669896758">"no seleccionado"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Preparando el contenido multimedia seleccionado"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> de <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> listos"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Ahora se incluye la copia de seguridad de las fotos"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Puedes seleccionar fotos de la cuenta de <xliff:g id="APP_NAME">%1$s</xliff:g> de <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Elegir aplicación"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Elegir cuenta"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Cambiar de cuenta"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Cargando todas tus fotos"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{¿Permitir que <xliff:g id="APP_NAME_0">^1</xliff:g> modifique este archivo de audio?}many{¿Permitir que <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> archivos de audio?}other{¿Permitir que <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> archivos de audio?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Modificando archivo de audio…}many{Modificando <xliff:g id="COUNT">^1</xliff:g> archivos de audio…}other{Modificando <xliff:g id="COUNT">^1</xliff:g> archivos de audio…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{¿Permitir que <xliff:g id="APP_NAME_0">^1</xliff:g> modifique este vídeo?}many{¿Permitir que <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> vídeos?}other{¿Permitir que <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> vídeos?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Protección de seguridad"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Alertas de transcodificación nativa"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Progreso de transcodificación nativa"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"No se pueden cargar algunas fotos"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Entendido"</string>
</resources>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index e74c07158..321984aea 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Meedia"</string>
<string name="storage_description" msgid="4081716890357580107">"Kohalik salvestusruum"</string>
<string name="app_label" msgid="9035307001052716210">"Meediumi salvestusruum"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Meedia"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Meediavalija"</string>
<string name="artist_label" msgid="8105600993099120273">"Esitaja"</string>
<string name="unknown" msgid="2059049215682829375">"Teadmata"</string>
<string name="root_images" msgid="5861633549189045666">"Pildid"</string>
@@ -39,13 +39,16 @@
<string name="allow" msgid="8885707816848569619">"Luba"</string>
<string name="deny" msgid="6040983710442068936">"Keela"</string>
<string name="picker_browse" msgid="5554477454636075934">"Sirvimine …"</string>
- <string name="picker_settings" msgid="6443463167344790260">"Pilvemeediarakendus"</string>
- <string name="picker_settings_system_settings_menu_title" msgid="3055084757610063581">"Pilvemeediarakendus"</string>
- <string name="picker_settings_title" msgid="5647700706470673258">"Pilvemeediarakendus"</string>
+ <string name="picker_settings" msgid="6443463167344790260">"Pilvemeedia rakendus"</string>
+ <string name="picker_settings_system_settings_menu_title" msgid="3055084757610063581">"Pilvemeedia rakendus"</string>
+ <string name="picker_settings_title" msgid="5647700706470673258">"Pilvemeedia rakendus"</string>
<string name="picker_settings_description" msgid="2916686824777214585">"Juurdepääs teie pilves olevale meediale, kui rakendus või veebisait palub teil fotosid või videoid valida"</string>
- <string name="picker_settings_selection_message" msgid="245453573086488596">"Pilvemeediarakendus:"</string>
+ <string name="picker_settings_selection_message" msgid="245453573086488596">"Pilvemeedia rakendus:"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Pole"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Pilvepõhist meediarakendust ei saanud muuta."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Meediavalija"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Meediavalija"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Meediumi sünkroonimine …"</string>
<string name="add" msgid="2894574044585549298">"Lisa"</string>
<string name="deselect" msgid="4297825044827769490">"Tühista valik"</string>
<string name="deselected" msgid="8488133193326208475">"Valik on tühistatud"</string>
@@ -63,7 +66,7 @@
<string name="picker_work_profile" msgid="2083221066869141576">"Lülituge tööprofiilile"</string>
<string name="picker_personal_profile" msgid="639484258397758406">"Lülituge isiklikule profiilile"</string>
<string name="picker_profile_admin_title" msgid="4172022376418293777">"Blokeeris teie administraator"</string>
- <string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"Juurdepääs tööandmetele isikliku rakenduse kaudu pole lubatud"</string>
+ <string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"Juurdepääs tööandmetele isikliku rakenduse kaudu pole lubatud."</string>
<string name="picker_profile_admin_msg_from_work" msgid="8048524337462790110">"Juurdepääs isiklikele andmetele töörakenduse kaudu pole lubatud"</string>
<string name="picker_profile_work_paused_title" msgid="382212880704235925">"Töörakendused on peatatud"</string>
<string name="picker_profile_work_paused_msg" msgid="6321552322125246726">"Tööfotode avamiseks lülitage töörakendused sisse ja proovige uuesti"</string>
@@ -93,9 +96,10 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Kontrollige internetiühendust ja proovige uuesti"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Proovi uuesti"</string>
<string name="not_selected" msgid="2244008151669896758">"pole valitud"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Valitud meedia ettevalmistamine"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>-st on valmis"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Varundatud fotod on nüüd kaasatud"</string>
- <string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Saate valida fotosid rakendusest <xliff:g id="APP_NAME">%1$s</xliff:g> konto <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> kaudu"</string>
+ <string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Saate valida konto <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> fotosid rakendusest <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="picker_banner_cloud_account_changed_title" msgid="4825058474378077327">"Rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> kontot värskendati"</string>
<string name="picker_banner_cloud_account_changed_desc" msgid="3433218869899792497">"Kasutaja <xliff:g id="USER_ACCOUNT">%1$s</xliff:g> fotod on nüüd siia kaasatud"</string>
<string name="picker_banner_cloud_choose_app_title" msgid="3165966147547974251">"Valige pilvemeediarakendus"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Valige rakendus"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Konto valimine"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Konto vahetamine"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Kõigi fotode toomine"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Kas lubada rakendusel <xliff:g id="APP_NAME_0">^1</xliff:g> seda helifaili muuta?}other{Kas lubada rakendusel <xliff:g id="APP_NAME_1">^1</xliff:g> <xliff:g id="COUNT">^2</xliff:g> helifaili muuta?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Helifaili muutmine …}other{<xliff:g id="COUNT">^1</xliff:g> helifaili muutmine …}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Kas lubada rakendusel <xliff:g id="APP_NAME_0">^1</xliff:g> seda videot muuta?}other{Kas lubada rakendusel <xliff:g id="APP_NAME_1">^1</xliff:g> <xliff:g id="COUNT">^2</xliff:g> videot muuta?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Ohutuskaitse"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Omakoodi transkodeerimise hoiatused"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Omakoodi transkodeerimise edenemine"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Mõnda fotot ei saa laadida"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Selge"</string>
</resources>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index 1a7bc4822..c1208182f 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Multimedia-edukia"</string>
<string name="storage_description" msgid="4081716890357580107">"Biltegi lokala"</string>
<string name="app_label" msgid="9035307001052716210">"Multimediaren memoria-unitatea"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Multimedia-edukia"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Multimedia-edukiaren hautatzailea"</string>
<string name="artist_label" msgid="8105600993099120273">"Artista"</string>
<string name="unknown" msgid="2059049215682829375">"Ezezaguna"</string>
<string name="root_images" msgid="5861633549189045666">"Irudiak"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Atzitu honen bidez gordetako hodeiko multimedia-edukia:"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Bat ere ez"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Ezin izan da aldatu hodeiko multimedia-aplikazioa."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Multimedia-edukiaren hautatzailea"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Multimedia-edukiaren hautatzailea"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Multimedia-edukia sinkronizatzen…"</string>
<string name="add" msgid="2894574044585549298">"Gehitu"</string>
<string name="deselect" msgid="4297825044827769490">"Desautatu"</string>
<string name="deselected" msgid="8488133193326208475">"Desautatuta"</string>
@@ -93,8 +96,9 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Egiaztatu Internetera konektatuta zaudela eta saiatu berriro"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Saiatu berriro"</string>
<string name="not_selected" msgid="2244008151669896758">"hautatu gabe"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Hautatutako multimedia-edukia prestatzen"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g>/<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> prest"</string>
- <string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Orain, babeskopiak dituzten argazkiak sartuta daude"</string>
+ <string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Orain, barnean hartzen dira babeskopiak dituzten argazkiak"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioko <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> kontuko argazkiak hauta ditzakezu"</string>
<string name="picker_banner_cloud_account_changed_title" msgid="4825058474378077327">"Eguneratu da <xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioko kontua"</string>
<string name="picker_banner_cloud_account_changed_desc" msgid="3433218869899792497">"Orain, <xliff:g id="USER_ACCOUNT">%1$s</xliff:g> kontuko argazkiak hemen sartuta daude"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Aukeratu aplikazio bat"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Aukeratu kontu bat"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Aldatu kontua"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Argazki guztiak eskuratzen"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Audio-fitxategiari aldaketak egiteko baimena eman nahi diozu <xliff:g id="APP_NAME_0">^1</xliff:g> aplikazioari?}other{<xliff:g id="COUNT">^2</xliff:g> audio-fitxategiri aldaketak egiteko baimena eman nahi diozu <xliff:g id="APP_NAME_1">^1</xliff:g> aplikazioari?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Audio-fitxategia aldatzen…}other{<xliff:g id="COUNT">^1</xliff:g> audio-fitxategi aldatzen…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Bideoari aldaketak egiteko baimena eman nahi diozu <xliff:g id="APP_NAME_0">^1</xliff:g> aplikazioari?}other{<xliff:g id="COUNT">^2</xliff:g> bideori aldaketak egiteko baimena eman nahi diozu <xliff:g id="APP_NAME_1">^1</xliff:g> aplikazioari?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Segurtasun-babesa"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Transkodetze-alerta natiboak"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Transkodetze natiboaren garapena"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Ezin dira kargatu argazki batzuk"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Ados"</string>
</resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 94e81c1ac..91d0d28ad 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -19,11 +19,11 @@
<string name="uid_label" msgid="8421971615411294156">"رسانه"</string>
<string name="storage_description" msgid="4081716890357580107">"فضای ذخیره‌سازی محلی"</string>
<string name="app_label" msgid="9035307001052716210">"فضای ذخیره‌سازی رسانه"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"رسانه"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"انتخابگر رسانه"</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_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>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"دسترسی به رسانه ابری از"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"هیچ‌کدام"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"اکنون نمی‌توانید برنامه رسانه ابری را تغییر دهید."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"انتخابگر رسانه"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"انتخابگر رسانه"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"درحال همگام‌سازی رسانه…"</string>
<string name="add" msgid="2894574044585549298">"افزودن"</string>
<string name="deselect" msgid="4297825044827769490">"لغو انتخاب"</string>
<string name="deselected" msgid="8488133193326208475">"لغو انتخاب‌شده"</string>
@@ -93,8 +96,9 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"اتصال اینترنت را بررسی کنید و دوباره امتحان کنید"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"امتحان مجدد"</string>
<string name="not_selected" msgid="2244008151669896758">"انتخاب نشده است"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"درحال آماده‌سازی رسانه انتخاب‌شده"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> مورد از <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> مورد آماده است"</string>
- <string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"عکس‌های پشتیبان‌گیری‌شده اکنون اضافه می‌شود"</string>
+ <string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"عکس‌های پشتیبان‌گیری‌شده اکنون اضافه شده‌اند"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"می‌توانید عکس‌های حساب <xliff:g id="APP_NAME">%1$s</xliff:g>‏ (<xliff:g id="USER_ACCOUNT">%2$s</xliff:g>) را انتخاب کنید"</string>
<string name="picker_banner_cloud_account_changed_title" msgid="4825058474378077327">"حساب <xliff:g id="APP_NAME">%1$s</xliff:g> به‌روز شد"</string>
<string name="picker_banner_cloud_account_changed_desc" msgid="3433218869899792497">"عکس‌های <xliff:g id="USER_ACCOUNT">%1$s</xliff:g> اکنون در اینجا اضافه می‌شود"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"انتخاب برنامه"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"انتخاب حساب"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"تغییر حساب"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"درحال دریافت همه عکس‌های شما"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{به <xliff:g id="APP_NAME_0">^1</xliff:g> اجازه می‌دهید این فایل صوتی را تغییر دهد؟}one{به <xliff:g id="APP_NAME_1">^1</xliff:g> اجازه می‌دهید <xliff:g id="COUNT">^2</xliff:g> فایل صوتی را تغییر دهد؟}other{به <xliff:g id="APP_NAME_1">^1</xliff:g> اجازه می‌دهید <xliff:g id="COUNT">^2</xliff:g> فایل صوتی را تغییر دهد؟}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{درحال اصلاح فایل صوتی…}one{درحال اصلاح <xliff:g id="COUNT">^1</xliff:g> فایل صوتی…}other{درحال اصلاح <xliff:g id="COUNT">^1</xliff:g> فایل صوتی…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{به <xliff:g id="APP_NAME_0">^1</xliff:g> اجازه می‌دهید این ویدیو را تغییر دهد؟}one{به <xliff:g id="APP_NAME_1">^1</xliff:g> اجازه می‌دهید <xliff:g id="COUNT">^2</xliff:g> ویدیو را تغییر دهد؟}other{به <xliff:g id="APP_NAME_1">^1</xliff:g> اجازه می‌دهید <xliff:g id="COUNT">^2</xliff:g> ویدیو را تغییر دهد؟}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"محافظت امنیتی"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"هشدارهای تراتبدیل محلی"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"پیشرفت تراتبدیل محلی"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"نمی‌توان برخی‌از عکس‌ها را بار کرد"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"متوجه‌ام"</string>
</resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index eda6c35f9..881a5ca26 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Media"</string>
<string name="storage_description" msgid="4081716890357580107">"Paikallinen tallennustila"</string>
<string name="app_label" msgid="9035307001052716210">"Median tallennustila"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Media"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Median valitsin"</string>
<string name="artist_label" msgid="8105600993099120273">"Artisti"</string>
<string name="unknown" msgid="2059049215682829375">"Tuntematon"</string>
<string name="root_images" msgid="5861633549189045666">"Kuvat"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Pääsy pilvimediaan:"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"–"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Pilvimediasovellusta ei voitu vaihtaa."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Median valitsin"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Median valitsin"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Synkronoidaan mediaa…"</string>
<string name="add" msgid="2894574044585549298">"Lisää"</string>
<string name="deselect" msgid="4297825044827769490">"Poista valinta"</string>
<string name="deselected" msgid="8488133193326208475">"Valinta poistettu"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Tarkista internetyhteytesi ja yritä uudelleen"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Yritä uudelleen"</string>
<string name="not_selected" msgid="2244008151669896758">"ei valittu"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Valitsemaasi mediaa valmistellaan"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g>/<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> valmiina"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Varmuuskopioidut kuvat löytyvät nyt täältä"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Voit valita sovelluksen <xliff:g id="APP_NAME">%1$s</xliff:g> kuvat tililtä <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Valitse sovellus"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Valitse tili"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Vaihda tiliä"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Ladataan kaikkia kuvia"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Saako <xliff:g id="APP_NAME_0">^1</xliff:g> muokata tätä audiotiedostoa?}other{Saako <xliff:g id="APP_NAME_1">^1</xliff:g> muokata <xliff:g id="COUNT">^2</xliff:g> audiotiedostoa?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Muokataan audiotiedostoa…}other{Muokataan <xliff:g id="COUNT">^1</xliff:g> audiotiedostoa…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Saako <xliff:g id="APP_NAME_0">^1</xliff:g> muokata tätä videota?}other{Saako <xliff:g id="APP_NAME_1">^1</xliff:g> muokata <xliff:g id="COUNT">^2</xliff:g> videota?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Turvallisuuden varmistaminen"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Natiivin transkoodin ilmoitukset"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Natiivin transkoodin edistyminen"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Joitain kuvia ei voi ladata"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"OK"</string>
</resources>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 88878c6ad..8ee7716a2 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Multimédia"</string>
<string name="storage_description" msgid="4081716890357580107">"Stockage local"</string>
<string name="app_label" msgid="9035307001052716210">"Stockage multimédia"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Contenu multimédia"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Sélecteur d\'éléments multimédias"</string>
<string name="artist_label" msgid="8105600993099120273">"Artiste"</string>
<string name="unknown" msgid="2059049215682829375">"Inconnu"</string>
<string name="root_images" msgid="5861633549189045666">"Images"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Accéder au contenu multimédia infonuagique à partir de"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Aucune"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Changement appli multimédia infonuagique imposs."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Sélecteur d\'éléments multimédias"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Sélecteur d\'éléments multimédias"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Synchronisation du contenu multimédia en cours…"</string>
<string name="add" msgid="2894574044585549298">"Ajouter"</string>
<string name="deselect" msgid="4297825044827769490">"Désélectionner"</string>
<string name="deselected" msgid="8488133193326208475">"Désélectionné"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Vérifiez votre connexion Internet et réessayez"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Réessayer"</string>
<string name="not_selected" msgid="2244008151669896758">"non sélectionné"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Préparation du contenu multimédia sélectionné en cours…"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> sur <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> prêt(s)"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Les photos sauvegardées sont maintenant incluses"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Vous pouvez sélectionner des photos du compte <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Choisir une application"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Choisir un compte"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Changer de compte"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Chargement de vos photos en cours…"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Autoriser <xliff:g id="APP_NAME_0">^1</xliff:g> à modifier ce fichier audio?}one{Autoriser <xliff:g id="APP_NAME_1">^1</xliff:g> à modifier <xliff:g id="COUNT">^2</xliff:g> fichier audio?}many{Autoriser <xliff:g id="APP_NAME_1">^1</xliff:g> à modifier <xliff:g id="COUNT">^2</xliff:g> fichiers audio?}other{Autoriser <xliff:g id="APP_NAME_1">^1</xliff:g> à modifier <xliff:g id="COUNT">^2</xliff:g> fichiers audio?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Modification du fichier audio en cours…}one{Modification de <xliff:g id="COUNT">^1</xliff:g> fichier audio en cours…}many{Modification de <xliff:g id="COUNT">^1</xliff:g> fichiers audio en cours…}other{Modification de <xliff:g id="COUNT">^1</xliff:g> fichiers audio en cours…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Autoriser <xliff:g id="APP_NAME_0">^1</xliff:g> à modifier cette vidéo?}one{Autoriser <xliff:g id="APP_NAME_1">^1</xliff:g> à modifier <xliff:g id="COUNT">^2</xliff:g> vidéo?}many{Autoriser <xliff:g id="APP_NAME_1">^1</xliff:g> à modifier <xliff:g id="COUNT">^2</xliff:g> vidéos?}other{Autoriser <xliff:g id="APP_NAME_1">^1</xliff:g> à modifier <xliff:g id="COUNT">^2</xliff:g> vidéos?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Protection de sécurité"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Alertes de transcodage natif"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Progression du transcodage natif"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Impossible de charger certaines photos"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"OK"</string>
</resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index d66bcb72d..485c651d5 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Multimédia"</string>
<string name="storage_description" msgid="4081716890357580107">"Stockage local"</string>
<string name="app_label" msgid="9035307001052716210">"Stockage multimédia"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Multimédia"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Sélecteur de fichiers multimédias"</string>
<string name="artist_label" msgid="8105600993099120273">"Artiste"</string>
<string name="unknown" msgid="2059049215682829375">"Inconnu"</string>
<string name="root_images" msgid="5861633549189045666">"Images"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Accéder aux contenus multimédias cloud à partir de"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Aucune"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Impossible de changer l\'appli multimédia cloud."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Sélecteur de fichiers multimédias"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Sélecteur de fichiers multimédias"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Synchronisation des fichiers multimédias…"</string>
<string name="add" msgid="2894574044585549298">"Ajouter"</string>
<string name="deselect" msgid="4297825044827769490">"Désélectionner"</string>
<string name="deselected" msgid="8488133193326208475">"Désélectionné"</string>
@@ -60,8 +63,8 @@
<string name="picker_photos" msgid="7415035516411087392">"Photos"</string>
<string name="picker_albums" msgid="4822511902115299142">"Albums"</string>
<string name="picker_preview" msgid="6257414886055861039">"Aperçu"</string>
- <string name="picker_work_profile" msgid="2083221066869141576">"Passer au professionnel"</string>
- <string name="picker_personal_profile" msgid="639484258397758406">"Passer au personnel"</string>
+ <string name="picker_work_profile" msgid="2083221066869141576">"Passer au profil professionnel"</string>
+ <string name="picker_personal_profile" msgid="639484258397758406">"Passer au profil personnel"</string>
<string name="picker_profile_admin_title" msgid="4172022376418293777">"Bloqué par votre administrateur"</string>
<string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"Vous n\'êtes pas autorisé à accéder à des données professionnelles depuis une appli personnelle"</string>
<string name="picker_profile_admin_msg_from_work" msgid="8048524337462790110">"Vous n\'êtes pas autorisé à accéder à des données à caractère personnel depuis une appli professionnelle"</string>
@@ -93,9 +96,10 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Vérifiez votre connexion Internet, puis réessayez"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Réessayer"</string>
<string name="not_selected" msgid="2244008151669896758">"non sélectionné"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Préparation des fichiers multimédias que vous avez sélectionnés"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"Prêt(s) : <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> sur <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Les photos sauvegardées sont désormais incluses"</string>
- <string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Vous pouvez sélectionner des photos de <xliff:g id="APP_NAME">%1$s</xliff:g>, compte <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
+ <string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Vous pouvez sélectionner des photos issues du compte <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> dans l\'appli <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="picker_banner_cloud_account_changed_title" msgid="4825058474378077327">"Compte <xliff:g id="APP_NAME">%1$s</xliff:g> mis à jour"</string>
<string name="picker_banner_cloud_account_changed_desc" msgid="3433218869899792497">"Les photos de <xliff:g id="USER_ACCOUNT">%1$s</xliff:g> sont désormais incluses ici"</string>
<string name="picker_banner_cloud_choose_app_title" msgid="3165966147547974251">"Sélectionner une appli multimédia cloud"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Sélectionner une appli"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Sélectionner un compte"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Changer de compte"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Chargement de toutes vos photos…"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Autoriser <xliff:g id="APP_NAME_0">^1</xliff:g> à modifier ce fichier audio ?}one{Autoriser <xliff:g id="APP_NAME_1">^1</xliff:g> à modifier <xliff:g id="COUNT">^2</xliff:g> fichier audio ?}many{Autoriser <xliff:g id="APP_NAME_1">^1</xliff:g> à modifier <xliff:g id="COUNT">^2</xliff:g> fichiers audio ?}other{Autoriser <xliff:g id="APP_NAME_1">^1</xliff:g> à modifier <xliff:g id="COUNT">^2</xliff:g> fichiers audio ?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Modification du fichier audio…}one{Modification de <xliff:g id="COUNT">^1</xliff:g> fichier audio…}many{Modification de <xliff:g id="COUNT">^1</xliff:g> fichiers audio…}other{Modification de <xliff:g id="COUNT">^1</xliff:g> fichiers audio…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Autoriser <xliff:g id="APP_NAME_0">^1</xliff:g> à modifier cette vidéo ?}one{Autoriser <xliff:g id="APP_NAME_1">^1</xliff:g> à modifier <xliff:g id="COUNT">^2</xliff:g> vidéo ?}many{Autoriser <xliff:g id="APP_NAME_1">^1</xliff:g> à modifier <xliff:g id="COUNT">^2</xliff:g> vidéos ?}other{Autoriser <xliff:g id="APP_NAME_1">^1</xliff:g> à modifier <xliff:g id="COUNT">^2</xliff:g> vidéos ?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Protection de sécurité"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Alertes de transcodage natif"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Progression du transcodage natif"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Impossible de charger certaines photos"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"OK"</string>
</resources>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 2bf371a34..140ec55c0 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Multimedia"</string>
<string name="storage_description" msgid="4081716890357580107">"Almacenamento local"</string>
<string name="app_label" msgid="9035307001052716210">"Almacenamento multimedia"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Contido multimedia"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Seleccionador multimedia"</string>
<string name="artist_label" msgid="8105600993099120273">"Artista"</string>
<string name="unknown" msgid="2059049215682829375">"Descoñecida"</string>
<string name="root_images" msgid="5861633549189045666">"Imaxes"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Acceder ao contido multimedia gardado na nube desde"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Ningunha"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"App multimedia con servizo na nube non cambiada."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Seleccionador de contido multimedia"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Seleccionador de contido multimedia"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Sincronizando contido multimedia…"</string>
<string name="add" msgid="2894574044585549298">"Engadir"</string>
<string name="deselect" msgid="4297825044827769490">"Anular selección"</string>
<string name="deselected" msgid="8488133193326208475">"Anulouse a selección"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Comproba a conexión a Internet e téntao de novo"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Tentar de novo"</string>
<string name="not_selected" msgid="2244008151669896758">"elemento non seleccionado"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Preparando recursos seleccionados"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"Elementos listos: <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> de <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Agora inclúense as fotos con copia de seguranza"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Podes seleccionar fotos da seguinte conta de <xliff:g id="APP_NAME">%1$s</xliff:g>: <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Escoller aplicación"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Seleccionar conta"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Cambiar de conta"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Cargando todas as fotos"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Queres permitir que <xliff:g id="APP_NAME_0">^1</xliff:g> modifique este ficheiro de audio?}other{Queres permitir que <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> ficheiros de audio?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Modificando 1 ficheiro de audio…}other{Modificando <xliff:g id="COUNT">^1</xliff:g> ficheiros de audio…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Queres permitir que <xliff:g id="APP_NAME_0">^1</xliff:g> modifique este vídeo?}other{Queres permitir que <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> vídeos?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Protección de seguranza"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Alertas de transcodificación nativa"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Progreso da transcodificación nativa"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Non se poden cargar algunhas fotos"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Entendido"</string>
</resources>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index a1275df38..1ab9a5c56 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/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="picker_app_label" msgid="4254039089502164761">"મીડિયા"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"મીડિયા પિકર"</string>
<string name="artist_label" msgid="8105600993099120273">"કલાકાર"</string>
<string name="unknown" msgid="2059049215682829375">"અજાણ"</string>
<string name="root_images" msgid="5861633549189045666">"છબીઓ"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"આમાંથી ક્લાઉડ મીડિયાને ઍક્સેસ કરો"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"એકપણ નહીં"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"આ સમયે ક્લાઉડ મીડિયા ઍપને બદલી શકાઈ નથી."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"મીડિયા પિકર"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"મીડિયા પિકર"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"મીડિયા સિંક કરી રહ્યાં છે…"</string>
<string name="add" msgid="2894574044585549298">"ઉમેરો"</string>
<string name="deselect" msgid="4297825044827769490">"નાપસંદ કરો"</string>
<string name="deselected" msgid="8488133193326208475">"નાપસંદ કર્યું"</string>
@@ -62,7 +65,7 @@
<string name="picker_preview" msgid="6257414886055861039">"પ્રીવ્યૂ કરો"</string>
<string name="picker_work_profile" msgid="2083221066869141576">"ઑફિસની પ્રોફાઇલ પર સ્વિચ કરો"</string>
<string name="picker_personal_profile" msgid="639484258397758406">"વ્યક્તિગત પ્રોફાઇલ પર સ્વિચ કરો"</string>
- <string name="picker_profile_admin_title" msgid="4172022376418293777">"તમારા વ્યવસ્થાપકે સુવિધા બ્લૉક કરી છે"</string>
+ <string name="picker_profile_admin_title" msgid="4172022376418293777">"તમારા ઍડમિને સુવિધા બ્લૉક કરી છે"</string>
<string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"વ્યક્તિગત ઍપ પરથી ઑફિસનો ડેટા ઍક્સેસ કરવાની પરવાનગી નથી"</string>
<string name="picker_profile_admin_msg_from_work" msgid="8048524337462790110">"ઑફિસ માટેની ઍપ પરથી વ્યક્તિગત ડેટા ઍક્સેસ કરવાની પરવાનગી નથી"</string>
<string name="picker_profile_work_paused_title" msgid="382212880704235925">"ઑફિસ માટેની ઍપ થોભાવવામાં આવી છે"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"તમારું ઇન્ટરનેટ કનેક્શન ચેક કરો અને ફરી પ્રયાસ કરો"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"ફરી પ્રયાસ કરો"</string>
<string name="not_selected" msgid="2244008151669896758">"પસંદ નહીં કરેલી"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"તમે પસંદ કરેલું મીડિયા તૈયાર કરી રહ્યાં છીએ"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>માંથી <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> તૈયાર"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"બૅકઅપ લીધેલા ફોટા હવે શામેલ કરવામાં આવ્યા છે"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"તમે <xliff:g id="APP_NAME">%1$s</xliff:g> એકાઉન્ટના <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> પરથી ફોટા પસંદ કરી શકો છો"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"ઍપ પસંદ કરો"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"એકાઉન્ટ પસંદ કરો"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"એકાઉન્ટ બદલો"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"તમારા બધા ફોટા મેળવવામાં આવી રહ્યાં છે"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g>ને આ ઑડિયો ફાઇલમાં ફેરફાર કરવાની મંજૂરી આપીએ?}one{<xliff:g id="APP_NAME_1">^1</xliff:g>ને <xliff:g id="COUNT">^2</xliff:g> ઑડિયો ફાઇલમાં ફેરફાર કરવાની મંજૂરી આપીએ?}other{<xliff:g id="APP_NAME_1">^1</xliff:g>ને <xliff:g id="COUNT">^2</xliff:g> ઑડિયો ફાઇલમાં ફેરફાર કરવાની મંજૂરી આપીએ?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{ઑડિયો ફાઇલમાં ફેરફાર કરી રહ્યાં છીએ…}one{<xliff:g id="COUNT">^1</xliff:g> ઑડિયો ફાઇલમાં ફેરફાર કરી રહ્યાં છીએ…}other{<xliff:g id="COUNT">^1</xliff:g> ઑડિયો ફાઇલમાં ફેરફાર કરી રહ્યાં છીએ…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g>ને આ વીડિયોમાં ફેરફાર કરવાની મંજૂરી આપીએ?}one{<xliff:g id="APP_NAME_1">^1</xliff:g>ને <xliff:g id="COUNT">^2</xliff:g> વીડિયોમાં ફેરફાર કરવાની મંજૂરી આપીએ?}other{<xliff:g id="APP_NAME_1">^1</xliff:g>ને <xliff:g id="COUNT">^2</xliff:g> વીડિયોમાં ફેરફાર કરવાની મંજૂરી આપીએ?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"સલામતી સંરક્ષણ"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Native Transcode Alerts"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Native Transcode Progress"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"અમુક ફોટા લોડ કરી શકાતા નથી"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"સમજાઈ ગયું"</string>
</resources>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index ff9ee11b2..673380955 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/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="picker_app_label" msgid="4254039089502164761">"मीडिया"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"मीडिया पिकर"</string>
<string name="artist_label" msgid="8105600993099120273">"कलाकार"</string>
<string name="unknown" msgid="2059049215682829375">"अज्ञात"</string>
<string name="root_images" msgid="5861633549189045666">"इमेज"</string>
@@ -46,9 +46,12 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"क्लाउड पर मौजूद मीडिया को यहां से ऐक्सेस करें:"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"कोई नहीं"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"इस समय क्लाउड मीडिया ऐप्लिकेशन नहीं बदला जा सका."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"मीडिया पिकर"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"मीडिया पिकर"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"मीडिया को सिंक किया जा रहा है…"</string>
<string name="add" msgid="2894574044585549298">"जोड़ें"</string>
- <string name="deselect" msgid="4297825044827769490">"चुना हुआ हटाएं"</string>
- <string name="deselected" msgid="8488133193326208475">"चुना हुआ हटाया गया"</string>
+ <string name="deselect" msgid="4297825044827769490">"चुने हुए का निशान हटाएं"</string>
+ <string name="deselected" msgid="8488133193326208475">"चुने हुए का निशान हटाया गया"</string>
<string name="select" msgid="2704765470563027689">"चुनें"</string>
<string name="selected" msgid="9151797369975828124">"चुना गया"</string>
<string name="select_up_to" msgid="6994294169508439957">"{count,plural, =1{ज़्यादा से ज़्यादा <xliff:g id="COUNT_0">^1</xliff:g> आइटम चुनें}one{ज़्यादा से ज़्यादा <xliff:g id="COUNT_1">^1</xliff:g> आइटम चुनें}other{ज़्यादा से ज़्यादा <xliff:g id="COUNT_1">^1</xliff:g> आइटम चुनें}}"</string>
@@ -73,7 +76,7 @@
<string name="picker_add_button_multi_select" msgid="4005164092275518399">"(<xliff:g id="COUNT">^1</xliff:g>) जोड़ें"</string>
<string name="picker_add_button_multi_select_permissions" msgid="5138751105800138838">"अनुमति दें (<xliff:g id="COUNT">^1</xliff:g>)"</string>
<string name="picker_category_camera" msgid="4857367052026843664">"कैमरा"</string>
- <string name="picker_category_downloads" msgid="793866660287361900">"डाउनलोड की गई चीज़ें"</string>
+ <string name="picker_category_downloads" msgid="793866660287361900">"डाउनलोड किए गए आइटम"</string>
<string name="picker_category_favorites" msgid="7008495397818966088">"पसंदीदा"</string>
<string name="picker_category_screenshots" msgid="7216102327587644284">"स्क्रीनशॉट"</string>
<!-- no translation found for picker_category_videos (1478458836380241356) -->
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"अपने इंटरनेट कनेक्शन की जांच करें और फिर से कोशिश करें"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"फिर से कोशिश करें"</string>
<string name="not_selected" msgid="2244008151669896758">"नहीं चुना गया"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"आपकी चुनी गई मीडिया तैयार की जा रही है"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> में से <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> तैयार हैं"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"बैक अप ली गई फ़ोटो अब जोड़ दी गई हैं"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"आपके पास, <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> वाले <xliff:g id="APP_NAME">%1$s</xliff:g> खाते से फ़ोटो चुनने का विकल्प है"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"ऐप्लिकेशन चुनें"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"खाता चुनें"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"खाता बदलें"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"सभी फ़ोटो लोड की जा रही हैं"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{क्या <xliff:g id="APP_NAME_0">^1</xliff:g> को इस ऑडियो फ़ाइल में बदलाव करने की अनुमति देनी है?}one{क्या <xliff:g id="APP_NAME_1">^1</xliff:g> को <xliff:g id="COUNT">^2</xliff:g> ऑडियो फ़ाइल में बदलाव करने की अनुमति देनी है?}other{क्या <xliff:g id="APP_NAME_1">^1</xliff:g> को <xliff:g id="COUNT">^2</xliff:g> ऑडियो फ़ाइलों में बदलाव करने की अनुमति देनी है?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{ऑडियो फ़ाइल में बदलाव किया जा रहा है…}one{<xliff:g id="COUNT">^1</xliff:g> ऑडियो फ़ाइल में बदलाव किया जा रहा है…}other{<xliff:g id="COUNT">^1</xliff:g> ऑडियो फ़ाइलों में बदलाव किया जा रहा है…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{क्या <xliff:g id="APP_NAME_0">^1</xliff:g> को इस वीडियो में बदलाव करने की अनुमति देनी है?}one{क्या <xliff:g id="APP_NAME_1">^1</xliff:g> को <xliff:g id="COUNT">^2</xliff:g> वीडियो में बदलाव करने की अनुमति देनी है?}other{क्या <xliff:g id="APP_NAME_1">^1</xliff:g> को <xliff:g id="COUNT">^2</xliff:g> वीडियो में बदलाव करने की अनुमति देनी है?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"सुरक्षा के लिए बचाव"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"नेटिव ट्रांसकोड सूचना"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"नेटिव ट्रांसकोड स्थिति"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"कुछ फ़ोटो लोड नहीं की जा सकीं"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"ठीक है"</string>
</resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 1a76759d3..b4a060590 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Mediji"</string>
<string name="storage_description" msgid="4081716890357580107">"Lokalna pohrana"</string>
<string name="app_label" msgid="9035307001052716210">"Pohranjivanje na mediju"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Mediji"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Alat za izbor medija"</string>
<string name="artist_label" msgid="8105600993099120273">"Izvođač"</string>
<string name="unknown" msgid="2059049215682829375">"Nepoznato"</string>
<string name="root_images" msgid="5861633549189045666">"Slike"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Pristupi medijima u oblaku putem"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Ništa"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Aplikaciju za medijske sadržaje u oblaku trenutačno nije moguće promijeniti."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Alat za izbor medija"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Alat za izbor medija"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Sinkroniziranje medija…"</string>
<string name="add" msgid="2894574044585549298">"Dodaj"</string>
<string name="deselect" msgid="4297825044827769490">"Poništi odabir"</string>
<string name="deselected" msgid="8488133193326208475">"Odabir poništen"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Provjerite internetsku vezu i pokušajte ponovo"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Pokušaj ponovo"</string>
<string name="not_selected" msgid="2244008151669896758">"nije odabrano"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Priprema odabranih medija"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"Spremno: <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> od <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Sad su uključene sigurnosno kopirane fotografije"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Možete odabrati aplikacije s računa <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Odaberite aplikaciju"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Odaberite račun"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Promijenite račun"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Dohvaćanje svih vaših fotografija"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Želite li dopustiti aplikaciji <xliff:g id="APP_NAME_0">^1</xliff:g> da izmijeni tu audiodatoteku?}one{Želite li dopustiti aplikaciji <xliff:g id="APP_NAME_1">^1</xliff:g> da izmijeni <xliff:g id="COUNT">^2</xliff:g> audiodatoteku?}few{Želite li dopustiti aplikaciji <xliff:g id="APP_NAME_1">^1</xliff:g> da izmijeni <xliff:g id="COUNT">^2</xliff:g> audiodatoteke?}other{Želite li dopustiti aplikaciji <xliff:g id="APP_NAME_1">^1</xliff:g> da izmijeni <xliff:g id="COUNT">^2</xliff:g> audiodatoteka?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Mijenjanje audiodatoteke…}one{Mijenjanje <xliff:g id="COUNT">^1</xliff:g> audiodatoteke…}few{Mijenjanje <xliff:g id="COUNT">^1</xliff:g> audiodatoteke…}other{Mijenjanje <xliff:g id="COUNT">^1</xliff:g> audiodatoteka…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Želite li dopustiti aplikaciji <xliff:g id="APP_NAME_0">^1</xliff:g> da izmijeni taj videozapis?}one{Želite li dopustiti aplikaciji <xliff:g id="APP_NAME_1">^1</xliff:g> da izmijeni <xliff:g id="COUNT">^2</xliff:g> videozapis?}few{Želite li dopustiti aplikaciji <xliff:g id="APP_NAME_1">^1</xliff:g> da izmijeni <xliff:g id="COUNT">^2</xliff:g> videozapisa?}other{Želite li dopustiti aplikaciji <xliff:g id="APP_NAME_1">^1</xliff:g> da izmijeni <xliff:g id="COUNT">^2</xliff:g> videozapisa?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Osiguranje"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Upozorenja nativnog konvertiranja"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Napredak nativnog konvertiranja"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Neke fotografije ne mogu se učitati"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Shvaćam"</string>
</resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 47e2fd3cc..e8147b8d1 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Média"</string>
<string name="storage_description" msgid="4081716890357580107">"Helyi tárhely"</string>
<string name="app_label" msgid="9035307001052716210">"Médiatároló"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Média"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Médiaválasztó"</string>
<string name="artist_label" msgid="8105600993099120273">"Előadó"</string>
<string name="unknown" msgid="2059049215682829375">"Ismeretlen"</string>
<string name="root_images" msgid="5861633549189045666">"Képek"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Hozzáférés a következő szolgáltatásban tárolt felhőbeli médiatartalmakhoz:"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Nincs"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Most nem módosítható a felhőbeli médiaalkalmazás."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Médiaválasztó"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Médiaválasztó"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Médiatartalom szinkronizálása…"</string>
<string name="add" msgid="2894574044585549298">"Hozzáadás"</string>
<string name="deselect" msgid="4297825044827769490">"Jelölés törlése"</string>
<string name="deselected" msgid="8488133193326208475">"Kijelölés megszüntetve"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Ellenőrizze internetkapcsolatát, és próbálkozzon újra"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Újra"</string>
<string name="not_selected" msgid="2244008151669896758">"nincs kiválasztva"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"A kiválasztott média előkészítése…"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>/<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> kész"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Mostantól rendelkezésre állnak a fotók, amelyekről biztonsági másolat készült"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Kiválaszthat fotókat a(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazásból (<xliff:g id="USER_ACCOUNT">%2$s</xliff:g>-fiók)"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Válasszon alkalmazást"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Fiók kiválasztása"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Másik fiók választása"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Folyamatban van az összes fotó lekérése"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Engedélyezi a(z) <xliff:g id="APP_NAME_0">^1</xliff:g> számára ennek a hangfájlnak a módosítását?}other{Engedélyezi a(z) <xliff:g id="APP_NAME_1">^1</xliff:g> számára <xliff:g id="COUNT">^2</xliff:g> hangfájl módosítását?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Az audiofájl módosítása folyamatban van…}other{<xliff:g id="COUNT">^1</xliff:g> audiofájl módosítása folyamatban van…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Engedélyezi a(z) <xliff:g id="APP_NAME_0">^1</xliff:g> számára ennek a videónak a módosítását?}other{Engedélyezi a(z) <xliff:g id="APP_NAME_1">^1</xliff:g> számára <xliff:g id="COUNT">^2</xliff:g> videó módosítását?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Biztonsági védelem"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Natív átkódolási értesítések"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Natív átkódolási folyamat"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Egyes fotók nem tölthetők be"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Értem"</string>
</resources>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index ec97ddcc6..1b5bfdb03 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/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="picker_app_label" msgid="4254039089502164761">"Մեդիա"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Մուլտիմեդիա ընտրիչ"</string>
<string name="artist_label" msgid="8105600993099120273">"Կատարող"</string>
<string name="unknown" msgid="2059049215682829375">"Անհայտ"</string>
<string name="root_images" msgid="5861633549189045666">"Պատկերներ"</string>
@@ -46,9 +46,12 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Օգտվեք ամպային մեդիա բովանդակությունից հետևյալ մատակարարից՝"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Չկա"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Չհաջողվեց փոխել ամպային մուլտիմեդիա հավելվածը։"</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Մուլտիմեդիա ընտրիչ"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Մուլտիմեդիա ընտրիչ"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Մեդիաֆայլերը համաժամացվում են…"</string>
<string name="add" msgid="2894574044585549298">"Ավելացնել"</string>
- <string name="deselect" msgid="4297825044827769490">"Ապընտրել"</string>
- <string name="deselected" msgid="8488133193326208475">"Ապընտրված"</string>
+ <string name="deselect" msgid="4297825044827769490">"Չեղարկել ընտրությունը"</string>
+ <string name="deselected" msgid="8488133193326208475">"Ընտրությունը չեղարկված է"</string>
<string name="select" msgid="2704765470563027689">"Ընտրել"</string>
<string name="selected" msgid="9151797369975828124">"Ընտրված"</string>
<string name="select_up_to" msgid="6994294169508439957">"{count,plural, =1{Ընտրեք մինչև <xliff:g id="COUNT_0">^1</xliff:g> տարր}one{Ընտրեք մինչև <xliff:g id="COUNT_1">^1</xliff:g> տարր}other{Ընտրեք մինչև <xliff:g id="COUNT_1">^1</xliff:g> տարր}}"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Ստուգեք ձեր ինտերնետ կապը և նորից փորձեք"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Նորից փորձել"</string>
<string name="not_selected" msgid="2244008151669896758">"ընտրված չէ"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Ձեր ընտրած մեդիաֆայլերի նախապատրաստում"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g>/<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> պատրաստ է"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Պահուստավորված լուսանկարներն այժմ ավելացված են"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Դուք կարող եք լուսանկարներ ընտրել «<xliff:g id="APP_NAME">%1$s</xliff:g>» հավելվածի <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> հաշվից"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Ընտրել հավելված"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Ընտրել հաշիվը"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Փոխել հաշիվը"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Ձեր բոլոր լուսանկարները բեռնվում են"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Թույլատրե՞լ <xliff:g id="APP_NAME_0">^1</xliff:g> հավելվածին վերականգնել այս աուդիո ֆայլն աղբարկղից}one{Թույլատրե՞լ <xliff:g id="APP_NAME_1">^1</xliff:g> հավելվածին վերականգնել <xliff:g id="COUNT">^2</xliff:g> աուդիո ֆայլ աղբարկղից}other{Թույլատրե՞լ <xliff:g id="APP_NAME_1">^1</xliff:g> հավելվածին վերականգնել <xliff:g id="COUNT">^2</xliff:g> աուդիո ֆայլ աղբարկղից}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Աուդիո ֆայլը փոփոխվում է…}one{<xliff:g id="COUNT">^1</xliff:g> աուդիո ֆայլ փոփոխվում է…}other{<xliff:g id="COUNT">^1</xliff:g> աուդիո ֆայլ փոփոխվում է…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Թույլատրե՞լ <xliff:g id="APP_NAME_0">^1</xliff:g> հավելվածին փոփոխել այս տեսանյութը}one{Թույլատրե՞լ <xliff:g id="APP_NAME_1">^1</xliff:g> հավելվածին փոփոխել <xliff:g id="COUNT">^2</xliff:g> տեսանյութ}other{Թույլատրե՞լ <xliff:g id="APP_NAME_1">^1</xliff:g> հավելվածին փոփոխել <xliff:g id="COUNT">^2</xliff:g> տեսանյութ}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Անվտանգության պաշտպանություն"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Տրանսկոդավորման մասին հիմնական ծանուցումներ"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Տրանսկոդավորման հիմնական գործընթաց"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Չհաջողվեց բեռնել որոշ լուսանկարներ"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Եղավ"</string>
</resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 4043b13a2..5ae9ebcfa 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Media"</string>
<string name="storage_description" msgid="4081716890357580107">"Penyimpanan lokal"</string>
<string name="app_label" msgid="9035307001052716210">"Penyimpanan Media"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Media"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Pemilih media"</string>
<string name="artist_label" msgid="8105600993099120273">"Artis"</string>
<string name="unknown" msgid="2059049215682829375">"Tidak diketahui"</string>
<string name="root_images" msgid="5861633549189045666">"Gambar"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Akses media cloud dari"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Tidak ada"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Saat ini tidak bisa mengubah aplikasi media cloud."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Pemilih media"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Pemilih media"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Menyinkronkan media…"</string>
<string name="add" msgid="2894574044585549298">"Tambahkan"</string>
<string name="deselect" msgid="4297825044827769490">"Batalkan pilihan"</string>
<string name="deselected" msgid="8488133193326208475">"Batal dipilih"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Periksa koneksi internet Anda, lalu coba lagi"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Coba lagi"</string>
<string name="not_selected" msgid="2244008151669896758">"tidak dipilih"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Menyiapkan media yang dipilih"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> dari <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> siap"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Foto yang dicadangkan kini disertakan"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Anda dapat memilih foto dari akun <xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Pilih aplikasi"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Pilih akun"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Ubah akun"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Mengambil semua foto Anda"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Izinkan <xliff:g id="APP_NAME_0">^1</xliff:g> mengubah file audio ini?}other{Izinkan <xliff:g id="APP_NAME_1">^1</xliff:g> mengubah <xliff:g id="COUNT">^2</xliff:g> file audio?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Mengubah file audio …}other{Mengubah <xliff:g id="COUNT">^1</xliff:g> file audio …}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Izinkan <xliff:g id="APP_NAME_0">^1</xliff:g> mengubah video ini?}other{Izinkan <xliff:g id="APP_NAME_1">^1</xliff:g> mengubah <xliff:g id="COUNT">^2</xliff:g> video?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Perlindungan keselamatan"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Peringatan Transcoding Native"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Progres Transcoding Native"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Tidak dapat memuat beberapa Foto"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Oke"</string>
</resources>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index 9f923f27c..c8886c207 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Margmiðlun"</string>
<string name="storage_description" msgid="4081716890357580107">"Staðbundin vistun"</string>
<string name="app_label" msgid="9035307001052716210">"Efnisgeymsla"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Efni"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Efnisval"</string>
<string name="artist_label" msgid="8105600993099120273">"Flytjandi"</string>
<string name="unknown" msgid="2059049215682829375">"Óþekkt"</string>
<string name="root_images" msgid="5861633549189045666">"Myndir"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Opna skýjaefni frá"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Ekkert"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Ekki tókst að breyta efnisforriti í skýi."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Efnisval"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Efnisval"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Samstillir efni…"</string>
<string name="add" msgid="2894574044585549298">"Bæta við"</string>
<string name="deselect" msgid="4297825044827769490">"Afvelja"</string>
<string name="deselected" msgid="8488133193326208475">"Afvalið"</string>
@@ -61,7 +64,7 @@
<string name="picker_albums" msgid="4822511902115299142">"Albúm"</string>
<string name="picker_preview" msgid="6257414886055861039">"Forskoða"</string>
<string name="picker_work_profile" msgid="2083221066869141576">"Skipta yfir í vinnusnið"</string>
- <string name="picker_personal_profile" msgid="639484258397758406">"Skipta yfir í eigið snið"</string>
+ <string name="picker_personal_profile" msgid="639484258397758406">"Skipta yfir í einkasnið"</string>
<string name="picker_profile_admin_title" msgid="4172022376418293777">"Útilokað af kerfisstjóra"</string>
<string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"Óheimilt er að opna vinnugögn í forriti til einkanota"</string>
<string name="picker_profile_admin_msg_from_work" msgid="8048524337462790110">"Óheimilt er að opna einkagögn í vinnuforriti"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Athugaðu nettenginguna og reyndu aftur"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Reyna aftur"</string>
<string name="not_selected" msgid="2244008151669896758">"ekki valið"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Undirbýr valið efni"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> af <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> til reiðu"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Afritaðar myndir eru nú hafðar með"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Þú getur valið myndir af reikningnum <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> í: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Velja forrit"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Veldu reikning"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Skipta um reikning"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Sækir allar myndirnar þínar"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Leyfa <xliff:g id="APP_NAME_0">^1</xliff:g> að breyta þessari hljóðskrá?}one{Leyfa <xliff:g id="APP_NAME_1">^1</xliff:g> að breyta <xliff:g id="COUNT">^2</xliff:g> hljóðskrá?}other{Leyfa <xliff:g id="APP_NAME_1">^1</xliff:g> að breyta <xliff:g id="COUNT">^2</xliff:g> hljóðskrám?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Breytir hljóðskrá…}one{Breytir <xliff:g id="COUNT">^1</xliff:g> hljóðskrá…}other{Breytir <xliff:g id="COUNT">^1</xliff:g> hljóðskrám…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Leyfa <xliff:g id="APP_NAME_0">^1</xliff:g> að breyta þessu myndskeiði?}one{Leyfa <xliff:g id="APP_NAME_1">^1</xliff:g> að breyta <xliff:g id="COUNT">^2</xliff:g> myndskeiði?}other{Leyfa <xliff:g id="APP_NAME_1">^1</xliff:g> að breyta <xliff:g id="COUNT">^2</xliff:g> myndskeiðum?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Öryggisbúnaður"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Viðvaranir fyrir sérforritaðar umkóðanir"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Sérforritað umkóðunarferli"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Ekki tekst að hlaða sumum myndum"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Ég skil"</string>
</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 19d628756..04408b614 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Supporti multimediali"</string>
<string name="storage_description" msgid="4081716890357580107">"Archiviazione locale"</string>
<string name="app_label" msgid="9035307001052716210">"Media Storage"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Contenuti multimediali"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Selettore media"</string>
<string name="artist_label" msgid="8105600993099120273">"Artista"</string>
<string name="unknown" msgid="2059049215682829375">"Sconosciuto"</string>
<string name="root_images" msgid="5861633549189045666">"Immagini"</string>
@@ -42,10 +42,13 @@
<string name="picker_settings" msgid="6443463167344790260">"App multimediale cloud"</string>
<string name="picker_settings_system_settings_menu_title" msgid="3055084757610063581">"App multimediale cloud"</string>
<string name="picker_settings_title" msgid="5647700706470673258">"App multimediale con funzionalità cloud"</string>
- <string name="picker_settings_description" msgid="2916686824777214585">"Accedi ai tuoi contenuti multimediali cloud quando un\'app o un sito web ti chiede di selezionare foto o video"</string>
+ <string name="picker_settings_description" msgid="2916686824777214585">"Accedi ai tuoi contenuti multimediali sul cloud quando un\'app o un sito web ti chiede di selezionare foto o video"</string>
<string name="picker_settings_selection_message" msgid="245453573086488596">"Accedi ai contenuti multimediali sul cloud da"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Nessuna"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Ora è impossibile cambiare app multimediale cloud."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Selettore media"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Selettore media"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Sincronizzazione dei media in corso…"</string>
<string name="add" msgid="2894574044585549298">"Aggiungi"</string>
<string name="deselect" msgid="4297825044827769490">"Deseleziona"</string>
<string name="deselected" msgid="8488133193326208475">"Deselezionato"</string>
@@ -67,7 +70,7 @@
<string name="picker_profile_admin_msg_from_work" msgid="8048524337462790110">"Non è consentito accedere ai dati personali da un\'app di lavoro"</string>
<string name="picker_profile_work_paused_title" msgid="382212880704235925">"Le app di lavoro sono in pausa"</string>
<string name="picker_profile_work_paused_msg" msgid="6321552322125246726">"Per aprire le foto relative al lavoro, attiva le app di lavoro e riprova"</string>
- <string name="picker_privacy_message" msgid="9132700451027116817">"Questa app può accedere soltanto alle foto selezionate da te"</string>
+ <string name="picker_privacy_message" msgid="9132700451027116817">"Questa app può accedere soltanto alle foto che selezioni"</string>
<string name="picker_header_permissions" msgid="675872774407768495">"Seleziona le foto e i video a cui può accedere questa app"</string>
<string name="picker_album_item_count" msgid="4420723302534177596">"{count,plural, =1{<xliff:g id="COUNT_0">^1</xliff:g> elemento}many{<xliff:g id="COUNT_1">^1</xliff:g> elementi}other{<xliff:g id="COUNT_1">^1</xliff:g> elementi}}"</string>
<string name="picker_add_button_multi_select" msgid="4005164092275518399">"Aggiungi (<xliff:g id="COUNT">^1</xliff:g>)"</string>
@@ -93,9 +96,10 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Controlla la connessione a Internet e riprova"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Riprova"</string>
<string name="not_selected" msgid="2244008151669896758">"Elemento non selezionato"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Preparazione dei contenuti multimediali selezionati in corso…"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> su <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> pronti"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Ora sono incluse le foto di cui hai eseguito il backup"</string>
- <string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Puoi selezionare foto dall\'account <xliff:g id="APP_NAME">%1$s</xliff:g> di <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
+ <string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Puoi selezionare foto dall\'account <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> nell\'app <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="picker_banner_cloud_account_changed_title" msgid="4825058474378077327">"Account <xliff:g id="APP_NAME">%1$s</xliff:g> aggiornato"</string>
<string name="picker_banner_cloud_account_changed_desc" msgid="3433218869899792497">"Ora le foto di <xliff:g id="USER_ACCOUNT">%1$s</xliff:g> sono incluse qui"</string>
<string name="picker_banner_cloud_choose_app_title" msgid="3165966147547974251">"Scegli un\'app multimediale con funzionalità cloud"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Scegli app"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Scegli account"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Cambia account"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Recupero di tutte le tue foto in corso…"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Consentire all\'app <xliff:g id="APP_NAME_0">^1</xliff:g> di modificare questo file audio?}many{Consentire all\'app <xliff:g id="APP_NAME_1">^1</xliff:g> di modificare <xliff:g id="COUNT">^2</xliff:g> file audio?}other{Consentire all\'app <xliff:g id="APP_NAME_1">^1</xliff:g> di modificare <xliff:g id="COUNT">^2</xliff:g> file audio?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Modifica del file audio in corso…}many{Modifica di <xliff:g id="COUNT">^1</xliff:g> file audio in corso…}other{Modifica di <xliff:g id="COUNT">^1</xliff:g> file audio in corso…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Consentire all\'app <xliff:g id="APP_NAME_0">^1</xliff:g> di modificare questo video?}many{Consentire all\'app <xliff:g id="APP_NAME_1">^1</xliff:g> di modificare <xliff:g id="COUNT">^2</xliff:g> video?}other{Consentire all\'app <xliff:g id="APP_NAME_1">^1</xliff:g> di modificare <xliff:g id="COUNT">^2</xliff:g> video?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Protezione di sicurezza"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Avvisi di transcodifica nativa"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Avanzamento di transcodifica nativa"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Impossibile caricare alcune foto"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"OK"</string>
</resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index a8ddffd52..4bd3784eb 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="picker_app_label" msgid="4254039089502164761">"מדיה"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"הכלי לבחירת מדיה"</string>
<string name="artist_label" msgid="8105600993099120273">"אומן"</string>
<string name="unknown" msgid="2059049215682829375">"לא ידוע"</string>
<string name="root_images" msgid="5861633549189045666">"תמונות"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"גישה למדיה בענן מתוך"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"ללא"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"לא ניתן להחליף את אפליקציית המדיה בענן כרגע."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"הכלי לבחירת מדיה"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"הכלי לבחירת מדיה"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"המדיה בתהליך סנכרון…"</string>
<string name="add" msgid="2894574044585549298">"הוספה"</string>
<string name="deselect" msgid="4297825044827769490">"ביטול הבחירה"</string>
<string name="deselected" msgid="8488133193326208475">"הבחירה בוטלה"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"מומלץ לבדוק את החיבור לאינטרנט ולנסות שוב"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"ניסיון נוסף"</string>
<string name="not_selected" msgid="2244008151669896758">"לא נבחר"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"המדיה שבחרת בתהליך הכנה"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> מתוך <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> מוכנים"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"התמונות שעברו גיבוי נכללות עכשיו"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"ניתן לבחור תמונות מחשבון <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> באפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"בחירת אפליקציה"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"בחירת חשבון"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"החלפת חשבון"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"איסוף התמונות מתבצע"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{לאפשר לאפליקציה <xliff:g id="APP_NAME_0">^1</xliff:g> לשנות את קובץ האודיו הזה?}one{לאפשר לאפליקציה <xliff:g id="APP_NAME_1">^1</xliff:g> לשנות <xliff:g id="COUNT">^2</xliff:g> קובצי אודיו?}two{לאפשר לאפליקציה <xliff:g id="APP_NAME_1">^1</xliff:g> לשנות <xliff:g id="COUNT">^2</xliff:g> קובצי אודיו?}other{לאפשר לאפליקציה <xliff:g id="APP_NAME_1">^1</xliff:g> לשנות <xliff:g id="COUNT">^2</xliff:g> קובצי אודיו?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{מתבצע שינוי בקובץ האודיו…}one{מתבצע שינוי ב-<xliff:g id="COUNT">^1</xliff:g> קובצי אודיו…}two{מתבצע שינוי ב-<xliff:g id="COUNT">^1</xliff:g> קובצי אודיו…}other{מתבצע שינוי ב-<xliff:g id="COUNT">^1</xliff:g> קובצי אודיו…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{לאפשר לאפליקציה <xliff:g id="APP_NAME_0">^1</xliff:g> לשנות את הסרטון הזה?}one{לאפשר לאפליקציה <xliff:g id="APP_NAME_1">^1</xliff:g> לשנות <xliff:g id="COUNT">^2</xliff:g> סרטונים?}two{לאפשר לאפליקציה <xliff:g id="APP_NAME_1">^1</xliff:g> לשנות <xliff:g id="COUNT">^2</xliff:g> סרטונים?}other{לאפשר לאפליקציה <xliff:g id="APP_NAME_1">^1</xliff:g> לשנות <xliff:g id="COUNT">^2</xliff:g> סרטונים?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"הגנה על בטיחות"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"התראות של המרת קידוד מקורית"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"התקדמות של המרת קידוד מקורית"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"לא ניתן לטעון תמונות מסוימות"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"הבנתי"</string>
</resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 5b0bef4de..41b649ce6 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/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="picker_app_label" msgid="4254039089502164761">"メディア"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"メディアの選択"</string>
<string name="artist_label" msgid="8105600993099120273">"アーティスト"</string>
<string name="unknown" msgid="2059049215682829375">"不明"</string>
<string name="root_images" msgid="5861633549189045666">"画像"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"クラウド メディアへのアクセス元"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"なし"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"クラウド メディアアプリを変更できませんでした。"</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"メディアの選択"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"メディアの選択"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"メディアを同期しています…"</string>
<string name="add" msgid="2894574044585549298">"追加"</string>
<string name="deselect" msgid="4297825044827769490">"選択を解除"</string>
<string name="deselected" msgid="8488133193326208475">"選択解除済み"</string>
@@ -63,7 +66,7 @@
<string name="picker_work_profile" msgid="2083221066869141576">"仕事用に切り替える"</string>
<string name="picker_personal_profile" msgid="639484258397758406">"個人用に切り替える"</string>
<string name="picker_profile_admin_title" msgid="4172022376418293777">"管理者によりブロックされています"</string>
- <string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"個人用アプリから仕事用データにアクセスすることは認められていません"</string>
+ <string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"個人用アプリから仕事用データにアクセスすることは許可されていません"</string>
<string name="picker_profile_admin_msg_from_work" msgid="8048524337462790110">"仕事用アプリから個人データにアクセスすることは認められていません"</string>
<string name="picker_profile_work_paused_title" msgid="382212880704235925">"仕事用アプリ一時停止中"</string>
<string name="picker_profile_work_paused_msg" msgid="6321552322125246726">"仕事用の写真を開くには、仕事用アプリを有効にしてからもう一度試してください。"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"インターネット接続を確認してもう一度お試しください"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"再試行"</string>
<string name="not_selected" msgid="2244008151669896758">"未選択"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"選択したメディアの準備をする"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g>/<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> 件準備完了"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"バックアップした写真が追加されました"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"<xliff:g id="APP_NAME">%1$s</xliff:g> のアカウント <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> の写真を選択できます"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"アプリを選択"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"アカウントを選択"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"アカウントを変更"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"すべての写真を取得しています"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{この音声ファイルの変更を <xliff:g id="APP_NAME_0">^1</xliff:g> に許可しますか?}other{<xliff:g id="COUNT">^2</xliff:g> 件の音声ファイルの変更を <xliff:g id="APP_NAME_1">^1</xliff:g> に許可しますか?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{音声ファイルを変更しています…}other{<xliff:g id="COUNT">^1</xliff:g> 件の音声ファイルを変更しています…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{この動画の変更を <xliff:g id="APP_NAME_0">^1</xliff:g> に許可しますか?}other{<xliff:g id="COUNT">^2</xliff:g> 本の動画の変更を <xliff:g id="APP_NAME_1">^1</xliff:g> に許可しますか?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"安全保護"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"ネイティブ コード変換アラート"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"ネイティブ コード変換進行状況"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"読み込めなかった写真があります"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"OK"</string>
</resources>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index ecb247611..1f1974e53 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/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="picker_app_label" msgid="4254039089502164761">"მედია"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"მედიის ამომრჩევი"</string>
<string name="artist_label" msgid="8105600993099120273">"შემსრულებელი"</string>
<string name="unknown" msgid="2059049215682829375">"უცნობი"</string>
<string name="root_images" msgid="5861633549189045666">"სურათები"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"ღრუბლოვან მედიაზე წვდომა აქედან:"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"არცერთი"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"ღრუბლური მედია აპის შეცვლა ამჯერად ვერ ხერხდება."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"მედიის ამომრჩევი"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"მედიის ამომრჩევი"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"მიმდინარეობს მედიის სინქრონიზაცია…"</string>
<string name="add" msgid="2894574044585549298">"დამატება"</string>
<string name="deselect" msgid="4297825044827769490">"არჩევის გაუქმება"</string>
<string name="deselected" msgid="8488133193326208475">"არჩევა გაუქმებულია"</string>
@@ -93,8 +96,9 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"შეამოწმეთ ინტერნეტთან კავშირი და სცადეთ ხელახლა"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"ცდა"</string>
<string name="not_selected" msgid="2244008151669896758">"არ არის არჩეული"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"მიმდინარეობს თქვენ მიერ არჩეული მედიის მომზადება"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> სულ <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>-დან მზადაა"</string>
- <string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"ფოტოების სარეზერვო ასლები ახლა განთავსებულია"</string>
+ <string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"უკვე ფოტოების სარეზერვო ასლების ჩათვლით"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"შეგიძლიათ აირჩიოთ ფოტოები <xliff:g id="APP_NAME">%1$s</xliff:g>-ის ანგარიშიდან <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
<string name="picker_banner_cloud_account_changed_title" msgid="4825058474378077327">"<xliff:g id="APP_NAME">%1$s</xliff:g> ანგარიში განახლებულია"</string>
<string name="picker_banner_cloud_account_changed_desc" msgid="3433218869899792497">"<xliff:g id="USER_ACCOUNT">%1$s</xliff:g>-ის ფოტოები ახლა აქ არის განთავსებული"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"აპის არჩევა"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"აირჩიეთ ანგარიში"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"ანგარიშის შეცვლა"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"თქვენი ყველა ფოტოს მიღება"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{აძლევთ უფლებას <xliff:g id="APP_NAME_0">^1</xliff:g>-ს, შეცვალოს ეს აუდიოფაილი?}other{აძლევთ უფლებას <xliff:g id="APP_NAME_1">^1</xliff:g>-ს, შეცვალოს <xliff:g id="COUNT">^2</xliff:g> აუდიოფაილი?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{მიმდინარეობს აუდიოფაილის მოდიფიკაცია…}other{მიმდინარეობს <xliff:g id="COUNT">^1</xliff:g> აუდიოფაილის მოდიფიკაცია…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{აძლევთ უფლებას <xliff:g id="APP_NAME_0">^1</xliff:g>-ს, შეცვალოს ეს ვიდეო?}other{აძლევთ უფლებას <xliff:g id="APP_NAME_1">^1</xliff:g>-ს, შეცვალოს <xliff:g id="COUNT">^2</xliff:g> ვიდეო?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"უსაფრთხოების დაცვა"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"ტრანსკოდირების ადგილობრივი გაფრთხილება"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"ტრანსკოდირების ადგილობრივი პროგრესი"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"ზოგიერთი ფოტოს ჩატვირთვა ვერ ხერხდება"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"გასაგებია"</string>
</resources>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index 245978fb4..081402708 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Мультимeдиа"</string>
<string name="storage_description" msgid="4081716890357580107">"Жергілікті жад"</string>
<string name="app_label" msgid="9035307001052716210">"Мультимедиа қоймасы"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Meдиа"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Meдиафайл таңдағыш"</string>
<string name="artist_label" msgid="8105600993099120273">"Орындаушы"</string>
<string name="unknown" msgid="2059049215682829375">"Белгісіз"</string>
<string name="root_images" msgid="5861633549189045666">"Кескіндер"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Бұлттық мультимедиа қолданбасына келесі жерден кіріңіз:"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Жоқ"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Бұлттық мультимедиа қолданбасы өзгертілмейді."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Meдиафайл таңдағыш"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Meдиафайл таңдағыш"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Медиафайл синхрондалып жатыр…"</string>
<string name="add" msgid="2894574044585549298">"Қосу"</string>
<string name="deselect" msgid="4297825044827769490">"Таңдамау"</string>
<string name="deselected" msgid="8488133193326208475">"Таңдау алынған"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Интернет байланысын тексеріп, әрекетті қайталаңыз."</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Қайталау"</string>
<string name="not_selected" msgid="2244008151669896758">"таңдалмаған"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Таңдалған мультимедиа әзірленіп жатыр"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g>/<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> дайын"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Сақтық көшірмесі жасалған фотосуреттер қосылды"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Фотосуреттерді <xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасының <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> аккаунтынан таңдай аласыз."</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Қолданба таңдау"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Аккаунт таңдау"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Аккаунтты өзгерту"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Барлық сурет алынып жатыр."</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> қолданбасына осы аудиофайлды өзгертуге рұқсат етілсін бе?}other{<xliff:g id="APP_NAME_1">^1</xliff:g> қолданбасына <xliff:g id="COUNT">^2</xliff:g> аудиофайлды өзгертуге рұқсат етілсін бе?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Аудиофайл өзгертілуде…}other{<xliff:g id="COUNT">^1</xliff:g> аудиофайл өзгертілуде…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> қолданбасына осы бейнені өзгертуге рұқсат етілсін бе?}other{<xliff:g id="APP_NAME_1">^1</xliff:g> қолданбасына <xliff:g id="COUNT">^2</xliff:g> бейнені өзгертуге рұқсат етілсін бе?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Қауіпсіздікті қорғау"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Түбірлік транскодтау туралы хабарландырулар"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Түбірлік транскодтау прогресі"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Кейбір фотосуреттерді жүктеу мүмкін емес"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Түсінікті"</string>
</resources>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index 17480e893..39e2f828d 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/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="picker_app_label" msgid="4254039089502164761">"មេឌៀ"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"មុខងារ​ជ្រើសរើស​មេឌៀ"</string>
<string name="artist_label" msgid="8105600993099120273">"សិល្បករ"</string>
<string name="unknown" msgid="2059049215682829375">"មិនស្គាល់"</string>
<string name="root_images" msgid="5861633549189045666">"រូបភាព"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"ចូលប្រើប្រាស់មេឌៀលើពពកពី"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"គ្មាន"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"មិនអាចប្ដូរ​កម្មវិធី​មេឌៀ​ពពក​នៅពេលនេះបានទេ។"</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"មុខងារ​ជ្រើសរើស​មេឌៀ"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"មុខងារ​ជ្រើសរើស​មេឌៀ"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"កំពុងធ្វើ​សមកាលកម្ម​មេឌៀ…"</string>
<string name="add" msgid="2894574044585549298">"បញ្ចូល"</string>
<string name="deselect" msgid="4297825044827769490">"ដក​ការជ្រើសរើស"</string>
<string name="deselected" msgid="8488133193326208475">"បានដក​ការជ្រើសរើស"</string>
@@ -93,9 +96,10 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"ពិនិត្យ​ការតភ្ជាប់​អ៊ីនធឺណិត​របស់អ្នក រួចព្យាយាម​ម្ដង​ទៀត"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"ព្យាយាមម្ដងទៀត"</string>
<string name="not_selected" msgid="2244008151669896758">"មិនបានជ្រើសរើសទេ"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"កំពុងរៀបចំមេឌៀដែលអ្នកបានជ្រើសរើស"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> នៃ <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> រួចរាល់ហើយ"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"ឥឡូវនេះមានរួមបញ្ចូលរូបថតដែលបានបម្រុងទុក"</string>
- <string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"អ្នកអាចជ្រើសរើសរូបថតពីគណនី <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> របស់ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"អ្នកអាចជ្រើសរើសរូបថតពីគណនី <xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
<string name="picker_banner_cloud_account_changed_title" msgid="4825058474378077327">"បានធ្វើបច្ចុប្បន្នភាពគណនី <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="picker_banner_cloud_account_changed_desc" msgid="3433218869899792497">"ឥឡូវនេះ រូបថតពី <xliff:g id="USER_ACCOUNT">%1$s</xliff:g> ត្រូវបានរួមបញ្ចូលនៅទីនេះ"</string>
<string name="picker_banner_cloud_choose_app_title" msgid="3165966147547974251">"ជ្រើសរើសកម្មវិធី​មេឌៀលើពពក"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"ជ្រើសរើស​កម្មវិធី"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"ជ្រើសរើស​គណនី"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"ប្ដូរ​គណនី"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"កំពុងផ្ទុករូបថតទាំងអស់របស់អ្នក"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{អនុញ្ញាតឱ្យ <xliff:g id="APP_NAME_0">^1</xliff:g> កែ​ឯកសារសំឡេង​នេះ​ឬ?}other{អនុញ្ញាតឱ្យ <xliff:g id="APP_NAME_1">^1</xliff:g> កែ​ឯកសារសំឡេង <xliff:g id="COUNT">^2</xliff:g> ឬ?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{កំពុងកែ​ឯកសារសំឡេង…}other{កំពុងកែ​ឯកសារសំឡេង <xliff:g id="COUNT">^1</xliff:g>…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{អនុញ្ញាតឱ្យ <xliff:g id="APP_NAME_0">^1</xliff:g> កែ​វីដេអូ​នេះ​ឬ?}other{អនុញ្ញាតឱ្យ <xliff:g id="APP_NAME_1">^1</xliff:g> កែ​វីដេអូ <xliff:g id="COUNT">^2</xliff:g> ឬ?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"ការការពារសុវត្ថិភាព"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"ការជូន​ដំណឹង​អំពី​ការបំប្លែង​កូដ​ដើម"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"ដំណើរ​វិវឌ្ឍ​នៃ​ការបំប្លែង​កូដ​ដើម"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"មិនអាចផ្ទុករូបថតមួយចំនួនបានទេ"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"យល់ហើយ"</string>
</resources>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index 2663f7bb2..d83ff1a95 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/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="picker_app_label" msgid="4254039089502164761">"ಮಾಧ್ಯಮ"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"ಮಾಧ್ಯಮ ಪಿಕರ್"</string>
<string name="artist_label" msgid="8105600993099120273">"ಕಲಾವಿದರು"</string>
<string name="unknown" msgid="2059049215682829375">"ಅಪರಿಚಿತ"</string>
<string name="root_images" msgid="5861633549189045666">"ಚಿತ್ರಗಳು"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"ಇದರಿಂದ ಕ್ಲೌಡ್ ಮಾಧ್ಯಮವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"ಯಾವುದೂ ಅಲ್ಲ"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"ಇದೀಗ ಕ್ಲೌಡ್ ಮೀಡಿಯಾ ಆ್ಯಪ್ ಬದಲಾಯಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"ಮಾಧ್ಯಮ ಪಿಕರ್"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"ಮಾಧ್ಯಮ ಪಿಕರ್"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"ಮಾಧ್ಯಮವನ್ನು ಸಿಂಕ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
<string name="add" msgid="2894574044585549298">"ಸೇರಿಸಿ"</string>
<string name="deselect" msgid="4297825044827769490">"ಆಯ್ಕೆ ರದ್ದುಮಾಡಿ"</string>
<string name="deselected" msgid="8488133193326208475">"ಆಯ್ಕೆ ರದ್ದುಮಾಡಲಾಗಿದೆ"</string>
@@ -60,16 +63,16 @@
<string name="picker_photos" msgid="7415035516411087392">"ಫೋಟೋಗಳು"</string>
<string name="picker_albums" msgid="4822511902115299142">"ಆಲ್ಬಮ್‌ಗಳು"</string>
<string name="picker_preview" msgid="6257414886055861039">"ಪೂರ್ವವೀಕ್ಷಣೆ"</string>
- <string name="picker_work_profile" msgid="2083221066869141576">"ಕೆಲಸಕ್ಕೆ ಬದಲಿಸಿ"</string>
- <string name="picker_personal_profile" msgid="639484258397758406">"ವೈಯಕ್ತಿಕಕ್ಕೆ ಬದಲಿಸಿ"</string>
+ <string name="picker_work_profile" msgid="2083221066869141576">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್‌ಗೆ ಬದಲಿಸಿ"</string>
+ <string name="picker_personal_profile" msgid="639484258397758406">"ವೈಯಕ್ತಿಕ ಪ್ರೊಫೈಲ್‌ಗೆ ಬದಲಿಸಿ"</string>
<string name="picker_profile_admin_title" msgid="4172022376418293777">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನಿರ್ಬಂಧಿಸಿದ್ದಾರೆ"</string>
- <string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"ವೈಯಕ್ತಿಕ ಆ್ಯಪ್ ಮೂಲಕ ಅಧಿಕೃತ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಲು ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ"</string>
+ <string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"ವೈಯಕ್ತಿಕ ಆ್ಯಪ್‌ನಿಂದ ಉದ್ಯೋಗದ ಡೇಟಾವನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ"</string>
<string name="picker_profile_admin_msg_from_work" msgid="8048524337462790110">"ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್ ಮೂಲಕ ಅಧಿಕೃತ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಲು ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ"</string>
<string name="picker_profile_work_paused_title" msgid="382212880704235925">"ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳನ್ನು ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="picker_profile_work_paused_msg" msgid="6321552322125246726">"ಕೆಲಸದ ಫೋಟೋಗಳನ್ನು ತೆರೆಯಲು, ನಿಮ್ಮ ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳನ್ನು ಆನ್ ಮಾಡಿ ನಂತರ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ"</string>
- <string name="picker_privacy_message" msgid="9132700451027116817">"ಈ ಆ್ಯಪ್ ನೀವು ಆಯ್ಕೆಮಾಡಿದ ಫೋಟೋಗಳನ್ನು ಮಾತ್ರ ಪ್ರವೇಶಿಸಬಹುದು"</string>
+ <string name="picker_privacy_message" msgid="9132700451027116817">"ಈ ಆ್ಯಪ್ ನೀವು ಆಯ್ಕೆಮಾಡಿದ ಫೋಟೋಗಳನ್ನು ಮಾತ್ರ ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಬಹುದು"</string>
<string name="picker_header_permissions" msgid="675872774407768495">"ಈ ಆ್ಯಪ್ ಅನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು ನೀವು ಅನುಮತಿಸುವ ಫೋಟೋಗಳು ಮತ್ತು ವೀಡಿಯೊಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
- <string name="picker_album_item_count" msgid="4420723302534177596">"{count,plural, =1{<xliff:g id="COUNT_0">^1</xliff:g>ಐಟಂ}one{<xliff:g id="COUNT_1">^1</xliff:g> ಐಟಂಗಳು}other{<xliff:g id="COUNT_1">^1</xliff:g> ಐಟಂಗಳು}}"</string>
+ <string name="picker_album_item_count" msgid="4420723302534177596">"{count,plural, =1{<xliff:g id="COUNT_0">^1</xliff:g> ಐಟಂ}one{<xliff:g id="COUNT_1">^1</xliff:g> ಐಟಂಗಳು}other{<xliff:g id="COUNT_1">^1</xliff:g> ಐಟಂಗಳು}}"</string>
<string name="picker_add_button_multi_select" msgid="4005164092275518399">"ಸೇರಿಸಿ (<xliff:g id="COUNT">^1</xliff:g>)"</string>
<string name="picker_add_button_multi_select_permissions" msgid="5138751105800138838">"(<xliff:g id="COUNT">^1</xliff:g>) ಅನುಮತಿಸಿ"</string>
<string name="picker_category_camera" msgid="4857367052026843664">"ಕ್ಯಾಮರಾ"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"ನಿಮ್ಮ ಇಂಟರ್ನೆಟ್ ಕನೆಕ್ಷನ್ ಅನ್ನು ಪರಿಶೀಲಿಸಿ ಹಾಗೂ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"ಮರುಪ್ರಯತ್ನಿಸಿ"</string>
<string name="not_selected" msgid="2244008151669896758">"ಆಯ್ಕೆಮಾಡಲಾಗಿಲ್ಲ"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"ನಿಮ್ಮ ಆಯ್ಕೆಮಾಡಿದ ಮೀಡಿಯಾವನ್ನು ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> ರಲ್ಲಿ <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> ಸಿದ್ಧವಾಗಿವೆ"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"ಬ್ಯಾಕಪ್ ಮಾಡಲಾದ ಫೋಟೋಗಳನ್ನು ಈಗ ಸೇರಿಸಲಾಗಿದೆ"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಖಾತೆಯ <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> ನಲ್ಲಿರುವ ಫೋಟೋಗಳನ್ನು ನೀವು ಆಯ್ಕೆಮಾಡಬಹುದು"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"ಆ್ಯಪ್ ಅನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"ಖಾತೆಯನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"ಖಾತೆಯನ್ನು ಬದಲಾಯಿಸಿ"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"ನಿಮ್ಮ ಎಲ್ಲಾ ಫೋಟೋಗಳನ್ನು ಪಡೆಯಲಾಗುತ್ತಿದೆ"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{ಈ ಆಡಿಯೋ ಫೈಲ್ ಅನ್ನು ಮಾರ್ಪಡಿಸಲು <xliff:g id="APP_NAME_0">^1</xliff:g> ಗೆ ಅನುಮತಿ ನೀಡಬೇಕೇ?}one{ಈ <xliff:g id="COUNT">^2</xliff:g> ಆಡಿಯೋ ಫೈಲ್‌ಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು <xliff:g id="APP_NAME_1">^1</xliff:g> ಗೆ ಅನುಮತಿ ನೀಡಬೇಕೇ?}other{ಈ <xliff:g id="COUNT">^2</xliff:g> ಆಡಿಯೋ ಫೈಲ್‌ಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು <xliff:g id="APP_NAME_1">^1</xliff:g> ಗೆ ಅನುಮತಿ ನೀಡಬೇಕೇ?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{ಆಡಿಯೋ ಫೈಲ್ ಅನ್ನು ಮಾರ್ಪಡಿಸಲಾಗುತ್ತಿದೆ…}one{<xliff:g id="COUNT">^1</xliff:g> ಆಡಿಯೋ ಫೈಲ್‌ಗಳನ್ನು ಮಾರ್ಪಡಿಸಲಾಗುತ್ತಿದೆ…}other{<xliff:g id="COUNT">^1</xliff:g> ಆಡಿಯೋ ಫೈಲ್‌ಗಳನ್ನು ಮಾರ್ಪಡಿಸಲಾಗುತ್ತಿದೆ…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{ಈ ವೀಡಿಯೊವನ್ನು ಮಾರ್ಪಡಿಸಲು <xliff:g id="APP_NAME_0">^1</xliff:g> ಗೆ ಅನುಮತಿ ನೀಡಬೇಕೇ?}one{ಈ <xliff:g id="COUNT">^2</xliff:g> ವೀಡಿಯೊಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು <xliff:g id="APP_NAME_1">^1</xliff:g> ಗೆ ಅನುಮತಿ ನೀಡಬೇಕೇ?}other{ಈ <xliff:g id="COUNT">^2</xliff:g> ವೀಡಿಯೊಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು <xliff:g id="APP_NAME_1">^1</xliff:g> ಗೆ ಅನುಮತಿ ನೀಡಬೇಕೇ?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"ಭದ್ರತಾ ರಕ್ಷಣೆ"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"ನೇಟಿವ್ ಟ್ರಾನ್ಸ್‌ಕೋಡ್ ಅಲರ್ಟ್‌ಗಳು"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"ನೇಟಿವ್ ಟ್ರಾನ್ಸ್‌ಕೋಡ್ ಪ್ರಗತಿ"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"ಕೆಲವು ಫೋಟೋಗಳನ್ನು ಲೋಡ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"ಅರ್ಥವಾಯಿತು"</string>
</resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 9b867da5c..0d31cd73c 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/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="picker_app_label" msgid="4254039089502164761">"미디어"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"미디어 선택 도구"</string>
<string name="artist_label" msgid="8105600993099120273">"아티스트"</string>
<string name="unknown" msgid="2059049215682829375">"알 수 없음"</string>
<string name="root_images" msgid="5861633549189045666">"이미지"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"클라우드 미디어 액세스 위치"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"없음"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"현재 클라우드 미디어 앱을 변경할 수 없습니다."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"미디어 선택 도구"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"미디어 선택 도구"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"미디어 동기화 중…"</string>
<string name="add" msgid="2894574044585549298">"추가"</string>
<string name="deselect" msgid="4297825044827769490">"선택 해제"</string>
<string name="deselected" msgid="8488133193326208475">"선택 해제됨"</string>
@@ -60,8 +63,8 @@
<string name="picker_photos" msgid="7415035516411087392">"사진"</string>
<string name="picker_albums" msgid="4822511902115299142">"앨범"</string>
<string name="picker_preview" msgid="6257414886055861039">"미리보기"</string>
- <string name="picker_work_profile" msgid="2083221066869141576">"직장으로 전환"</string>
- <string name="picker_personal_profile" msgid="639484258397758406">"개인으로 전환"</string>
+ <string name="picker_work_profile" msgid="2083221066869141576">"직장 프로필로 전환"</string>
+ <string name="picker_personal_profile" msgid="639484258397758406">"개인 프로필로 전환"</string>
<string name="picker_profile_admin_title" msgid="4172022376418293777">"관리자가 차단함"</string>
<string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"개인 앱에서는 업무 데이터에 액세스할 수 없습니다."</string>
<string name="picker_profile_admin_msg_from_work" msgid="8048524337462790110">"직장 앱에서는 개인 데이터에 액세스할 수 없습니다."</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"인터넷 연결 상태를 확인하고 다시 시도해 주세요."</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"다시 시도"</string>
<string name="not_selected" msgid="2244008151669896758">"선택되지 않음"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"선택한 미디어를 준비하는 중"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g>/<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>개 준비됨"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"이제 백업된 사진이 포함됨"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"<xliff:g id="APP_NAME">%1$s</xliff:g> 계정(<xliff:g id="USER_ACCOUNT">%2$s</xliff:g>)에서 사진을 선택할 수 있습니다."</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"앱 선택"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"계정 선택"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"계정 변경"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"모든 사진 가져오는 중"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g>에서 이 오디오 파일을 수정하도록 허용하시겠습니까?}other{<xliff:g id="APP_NAME_1">^1</xliff:g>에서 오디오 파일 <xliff:g id="COUNT">^2</xliff:g>개를 수정하도록 허용하시겠습니까?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{오디오 파일 수정 중…}other{오디오 파일 <xliff:g id="COUNT">^1</xliff:g>개 수정 중…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g>에서 이 동영상을 수정하도록 허용하시겠습니까?}other{<xliff:g id="APP_NAME_1">^1</xliff:g>에서 동영상 <xliff:g id="COUNT">^2</xliff:g>개를 수정하도록 허용하시겠습니까?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"안전 보안"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"네이티브 트랜스코드 알림"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"네이티브 트랜스코드 진행 상황"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"일부 사진을 로드할 수 없음"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"확인"</string>
</resources>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 12a50123f..46d6c6b43 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/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="picker_app_label" msgid="4254039089502164761">"Медиа"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Медиа файлдарды тандагыч"</string>
<string name="artist_label" msgid="8105600993099120273">"Аткаруучу"</string>
<string name="unknown" msgid="2059049215682829375">"Белгисиз"</string>
<string name="root_images" msgid="5861633549189045666">"Сүрөттөр"</string>
@@ -46,12 +46,15 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Төмөнкүдөн алынган булуттагы мультимедианы колдонуу:"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Жок"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Мультимедиа колдонмосу өзгөргөн жок."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Медиа файлдарды тандагыч"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Медиа файлдарды тандагыч"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Медиа файлдар шайкештирилүүдө…"</string>
<string name="add" msgid="2894574044585549298">"Кошуу"</string>
<string name="deselect" msgid="4297825044827769490">"Тандоодон чыгаруу"</string>
<string name="deselected" msgid="8488133193326208475">"Тандоодон чыгарылды"</string>
<string name="select" msgid="2704765470563027689">"Тандоо"</string>
<string name="selected" msgid="9151797369975828124">"Тандалды"</string>
- <string name="select_up_to" msgid="6994294169508439957">"{count,plural, =1{<xliff:g id="COUNT_0">^1</xliff:g> объектке чейин тандаңыз}other{<xliff:g id="COUNT_1">^1</xliff:g> объектке чейин тандаңыз}}"</string>
+ <string name="select_up_to" msgid="6994294169508439957">"{count,plural, =1{<xliff:g id="COUNT_0">^1</xliff:g> нерсеге чейин тандаңыз}other{<xliff:g id="COUNT_1">^1</xliff:g> нерсеге чейин тандаңыз}}"</string>
<string name="recent" msgid="6694613584743207874">"Акыркы"</string>
<string name="picker_photos_empty_message" msgid="5980619500554575558">"Сүрөттөр же видеолор жок"</string>
<string name="picker_album_media_empty_message" msgid="7061850698189881671">"Колдоого алынган сүрөттөр же видеолор жок"</string>
@@ -67,7 +70,7 @@
<string name="picker_profile_admin_msg_from_work" msgid="8048524337462790110">"Жеке маалыматка жумуш колдонмосунан кирүүгө тыюу салынат"</string>
<string name="picker_profile_work_paused_title" msgid="382212880704235925">"Жумуш колдонмолору тындырылды"</string>
<string name="picker_profile_work_paused_msg" msgid="6321552322125246726">"Жумуш сүрөттөрүн ачуу үчүн жумуш колдонмолорун иштетип, кайра аракет кылыңыз"</string>
- <string name="picker_privacy_message" msgid="9132700451027116817">"Бул колдонмо сиз тандаган сүрөттөргө гана кире алат"</string>
+ <string name="picker_privacy_message" msgid="9132700451027116817">"Бул колдонмого сиз тандаган сүрөттөр гана жеткиликтүү"</string>
<string name="picker_header_permissions" msgid="675872774407768495">"Бул колдонмо кире турган сүрөттөрдү жана видеолорду тандаңыз"</string>
<string name="picker_album_item_count" msgid="4420723302534177596">"{count,plural, =1{<xliff:g id="COUNT_0">^1</xliff:g> нерсе}other{<xliff:g id="COUNT_1">^1</xliff:g> нерсе}}"</string>
<string name="picker_add_button_multi_select" msgid="4005164092275518399">"Кошуу (<xliff:g id="COUNT">^1</xliff:g>)"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Интернет байланышыңызды текшерип, кайталап көрүңүз"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Кайталоо"</string>
<string name="not_selected" msgid="2244008151669896758">"тандалган жок"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Тандаган медиа файлдарыңыз даярдалууда"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> ичинен <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> даяр"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Эми камдык көчүрмөсү сакталган сүрөттөр камтылат"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"<xliff:g id="APP_NAME">%1$s</xliff:g> аккаунтундагы (<xliff:g id="USER_ACCOUNT">%2$s</xliff:g>) сүрөттөрдү тандай аласыз"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Колдонмо тандаңыз"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Аккаунт тандоо"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Аккаунтту өзгөртүү"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Бардык сүрөттөрүңүз алынууда"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> колдонмосу бул аудио файлды өзгөртсүнбү?}other{<xliff:g id="APP_NAME_1">^1</xliff:g> колдонмосу <xliff:g id="COUNT">^2</xliff:g> аудио файлды өзгөртсүнбү?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Аудио файл өзгөртүлүүдө…}other{<xliff:g id="COUNT">^1</xliff:g> аудио файл өзгөртүлүүдө…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> колдонмосу бул видеону өзгөртсүнбү?}other{<xliff:g id="APP_NAME_1">^1</xliff:g> колдонмосу <xliff:g id="COUNT">^2</xliff:g> видеону өзгөртсүнбү?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Коопсуздукту коргоо"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Камтылган транскоддоо эскертүүлөрү"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Камтылган транскоддоо жүргүзүлүүдө"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Айрым сүрөттөр жүктөлбөй жатат"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Түшүндүм"</string>
</resources>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index dcbb981e8..a9a2ac288 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/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="picker_app_label" msgid="4254039089502164761">"ສື່"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"ຕົວເລືອກມີເດຍ"</string>
<string name="artist_label" msgid="8105600993099120273">"ສິນລະປິນ"</string>
<string name="unknown" msgid="2059049215682829375">"ບໍ່ຮູ້ຈັກ"</string>
<string name="root_images" msgid="5861633549189045666">"ຮູບພາບ"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"ເຂົ້າເຖິງມີເດຍໃນລະບົບຄລາວຈາກ"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"ບໍ່ມີ"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"ບໍ່ສາມາດປ່ຽນແອັບມີເດຍໃນລະບົບຄລາວໄດ້ໃນຕອນນີ້."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"ຕົວເລືອກມີເດຍ"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"ຕົວເລືອກມີເດຍ"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"ກຳລັງຊິ້ງຂໍ້ມູນມີເດຍ…"</string>
<string name="add" msgid="2894574044585549298">"ເພີ່ມ"</string>
<string name="deselect" msgid="4297825044827769490">"ເຊົາເລືອກ"</string>
<string name="deselected" msgid="8488133193326208475">"ເຊົາເລືອກແລ້ວ"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"ກະລຸນາກວດສອບການເຊື່ອມຕໍ່ອິນເຕີເນັດຂອງທ່ານແລ້ວລອງໃໝ່"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"ລອງໃໝ່"</string>
<string name="not_selected" msgid="2244008151669896758">"ບໍ່ໄດ້ເລືອກ"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"ກຳລັງກຽມມີເດຍທີ່ທ່ານເລືອກໄວ້"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"ພ້ອມແລ້ວ <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> ຈາກທັງໝົດ <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"ຕອນນີ້ຮວມຮູບພາບທີ່ສຳຮອງຂໍ້ມູນໄວ້ແລ້ວ"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"ທ່ານສາມາດເລືອກຮູບພາບໄດ້ຈາກບັນຊີ <xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"ເລືອກແອັບ"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"ເລືອກບັນຊີ"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"ປ່ຽນບັນຊີ"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"ກຳລັງໂຫຼດຮູບພາບທັງໝົດຂອງທ່ານ"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{ອະນຸຍາດໃຫ້ <xliff:g id="APP_NAME_0">^1</xliff:g> ແກ້ໄຂໄຟລ໌ສຽງນີ້ບໍ?}other{ອະນຸຍາດໃຫ້ <xliff:g id="APP_NAME_1">^1</xliff:g> ແກ້ໄຂໄຟລ໌ສຽງ <xliff:g id="COUNT">^2</xliff:g> ໄຟລ໌ບໍ?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{ກຳລັງແກ້ໄຂໄຟລ໌ສຽງ…}other{ກຳລັງແກ້ໄຂໄຟລ໌ສຽງ <xliff:g id="COUNT">^1</xliff:g> ໄຟລ໌…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{ອະນຸຍາດໃຫ້ <xliff:g id="APP_NAME_0">^1</xliff:g> ແກ້ໄຂວິດີໂອນີ້ບໍ?}other{ອະນຸຍາດໃຫ້ <xliff:g id="APP_NAME_1">^1</xliff:g> ແກ້ໄຂວິດີໂອ <xliff:g id="COUNT">^2</xliff:g> ລາຍການບໍ?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"ການປ້ອງກັນຄວາມປອດໄພ"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"ແຈ້ງເຕືອນການປ່ຽນຮູບແບບລະຫັດເດີມ"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"ຄວາມຄືບໜ້າຂອງການປ່ຽນຮູບແບບລະຫັດເດີມ"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"ບໍ່ສາມາດໂຫຼດບາງຮູບພາບໄດ້"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"ເຂົ້າໃຈແລ້ວ"</string>
</resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 0767478c1..5d6c4287a 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Medija"</string>
<string name="storage_description" msgid="4081716890357580107">"Vietinė saugykla"</string>
<string name="app_label" msgid="9035307001052716210">"Medijos saugykla"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Medija"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Medijos pasirinkimo priemonė"</string>
<string name="artist_label" msgid="8105600993099120273">"Atlikėjas"</string>
<string name="unknown" msgid="2059049215682829375">"Nežinoma"</string>
<string name="root_images" msgid="5861633549189045666">"Vaizdai"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Pasiekti mediją debesyje iš"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Nėra"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Šiuo metu nepavyko pakeisti debesies medijos programos."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Medijos pasirinkimo priemonė"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Medijos pasirinkimo priemonė"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Sinchronizuojama medija…"</string>
<string name="add" msgid="2894574044585549298">"Pridėti"</string>
<string name="deselect" msgid="4297825044827769490">"Panaikinti pasirinkimą"</string>
<string name="deselected" msgid="8488133193326208475">"Pasirinkimas panaikintas"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Patikrinkite interneto ryšį ir bandykite dar kartą"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Bandyti dar kartą"</string>
<string name="not_selected" msgid="2244008151669896758">"nepasirinkta"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Ruošiami pasirinkti medijos failai"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"Paruošta: <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> iš <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Dabar įtraukiamos atsarginės nuotraukų kopijos"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Galite pasirinkti nuotraukas iš „<xliff:g id="APP_NAME">%1$s</xliff:g>“ paskyros <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Pasirinkti programą"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Pasirinkti paskyrą"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Pakeisti paskyrą"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Gaunamos visos nuotraukos"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Leisti programai „<xliff:g id="APP_NAME_0">^1</xliff:g>“ keisti šį garso failą?}one{Leisti programai „<xliff:g id="APP_NAME_1">^1</xliff:g>“ keisti <xliff:g id="COUNT">^2</xliff:g> garso failą?}few{Leisti programai „<xliff:g id="APP_NAME_1">^1</xliff:g>“ keisti <xliff:g id="COUNT">^2</xliff:g> garso failus?}many{Leisti programai „<xliff:g id="APP_NAME_1">^1</xliff:g>“ keisti <xliff:g id="COUNT">^2</xliff:g> garso failo?}other{Leisti programai „<xliff:g id="APP_NAME_1">^1</xliff:g>“ keisti <xliff:g id="COUNT">^2</xliff:g> garso failų?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Keičiamas garso failas…}one{Keičiamas <xliff:g id="COUNT">^1</xliff:g> garso failas…}few{Keičiami <xliff:g id="COUNT">^1</xliff:g> garso failai…}many{Keičiama <xliff:g id="COUNT">^1</xliff:g> garso failo…}other{Keičiama <xliff:g id="COUNT">^1</xliff:g> garso failų…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Leisti programai „<xliff:g id="APP_NAME_0">^1</xliff:g>“ keisti šį vaizdo įrašą?}one{Leisti programai „<xliff:g id="APP_NAME_1">^1</xliff:g>“ keisti <xliff:g id="COUNT">^2</xliff:g> vaizdo įrašą?}few{Leisti programai „<xliff:g id="APP_NAME_1">^1</xliff:g>“ keisti <xliff:g id="COUNT">^2</xliff:g> vaizdo įrašus?}many{Leisti programai „<xliff:g id="APP_NAME_1">^1</xliff:g>“ keisti <xliff:g id="COUNT">^2</xliff:g> vaizdo įrašo?}other{Leisti programai „<xliff:g id="APP_NAME_1">^1</xliff:g>“ keisti <xliff:g id="COUNT">^2</xliff:g> vaizdo įrašų?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Apsauga"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Native Transcode Alerts"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Native Transcode Progress"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Nepavyko įkelti kai kurių nuotraukų"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Supratau"</string>
</resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index e8df90906..178f65582 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Multivide"</string>
<string name="storage_description" msgid="4081716890357580107">"Lokālā krātuve"</string>
<string name="app_label" msgid="9035307001052716210">"Multivides krātuve"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Multivide"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Multivides atlasītājs"</string>
<string name="artist_label" msgid="8105600993099120273">"Izpildītājs"</string>
<string name="unknown" msgid="2059049215682829375">"Nezināms"</string>
<string name="root_images" msgid="5861633549189045666">"Attēli"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Piekļūstiet mākoņa multivides saturam no"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Nav"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Nevarēja mainīt mākoņa multivides lietotni."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Multivides atlasītājs"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Multivides atlasītājs"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Notiek multivides satura sinhronizēšana…"</string>
<string name="add" msgid="2894574044585549298">"Pievienot"</string>
<string name="deselect" msgid="4297825044827769490">"Noņemt atlasi"</string>
<string name="deselected" msgid="8488133193326208475">"Atlase noņemta"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Pārbaudiet interneta savienojumu un mēģiniet vēlreiz"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Mēģināt vēlreiz"</string>
<string name="not_selected" msgid="2244008151669896758">"nav atlasīts"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Notiek jūsu atlasītā multivides satura sagatavošana"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"Gatavs: <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> no <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Dublētie fotoattēli ir iekļauti"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Varat atlasīt fotoattēlus no lietotnes “<xliff:g id="APP_NAME">%1$s</xliff:g>” konta <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Izvēlēties lietotni"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Izvēlēties kontu"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Mainīt kontu"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Notiek visu jūsu fotoattēlu ielāde…"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Vai atļaut lietotnei <xliff:g id="APP_NAME_0">^1</xliff:g> pārveidot šo audio failu?}zero{Vai atļaut lietotnei <xliff:g id="APP_NAME_1">^1</xliff:g> pārveidot <xliff:g id="COUNT">^2</xliff:g> audio failus?}one{Vai atļaut lietotnei <xliff:g id="APP_NAME_1">^1</xliff:g> pārveidot <xliff:g id="COUNT">^2</xliff:g> audio failu?}other{Vai atļaut lietotnei <xliff:g id="APP_NAME_1">^1</xliff:g> pārveidot <xliff:g id="COUNT">^2</xliff:g> audio failus?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Notiek audio faila pārveidošana…}zero{Notiek <xliff:g id="COUNT">^1</xliff:g> audio failu pārveidošana…}one{Notiek <xliff:g id="COUNT">^1</xliff:g> audio faila pārveidošana…}other{Notiek <xliff:g id="COUNT">^1</xliff:g> audio failu pārveidošana…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Vai atļaut lietotnei <xliff:g id="APP_NAME_0">^1</xliff:g> pārveidot šo videoklipu?}zero{Vai atļaut lietotnei <xliff:g id="APP_NAME_1">^1</xliff:g> pārveidot <xliff:g id="COUNT">^2</xliff:g> videoklipus?}one{Vai atļaut lietotnei <xliff:g id="APP_NAME_1">^1</xliff:g> pārveidot <xliff:g id="COUNT">^2</xliff:g> videoklipu?}other{Vai atļaut lietotnei <xliff:g id="APP_NAME_1">^1</xliff:g> pārveidot <xliff:g id="COUNT">^2</xliff:g> videoklipus?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Drošības aizsardzība"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Brīdinājumi par mantotā formāta pārkodēšanu"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Mantotā formāta pārkodēšanas norise"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Nevar ielādēt dažus fotoattēlus"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Labi"</string>
</resources>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index f7d31b2b5..c908243aa 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/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="picker_app_label" msgid="4254039089502164761">"Аудиовизуелни содржини"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Избирач на аудиовизуелни содржини"</string>
<string name="artist_label" msgid="8105600993099120273">"Изведувач"</string>
<string name="unknown" msgid="2059049215682829375">"Непознат"</string>
<string name="root_images" msgid="5861633549189045666">"Слики"</string>
@@ -42,10 +42,13 @@
<string name="picker_settings" msgid="6443463167344790260">"Апликација за содржини во облак"</string>
<string name="picker_settings_system_settings_menu_title" msgid="3055084757610063581">"Апликација за содржини во облак"</string>
<string name="picker_settings_title" msgid="5647700706470673258">"Апликација за аудиовизуелни содржини во облак"</string>
- <string name="picker_settings_description" msgid="2916686824777214585">"Пристап до вашите аудиовизуелни содржини во облак кога некоја апликација или веб-сајт ќе ве праша да изберете фотографии или видеа"</string>
- <string name="picker_settings_selection_message" msgid="245453573086488596">"Пристапете до аудиовизуелните содржини во облак од"</string>
+ <string name="picker_settings_description" msgid="2916686824777214585">"Пристапувајте до вашите аудиовизуелни содржини во облак кога некоја апликација или веб-сајт ќе побара да изберете фотографии или видеа"</string>
+ <string name="picker_settings_selection_message" msgid="245453573086488596">"Пристапувајте до аудиовизуелните содржини во облак од"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Нема"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Не може да се промени апликацијата за аудиовизуелни содржини во облак во моментов."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Избирач на аудиовизуелни содржини"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Избирач на аудиовизуелни содржини"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Се синхронизираат аудиовизуелните содржини…"</string>
<string name="add" msgid="2894574044585549298">"Додај"</string>
<string name="deselect" msgid="4297825044827769490">"Поништи го изборот"</string>
<string name="deselected" msgid="8488133193326208475">"Изборот е поништен"</string>
@@ -60,8 +63,8 @@
<string name="picker_photos" msgid="7415035516411087392">"Фотографии"</string>
<string name="picker_albums" msgid="4822511902115299142">"Албуми"</string>
<string name="picker_preview" msgid="6257414886055861039">"Преглед"</string>
- <string name="picker_work_profile" msgid="2083221066869141576">"Префрли на работен профил"</string>
- <string name="picker_personal_profile" msgid="639484258397758406">"Префрли на личен профил"</string>
+ <string name="picker_work_profile" msgid="2083221066869141576">"Префрлете се на работен профил"</string>
+ <string name="picker_personal_profile" msgid="639484258397758406">"Префрлете се на личен профил"</string>
<string name="picker_profile_admin_title" msgid="4172022376418293777">"Блокирано од администраторот"</string>
<string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"Не е дозволено пристапување до работни податоци од лична апликација"</string>
<string name="picker_profile_admin_msg_from_work" msgid="8048524337462790110">"Не е дозволено пристапување до лични податоци од работна апликација"</string>
@@ -93,8 +96,9 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Проверете ја интернет-врската и обидете се повторно"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Повторно"</string>
<string name="not_selected" msgid="2244008151669896758">"не е избрано"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Вашите избрани аудиовизуелни содржини се подготвуваат"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"Подготвени: <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> од <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>"</string>
- <string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Бекап од фотографиите сега е влучен"</string>
+ <string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Сега се опфатени фотографии од бекап"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Можете да изберете фотографии од сметката <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> на <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="picker_banner_cloud_account_changed_title" msgid="4825058474378077327">"Сметката на <xliff:g id="APP_NAME">%1$s</xliff:g> е ажурирана"</string>
<string name="picker_banner_cloud_account_changed_desc" msgid="3433218869899792497">"Фотографиите од <xliff:g id="USER_ACCOUNT">%1$s</xliff:g> сега се вклучени овде"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Изберете апликација"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Изберете сметка"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Променете ја сметката"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Се вчитуваат сите ваши фотографии"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Да се дозволи <xliff:g id="APP_NAME_0">^1</xliff:g> да ја измени аудиодатотекава?}one{Да се дозволи <xliff:g id="APP_NAME_1">^1</xliff:g> да измени <xliff:g id="COUNT">^2</xliff:g> аудиодатотека?}other{Да се дозволи <xliff:g id="APP_NAME_1">^1</xliff:g> да измени <xliff:g id="COUNT">^2</xliff:g> аудиодатотеки?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Се изменува аудиодатотеката…}one{Се изменуваат <xliff:g id="COUNT">^1</xliff:g> аудиодатотека…}other{Се изменуваат <xliff:g id="COUNT">^1</xliff:g> аудиодатотеки…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Да се дозволи <xliff:g id="APP_NAME_0">^1</xliff:g> да го измени видеово?}one{Да се дозволи <xliff:g id="APP_NAME_1">^1</xliff:g> да измени <xliff:g id="COUNT">^2</xliff:g> видео?}other{Да се дозволи <xliff:g id="APP_NAME_1">^1</xliff:g> да измени <xliff:g id="COUNT">^2</xliff:g> видеа?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Безбедносна заштита"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Предупредувања за матичното транскодирање"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Напредок на матичното транскодирање"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Некои фотографии не може да се вчитаат"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Сфатив"</string>
</resources>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index ac564d182..c2728515c 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/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="picker_app_label" msgid="4254039089502164761">"മീഡിയ"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"മീഡിയ പിക്കർ"</string>
<string name="artist_label" msgid="8105600993099120273">"ആർട്ടിസ്‌റ്റ്"</string>
<string name="unknown" msgid="2059049215682829375">"അജ്ഞാതം"</string>
<string name="root_images" msgid="5861633549189045666">"ചിത്രങ്ങൾ"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"ക്ലൗഡ് മീഡിയ ആപ്പിൽ നിന്ന്"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"ഒന്നുമില്ല"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"ക്ലൗഡ് മീഡിയ ആപ്പ് ഇപ്പോൾ മാറ്റാനാകുന്നില്ല."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"മീഡിയാ പിക്കർ"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"മീഡിയാ പിക്കർ"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"മീഡിയാ സമന്വയിപ്പിക്കുന്നു…"</string>
<string name="add" msgid="2894574044585549298">"ചേർക്കുക"</string>
<string name="deselect" msgid="4297825044827769490">"തിരഞ്ഞെടുത്തത് മാറ്റുക"</string>
<string name="deselected" msgid="8488133193326208475">"തിരഞ്ഞെടുത്തത് മാറ്റി"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"നിങ്ങളുടെ ഇന്റർനെറ്റ് കണക്ഷൻ പരിശോധിച്ച് വീണ്ടും ശ്രമിക്കുക"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"വീണ്ടും ശ്രമിക്കുക"</string>
<string name="not_selected" msgid="2244008151669896758">"തിരഞ്ഞെടുത്തിട്ടില്ല"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"നിങ്ങൾ തിരഞ്ഞെടുത്ത മീഡിയ തയ്യാറാക്കുന്നു"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>-ൽ <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> എണ്ണം തയ്യാറാണ്"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"ബാക്കപ്പ് ചെയ്ത ഫോട്ടോകൾ ഇപ്പോൾ ഉൾപ്പെടുത്തിയിരിക്കുന്നു"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"നിങ്ങൾക്ക് <xliff:g id="APP_NAME">%1$s</xliff:g> അക്കൗണ്ടിൽ <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> നിന്ന് ഫോട്ടോകൾ തിരഞ്ഞെടുക്കാം"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"ആപ്പ് തിരഞ്ഞെടുക്കുക"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"അക്കൗണ്ട് തിരഞ്ഞെടുക്കുക"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"അക്കൗണ്ട് മാറ്റുക"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"നിങ്ങളുടെ ഫോട്ടോകളെല്ലാം ലഭ്യമാക്കുന്നു"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{ഈ ഓഡിയോ ഫയൽ പരിഷ്ക്കരിക്കാൻ <xliff:g id="APP_NAME_0">^1</xliff:g> എന്നതിനെ അനുവദിക്കണോ?}other{<xliff:g id="COUNT">^2</xliff:g> ഓഡിയോ ഫയലുകൾ പരിഷ്ക്കരിക്കാൻ <xliff:g id="APP_NAME_1">^1</xliff:g> എന്നതിനെ അനുവദിക്കണോ?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{ഓഡിയോ ഫയൽ പരിഷ്‌ക്കരിക്കുന്നു…}other{<xliff:g id="COUNT">^1</xliff:g> ഓഡിയോ ഫയലുകൾ പരിഷ്‌ക്കരിക്കുന്നു…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{ഈ വീഡിയോ പരിഷ്ക്കരിക്കാൻ <xliff:g id="APP_NAME_0">^1</xliff:g> എന്നതിനെ അനുവദിക്കണോ?}other{<xliff:g id="COUNT">^2</xliff:g> വീഡിയോകൾ പരിഷ്ക്കരിക്കാൻ <xliff:g id="APP_NAME_1">^1</xliff:g> എന്നതിനെ അനുവദിക്കണോ?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"സുരക്ഷാ പരിരക്ഷ"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"നേറ്റീവ് ട്രാൻസ്കോഡ് മുന്നറിയിപ്പുകൾ"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"നേറ്റീവ് ട്രാൻസ്കോഡ് പുരോഗതി"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"ചില ഫോട്ടോകൾ ലോഡ് ചെയ്യാനാകുന്നില്ല"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"മനസ്സിലായി"</string>
</resources>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index f688f7dd1..2ef0cf6b4 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -19,11 +19,11 @@
<string name="uid_label" msgid="8421971615411294156">"Медиа"</string>
<string name="storage_description" msgid="4081716890357580107">"Дотоод сан"</string>
<string name="app_label" msgid="9035307001052716210">"Медиа санах ой"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Медиа"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Медиа сонгогч"</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_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>
@@ -42,10 +42,13 @@
<string name="picker_settings" msgid="6443463167344790260">"Үүлэн медиа апп"</string>
<string name="picker_settings_system_settings_menu_title" msgid="3055084757610063581">"Үүлэн медиа апп"</string>
<string name="picker_settings_title" msgid="5647700706470673258">"Үүлэн медиа апп"</string>
- <string name="picker_settings_description" msgid="2916686824777214585">"Апп эсвэл вебсайт танаас зураг эсвэл видео сонгохыг хүсэх үед таны үүлэн медиадаа хандана уу"</string>
+ <string name="picker_settings_description" msgid="2916686824777214585">"Апп эсвэл вебсайт танаас зураг эсвэл видео сонгохыг хүсвэл үүлэн медиадаа хандана уу"</string>
<string name="picker_settings_selection_message" msgid="245453573086488596">"Дараахаас үүлэн медиад хандах"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Байхгүй"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Энэ удаад үүлэн медиа аппыг өөрчилж чадсангүй."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Медиа сонгогч"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Медиа сонгогч"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Медиаг синк хийж байна…"</string>
<string name="add" msgid="2894574044585549298">"Нэмэх"</string>
<string name="deselect" msgid="4297825044827769490">"Сонголтыг цуцлах"</string>
<string name="deselected" msgid="8488133193326208475">"Сонголтыг цуцалсан"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Интернэт холболтоо шалгаад, дахин оролдоно уу"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Дахин оролдох"</string>
<string name="not_selected" msgid="2244008151669896758">"сонгоогүй"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Таны сонгосон медиаг бэлтгэж байна"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>-с <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> бэлэн"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Одоо хуулбарласан зургийг багтаасан"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Та <xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> бүртгэлээс зураг сонгох боломжтой"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Апп сонгох"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Бүртгэл сонгох"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Бүртгэл өөрчлөх"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Таны бүх зургийг авч байна"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g>-д энэ аудио файлыг өөрчлөхийг зөвшөөрөх үү?}other{<xliff:g id="APP_NAME_1">^1</xliff:g>-д <xliff:g id="COUNT">^2</xliff:g> аудио файлыг өөрчлөхийг зөвшөөрөх үү?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Аудио файлыг өөрчилж байна…}other{<xliff:g id="COUNT">^1</xliff:g> аудио файлыг өөрчилж байна…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g>-д энэ видеог өөрчлөхийг зөвшөөрөх үү?}other{<xliff:g id="APP_NAME_1">^1</xliff:g>-д <xliff:g id="COUNT">^2</xliff:g> видеог өөрчлөхийг зөвшөөрөх үү?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Аюулгүй байдлын хамгаалалт"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Уугуул хөрвүүлгийн сэрэмжлүүлэг"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Уугуул хөрвүүлгийн явц"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Зарим зургийг ачаалах боломжгүй"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Ойлголоо"</string>
</resources>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 563aac436..4805f63a3 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/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="picker_app_label" msgid="4254039089502164761">"मीडिया"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"मीडिया पिकर"</string>
<string name="artist_label" msgid="8105600993099120273">"कलाकार"</string>
<string name="unknown" msgid="2059049215682829375">"अज्ञात"</string>
<string name="root_images" msgid="5861633549189045666">"इमेज"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"येथून क्लाउड मीडिया अ‍ॅक्सेस करा"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"काहीही नाही"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"क्लाउड मीडिया अ‍ॅप या क्षणी बदलू शकत नाही."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"मीडिया पिकर"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"मीडिया पिकर"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"मीडिया सिंक करत आहे…"</string>
<string name="add" msgid="2894574044585549298">"जोडा"</string>
<string name="deselect" msgid="4297825044827769490">"निवड रद्द करा"</string>
<string name="deselected" msgid="8488133193326208475">"निवड रद्द केली आहे"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"तुमचे इंटरनेट कनेक्शन तपासा आणि पुन्हा प्रयत्न करा"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"पुन्हा प्रयत्न करा"</string>
<string name="not_selected" msgid="2244008151669896758">"निवडला नाही"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"तुमचा निवडलेला मीडिया तयार करत आहे"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> पैकी <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> तयार"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"बॅकअप घेतलेल्या फोटोचा आता समावेश केला आहे"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"तुम्ही <xliff:g id="APP_NAME">%1$s</xliff:g> खात्याच्या <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> वरून फोटो निवडू शकता"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"ॲप निवडा"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"खाते निवडा"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"खाते बदला"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"तुमचे सर्व फोटो मिळवत आहे"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> ला या ऑडिओ फाइलमध्ये फेरबदल करण्याची अनुमती द्यायची आहे का?}other{<xliff:g id="APP_NAME_1">^1</xliff:g> ला <xliff:g id="COUNT">^2</xliff:g> ऑडिओ फाइलमध्ये फेरबदल करण्याची अनुमती द्यायची आहे का?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{ऑडिओ फाइलमध्ये फेरबदल करत आहे…}other{<xliff:g id="COUNT">^1</xliff:g> ऑडिओ फाइलमध्ये फेरबदल करत आहे…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> ला या व्हिडिओमध्ये फेरबदल करण्याची अनुमती द्यायची आहे का?}other{<xliff:g id="APP_NAME_1">^1</xliff:g> ला <xliff:g id="COUNT">^2</xliff:g> व्हिडिओमध्ये फेरबदल करण्याची अनुमती द्यायची आहे का?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"सुरक्षितता संरक्षण"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"मूळ ट्रान्सकोड सूचना"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"मूळ ट्रान्सकोड प्रगती"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"काही फोटो लोड करू शकत नाही"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"समजले"</string>
</resources>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 1c09a563d..5085b7c5c 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Media"</string>
<string name="storage_description" msgid="4081716890357580107">"Storan setempat"</string>
<string name="app_label" msgid="9035307001052716210">"Storan Media"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Media"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Pemilih Media"</string>
<string name="artist_label" msgid="8105600993099120273">"Artis"</string>
<string name="unknown" msgid="2059049215682829375">"Tidak diketahui"</string>
<string name="root_images" msgid="5861633549189045666">"Imej"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Akses media awan daripada"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Tiada"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Tidak dapat menukar apl media awan pada masa ini."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Pemilih media"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Pemilih media"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Menyegerakkan media…"</string>
<string name="add" msgid="2894574044585549298">"Tambah"</string>
<string name="deselect" msgid="4297825044827769490">"Nyahpilih"</string>
<string name="deselected" msgid="8488133193326208475">"Dinyahpilih"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Semak sambungan Internet anda, kemudian cuba lagi"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Cuba lagi"</string>
<string name="not_selected" msgid="2244008151669896758">"tidak dipilih"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Menyediakan media pilihan anda"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> daripada <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> sudah bersedia"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Foto yang disandarkan kini disertakan"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Anda boleh memilih foto daripada akaun <xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Pilih apl"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Pilih akaun"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Tukar akaun"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Mendapatkan semua foto anda"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Benarkan <xliff:g id="APP_NAME_0">^1</xliff:g> mengubah suai fail audio ini?}other{Benarkan <xliff:g id="APP_NAME_1">^1</xliff:g> mengubah suai <xliff:g id="COUNT">^2</xliff:g> fail audio?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Mengubah suai fail audio…}other{Mengubah suai <xliff:g id="COUNT">^1</xliff:g> fail audio…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Benarkan <xliff:g id="APP_NAME_0">^1</xliff:g> mengubah suai video ini?}other{Benarkan <xliff:g id="APP_NAME_1">^1</xliff:g> mengubah suai <xliff:g id="COUNT">^2</xliff:g> video?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Perlindungan keselamatan"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Amaran Transkod Asal"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Kemajuan Transkod Asal"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Tidak dapat memuatkan beberapa Foto"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"OK"</string>
</resources>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index 867a49de8..2df7bda22 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/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="picker_app_label" msgid="4254039089502164761">"မီဒီယာ"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"မီဒီယာရွေးရန်"</string>
<string name="artist_label" msgid="8105600993099120273">"အနုပညာရှင်"</string>
<string name="unknown" msgid="2059049215682829375">"အမျိုးအမည်မသိ"</string>
<string name="root_images" msgid="5861633549189045666">"ပုံများ"</string>
@@ -42,10 +42,13 @@
<string name="picker_settings" msgid="6443463167344790260">"Cloud မီဒီယာအက်ပ်"</string>
<string name="picker_settings_system_settings_menu_title" msgid="3055084757610063581">"Cloud မီဒီယာအက်ပ်"</string>
<string name="picker_settings_title" msgid="5647700706470673258">"Cloud မီဒီယာအက်ပ်"</string>
- <string name="picker_settings_description" msgid="2916686824777214585">"အက်ပ် (သို့) ဝဘ်ဆိုက်က သင့်အား ဓာတ်ပုံ (သို့) ဗီဒီယိုများ ရွေးခိုင်းသောအခါ သင်၏ cloud မီဒီယာကို ဝင်ပါ"</string>
+ <string name="picker_settings_description" msgid="2916686824777214585">"အက်ပ် (သို့) ဝဘ်ဆိုက်က သင့်အား ဓာတ်ပုံ (သို့) ဗီဒီယိုများ ရွေးခိုင်းသောအခါ သင်၏ cloud မီဒီယာကို ဝင်သည်"</string>
<string name="picker_settings_selection_message" msgid="245453573086488596">"Cloud မီဒီယာကို ဤနေရာမှ ဝင်သုံးရန်"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"မရှိ"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"လောလောဆယ် cloud မီဒီယာ အက်ပ်ကို ပြောင်း၍မရပါ။"</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"မီဒီယာရွေးခြင်း"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"မီဒီယာရွေးခြင်း"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"မီဒီယာကို စင့်ခ်လုပ်နေသည်…"</string>
<string name="add" msgid="2894574044585549298">"ထည့်ရန်"</string>
<string name="deselect" msgid="4297825044827769490">"မရွေးပါနှင့်"</string>
<string name="deselected" msgid="8488133193326208475">"ရွေးချယ်မထားပါ"</string>
@@ -93,9 +96,10 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"သင်၏ အင်တာနက် ချိတ်ဆက်မှုကို စစ်ဆေးပြီး ထပ်စမ်းကြည့်ပါ"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"ထပ်စမ်းကြည့်ရန်"</string>
<string name="not_selected" msgid="2244008151669896758">"ရွေးချယ်မထားပါ"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"သင်ရွေးထားသော မီဒီယာကို ပြင်ဆင်နေသည်"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> အနက် <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> အသင့်ဖြစ်ပြီ"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"အရန်သိမ်းထားသော ဓာတ်ပုံများ ယခုထည့်သွင်းထားပြီ"</string>
- <string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> အကောင့်မှ ဓာတ်ပုံများ ရွေးနိုင်သည်"</string>
+ <string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"<xliff:g id="APP_NAME">%1$s</xliff:g> အကောင့် <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> မှ ဓာတ်ပုံများ ရွေးနိုင်သည်"</string>
<string name="picker_banner_cloud_account_changed_title" msgid="4825058474378077327">"<xliff:g id="APP_NAME">%1$s</xliff:g> အကောင့် အပ်ဒိတ်လုပ်လိုက်သည်"</string>
<string name="picker_banner_cloud_account_changed_desc" msgid="3433218869899792497">"<xliff:g id="USER_ACCOUNT">%1$s</xliff:g> မှ ဓာတ်ပုံများကို ဤနေရာတွင် ယခုထည့်သွင်းထားပါပြီ"</string>
<string name="picker_banner_cloud_choose_app_title" msgid="3165966147547974251">"cloud မီဒီယာအက်ပ် ရွေးရန်"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"အက်ပ်ရွေးရန်"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"အကောင့်ရွေးရန်"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"အကောင့်ပြောင်းရန်"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"သင့်ဓာတ်ပုံအားလုံးကို ရယူနေသည်"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> ကို ဤအသံဖိုင် ပြင်ဆင်ခွင့်ပြုမလား။}other{<xliff:g id="APP_NAME_1">^1</xliff:g> ကို အသံဖိုင် <xliff:g id="COUNT">^2</xliff:g> ဖိုင် ပြင်ဆင်ခွင့်ပြုမလား။}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{အသံဖိုင်ကို ပြင်ဆင်နေသည်…}other{အသံဖိုင် <xliff:g id="COUNT">^1</xliff:g> ခုကို ပြင်ဆင်နေသည်…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> ကို ဤဗီဒီယို ပြင်ဆင်ခွင့်ပြုမလား။}other{<xliff:g id="APP_NAME_1">^1</xliff:g> ကို ဗီဒီယို <xliff:g id="COUNT">^2</xliff:g> ခု ပြင်ဆင်ခွင့်ပြုမလား။}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"လုံခြုံရေး ကာကွယ်မှု"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"မူရင်းမီဒီယာကုဒ်ပြောင်းသည့် သတိပေးချက်များ"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"မူရင်းမီဒီယာကုဒ်ပြောင်းသည့် အခြေအနေ"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"ဓာတ်ပုံအချို့ကို ဖွင့်၍ မရပါ"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"ရပြီ"</string>
</resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 6507c11c2..7ab3ea88a 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Medier"</string>
<string name="storage_description" msgid="4081716890357580107">"Lokal lagring"</string>
<string name="app_label" msgid="9035307001052716210">"Medielagring"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Medier"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Medievelger"</string>
<string name="artist_label" msgid="8105600993099120273">"Artist"</string>
<string name="unknown" msgid="2059049215682829375">"Ukjent"</string>
<string name="root_images" msgid="5861633549189045666">"Bilder"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Åpne skymedier fra"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Ingen"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Kunne ikke endre skymedieappen akkurat nå."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Medievelger"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Medievelger"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Synkroniserer medieinnholdet …"</string>
<string name="add" msgid="2894574044585549298">"Legg til"</string>
<string name="deselect" msgid="4297825044827769490">"Fjern merking"</string>
<string name="deselected" msgid="8488133193326208475">"Ikke valgt"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Sjekk internettilkoblingen og prøv på nytt"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Prøv på nytt"</string>
<string name="not_selected" msgid="2244008151669896758">"ikke valgt"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Klargjør det valgte medieinnholdet"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> av <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> er klare"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Nå er sikkerhetskopierte bilder inkludert"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Du kan velge bilder fra <xliff:g id="APP_NAME">%1$s</xliff:g>-kontoen <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Velg app"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Velg konto"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Bytt konto"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Laster inn alle bildene dine"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Vil du tillate at <xliff:g id="APP_NAME_0">^1</xliff:g> endrer denne lydfilen?}other{Vil du tillate at <xliff:g id="APP_NAME_1">^1</xliff:g> endrer <xliff:g id="COUNT">^2</xliff:g> lydfiler?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Endrer lydfilen …}other{Endrer <xliff:g id="COUNT">^1</xliff:g> lydfiler …}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Vil du tillate at <xliff:g id="APP_NAME_0">^1</xliff:g> endrer denne videoen?}other{Vil du tillate at <xliff:g id="APP_NAME_1">^1</xliff:g> endrer <xliff:g id="COUNT">^2</xliff:g> videoer?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Beskyttelse"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Integrerte omkodingsvarsler"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Integrert omkodingsfremdrift"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Noen bilder kan ikke lastes inn"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Greit"</string>
</resources>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index 09749c198..600979d57 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/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="picker_app_label" msgid="4254039089502164761">"मिडिया"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"मिडिया पिकर"</string>
<string name="artist_label" msgid="8105600993099120273">"कलाकार"</string>
<string name="unknown" msgid="2059049215682829375">"अज्ञात"</string>
<string name="root_images" msgid="5861633549189045666">"फोटो"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"यसबाट क्लाउड मिडिया प्रयोग गर्नुहोस्"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"कुनै पनि होइन"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"अहिले क्लाउड मिडिया एप परिवर्तन गर्न सकिएन।"</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"मिडिया पिकर"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"मिडिया पिकर"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"मिडिया सिंक हुँदै छ…"</string>
<string name="add" msgid="2894574044585549298">"हाल्नुहोस्"</string>
<string name="deselect" msgid="4297825044827769490">"चयन रद्द गर्नुहोस्"</string>
<string name="deselected" msgid="8488133193326208475">"चयन रद्द गरियो"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"इन्टरनेट जाँच्नुहोस् र फेरि प्रयास गर्नुहोस्"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"फेरि प्रयास गर्नुहोस्"</string>
<string name="not_selected" msgid="2244008151669896758">"चयन गरिएको छैन"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"तपाईंले चयन गर्नुभएको मिडिया तयार गरिँदै छ"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> मध्ये <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> वटा फोटो तयार छन्"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"अब ब्याकअप गरिएका फोटोहरू समावेश गरिएका छन्"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"तपाईं <xliff:g id="APP_NAME">%1$s</xliff:g> मा <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> खाता प्रयोग गरी राखिएका फोटोहरू चयन गर्न सक्नुहुन्छ"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"एप छनौट गर्नुहोस्"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"खाता छनौट गर्नुहोस्"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"खाता बदल्नुहोस्"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"तपाईंका सबै फोटोहरू प्राप्त गरिँदै छन्"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> लाई यो अडियो फाइल परिमार्जन गर्न दिने हो?}other{<xliff:g id="APP_NAME_1">^1</xliff:g> लाई <xliff:g id="COUNT">^2</xliff:g> वटा अडियो फाइल परिमार्जन गर्न दिने हो?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{अडियो फाइल परिमार्जन गरिँदै छ…}other{<xliff:g id="COUNT">^1</xliff:g> वटा अडियो फाइल परिमार्जन गरिँदै छन्…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> लाई यो भिडियो परिमार्जन गर्न दिने हो?}other{<xliff:g id="APP_NAME_1">^1</xliff:g> लाई <xliff:g id="COUNT">^2</xliff:g> वटा भिडियो परिमार्जन गर्न दिने हो?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"सेफ्टी प्रोटेक्सन"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"नेटिभ ट्रान्स्कोड अलर्ट"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"नेटिभ ट्रान्स्कोड प्रोग्रेस"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"केही फोटोहरू लोड गर्न सकिँदैन"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"बुझेँ"</string>
</resources>
diff --git a/res/values-night-v31/styles.xml b/res/values-night-v31/styles.xml
index 2a936f09a..58249be8a 100644
--- a/res/values-night-v31/styles.xml
+++ b/res/values-night-v31/styles.xml
@@ -14,7 +14,8 @@
limitations under the License.
-->
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<style name="PickerMaterialTheme" parent="@style/Theme.Material3.DayNight.NoActionBar">
<item name="materialAlertDialogTheme">@style/ProfileDialogTheme</item>
@@ -40,6 +41,8 @@
<item name="pickerBannerPrimaryTextColor">?android:attr/textColorSecondary</item>
<item name="pickerBannerSecondaryTextColor">?android:attr/textColorSecondary</item>
<item name="pickerBannerButtonTextColor">@android:color/system_accent1_300</item>
+ <item name="categoryDefaultThumbnailColor">@android:color/system_accent1_300</item>
+ <item name="categoryDefaultThumbnailCircleColor">?androidprv:attr/materialColorSurfaceContainer</item>
</style>
</resources>
diff --git a/res/values-night/styles.xml b/res/values-night/styles.xml
index 72f234d1a..599ce12c1 100644
--- a/res/values-night/styles.xml
+++ b/res/values-night/styles.xml
@@ -14,7 +14,8 @@
limitations under the License.
-->
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<style name="PickerDialogTheme"
parent="@android:style/Theme.DeviceDefault.Dialog.Alert">
@@ -59,6 +60,8 @@
<item name="pickerBannerPrimaryTextColor">?android:attr/textColorSecondary</item>
<item name="pickerBannerSecondaryTextColor">?android:attr/textColorSecondary</item>
<item name="pickerBannerButtonTextColor">?android:attr/colorAccent</item>
+ <item name="categoryDefaultThumbnailColor">?android:attr/colorAccent</item>
+ <item name="categoryDefaultThumbnailCircleColor">?androidprv:attr/materialColorSurfaceContainer</item>
</style>
</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 027622132..662a67926 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Media"</string>
<string name="storage_description" msgid="4081716890357580107">"Lokale opslag"</string>
<string name="app_label" msgid="9035307001052716210">"Mediaopslag"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Media"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Mediakiezer"</string>
<string name="artist_label" msgid="8105600993099120273">"Artiest"</string>
<string name="unknown" msgid="2059049215682829375">"Onbekend"</string>
<string name="root_images" msgid="5861633549189045666">"Afbeeldingen"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Cloudmedia openen vanuit"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Geen"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Cloudmedia-app kan nu niet worden gewijzigd."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Mediakiezer"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Mediakiezer"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Media synchroniseren…"</string>
<string name="add" msgid="2894574044585549298">"Toevoegen"</string>
<string name="deselect" msgid="4297825044827769490">"Deselecteren"</string>
<string name="deselected" msgid="8488133193326208475">"Gedeselecteerd"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Check de internetverbinding en probeer het opnieuw"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Opnieuw proberen"</string>
<string name="not_selected" msgid="2244008151669896758">"niet geselecteerd"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Je geselecteerde media voorbereiden"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> van <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> klaar"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Nu ook met foto\'s waarvan een back-up is gemaakt"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Je kunt foto\'s selecteren uit het <xliff:g id="APP_NAME">%1$s</xliff:g>-account <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"App selecteren"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Account kiezen"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Account wijzigen"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Al je foto\'s ophalen"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> toestaan dit audiobestand aan te passen?}other{<xliff:g id="APP_NAME_1">^1</xliff:g> toestaan <xliff:g id="COUNT">^2</xliff:g> audiobestanden aan te passen?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Audiobestand aanpassen…}other{<xliff:g id="COUNT">^1</xliff:g> audiobestanden aanpassen…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> toestaan deze video aan te passen?}other{<xliff:g id="APP_NAME_1">^1</xliff:g> toestaan <xliff:g id="COUNT">^2</xliff:g> video\'s aan te passen?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Beveiliging"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Meldingen voor native transcodering"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Voortgang van native transcodering"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Kan bepaalde foto\'s niet laden"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"OK"</string>
</resources>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index d9860112f..2c7c58e2c 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/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="picker_app_label" msgid="4254039089502164761">"ମିଡିଆ"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"ମିଡିଆ ପିକର"</string>
<string name="artist_label" msgid="8105600993099120273">"କଳାକାର"</string>
<string name="unknown" msgid="2059049215682829375">"ଅଜଣା"</string>
<string name="root_images" msgid="5861633549189045666">"ଇମେଜ୍‌"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"ଏଠାରୁ କ୍ଲାଉଡ ମିଡିଆକୁ ଆକ୍ସେସ କରନ୍ତୁ"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"କିଛି ନାହିଁ"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"ଏହି ସମୟରେ କ୍ଲାଉଡ ମିଡିଆ ଆପ ପରିବର୍ତ୍ତନ ହେଲା ନାହିଁ।"</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"ମିଡିଆ ପିକର"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"ମିଡିଆ ପିକର"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"ମିଡିଆ ସିଙ୍କ କରାଯାଉଛି…"</string>
<string name="add" msgid="2894574044585549298">"ଯୋଗ କରନ୍ତୁ"</string>
<string name="deselect" msgid="4297825044827769490">"ଅଚୟନ କରନ୍ତୁ"</string>
<string name="deselected" msgid="8488133193326208475">"ଅଚୟନ କରାଯାଇଛି"</string>
@@ -56,14 +59,14 @@
<string name="picker_photos_empty_message" msgid="5980619500554575558">"କୌଣସି ଫଟୋ କିମ୍ବା ଭିଡିଓ ନାହିଁ"</string>
<string name="picker_album_media_empty_message" msgid="7061850698189881671">"କୌଣସି ସମର୍ଥିତ ଫଟୋ କିମ୍ବା ଭିଡିଓ ନାହିଁ"</string>
<string name="picker_albums_empty_message" msgid="8341079772950966815">"କୌଣସି ଆଲବମ ନାହିଁ"</string>
- <string name="picker_view_selected" msgid="2266031384396143883">"ଚୟନିତଗୁଡ଼ିକୁ ଦେଖନ୍ତୁ"</string>
+ <string name="picker_view_selected" msgid="2266031384396143883">"ଚୟନିତଗୁଡ଼ିକୁ ଭ୍ୟୁ କରନ୍ତୁ"</string>
<string name="picker_photos" msgid="7415035516411087392">"ଫଟୋ"</string>
<string name="picker_albums" msgid="4822511902115299142">"ଆଲବମ"</string>
<string name="picker_preview" msgid="6257414886055861039">"ପ୍ରିଭ୍ୟୁ"</string>
- <string name="picker_work_profile" msgid="2083221066869141576">"ୱାର୍କକୁ ସ୍ୱିଚ୍ କରନ୍ତୁ"</string>
- <string name="picker_personal_profile" msgid="639484258397758406">"ବ୍ୟକ୍ତିଗତକୁ ସ୍ୱିଚ୍ କରନ୍ତୁ"</string>
- <string name="picker_profile_admin_title" msgid="4172022376418293777">"ଆପଣଙ୍କ ଆଡମିନଙ୍କ ଦ୍ୱାରା ବ୍ଲକ୍ କରାଯାଇଛି"</string>
- <string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"କୌଣସି ବ୍ୟକ୍ତିଗତ ଆପରୁ ୱାର୍କ ଡାଟାକୁ ଆକ୍ସେସ୍ କରିବା ପାଇଁ ଅନୁମତି ଦିଆଯାଇନାହିଁ"</string>
+ <string name="picker_work_profile" msgid="2083221066869141576">"ୱାର୍କକୁ ସୁଇଚ କରନ୍ତୁ"</string>
+ <string name="picker_personal_profile" msgid="639484258397758406">"ବ୍ୟକ୍ତିଗତକୁ ସୁଇଚ କରନ୍ତୁ"</string>
+ <string name="picker_profile_admin_title" msgid="4172022376418293777">"ଆପଣଙ୍କ ଆଡମିନଙ୍କ ଦ୍ୱାରା ବ୍ଲକ କରାଯାଇଛି"</string>
+ <string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"କୌଣସି ବ୍ୟକ୍ତିଗତ ଆପରୁ ୱାର୍କ ଡାଟାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଅନୁମତି ଦିଆଯାଇନାହିଁ"</string>
<string name="picker_profile_admin_msg_from_work" msgid="8048524337462790110">"କୌଣସି ୱାର୍କ ଆପରୁ ବ୍ୟକ୍ତିଗତ ଡାଟାକୁ ଆକ୍ସେସ୍ କରିବା ପାଇଁ ଅନୁମତି ଦିଆଯାଇନାହିଁ"</string>
<string name="picker_profile_work_paused_title" msgid="382212880704235925">"ୱାର୍କ ଆପଗୁଡ଼ିକୁ ବିରତ କରାଯାଇଛି"</string>
<string name="picker_profile_work_paused_msg" msgid="6321552322125246726">"ୱାର୍କ ଫଟୋଗୁଡ଼ିକୁ ଖୋଲିବାକୁ, ଆପଣଙ୍କ ୱାର୍କ ଆପଗୁଡ଼ିକୁ ଚାଲୁ କରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"ଆପଣଙ୍କ ଇଣ୍ଟରନେଟ କନେକ୍ସନ ଯାଞ୍ଚ କରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
<string name="not_selected" msgid="2244008151669896758">"ଚୟନ କରାଯାଇନାହିଁ"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"ଆପଣଙ୍କ ଚୟନିତ ମିଡିଆକୁ ପ୍ରସ୍ତୁତ କରାଯାଉଛି"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>ରୁ <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g>ଟି ପ୍ରସ୍ତୁତ ଅଛି"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"ବ୍ୟାକଅପ ନିଆଯାଇଥିବା ଫଟୋଗୁଡ଼ିକୁ ବର୍ତ୍ତମାନ ଅନ୍ତର୍ଭୁକ୍ତ କରାଯାଇଛି"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"ଆପଣ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆକାଉଣ୍ଟ <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>ରୁ ଫଟୋଗୁଡ଼ିକୁ ଚୟନ କରିପାରିବେ"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"ଆପ ବାଛନ୍ତୁ"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"ଆକାଉଣ୍ଟ ବାଛନ୍ତୁ"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"ଆକାଉଣ୍ଟ ବଦଳାନ୍ତୁ"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"ଆପଣଙ୍କର ସମସ୍ତ ଫଟୋ ପ୍ରାପ୍ତ କରାଯାଉଛି"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{ଏହି ଅଡିଓ ଫାଇଲକୁ ପରିବର୍ତ୍ତନ କରିବା ପାଇଁ <xliff:g id="APP_NAME_0">^1</xliff:g>କୁ ଅନୁମତି ଦେବେ?}other{<xliff:g id="COUNT">^2</xliff:g>ଟି ଅଡିଓ ଫାଇଲକୁ ପରିବର୍ତ୍ତନ କରିବା ପାଇଁ <xliff:g id="APP_NAME_1">^1</xliff:g>କୁ ଅନୁମତି ଦେବେ?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{ଅଡିଓ ଫାଇଲ ପରିବର୍ତ୍ତନ କରାଯାଉଛି…}other{<xliff:g id="COUNT">^1</xliff:g>ଟି ଅଡିଓ ଫାଇଲ ପରିବର୍ତ୍ତନ କରାଯାଉଛି…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{ଏହି ଭିଡିଓକୁ ପରିବର୍ତ୍ତନ କରିବା ପାଇଁ <xliff:g id="APP_NAME_0">^1</xliff:g>କୁ ଅନୁମତି ଦେବେ?}other{<xliff:g id="COUNT">^2</xliff:g>ଟି ଭିଡିଓକୁ ପରିବର୍ତ୍ତନ କରିବା ପାଇଁ <xliff:g id="APP_NAME_1">^1</xliff:g>କୁ ଅନୁମତି ଦେବେ?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"ସୁରକ୍ଷିତ ସୁରକ୍ଷା"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"ନେଟିଭ ଟ୍ରାନ୍ସକୋଡ ଆଲର୍ଟ"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"ନେଟିଭ ଟ୍ରାନ୍ସକୋଡ ପ୍ରୋଗ୍ରେସ"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"କିଛି ଫଟୋ ଲୋଡ କରାଯାଇପାରିବ ନାହିଁ"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"ବୁଝିଗଲି"</string>
</resources>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index fda3c9452..859b3106f 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/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="picker_app_label" msgid="4254039089502164761">"ਮੀਡੀਆ"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"ਮੀਡੀਆ ਚੋਣਕਾਰ"</string>
<string name="artist_label" msgid="8105600993099120273">"ਕਲਾਕਾਰ"</string>
<string name="unknown" msgid="2059049215682829375">"ਅਗਿਆਤ"</string>
<string name="root_images" msgid="5861633549189045666">"ਚਿੱਤਰ"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"ਇੱਥੋਂ ਕਲਾਊਡ ਮੀਡੀਆ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"ਕੋਈ ਨਹੀਂ"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"ਇਸ ਸਮੇਂ ਕਲਾਊਡ ਮੀਡੀਆ ਐਪ ਨੂੰ ਬਦਲਿਆ ਨਹੀਂ ਜਾ ਸਕਿਆ।"</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"ਮੀਡੀਆ ਚੋਣਕਾਰ"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"ਮੀਡੀਆ ਚੋਣਕਾਰ"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"ਮੀਡੀਆ ਸਿੰਕ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
<string name="add" msgid="2894574044585549298">"ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="deselect" msgid="4297825044827769490">"ਅਣ-ਚੁਣਿਆ ਕਰੋ"</string>
<string name="deselected" msgid="8488133193326208475">"ਅਣ-ਚੁਣਿਆ"</string>
@@ -93,9 +96,10 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"ਆਪਣੇ ਇੰਟਰਨੈੱਟ ਕਨੈਕਸ਼ਨ ਦੀ ਜਾਂਚ ਕਰ ਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"ਮੁੜ-ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
<string name="not_selected" msgid="2244008151669896758">"ਚੁਣਿਆ ਨਹੀਂ ਗਿਆ"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"ਤੁਹਾਡਾ ਚੁਣਿਆ ਗਿਆ ਮੀਡੀਆ ਤਿਆਰ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> ਵਿੱਚੋਂ <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> ਤਿਆਰ"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"ਬੈਕਅੱਪ ਕੀਤੀਆਂ ਫ਼ੋਟੋਆਂ ਨੂੰ ਹੁਣ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ"</string>
- <string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"ਤੁਸੀਂ ਖਾਤੇ <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> ਦੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਵਿੱਚੋਂ ਫ਼ੋਟੋਆਂ ਨੂੰ ਚੁਣੋ"</string>
+ <string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"ਤੁਸੀਂ <xliff:g id="APP_NAME">%1$s</xliff:g> ਵਿੱਚੋਂ <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> ਖਾਤੇ ਤੋਂ ਫ਼ੋਟੋਆਂ ਚੁਣ ਸਕਦੇ ਹੋ"</string>
<string name="picker_banner_cloud_account_changed_title" msgid="4825058474378077327">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਖਾਤੇ ਨੂੰ ਅੱਪਡੇਟ ਕੀਤਾ ਗਿਆ"</string>
<string name="picker_banner_cloud_account_changed_desc" msgid="3433218869899792497">"<xliff:g id="USER_ACCOUNT">%1$s</xliff:g> ਦੀਆਂ ਫ਼ੋਟੋਆਂ ਨੂੰ ਹੁਣ ਇੱਥੇ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
<string name="picker_banner_cloud_choose_app_title" msgid="3165966147547974251">"ਕਲਾਊਡ ਮੀਡੀਆ ਐਪ ਨੂੰ ਚੁਣੋ"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"ਐਪ ਚੁਣੋ"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"ਖਾਤਾ ਚੁਣੋ"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"ਖਾਤਾ ਬਦਲੋ"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"ਤੁਹਾਡੀਆਂ ਸਾਰੀਆਂ ਫ਼ੋਟੋਆਂ ਪ੍ਰਾਪਤ ਕੀਤੀਆਂ ਜਾ ਰਹੀਆਂ ਹਨ"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{ਕੀ <xliff:g id="APP_NAME_0">^1</xliff:g> ਨੂੰ ਇਸ ਆਡੀਓ ਫ਼ਾਈਲ ਨੂੰ ਸੋਧਣ ਦੇਣਾ ਹੈ?}one{ਕੀ <xliff:g id="APP_NAME_1">^1</xliff:g> ਨੂੰ <xliff:g id="COUNT">^2</xliff:g> ਆਡੀਓ ਫ਼ਾਈਲ ਨੂੰ ਸੋਧਣ ਦੇਣਾ ਹੈ?}other{ਕੀ <xliff:g id="APP_NAME_1">^1</xliff:g> ਨੂੰ <xliff:g id="COUNT">^2</xliff:g> ਆਡੀਓ ਫ਼ਾਈਲਾਂ ਨੂੰ ਸੋਧਣ ਦੇਣਾ ਹੈ?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{ਆਡੀਓ ਫ਼ਾਈਲ ਸੋਧੀ ਜਾ ਰਹੀ ਹੈ…}one{<xliff:g id="COUNT">^1</xliff:g> ਆਡੀਓ ਫ਼ਾਈਲ ਸੋਧੀ ਜਾ ਰਹੀ ਹੈ…}other{<xliff:g id="COUNT">^1</xliff:g> ਆਡੀਓ ਫ਼ਾਈਲਾਂ ਸੋਧੀਆਂ ਜਾ ਰਹੀਆਂ ਹਨ…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{ਕੀ <xliff:g id="APP_NAME_0">^1</xliff:g> ਨੂੰ ਇਸ ਵੀਡੀਓ ਨੂੰ ਸੋਧਣ ਦੇਣਾ ਹੈ?}one{ਕੀ <xliff:g id="APP_NAME_1">^1</xliff:g> ਨੂੰ <xliff:g id="COUNT">^2</xliff:g> ਵੀਡੀਓ ਨੂੰ ਸੋਧਣ ਦੇਣਾ ਹੈ?}other{ਕੀ <xliff:g id="APP_NAME_1">^1</xliff:g> ਨੂੰ <xliff:g id="COUNT">^2</xliff:g> ਵੀਡੀਓ ਨੂੰ ਸੋਧਣ ਦੇਣਾ ਹੈ?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"ਸੁਰੱਖਿਆ ਬਚਾਅ"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"ਨੇਟਿਵ ਟ੍ਰਾਂਸਕੋਡ ਸੁਚੇਤਨਾਵਾਂ"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"ਨੇਟਿਵ ਟ੍ਰਾਂਸਕੋਡ ਪ੍ਰਗਤੀ"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"ਕੁਝ ਫ਼ੋਟੋਆਂ ਨੂੰ ਲੋਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"ਸਮਝ ਲਿਆ"</string>
</resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 2cd3119e3..8d3604163 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Multimedia"</string>
<string name="storage_description" msgid="4081716890357580107">"Pamięć lokalna"</string>
<string name="app_label" msgid="9035307001052716210">"Przechowywanie multimediów"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Multimedia"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Wybór mediów"</string>
<string name="artist_label" msgid="8105600993099120273">"Wykonawca"</string>
<string name="unknown" msgid="2059049215682829375">"Nieznany"</string>
<string name="root_images" msgid="5861633549189045666">"Obrazy"</string>
@@ -46,10 +46,13 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Otwieraj multimedia w chmurze za pomocą:"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Brak"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Nie udało się zmienić aplikacji do multimediów w chmurze."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Wybór mediów"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Wybór mediów"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Synchronizuję multimedia…"</string>
<string name="add" msgid="2894574044585549298">"Dodaj"</string>
- <string name="deselect" msgid="4297825044827769490">"Odznacz"</string>
+ <string name="deselect" msgid="4297825044827769490">"Usuń wybór"</string>
<string name="deselected" msgid="8488133193326208475">"Usunięto wybór"</string>
- <string name="select" msgid="2704765470563027689">"Zaznacz"</string>
+ <string name="select" msgid="2704765470563027689">"Wybierz"</string>
<string name="selected" msgid="9151797369975828124">"Wybrano"</string>
<string name="select_up_to" msgid="6994294169508439957">"{count,plural, =1{Wybierz maksymalnie <xliff:g id="COUNT_0">^1</xliff:g> element}few{Wybierz maksymalnie <xliff:g id="COUNT_1">^1</xliff:g> elementy}many{Wybierz maksymalnie <xliff:g id="COUNT_1">^1</xliff:g> elementów}other{Wybierz maksymalnie <xliff:g id="COUNT_1">^1</xliff:g> elementu}}"</string>
<string name="recent" msgid="6694613584743207874">"Ostatnie"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Sprawdź połączenie z internetem i spróbuj ponownie"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Ponów"</string>
<string name="not_selected" msgid="2244008151669896758">"nie wybrano"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Przygotowywanie wybranych multimediów"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"Gotowe <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> z <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Teraz znajdziesz tu kopie zapasowe zdjęć"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Możesz wybrać zdjęcia z aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>, z konta <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Wybierz aplikację"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Wybierz konto"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Zmień konto"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Pobieram wszystkie Twoje zdjęcia"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Zezwolić aplikacji <xliff:g id="APP_NAME_0">^1</xliff:g> na zmodyfikowanie tego pliku audio?}few{Zezwolić aplikacji <xliff:g id="APP_NAME_1">^1</xliff:g> na zmodyfikowanie <xliff:g id="COUNT">^2</xliff:g> plików audio?}many{Zezwolić aplikacji <xliff:g id="APP_NAME_1">^1</xliff:g> na zmodyfikowanie <xliff:g id="COUNT">^2</xliff:g> plików audio?}other{Zezwolić aplikacji <xliff:g id="APP_NAME_1">^1</xliff:g> na zmodyfikowanie <xliff:g id="COUNT">^2</xliff:g> pliku audio?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Modyfikuję plik audio…}few{Modyfikuję <xliff:g id="COUNT">^1</xliff:g> pliki audio…}many{Modyfikuję <xliff:g id="COUNT">^1</xliff:g> plików audio…}other{Modyfikuję <xliff:g id="COUNT">^1</xliff:g> pliku audio…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Zezwolić aplikacji <xliff:g id="APP_NAME_0">^1</xliff:g> na zmodyfikowanie tego filmu?}few{Zezwolić aplikacji <xliff:g id="APP_NAME_1">^1</xliff:g> na zmodyfikowanie <xliff:g id="COUNT">^2</xliff:g> filmów?}many{Zezwolić aplikacji <xliff:g id="APP_NAME_1">^1</xliff:g> na zmodyfikowanie <xliff:g id="COUNT">^2</xliff:g> filmów?}other{Zezwolić aplikacji <xliff:g id="APP_NAME_1">^1</xliff:g> na zmodyfikowanie <xliff:g id="COUNT">^2</xliff:g> filmu?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Sprzęt zabezpieczający"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Alerty dotyczące transkodowania natywnego"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Postępy transkodowania natywnego"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Nie można wczytać niektórych zdjęć"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"OK"</string>
</resources>
diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml
index 76b2e27ca..3c02de6ea 100644
--- a/res/values-pt-rBR/strings.xml
+++ b/res/values-pt-rBR/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Mídia"</string>
<string name="storage_description" msgid="4081716890357580107">"Armazenamento local"</string>
<string name="app_label" msgid="9035307001052716210">"Armazenamento de mídia"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Mídia"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Seletor de mídia"</string>
<string name="artist_label" msgid="8105600993099120273">"Artista"</string>
<string name="unknown" msgid="2059049215682829375">"Desconhecido"</string>
<string name="root_images" msgid="5861633549189045666">"Imagens"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Acessar a mídia em nuvem de"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Nenhum"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Não foi possível mudar o app de mídia em nuvem."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Seletor de mídia"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Seletor de mídia"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Sincronizando mídia…"</string>
<string name="add" msgid="2894574044585549298">"Adicionar"</string>
<string name="deselect" msgid="4297825044827769490">"Desmarcar"</string>
<string name="deselected" msgid="8488133193326208475">"Desmarcada"</string>
@@ -60,8 +63,8 @@
<string name="picker_photos" msgid="7415035516411087392">"Fotos"</string>
<string name="picker_albums" msgid="4822511902115299142">"Álbuns"</string>
<string name="picker_preview" msgid="6257414886055861039">"Visualização"</string>
- <string name="picker_work_profile" msgid="2083221066869141576">"Mudar para \"Trabalho\""</string>
- <string name="picker_personal_profile" msgid="639484258397758406">"Mudar para \"Pessoal\""</string>
+ <string name="picker_work_profile" msgid="2083221066869141576">"Mudar para Trabalho"</string>
+ <string name="picker_personal_profile" msgid="639484258397758406">"Mudar para Pessoal"</string>
<string name="picker_profile_admin_title" msgid="4172022376418293777">"Bloqueado pelo administrador"</string>
<string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"Não é permitido o acesso a dados de trabalho em um app pessoal"</string>
<string name="picker_profile_admin_msg_from_work" msgid="8048524337462790110">"Não é permitido o acesso a dados pessoais em um app de trabalho"</string>
@@ -93,8 +96,9 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Confira sua conexão de Internet e tente de novo"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Tentar novamente"</string>
<string name="not_selected" msgid="2244008151669896758">"não selecionado"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Preparando a mídia selecionada"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> de <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> itens prontos"</string>
- <string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Fotos salvas em backup agora estão incluídas"</string>
+ <string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"As fotos salvas em backup agora estão incluídas"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Selecione fotos da conta <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> do app <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="picker_banner_cloud_account_changed_title" msgid="4825058474378077327">"A conta do app <xliff:g id="APP_NAME">%1$s</xliff:g> foi atualizada"</string>
<string name="picker_banner_cloud_account_changed_desc" msgid="3433218869899792497">"As fotos da conta <xliff:g id="USER_ACCOUNT">%1$s</xliff:g> agora estão incluídas aqui"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Selecionar app"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Escolher conta"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Trocar conta"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Acessando todas as suas fotos"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Permitir que o app <xliff:g id="APP_NAME_0">^1</xliff:g> modifique esse arquivo de áudio?}one{Permitir que o app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> arquivo de áudio?}many{Permitir que o app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> arquivos de áudio?}other{Permitir que o app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> arquivos de áudio?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Modificando o arquivo de áudio…}one{Modificando <xliff:g id="COUNT">^1</xliff:g> arquivo de áudio…}many{Modificando <xliff:g id="COUNT">^1</xliff:g> arquivos de áudio…}other{Modificando <xliff:g id="COUNT">^1</xliff:g> arquivos de áudio…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Permitir que o app <xliff:g id="APP_NAME_0">^1</xliff:g> modifique esse vídeo?}one{Permitir que o app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> vídeo?}many{Permitir que o app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> vídeos?}other{Permitir que o app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> vídeos?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Proteção"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Alertas da transcodificação nativa"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Progresso da transcodificação nativa"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Não é possível carregar algumas fotos"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Entendi"</string>
</resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index eb9f0b48d..7e6a292fd 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Multimédia"</string>
<string name="storage_description" msgid="4081716890357580107">"Armazenamento local"</string>
<string name="app_label" msgid="9035307001052716210">"Armazenamento de multimédia"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Multimédia"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Seletor de meios"</string>
<string name="artist_label" msgid="8105600993099120273">"Artista"</string>
<string name="unknown" msgid="2059049215682829375">"Desconhecido"</string>
<string name="root_images" msgid="5861633549189045666">"Imagens"</string>
@@ -46,8 +46,11 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Aceda a multimédia na nuvem a partir de"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Nenhuma"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Impossível alterar a app de multimédia na nuvem."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Seletor de meios"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Seletor de meios"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"A sincronizar conteúdo multimédia…"</string>
<string name="add" msgid="2894574044585549298">"Adicionar"</string>
- <string name="deselect" msgid="4297825044827769490">"Desselecionar"</string>
+ <string name="deselect" msgid="4297825044827769490">"Desmarcar"</string>
<string name="deselected" msgid="8488133193326208475">"Desmarcado"</string>
<string name="select" msgid="2704765470563027689">"Selecionar"</string>
<string name="selected" msgid="9151797369975828124">"Selecionado"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Verifique a ligação à Internet e tente novamente"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Tentar novamente"</string>
<string name="not_selected" msgid="2244008151669896758">"não selecionado"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"A preparar conteúdo multimédia selecionado"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> de <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> item(ns) pronto(s)"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"As fotos com cópia de segurança já estão incluídas"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Pode selecionar fotos da app <xliff:g id="APP_NAME">%1$s</xliff:g> da conta <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Escolher app"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Escolher conta"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Alterar conta"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"A obter todas as suas fotos"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> modifique este ficheiro de áudio?}many{Permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> ficheiros de áudio?}other{Permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> ficheiros de áudio?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{A modificar o ficheiro de áudio…}many{A modificar <xliff:g id="COUNT">^1</xliff:g> ficheiro(s) de áudio…}other{A modificar <xliff:g id="COUNT">^1</xliff:g> ficheiro(s) de áudio…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Permitir que a app <xliff:g id="APP_NAME_0">^1</xliff:g> modifique este vídeo?}many{Permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> vídeos?}other{Permitir que a app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> vídeos?}}"</string>
@@ -149,4 +154,7 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Proteção de segurança"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Alertas de transcodificação nativa"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Progresso de transcodificação nativa"</string>
+ <string name="dialog_error_message" msgid="5120432204743681606">"Tente mais tarde. As suas fotos vão estar disponíveis quando o problema estiver resolvido."</string>
+ <string name="dialog_error_title" msgid="636349284077820636">"Não é possível carregar algumas fotos"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"OK"</string>
</resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 76b2e27ca..3c02de6ea 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Mídia"</string>
<string name="storage_description" msgid="4081716890357580107">"Armazenamento local"</string>
<string name="app_label" msgid="9035307001052716210">"Armazenamento de mídia"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Mídia"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Seletor de mídia"</string>
<string name="artist_label" msgid="8105600993099120273">"Artista"</string>
<string name="unknown" msgid="2059049215682829375">"Desconhecido"</string>
<string name="root_images" msgid="5861633549189045666">"Imagens"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Acessar a mídia em nuvem de"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Nenhum"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Não foi possível mudar o app de mídia em nuvem."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Seletor de mídia"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Seletor de mídia"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Sincronizando mídia…"</string>
<string name="add" msgid="2894574044585549298">"Adicionar"</string>
<string name="deselect" msgid="4297825044827769490">"Desmarcar"</string>
<string name="deselected" msgid="8488133193326208475">"Desmarcada"</string>
@@ -60,8 +63,8 @@
<string name="picker_photos" msgid="7415035516411087392">"Fotos"</string>
<string name="picker_albums" msgid="4822511902115299142">"Álbuns"</string>
<string name="picker_preview" msgid="6257414886055861039">"Visualização"</string>
- <string name="picker_work_profile" msgid="2083221066869141576">"Mudar para \"Trabalho\""</string>
- <string name="picker_personal_profile" msgid="639484258397758406">"Mudar para \"Pessoal\""</string>
+ <string name="picker_work_profile" msgid="2083221066869141576">"Mudar para Trabalho"</string>
+ <string name="picker_personal_profile" msgid="639484258397758406">"Mudar para Pessoal"</string>
<string name="picker_profile_admin_title" msgid="4172022376418293777">"Bloqueado pelo administrador"</string>
<string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"Não é permitido o acesso a dados de trabalho em um app pessoal"</string>
<string name="picker_profile_admin_msg_from_work" msgid="8048524337462790110">"Não é permitido o acesso a dados pessoais em um app de trabalho"</string>
@@ -93,8 +96,9 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Confira sua conexão de Internet e tente de novo"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Tentar novamente"</string>
<string name="not_selected" msgid="2244008151669896758">"não selecionado"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Preparando a mídia selecionada"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> de <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> itens prontos"</string>
- <string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Fotos salvas em backup agora estão incluídas"</string>
+ <string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"As fotos salvas em backup agora estão incluídas"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Selecione fotos da conta <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> do app <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="picker_banner_cloud_account_changed_title" msgid="4825058474378077327">"A conta do app <xliff:g id="APP_NAME">%1$s</xliff:g> foi atualizada"</string>
<string name="picker_banner_cloud_account_changed_desc" msgid="3433218869899792497">"As fotos da conta <xliff:g id="USER_ACCOUNT">%1$s</xliff:g> agora estão incluídas aqui"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Selecionar app"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Escolher conta"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Trocar conta"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Acessando todas as suas fotos"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Permitir que o app <xliff:g id="APP_NAME_0">^1</xliff:g> modifique esse arquivo de áudio?}one{Permitir que o app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> arquivo de áudio?}many{Permitir que o app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> arquivos de áudio?}other{Permitir que o app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> arquivos de áudio?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Modificando o arquivo de áudio…}one{Modificando <xliff:g id="COUNT">^1</xliff:g> arquivo de áudio…}many{Modificando <xliff:g id="COUNT">^1</xliff:g> arquivos de áudio…}other{Modificando <xliff:g id="COUNT">^1</xliff:g> arquivos de áudio…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Permitir que o app <xliff:g id="APP_NAME_0">^1</xliff:g> modifique esse vídeo?}one{Permitir que o app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> vídeo?}many{Permitir que o app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> vídeos?}other{Permitir que o app <xliff:g id="APP_NAME_1">^1</xliff:g> modifique <xliff:g id="COUNT">^2</xliff:g> vídeos?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Proteção"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Alertas da transcodificação nativa"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Progresso da transcodificação nativa"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Não é possível carregar algumas fotos"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Entendi"</string>
</resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 7682e076f..f0b12d141 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Conținut media"</string>
<string name="storage_description" msgid="4081716890357580107">"Stocare locală"</string>
<string name="app_label" msgid="9035307001052716210">"Stocarea conținutului media"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Media"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Selector de suport"</string>
<string name="artist_label" msgid="8105600993099120273">"Artist"</string>
<string name="unknown" msgid="2059049215682829375">"Necunoscut"</string>
<string name="root_images" msgid="5861633549189045666">"Imagini"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Accesează conținutul media în cloud din"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Niciuna"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Nu s-a putut schimba aplicația media pentru cloud"</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Selector de suport"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Selector de suport"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Se sincronizează conținutul media…"</string>
<string name="add" msgid="2894574044585549298">"Adaugă"</string>
<string name="deselect" msgid="4297825044827769490">"Debifează"</string>
<string name="deselected" msgid="8488133193326208475">"Deselectat"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Verifică-ți conexiunea la internet și încearcă din nou"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Încearcă din nou"</string>
<string name="not_selected" msgid="2244008151669896758">"neselectat"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Se pregătește conținutul media selectat"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"Finalizate: <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> din <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Fotografiile cu backup sunt incluse acum"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Poți selecta fotografii din contul <xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Alege aplicația"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Alege un cont"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Schimbă contul"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Se încarcă toate fotografiile"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Permiți ca <xliff:g id="APP_NAME_0">^1</xliff:g> să modifice acest fișier audio?}few{Permiți ca <xliff:g id="APP_NAME_1">^1</xliff:g> să modifice <xliff:g id="COUNT">^2</xliff:g> fișiere audio?}other{Permiți ca <xliff:g id="APP_NAME_1">^1</xliff:g> să modifice <xliff:g id="COUNT">^2</xliff:g> de fișiere audio?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Se modifică fișierul audio…}few{Se modifică <xliff:g id="COUNT">^1</xliff:g> fișiere audio…}other{Se modifică <xliff:g id="COUNT">^1</xliff:g> de fișiere audio…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Permiți ca <xliff:g id="APP_NAME_0">^1</xliff:g> să modifice acest videoclip?}few{Permiți ca <xliff:g id="APP_NAME_1">^1</xliff:g> să modifice <xliff:g id="COUNT">^2</xliff:g> videoclipuri?}other{Permiți ca <xliff:g id="APP_NAME_1">^1</xliff:g> să modifice <xliff:g id="COUNT">^2</xliff:g> de videoclipuri?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Protecția în caz de accidente"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Alerte privind transcodarea în codul nativ"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Progresul transcodării în codul nativ"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Unele fotografii nu pot fi încărcate"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"OK"</string>
</resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 25d46684a..0b212b7c1 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/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="picker_app_label" msgid="4254039089502164761">"Мультимедиа"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Инструмент выбора медиа"</string>
<string name="artist_label" msgid="8105600993099120273">"Исполнитель"</string>
<string name="unknown" msgid="2059049215682829375">"Неизвестно"</string>
<string name="root_images" msgid="5861633549189045666">"Изображения"</string>
@@ -43,9 +43,12 @@
<string name="picker_settings_system_settings_menu_title" msgid="3055084757610063581">"Приложение для мультимедиа в облаке"</string>
<string name="picker_settings_title" msgid="5647700706470673258">"Приложение для мультимедиа в облаке"</string>
<string name="picker_settings_description" msgid="2916686824777214585">"Выбирайте свои фото и видео из облака в приложениях или на сайтах."</string>
- <string name="picker_settings_selection_message" msgid="245453573086488596">"Получите доступ к мультимедиа в облаке"</string>
+ <string name="picker_settings_selection_message" msgid="245453573086488596">"Какое приложение использовать для доступа к медиафайлам в облаке?"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Нет"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Не удалось изменить приложение для мультимедиа."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Инструмент выбора медиа"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Инструмент выбора медиа"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Синхронизация медиаконтента…"</string>
<string name="add" msgid="2894574044585549298">"Добавить"</string>
<string name="deselect" msgid="4297825044827769490">"Отменить выбор"</string>
<string name="deselected" msgid="8488133193326208475">"Выбор отменен"</string>
@@ -93,8 +96,9 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Проверьте подключение к интернету и повторите попытку."</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Повторить"</string>
<string name="not_selected" msgid="2244008151669896758">"не выбрано"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Подготовка выбранных медиафайлов"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"Предзагрузка: <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> из <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>"</string>
- <string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Резервные копии фотографий добавлены"</string>
+ <string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Теперь можно выбирать фотографии в облаке"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Вы можете выбрать фотографии из аккаунта <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"."</string>
<string name="picker_banner_cloud_account_changed_title" msgid="4825058474378077327">"<xliff:g id="APP_NAME">%1$s</xliff:g>: аккаунт обновлен"</string>
<string name="picker_banner_cloud_account_changed_desc" msgid="3433218869899792497">"Фотографии из аккаунта <xliff:g id="USER_ACCOUNT">%1$s</xliff:g> теперь хранятся здесь."</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Выбрать приложение"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Выбрать аккаунт"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Сменить аккаунт"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Ваши фотографии загружаются"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Разрешить приложению \"<xliff:g id="APP_NAME_0">^1</xliff:g>\" изменить этот аудиофайл?}one{Разрешить приложению \"<xliff:g id="APP_NAME_1">^1</xliff:g>\" изменить <xliff:g id="COUNT">^2</xliff:g> аудиофайл?}few{Разрешить приложению \"<xliff:g id="APP_NAME_1">^1</xliff:g>\" изменить <xliff:g id="COUNT">^2</xliff:g> аудиофайла?}many{Разрешить приложению \"<xliff:g id="APP_NAME_1">^1</xliff:g>\" изменить <xliff:g id="COUNT">^2</xliff:g> аудиофайлов?}other{Разрешить приложению \"<xliff:g id="APP_NAME_1">^1</xliff:g>\" изменить <xliff:g id="COUNT">^2</xliff:g> аудиофайла?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Изменение аудиофайла…}one{Изменение <xliff:g id="COUNT">^1</xliff:g> аудиофайла…}few{Изменение <xliff:g id="COUNT">^1</xliff:g> аудиофайлов…}many{Изменение <xliff:g id="COUNT">^1</xliff:g> аудиофайлов…}other{Изменение <xliff:g id="COUNT">^1</xliff:g> аудиофайла…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Разрешить приложению \"<xliff:g id="APP_NAME_0">^1</xliff:g>\" изменить это видео?}one{Разрешить приложению \"<xliff:g id="APP_NAME_1">^1</xliff:g>\" изменить <xliff:g id="COUNT">^2</xliff:g> видео?}few{Разрешить приложению \"<xliff:g id="APP_NAME_1">^1</xliff:g>\" изменить <xliff:g id="COUNT">^2</xliff:g> видео?}many{Разрешить приложению \"<xliff:g id="APP_NAME_1">^1</xliff:g>\" изменить <xliff:g id="COUNT">^2</xliff:g> видео?}other{Разрешить приложению \"<xliff:g id="APP_NAME_1">^1</xliff:g>\" изменить <xliff:g id="COUNT">^2</xliff:g> видео?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Защита безопасности"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Уведомления нативного перекодирования"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Прогресс нативного перекодирования"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Не удается загрузить некоторые фотографии"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"ОК"</string>
</resources>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index c339669a6..9ed5bd18e 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/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="picker_app_label" msgid="4254039089502164761">"මාධ්‍ය"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"මාධ්‍ය තෝරනය"</string>
<string name="artist_label" msgid="8105600993099120273">"කලාකරු"</string>
<string name="unknown" msgid="2059049215682829375">"නොදනී"</string>
<string name="root_images" msgid="5861633549189045666">"රූප"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"මෙයින් ක්ලවුඩ් මාධ්‍ය වෙත ප්‍රවේශ වන්න"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"කිසිවක් නැත"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"මෙම අවස්ථාවේ ක්ලවුඩ් මාධ්‍ය යෙදුම වෙනස් කළ නොහැක."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"මාධ්‍ය තෝරනය"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"මාධ්‍ය තෝරනය"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"මාධ්‍ය සමමුහුර්ත කරමින්…"</string>
<string name="add" msgid="2894574044585549298">"එක් කරන්න"</string>
<string name="deselect" msgid="4297825044827769490">"නොතෝරන්න"</string>
<string name="deselected" msgid="8488133193326208475">"නොතෝරන ලද"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"ඔබේ අන්තර්ජාල සබැඳුම පරීක්ෂා කර නැවත උත්සාහ කරන්න"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"යළි උත්සාහ කරන්න"</string>
<string name="not_selected" msgid="2244008151669896758">"තෝරා නොමැත"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"ඔබ තෝරන ලද මාධ්‍ය සූදානම් කරමින්"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>කින් <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g>ක් සූදානම්"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"උපස්ථ කළ ඡායාරූප දැන් ඇතුළත් කර ඇත"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"ඔබට <xliff:g id="APP_NAME">%1$s</xliff:g> ගිණුමෙන් <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> ඡායාරූප තෝරා ගත හැක"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"යෙදුම තෝරා ගන්න"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"ගිණුම තෝරා ගන්න"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"ගිණුම වෙනස් කරන්න"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"ඔබේ සියලු ඡායාරූප ලබා ගැනීම"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> හට මෙම ශ්‍රව්‍ය ගොනුව වෙනස් කිරීමට ඉඩ දෙන්නද?}one{<xliff:g id="APP_NAME_1">^1</xliff:g> හට ශ්‍රව්‍ය ගොනු <xliff:g id="COUNT">^2</xliff:g>ක් වෙනස් කිරීමට ඉඩ දෙන්නද?}other{<xliff:g id="APP_NAME_1">^1</xliff:g> හට ශ්‍රව්‍ය ගොනු <xliff:g id="COUNT">^2</xliff:g>ක් වෙනස් කිරීමට ඉඩ දෙන්නද?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{ශ්‍රව්‍ය ගොනුව වෙනස් කරමින්…}one{ශ්‍රව්‍ය ගොනු <xliff:g id="COUNT">^1</xliff:g>ක් වෙනස් කරමින්…}other{ශ්‍රව්‍ය ගොනු <xliff:g id="COUNT">^1</xliff:g>ක් වෙනස් කරමින්…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> හට මෙම වීඩියෝව වෙනස් කිරීමට ඉඩ දෙන්නද?}one{<xliff:g id="APP_NAME_1">^1</xliff:g> හට වීඩියෝ <xliff:g id="COUNT">^2</xliff:g>ක් වෙනස් කිරීමට ඉඩ දෙන්නද?}other{<xliff:g id="APP_NAME_1">^1</xliff:g> හට වීඩියෝ <xliff:g id="COUNT">^2</xliff:g>ක් වෙනස් කිරීමට ඉඩ දෙන්නද?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"සුරක්ෂිතතා ආරක්ෂණය"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"සහජ ට්‍රාන්ස්කෝඩ් ඇඟවීම්"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"සහජ ට්‍රාන්ස්කෝඩ් ප්‍රගතිය"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"සමහර ඡායාරූප පූරණය කළ නොහැක"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"තේරුණා"</string>
</resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 80eebfc73..def0ce037 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Médiá"</string>
<string name="storage_description" msgid="4081716890357580107">"Miestne úložisko"</string>
<string name="app_label" msgid="9035307001052716210">"Úložisko médií"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Médiá"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Nástroj na výber médií"</string>
<string name="artist_label" msgid="8105600993099120273">"Interpret"</string>
<string name="unknown" msgid="2059049215682829375">"Neznáme"</string>
<string name="root_images" msgid="5861633549189045666">"Obrázky"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Získavať prístup k médiám v cloude v aplikácii"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Žiadne"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Momentálne sa nepodarilo zmeniť cloudový prehrávač"</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Nástroj na výber médií"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Nástroj na výber médií"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Synchronizujú sa médiá…"</string>
<string name="add" msgid="2894574044585549298">"Pridať"</string>
<string name="deselect" msgid="4297825044827769490">"Zrušiť výber"</string>
<string name="deselected" msgid="8488133193326208475">"Výber bol zrušený"</string>
@@ -60,14 +63,14 @@
<string name="picker_photos" msgid="7415035516411087392">"Fotky"</string>
<string name="picker_albums" msgid="4822511902115299142">"Albumy"</string>
<string name="picker_preview" msgid="6257414886055861039">"Ukážka"</string>
- <string name="picker_work_profile" msgid="2083221066869141576">"Prepnúť na pracovný"</string>
- <string name="picker_personal_profile" msgid="639484258397758406">"Prepnúť na osobný"</string>
+ <string name="picker_work_profile" msgid="2083221066869141576">"Prepnúť na pracovný profil"</string>
+ <string name="picker_personal_profile" msgid="639484258397758406">"Prepnúť na osobný profil"</string>
<string name="picker_profile_admin_title" msgid="4172022376418293777">"Blokované vaším správcom"</string>
<string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"Prístup k pracovným údajom z osobnej aplikácie nie je povolený"</string>
<string name="picker_profile_admin_msg_from_work" msgid="8048524337462790110">"Prístup k osobným údajom z pracovnej aplikácie nie je povolený"</string>
<string name="picker_profile_work_paused_title" msgid="382212880704235925">"Pracovné aplikácie sú pozastavené"</string>
<string name="picker_profile_work_paused_msg" msgid="6321552322125246726">"Ak chcete otvoriť pracovné fotky, zapnite pracovné aplikácie a skúste to znova"</string>
- <string name="picker_privacy_message" msgid="9132700451027116817">"Táto aplikácia môže mať prístup iba k fotkám, ktoré vyberiete"</string>
+ <string name="picker_privacy_message" msgid="9132700451027116817">"Táto aplikácia má prístup iba k fotkám, ktoré vyberiete"</string>
<string name="picker_header_permissions" msgid="675872774407768495">"Vyberte fotky a videá, ku ktorým má mať táto aplikácia prístup"</string>
<string name="picker_album_item_count" msgid="4420723302534177596">"{count,plural, =1{<xliff:g id="COUNT_0">^1</xliff:g> položka}few{<xliff:g id="COUNT_1">^1</xliff:g> položky}many{<xliff:g id="COUNT_1">^1</xliff:g> items}other{<xliff:g id="COUNT_1">^1</xliff:g> položiek}}"</string>
<string name="picker_add_button_multi_select" msgid="4005164092275518399">"Pridať (<xliff:g id="COUNT">^1</xliff:g>)"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Skontrolujte internetové pripojenie a skúste to znova"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Skúsiť znova"</string>
<string name="not_selected" msgid="2244008151669896758">"nevybrané"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Pripravujú sa vybrané médiá"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"Pripravené: <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> z <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Zálohované fotky sú teraz zahrnuté"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Môžete vybrať fotky z účtu <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Vybrať aplikáciu"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Vybrať účet"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Zmeniť účet"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Načítavajú sa všekty vaše fotky"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Chcete povoliť aplikácii <xliff:g id="APP_NAME_0">^1</xliff:g> upraviť tento zvukový súbor?}few{Chcete povoliť aplikácii <xliff:g id="APP_NAME_1">^1</xliff:g> upraviť <xliff:g id="COUNT">^2</xliff:g> zvukové súbory?}many{Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to modify <xliff:g id="COUNT">^2</xliff:g> audio files?}other{Chcete povoliť aplikácii <xliff:g id="APP_NAME_1">^1</xliff:g> upraviť <xliff:g id="COUNT">^2</xliff:g> zvukových súborov?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Upravuje sa zvukový súbor…}few{Upravujú sa <xliff:g id="COUNT">^1</xliff:g> zvukové súbory…}many{Modifying <xliff:g id="COUNT">^1</xliff:g> audio files…}other{Upravuje sa <xliff:g id="COUNT">^1</xliff:g> zvukových súborov…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Chcete povoliť aplikácii <xliff:g id="APP_NAME_0">^1</xliff:g> upraviť toto video?}few{Chcete povoliť aplikácii <xliff:g id="APP_NAME_1">^1</xliff:g> upraviť <xliff:g id="COUNT">^2</xliff:g> videá?}many{Allow <xliff:g id="APP_NAME_1">^1</xliff:g> to modify <xliff:g id="COUNT">^2</xliff:g> videos?}other{Chcete povoliť aplikácii <xliff:g id="APP_NAME_1">^1</xliff:g> upraviť <xliff:g id="COUNT">^2</xliff:g> videí?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Bezpečnosť"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Upozornenia natívneho prekódovania"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Postup natívneho prekódovania"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Niektoré fotky sa nedajú načítať"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Dobre"</string>
</resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 0f7e3806b..aca8523e0 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Predstavnost"</string>
<string name="storage_description" msgid="4081716890357580107">"Lokalna shramba"</string>
<string name="app_label" msgid="9035307001052716210">"Shramba za predstavnost"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Predstavnost"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Orodje za izbiranje predstavnosti"</string>
<string name="artist_label" msgid="8105600993099120273">"Izvajalec"</string>
<string name="unknown" msgid="2059049215682829375">"Neznano"</string>
<string name="root_images" msgid="5861633549189045666">"Slike"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Dostop do predstavnosti v oblaku v storitvi"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Brez"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Zamenjava aplikacije za predstavnost v oblaku trenutno ni mogoča."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Orodje za izbiranje predstavnosti"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Orodje za izbiranje predstavnosti"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Sinhroniziranje predstavnosti …"</string>
<string name="add" msgid="2894574044585549298">"Dodaj"</string>
<string name="deselect" msgid="4297825044827769490">"Počisti izbiro"</string>
<string name="deselected" msgid="8488133193326208475">"Izbor je preklican"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Preverite internetno povezavo in poskusite znova."</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Poskusi znova"</string>
<string name="not_selected" msgid="2244008151669896758">"ni izbrano"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Pripravljanje izbranih predstavnostnih vsebin"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"Pripravljenih: <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> od <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Varnostno kopirane fotografije so zdaj vključene"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Izberete lahko fotografije iz računa <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> za aplikacijo <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Izbira aplikacije"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Izbira računa"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Sprememba računa"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Pridobivanje vseh vaših fotografij"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Želite dovoliti aplikaciji <xliff:g id="APP_NAME_0">^1</xliff:g>, da spremeni to zvočno datoteko?}one{Želite dovoliti aplikaciji <xliff:g id="APP_NAME_1">^1</xliff:g>, da spremeni <xliff:g id="COUNT">^2</xliff:g> zvočno datoteko?}two{Želite dovoliti aplikaciji <xliff:g id="APP_NAME_1">^1</xliff:g>, da spremeni <xliff:g id="COUNT">^2</xliff:g> zvočni datoteki?}few{Želite dovoliti aplikaciji <xliff:g id="APP_NAME_1">^1</xliff:g>, da spremeni <xliff:g id="COUNT">^2</xliff:g> zvočne datoteke?}other{Želite dovoliti aplikaciji <xliff:g id="APP_NAME_1">^1</xliff:g>, da spremeni <xliff:g id="COUNT">^2</xliff:g> zvočnih datotek?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Spreminjanje zvočne datoteke …}one{Spreminjanje <xliff:g id="COUNT">^1</xliff:g> zvočne datoteke …}two{Spreminjanje <xliff:g id="COUNT">^1</xliff:g> zvočnih datotek …}few{Spreminjanje <xliff:g id="COUNT">^1</xliff:g> zvočnih datotek …}other{Spreminjanje <xliff:g id="COUNT">^1</xliff:g> zvočnih datotek …}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Želite dovoliti aplikaciji <xliff:g id="APP_NAME_0">^1</xliff:g>, da spremeni ta videoposnetek?}one{Želite dovoliti aplikaciji <xliff:g id="APP_NAME_1">^1</xliff:g>, da spremeni <xliff:g id="COUNT">^2</xliff:g> videoposnetek?}two{Želite dovoliti aplikaciji <xliff:g id="APP_NAME_1">^1</xliff:g>, da spremeni <xliff:g id="COUNT">^2</xliff:g> videoposnetka?}few{Želite dovoliti aplikaciji <xliff:g id="APP_NAME_1">^1</xliff:g>, da spremeni <xliff:g id="COUNT">^2</xliff:g> videoposnetke?}other{Želite dovoliti aplikaciji <xliff:g id="APP_NAME_1">^1</xliff:g>, da spremeni <xliff:g id="COUNT">^2</xliff:g> videoposnetkov?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Varnostna zaščita"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Opozorila o izvornem prekodiranju"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Napredek izvornega prekodiranja"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Nekaterih fotografij ni mogoče naložiti"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Razumem"</string>
</resources>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index ff2a35d53..51376e486 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Media"</string>
<string name="storage_description" msgid="4081716890357580107">"Hapësira ruajtëse lokale"</string>
<string name="app_label" msgid="9035307001052716210">"Hapësira ruajtëse e medias"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Media"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Zgjedhësi i medias"</string>
<string name="artist_label" msgid="8105600993099120273">"Artisti"</string>
<string name="unknown" msgid="2059049215682829375">"I panjohur"</string>
<string name="root_images" msgid="5861633549189045666">"Fotografitë"</string>
@@ -42,10 +42,13 @@
<string name="picker_settings" msgid="6443463167344790260">"Aplikacioni i medias në renë kompjuterike"</string>
<string name="picker_settings_system_settings_menu_title" msgid="3055084757610063581">"Aplikacion i medias në renë kompjuterike"</string>
<string name="picker_settings_title" msgid="5647700706470673258">"Aplikacioni i medias në renë kompjuterike"</string>
- <string name="picker_settings_description" msgid="2916686824777214585">"Qasu te media jote në renë kompjuterike kur një aplikacion ose sajt uebi të kërkon të zgjedhësh fotografitë ose videot"</string>
+ <string name="picker_settings_description" msgid="2916686824777214585">"Qasu te media jote në renë kompjuterike kur një aplikacion ose uebsajt të kërkon të zgjedhësh fotografitë ose videot"</string>
<string name="picker_settings_selection_message" msgid="245453573086488596">"Qasu te media në renë kompjuterike nga"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Asnjë"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Aplikacioni i medias në renë kompjuterike nuk mund të ndryshohej në këtë moment."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Zgjedhësi i medias"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Zgjedhësi i medias"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Media po sinkronizohet…"</string>
<string name="add" msgid="2894574044585549298">"Shto"</string>
<string name="deselect" msgid="4297825044827769490">"Hiq përzgjedhjen"</string>
<string name="deselected" msgid="8488133193326208475">"Zgjedhja është hequr"</string>
@@ -60,8 +63,8 @@
<string name="picker_photos" msgid="7415035516411087392">"Fotografitë"</string>
<string name="picker_albums" msgid="4822511902115299142">"Albumet"</string>
<string name="picker_preview" msgid="6257414886055861039">"Pamja paraprake"</string>
- <string name="picker_work_profile" msgid="2083221066869141576">"Ndryshoje te puna"</string>
- <string name="picker_personal_profile" msgid="639484258397758406">"Ndryshoje te personale"</string>
+ <string name="picker_work_profile" msgid="2083221066869141576">"Kalo te profili i punës"</string>
+ <string name="picker_personal_profile" msgid="639484258397758406">"Kalo te profili personal"</string>
<string name="picker_profile_admin_title" msgid="4172022376418293777">"Bllokuar nga administratori yt"</string>
<string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"Qasja e të dhënave të punës nga një aplikacion personal nuk lejohet"</string>
<string name="picker_profile_admin_msg_from_work" msgid="8048524337462790110">"Qasja e të dhënave personale nga një aplikacion pune nuk lejohet"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Kontrollo lidhjen e internetit dhe provo përsëri"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Riprovo"</string>
<string name="not_selected" msgid="2244008151669896758">"nuk është zgjedhur"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Media e zgjedhur po përgatitet"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> nga <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> gati"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Fotografitë e rezervuara tani janë të përfshira"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Mund të zgjedhësh fotografi nga llogaria e<xliff:g id="USER_ACCOUNT">%2$s</xliff:g> në <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Zgjidh aplikacionin"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Zgjidh llogarinë"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Ndrysho llogarinë"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Po merren të gjitha fotografitë e tua"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Të lejohet <xliff:g id="APP_NAME_0">^1</xliff:g> që ta modifikojë këtë skedar audio?}other{Të lejohet <xliff:g id="APP_NAME_1">^1</xliff:g> që të modifikojë <xliff:g id="COUNT">^2</xliff:g> skedarë audio?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Skedari audio po modifikohet…}other{<xliff:g id="COUNT">^1</xliff:g> skedarë audio po modifikohen…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Të lejohet <xliff:g id="APP_NAME_0">^1</xliff:g> që ta modifikojë këtë video?}other{Të lejohet <xliff:g id="APP_NAME_1">^1</xliff:g> që të modifikojë <xliff:g id="COUNT">^2</xliff:g> video?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Mbrojtja e sigurisë"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Sinjalizimet e transkodimit origjinal"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Progresi i transkodimit origjinal"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Disa fotografi nuk mund të ngarkohen"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"E kuptova"</string>
</resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 98f988e15..5540ae985 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/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="picker_app_label" msgid="4254039089502164761">"Медији"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Бирач медија"</string>
<string name="artist_label" msgid="8105600993099120273">"Извођач"</string>
<string name="unknown" msgid="2059049215682829375">"Непознато"</string>
<string name="root_images" msgid="5861633549189045666">"Слике"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Приступајте медијима у клауду из"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Ништа"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Промена апликације за медије у клауду није успела."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Бирач медија"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Бирач медија"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Медији се синхронизују…"</string>
<string name="add" msgid="2894574044585549298">"Додај"</string>
<string name="deselect" msgid="4297825044827769490">"Опозови избор"</string>
<string name="deselected" msgid="8488133193326208475">"Опозван је избор"</string>
@@ -53,8 +56,8 @@
<string name="selected" msgid="9151797369975828124">"Изабрано"</string>
<string name="select_up_to" msgid="6994294169508439957">"{count,plural, =1{Изаберите највише <xliff:g id="COUNT_0">^1</xliff:g> ставку}one{Изаберите највише <xliff:g id="COUNT_1">^1</xliff:g> ставку}few{Изаберите највише <xliff:g id="COUNT_1">^1</xliff:g> ставке}other{Изаберите највише <xliff:g id="COUNT_1">^1</xliff:g> ставки}}"</string>
<string name="recent" msgid="6694613584743207874">"Недавно"</string>
- <string name="picker_photos_empty_message" msgid="5980619500554575558">"Нема слика нити видео снимака"</string>
- <string name="picker_album_media_empty_message" msgid="7061850698189881671">"Нема подржаних слика нити видео снимака"</string>
+ <string name="picker_photos_empty_message" msgid="5980619500554575558">"Нема слика нити видеа"</string>
+ <string name="picker_album_media_empty_message" msgid="7061850698189881671">"Нема подржаних слика нити видеа"</string>
<string name="picker_albums_empty_message" msgid="8341079772950966815">"Нема албума"</string>
<string name="picker_view_selected" msgid="2266031384396143883">"Прикажи изабранo"</string>
<string name="picker_photos" msgid="7415035516411087392">"Слике"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Проверите интернет везу и пробајте поново"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Пробај поново"</string>
<string name="not_selected" msgid="2244008151669896758">"није изабрано"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Припремају се одабрани медијски фајлови"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"Спремно:<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> од <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Сада су уврштене резервне копије слика"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Можете да изаберете слике са налога <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> за <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -106,34 +110,35 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Одабери апликацију"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Одабери налог"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Промени налог"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Преузимају се све слике"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Желите ли да дозволите да <xliff:g id="APP_NAME_0">^1</xliff:g> измени овај аудио фајл?}one{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> измени <xliff:g id="COUNT">^2</xliff:g> аудио фајл?}few{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> измени <xliff:g id="COUNT">^2</xliff:g> аудио фајла?}other{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> измени <xliff:g id="COUNT">^2</xliff:g> аудио фајлова?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Мења се аудио фајл…}one{Мења се <xliff:g id="COUNT">^1</xliff:g> аудио фајл…}few{Мењају се <xliff:g id="COUNT">^1</xliff:g> аудио фајла…}other{Мења се <xliff:g id="COUNT">^1</xliff:g> аудио фајлова…}}"</string>
- <string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Желите ли да дозволите да <xliff:g id="APP_NAME_0">^1</xliff:g> измени овај видео?}one{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> измени <xliff:g id="COUNT">^2</xliff:g> видео?}few{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> измени <xliff:g id="COUNT">^2</xliff:g> видео снимка?}other{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> измени <xliff:g id="COUNT">^2</xliff:g> видео снимака?}}"</string>
- <string name="permission_progress_write_video" msgid="7014908418349819148">"{count,plural, =1{Мења се видео…}one{Мења се <xliff:g id="COUNT">^1</xliff:g> видео…}few{Мењају се <xliff:g id="COUNT">^1</xliff:g> видео снимка…}other{Мења се <xliff:g id="COUNT">^1</xliff:g> видео снимака…}}"</string>
+ <string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Желите ли да дозволите да <xliff:g id="APP_NAME_0">^1</xliff:g> измени овај видео?}one{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> измени <xliff:g id="COUNT">^2</xliff:g> видео?}few{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> измени <xliff:g id="COUNT">^2</xliff:g> видео снимка?}other{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> измени <xliff:g id="COUNT">^2</xliff:g> видеа?}}"</string>
+ <string name="permission_progress_write_video" msgid="7014908418349819148">"{count,plural, =1{Мења се видео…}one{Мења се <xliff:g id="COUNT">^1</xliff:g> видео…}few{Мењају се <xliff:g id="COUNT">^1</xliff:g> видео снимка…}other{Мења се <xliff:g id="COUNT">^1</xliff:g> видеа…}}"</string>
<string name="permission_write_image" msgid="3518991791620523786">"{count,plural, =1{Желите ли да дозволите да <xliff:g id="APP_NAME_0">^1</xliff:g> измени ову слику?}one{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> измени <xliff:g id="COUNT">^2</xliff:g> слику?}few{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> измени <xliff:g id="COUNT">^2</xliff:g> слике?}other{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> измени <xliff:g id="COUNT">^2</xliff:g> слика?}}"</string>
<string name="permission_progress_write_image" msgid="3623580315590025262">"{count,plural, =1{Мења се слика…}one{Мења се <xliff:g id="COUNT">^1</xliff:g> слика…}few{Мењају се <xliff:g id="COUNT">^1</xliff:g> слике…}other{Мења се <xliff:g id="COUNT">^1</xliff:g> слика…}}"</string>
<string name="permission_write_generic" msgid="7431128739233656991">"{count,plural, =1{Желите ли да дозволите да <xliff:g id="APP_NAME_0">^1</xliff:g> измени ову ставку?}one{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> измени <xliff:g id="COUNT">^2</xliff:g> ставку?}few{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> измени <xliff:g id="COUNT">^2</xliff:g> ставке?}other{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> измени <xliff:g id="COUNT">^2</xliff:g> ставки?}}"</string>
<string name="permission_progress_write_generic" msgid="2806560971318391443">"{count,plural, =1{Мења се ставка…}one{Мења се <xliff:g id="COUNT">^1</xliff:g> ставка…}few{Мењају се <xliff:g id="COUNT">^1</xliff:g> ставке…}other{Мења се <xliff:g id="COUNT">^1</xliff:g> ставки…}}"</string>
<string name="permission_trash_audio" msgid="6554672354767742206">"{count,plural, =1{Желите ли да дозволите да <xliff:g id="APP_NAME_0">^1</xliff:g> премести овај аудио фајл у отпад?}one{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> аудио фајл у отпад?}few{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> аудио фајла у отпад?}other{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> аудио фајлова у отпад?}}"</string>
<string name="permission_progress_trash_audio" msgid="3116279868733641329">"{count,plural, =1{Аудио фајл се премешта у отпад…}one{<xliff:g id="COUNT">^1</xliff:g> аудио фајл се премешта у отпад…}few{<xliff:g id="COUNT">^1</xliff:g> аудио фајла се премештају у отпад…}other{<xliff:g id="COUNT">^1</xliff:g> аудио фајлова се премешта у отпад…}}"</string>
- <string name="permission_trash_video" msgid="7555850843259959642">"{count,plural, =1{Желите ли да дозволите да <xliff:g id="APP_NAME_0">^1</xliff:g> премести овај видео у отпад?}one{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> видео у отпад?}few{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> видео снимка у отпад?}other{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> видео снимака у отпад?}}"</string>
- <string name="permission_progress_trash_video" msgid="4637821778329459681">"{count,plural, =1{Видео се премешта у отпад…}one{<xliff:g id="COUNT">^1</xliff:g> видео се премешта у отпад…}few{<xliff:g id="COUNT">^1</xliff:g> видео снимка се премештају у отпад…}other{<xliff:g id="COUNT">^1</xliff:g> видео снимака се премешта у отпад…}}"</string>
+ <string name="permission_trash_video" msgid="7555850843259959642">"{count,plural, =1{Желите ли да дозволите да <xliff:g id="APP_NAME_0">^1</xliff:g> премести овај видео у отпад?}one{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> видео у отпад?}few{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> видео снимка у отпад?}other{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> видеа у отпад?}}"</string>
+ <string name="permission_progress_trash_video" msgid="4637821778329459681">"{count,plural, =1{Видео се премешта у отпад…}one{<xliff:g id="COUNT">^1</xliff:g> видео се премешта у отпад…}few{<xliff:g id="COUNT">^1</xliff:g> видео снимка се премештају у отпад…}other{<xliff:g id="COUNT">^1</xliff:g> видеа се премешта у отпад…}}"</string>
<string name="permission_trash_image" msgid="3333128084684156675">"{count,plural, =1{Желите ли да дозволите да <xliff:g id="APP_NAME_0">^1</xliff:g> премести ову слику у отпад?}one{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> слику у отпад?}few{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> слике у отпад?}other{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> слика у отпад?}}"</string>
<string name="permission_progress_trash_image" msgid="3063857679090024764">"{count,plural, =1{Слика се премешта у отпад…}one{<xliff:g id="COUNT">^1</xliff:g> слика се премешта у отпад…}few{<xliff:g id="COUNT">^1</xliff:g> слике се премештају у отпад…}other{<xliff:g id="COUNT">^1</xliff:g> слика се премешта у отпад…}}"</string>
<string name="permission_trash_generic" msgid="5545420534785075362">"{count,plural, =1{Желите ли да дозволите да <xliff:g id="APP_NAME_0">^1</xliff:g> премести ову ставку у отпад?}one{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> ставку у отпад?}few{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> ставке у отпад?}other{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> ставки у отпад?}}"</string>
<string name="permission_progress_trash_generic" msgid="7815124979717814057">"{count,plural, =1{Ставка се премешта у отпад…}one{<xliff:g id="COUNT">^1</xliff:g> ставка се премешта у отпад…}few{<xliff:g id="COUNT">^1</xliff:g> ставке се премештају у отпад…}other{<xliff:g id="COUNT">^1</xliff:g> ставки се премешта у отпад…}}"</string>
<string name="permission_untrash_audio" msgid="8404597563284002472">"{count,plural, =1{Желите ли да дозволите да <xliff:g id="APP_NAME_0">^1</xliff:g> премести овај аудио фајл из отпада?}one{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> аудио фајл из отпада?}few{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> аудио фајла из отпада?}other{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> аудио фајлова из отпада?}}"</string>
<string name="permission_progress_untrash_audio" msgid="2775372344946464508">"{count,plural, =1{Аудио фајл се премешта из отпада…}one{<xliff:g id="COUNT">^1</xliff:g> аудио фајл се премешта из отпада…}few{<xliff:g id="COUNT">^1</xliff:g> аудио фајла се премештају из отпада…}other{<xliff:g id="COUNT">^1</xliff:g> аудио фајлова се премешта из отпада…}}"</string>
- <string name="permission_untrash_video" msgid="3178914827607608162">"{count,plural, =1{Желите ли да дозволите да <xliff:g id="APP_NAME_0">^1</xliff:g> премести овај видео из отпада?}one{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> видео из отпада?}few{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> видео снимка из отпада?}other{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> видео снимака из отпада?}}"</string>
- <string name="permission_progress_untrash_video" msgid="5500929409733841567">"{count,plural, =1{Видео се премешта из отпада…}one{<xliff:g id="COUNT">^1</xliff:g> видео се премешта из отпада…}few{<xliff:g id="COUNT">^1</xliff:g> видео снимка се премештају из отпада…}other{<xliff:g id="COUNT">^1</xliff:g> видео снимака се премешта из отпада…}}"</string>
+ <string name="permission_untrash_video" msgid="3178914827607608162">"{count,plural, =1{Желите ли да дозволите да <xliff:g id="APP_NAME_0">^1</xliff:g> премести овај видео из отпада?}one{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> видео из отпада?}few{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> видео снимка из отпада?}other{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> видеа из отпада?}}"</string>
+ <string name="permission_progress_untrash_video" msgid="5500929409733841567">"{count,plural, =1{Видео се премешта из отпада…}one{<xliff:g id="COUNT">^1</xliff:g> видео се премешта из отпада…}few{<xliff:g id="COUNT">^1</xliff:g> видео снимка се премештају из отпада…}other{<xliff:g id="COUNT">^1</xliff:g> видеа се премешта из отпада…}}"</string>
<string name="permission_untrash_image" msgid="3397523279351032265">"{count,plural, =1{Желите ли да дозволите да <xliff:g id="APP_NAME_0">^1</xliff:g> премести ову слику из отпада?}one{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> слику из отпада?}few{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> слике из отпада?}other{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> слика из отпада?}}"</string>
<string name="permission_progress_untrash_image" msgid="5295061520504846264">"{count,plural, =1{Слика се премешта из отпада…}one{<xliff:g id="COUNT">^1</xliff:g> слика се премешта из отпада…}few{<xliff:g id="COUNT">^1</xliff:g> слике се премештају из отпада…}other{<xliff:g id="COUNT">^1</xliff:g> слика се премешта из отпада…}}"</string>
<string name="permission_untrash_generic" msgid="2118366929431671046">"{count,plural, =1{Желите ли да дозволите да <xliff:g id="APP_NAME_0">^1</xliff:g> премести ову ставку из отпада?}one{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> ставку из отпада?}few{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> ставке из отпада?}other{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> премести <xliff:g id="COUNT">^2</xliff:g> ставки из отпада?}}"</string>
<string name="permission_progress_untrash_generic" msgid="1489511601966842579">"{count,plural, =1{Ставка се премешта из отпада…}one{<xliff:g id="COUNT">^1</xliff:g> ставка се премешта из отпада…}few{<xliff:g id="COUNT">^1</xliff:g> ставке се премештају из отпада…}other{<xliff:g id="COUNT">^1</xliff:g> ставки се премешта из отпада…}}"</string>
<string name="permission_delete_audio" msgid="3326674742892796627">"{count,plural, =1{Желите ли да дозволите да <xliff:g id="APP_NAME_0">^1</xliff:g> избрише овај аудио фајл?}one{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> избрише <xliff:g id="COUNT">^2</xliff:g> аудио фајл?}few{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> избрише <xliff:g id="COUNT">^2</xliff:g> аудио фајла?}other{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> избрише <xliff:g id="COUNT">^2</xliff:g> аудио фајлова?}}"</string>
<string name="permission_progress_delete_audio" msgid="1734871539021696401">"{count,plural, =1{Брише се аудио фајл…}one{Брише се <xliff:g id="COUNT">^1</xliff:g> аудио фајл…}few{Бришу се <xliff:g id="COUNT">^1</xliff:g> аудио фајла…}other{Брише се <xliff:g id="COUNT">^1</xliff:g> аудио фајлова…}}"</string>
- <string name="permission_delete_video" msgid="604024971828349279">"{count,plural, =1{Желите ли да дозволите да <xliff:g id="APP_NAME_0">^1</xliff:g> избрише овај видео?}one{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> избрише <xliff:g id="COUNT">^2</xliff:g> видео?}few{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> избрише <xliff:g id="COUNT">^2</xliff:g> видео снимка?}other{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> избрише <xliff:g id="COUNT">^2</xliff:g> видео снимака?}}"</string>
- <string name="permission_progress_delete_video" msgid="1846702435073793157">"{count,plural, =1{Брише се видео…}one{Брише се <xliff:g id="COUNT">^1</xliff:g> видео…}few{Бришу се <xliff:g id="COUNT">^1</xliff:g> видео снимка…}other{Брише се <xliff:g id="COUNT">^1</xliff:g> видео снимака…}}"</string>
+ <string name="permission_delete_video" msgid="604024971828349279">"{count,plural, =1{Желите ли да дозволите да <xliff:g id="APP_NAME_0">^1</xliff:g> избрише овај видео?}one{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> избрише <xliff:g id="COUNT">^2</xliff:g> видео?}few{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> избрише <xliff:g id="COUNT">^2</xliff:g> видео снимка?}other{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> избрише <xliff:g id="COUNT">^2</xliff:g> видеа?}}"</string>
+ <string name="permission_progress_delete_video" msgid="1846702435073793157">"{count,plural, =1{Брише се видео…}one{Брише се <xliff:g id="COUNT">^1</xliff:g> видео…}few{Бришу се <xliff:g id="COUNT">^1</xliff:g> видео снимка…}other{Брише се <xliff:g id="COUNT">^1</xliff:g> видеа…}}"</string>
<string name="permission_delete_image" msgid="3109056012794330510">"{count,plural, =1{Желите ли да дозволите да <xliff:g id="APP_NAME_0">^1</xliff:g> избрише ову слику?}one{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> избрише <xliff:g id="COUNT">^2</xliff:g> слику?}few{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> избрише <xliff:g id="COUNT">^2</xliff:g> слике?}other{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> избрише <xliff:g id="COUNT">^2</xliff:g> слика?}}"</string>
<string name="permission_progress_delete_image" msgid="8580517204901148906">"{count,plural, =1{Брише се слика…}one{Брише се <xliff:g id="COUNT">^1</xliff:g> слика…}few{Бришу се <xliff:g id="COUNT">^1</xliff:g> слике…}other{Брише се <xliff:g id="COUNT">^1</xliff:g> слика…}}"</string>
<string name="permission_delete_generic" msgid="7891939881065520271">"{count,plural, =1{Желите ли да дозволите да <xliff:g id="APP_NAME_0">^1</xliff:g> избрише ову ставку?}one{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> избрише <xliff:g id="COUNT">^2</xliff:g> ставку?}few{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> избрише <xliff:g id="COUNT">^2</xliff:g> ставке?}other{Желите ли да дозволите да <xliff:g id="APP_NAME_1">^1</xliff:g> избрише <xliff:g id="COUNT">^2</xliff:g> ставки?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Сигурносна заштита"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Обавештења о основном транскодирању"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Ток основног транскодирања"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Учитавање неких слика није успело"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Важи"</string>
</resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 8f1ca526d..631e436f7 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Media"</string>
<string name="storage_description" msgid="4081716890357580107">"Lokal lagring"</string>
<string name="app_label" msgid="9035307001052716210">"Medialagring"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Media"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Medieväljaren"</string>
<string name="artist_label" msgid="8105600993099120273">"Artist"</string>
<string name="unknown" msgid="2059049215682829375">"Okänd"</string>
<string name="root_images" msgid="5861633549189045666">"Bilder"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Få tillgång till media i molnet från"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Inga"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Det går inte att byta molnmedieapp just nu."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Medieväljaren"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Medieväljaren"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Synkroniserar media …"</string>
<string name="add" msgid="2894574044585549298">"Lägg till"</string>
<string name="deselect" msgid="4297825044827769490">"Avmarkera"</string>
<string name="deselected" msgid="8488133193326208475">"Avmarkerad"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Kontrollera internetanslutningen och försök igen"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Försök igen"</string>
<string name="not_selected" msgid="2244008151669896758">"inte valt"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Din valda media förbereds"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> av <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> är redo"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Säkerhetskopierade foton tas nu med"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Du kan välja foton från <xliff:g id="APP_NAME">%1$s</xliff:g>-kontot <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Välj app"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Välj konto"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Byt konto"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Läser in alla dina foton"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Vill du tillåta att <xliff:g id="APP_NAME_0">^1</xliff:g> ändrar den här ljudfilen?}other{Vill du tillåta att <xliff:g id="APP_NAME_1">^1</xliff:g> ändrar <xliff:g id="COUNT">^2</xliff:g> ljudfiler?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Ljudfilen ändras …}other{<xliff:g id="COUNT">^1</xliff:g> ljudfiler ändras …}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Vill du tillåta att <xliff:g id="APP_NAME_0">^1</xliff:g> ändrar den här videon?}other{Vill du tillåta att <xliff:g id="APP_NAME_1">^1</xliff:g> ändrar <xliff:g id="COUNT">^2</xliff:g> videor?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Säkerhet"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Omkodningsvarningar för Native"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Omkodningsförlopp för Native"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Det gick inte att läsa in vissa foton"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"OK"</string>
</resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 5cccb81cd..7e7f22aa5 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Maudhui"</string>
<string name="storage_description" msgid="4081716890357580107">"Hifadhi ya ndani"</string>
<string name="app_label" msgid="9035307001052716210">"Hifadhi ya Maudhui"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Maudhui"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Kiteua maudhui"</string>
<string name="artist_label" msgid="8105600993099120273">"Msanii"</string>
<string name="unknown" msgid="2059049215682829375">"Isiyojulikana"</string>
<string name="root_images" msgid="5861633549189045666">"Picha"</string>
@@ -39,13 +39,16 @@
<string name="allow" msgid="8885707816848569619">"Ruhusu"</string>
<string name="deny" msgid="6040983710442068936">"Kataa"</string>
<string name="picker_browse" msgid="5554477454636075934">"Vinjari…"</string>
- <string name="picker_settings" msgid="6443463167344790260">"Programu ya maudhui ya Wingu"</string>
- <string name="picker_settings_system_settings_menu_title" msgid="3055084757610063581">"Programu ya maudhui ya Wingu"</string>
- <string name="picker_settings_title" msgid="5647700706470673258">"Programu ya maudhui ya kwenye wingu"</string>
+ <string name="picker_settings" msgid="6443463167344790260">"Programu ya maudhui ya wingu"</string>
+ <string name="picker_settings_system_settings_menu_title" msgid="3055084757610063581">"Programu ya maudhui ya wingu"</string>
+ <string name="picker_settings_title" msgid="5647700706470673258">"Programu ya maudhui ya wingu"</string>
<string name="picker_settings_description" msgid="2916686824777214585">"Fikia maudhui kwenye wingu lako programu au tovuti inapokuomba uchague picha au video"</string>
<string name="picker_settings_selection_message" msgid="245453573086488596">"Fikia maudhui ya kwenye wingu katika"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Hamna"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Imeshindwa kubadilisha programu ya maudhui ya wingu kwa wakati huu."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Kiteua maudhui"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Kiteua maudhui"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Inasawazisha maudhui…"</string>
<string name="add" msgid="2894574044585549298">"Weka"</string>
<string name="deselect" msgid="4297825044827769490">"Acha kuchagua"</string>
<string name="deselected" msgid="8488133193326208475">"Umeacha kuchagua"</string>
@@ -60,8 +63,8 @@
<string name="picker_photos" msgid="7415035516411087392">"Picha"</string>
<string name="picker_albums" msgid="4822511902115299142">"Albamu"</string>
<string name="picker_preview" msgid="6257414886055861039">"Onyesho la kukagua"</string>
- <string name="picker_work_profile" msgid="2083221066869141576">"Badili uweke wasifu wa kazini"</string>
- <string name="picker_personal_profile" msgid="639484258397758406">"Badili uweke wasifu wa binafsi"</string>
+ <string name="picker_work_profile" msgid="2083221066869141576">"Badili utumie wasifu wa kazini"</string>
+ <string name="picker_personal_profile" msgid="639484258397758406">"Badili utumie wasifu wa binafsi"</string>
<string name="picker_profile_admin_title" msgid="4172022376418293777">"Umezuiwa na msimamizi wako"</string>
<string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"Huruhusiwi kufikia data ya kazini kwenye programu ya binafsi"</string>
<string name="picker_profile_admin_msg_from_work" msgid="8048524337462790110">"Huruhusiwi kufikia data binafsi kwenye programu ya kazini"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Angalia muunganisho wako wa intaneti na ujaribu tena"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Jaribu tena"</string>
<string name="not_selected" msgid="2244008151669896758">"haijachaguliwa"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Inaandaa maudhui yako uliyochagua"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> kati ya <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> ziko tayari"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Picha zilizohifadhiwa nakala zimejumuishwa sasa"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Unaweza kuchagua picha zilizotoka kwenye akaunti ya <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> katika programu ya <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Chagua programu"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Chagua akaunti"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Badilisha akaunti"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Inapakia picha zako zote"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Ungependa kuruhusu <xliff:g id="APP_NAME_0">^1</xliff:g> ibadilishe faili hii ya sauti?}other{Ungependa kuruhusu <xliff:g id="APP_NAME_1">^1</xliff:g> ibadilishe faili <xliff:g id="COUNT">^2</xliff:g> za sauti?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Inarekebisha faili ya sauti…}other{Inarekebisha faili <xliff:g id="COUNT">^1</xliff:g> za sauti…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Ungependa kuruhusu <xliff:g id="APP_NAME_0">^1</xliff:g> ibadilishe video hii?}other{Ungependa kuruhusu <xliff:g id="APP_NAME_1">^1</xliff:g> ibadilishe video <xliff:g id="COUNT">^2</xliff:g>?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Ulinzi wa Usalama"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Arifa za Ubadilishaji Asilia wa Muundo wa Faili"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Maendeleo ya Ubadilishaji Asilia wa Muundo wa Faili"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Imeshindwa kupakia baadhi ya Picha"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Nimeelewa"</string>
</resources>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index 1241a5dd1..2e84a7834 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/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="picker_app_label" msgid="4254039089502164761">"மீடியா"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"மீடியா தேர்வுக் கருவி"</string>
<string name="artist_label" msgid="8105600993099120273">"கலைஞர்"</string>
<string name="unknown" msgid="2059049215682829375">"அறியாதது"</string>
<string name="root_images" msgid="5861633549189045666">"Images"</string>
@@ -46,12 +46,15 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"கிளவுட் மீடியாவை இதிலிருந்து அணுகும்"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"எதுவுமில்லை"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"இப்போது கிளவுடு மீடியா ஆப்ஸை மாற்ற முடியாது"</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"மீடியா தேர்வுக் கருவி"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"மீடியா தேர்வுக் கருவி"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"மீடியாவை ஒத்திசைக்கிறது…"</string>
<string name="add" msgid="2894574044585549298">"சேர்"</string>
<string name="deselect" msgid="4297825044827769490">"தேர்வுநீக்கு"</string>
<string name="deselected" msgid="8488133193326208475">"தேர்வுநீக்கப்பட்டது"</string>
<string name="select" msgid="2704765470563027689">"தேர்ந்தெடு"</string>
<string name="selected" msgid="9151797369975828124">"தேர்ந்தெடுக்கப்பட்டது"</string>
- <string name="select_up_to" msgid="6994294169508439957">"{count,plural, =1{<xliff:g id="COUNT_0">^1</xliff:g> படத்தைத் தேர்ந்தெடுங்கள்}other{<xliff:g id="COUNT_1">^1</xliff:g> படங்களைத் தேர்ந்தெடுங்கள்}}"</string>
+ <string name="select_up_to" msgid="6994294169508439957">"{count,plural, =1{<xliff:g id="COUNT_0">^1</xliff:g> படத்தைத் தேர்ந்தெடுங்கள்}other{<xliff:g id="COUNT_1">^1</xliff:g> படங்கள் வரை தேர்ந்தெடுங்கள்}}"</string>
<string name="recent" msgid="6694613584743207874">"சமீபத்தியவை"</string>
<string name="picker_photos_empty_message" msgid="5980619500554575558">"படங்களோ வீடியோக்களோ இல்லை"</string>
<string name="picker_album_media_empty_message" msgid="7061850698189881671">"ஆதரிக்கப்படும் படங்களோ வீடியோக்களோ இல்லை"</string>
@@ -93,9 +96,10 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"உங்கள் இணைய இணைப்பைச் சரிபார்த்துவிட்டு மீண்டும் முயலவும்"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"மீண்டும் முயல்க"</string>
<string name="not_selected" msgid="2244008151669896758">"தேர்ந்தெடுக்கப்படவில்லை"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"நீங்கள் தேர்ந்தெடுத்த மீடியா தயாராகிறது"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> / <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> தயாராக உள்ளது"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"காப்புப் பிரதி எடுக்கப்பட்ட படங்கள் இப்போது சேர்க்கப்பட்டுள்ளன"</string>
- <string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸிலிருந்தும் <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> கணக்கிலிருந்தும் படங்களைத் தேர்ந்தெடுக்கலாம்"</string>
+ <string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸில் <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> கணக்கிலிருந்தும் படங்களைத் தேர்ந்தெடுக்கலாம்"</string>
<string name="picker_banner_cloud_account_changed_title" msgid="4825058474378077327">"<xliff:g id="APP_NAME">%1$s</xliff:g> கணக்கு புதுப்பிக்கப்பட்டது"</string>
<string name="picker_banner_cloud_account_changed_desc" msgid="3433218869899792497">"<xliff:g id="USER_ACCOUNT">%1$s</xliff:g> கணக்கிலிருந்த படங்களும் இப்போது சேர்க்கப்பட்டுள்ளன"</string>
<string name="picker_banner_cloud_choose_app_title" msgid="3165966147547974251">"கிளவுட் மீடியா ஆப்ஸைத் தேர்வுசெய்தல்"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"ஆப்ஸைத் தேர்வுசெய்க"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"கணக்கைத் தேர்வுசெய்க"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"கணக்கை மாற்று"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"உங்கள் படங்கள் அனைத்தையும் பெறுகிறது"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{இந்த ஆடியோ ஃபைலில் மாற்றங்களைச் செய்ய <xliff:g id="APP_NAME_0">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?}other{<xliff:g id="COUNT">^2</xliff:g> ஆடியோ ஃபைல்களில் மாற்றங்களைச் செய்ய <xliff:g id="APP_NAME_1">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{ஆடியோ ஃபைலை மாற்றியமைக்கிறது…}other{<xliff:g id="COUNT">^1</xliff:g> ஆடியோ ஃபைல்களை மாற்றியமைக்கிறது…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{இந்த வீடியோவில் மாற்றங்களைச் செய்ய <xliff:g id="APP_NAME_0">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?}other{<xliff:g id="COUNT">^2</xliff:g> வீடியோக்களில் மாற்றங்களைச் செய்ய <xliff:g id="APP_NAME_1">^1</xliff:g> ஆப்ஸை அனுமதிக்கவா?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"பாதுகாப்பு வளையம்"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"நேட்டிவ் குறிமாற்ற விழிப்பூட்டல்கள்"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"நேட்டிவ் குறிமாற்றச் செயல்நிலை"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"சில படங்களைப் பதிவேற்ற முடியவில்லை"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"சரி"</string>
</resources>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index da65034f9..4da3c57a5 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/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="picker_app_label" msgid="4254039089502164761">"మీడియా"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"మీడియా సెలెక్టర్"</string>
<string name="artist_label" msgid="8105600993099120273">"కళాకారుడు"</string>
<string name="unknown" msgid="2059049215682829375">"తెలియదు"</string>
<string name="root_images" msgid="5861633549189045666">"ఇమేజ్‌లు"</string>
@@ -46,9 +46,12 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"దాని నుండి క్లౌడ్ మీడియాను యాక్సెస్ చేయండి"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"ఏవీ లేవు"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"ఈ సమయంలో క్లౌడ్ మీడియా యాప్ మార్చడం సాధ్యపడలేదు."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"మీడియా సెలెక్టర్"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"మీడియా సెలెక్టర్"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"మీడియాను సింక్ చేస్తోంది…"</string>
<string name="add" msgid="2894574044585549298">"జోడించండి"</string>
<string name="deselect" msgid="4297825044827769490">"ఎంపికను తొలగించండి"</string>
- <string name="deselected" msgid="8488133193326208475">"ఎంపికను తొలగించండి"</string>
+ <string name="deselected" msgid="8488133193326208475">"ఎంపిక తొలగించబడింది"</string>
<string name="select" msgid="2704765470563027689">"ఎంచుకోండి"</string>
<string name="selected" msgid="9151797369975828124">"ఎంచుకోబడింది"</string>
<string name="select_up_to" msgid="6994294169508439957">"{count,plural, =1{గరిష్ఠంగా <xliff:g id="COUNT_0">^1</xliff:g> ఐటెమ్‌ను ఎంచుకోండి}other{గరిష్ఠంగా <xliff:g id="COUNT_1">^1</xliff:g> ఐటెమ్‌లను ఎంచుకోండి}}"</string>
@@ -60,7 +63,7 @@
<string name="picker_photos" msgid="7415035516411087392">"ఫోటోలు"</string>
<string name="picker_albums" msgid="4822511902115299142">"ఆల్బమ్‌లు"</string>
<string name="picker_preview" msgid="6257414886055861039">"ప్రివ్యూ"</string>
- <string name="picker_work_profile" msgid="2083221066869141576">"ఆఫీస్ ప్రొఫైల్‌కు మార్చండి"</string>
+ <string name="picker_work_profile" msgid="2083221066869141576">"వర్క్ ప్రొఫైల్‌కు మార్చండి"</string>
<string name="picker_personal_profile" msgid="639484258397758406">"వ్యక్తిగత ప్రొఫైల్‌కు మార్చండి"</string>
<string name="picker_profile_admin_title" msgid="4172022376418293777">"మీ అడ్మిన్ బ్లాక్ చేశారు"</string>
<string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"వ్యక్తిగత యాప్ నుండి వర్క్ డేటాను యాక్సెస్ చేయడం అనుమతించబడదు"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"మీ ఇంటర్నెట్ కనెక్షన్‌ను చెక్ చేసి, మళ్ళీ ట్రై చేయండి"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"మళ్లీ ట్రై చేయండి"</string>
<string name="not_selected" msgid="2244008151669896758">"ఎంచుకోబడలేదు"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"మీరు ఎంచుకున్న మీడియాను సిద్ధం చేస్తోంది"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>లో <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> సిద్ధంగా ఉన్నాయి"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"బ్యాకప్ చేసిన ఫోటోలు ఇప్పుడు చేర్చబడ్డాయి"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"మీరు <xliff:g id="APP_NAME">%1$s</xliff:g> ఖాతా <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> నుండి ఫోటోలను ఎంచుకోవచ్చు"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"యాప్‌ను ఎంచుకోండి"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"ఖాతాను ఎంచుకోండి"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"ఖాతాను మార్చండి"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"మీ ఫోటోలన్నీ లోడ్ అవుతున్నాయి"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{ఈ ఆడియో ఫైల్‌ను ఎడిట్ చేయడానికి <xliff:g id="APP_NAME_0">^1</xliff:g>‌ను అనుమతించాలా?}other{<xliff:g id="COUNT">^2</xliff:g> ఆడియో ఫైళ్లను ఎడిట్ చేయడానికి <xliff:g id="APP_NAME_1">^1</xliff:g>‌ను అనుమతించాలా?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{ఆడియో ఫైల్‌ను సవరిస్తోంది…}other{<xliff:g id="COUNT">^1</xliff:g> ఆడియో ఫైళ్లను సవరిస్తోంది…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{ఈ వీడియోను ఎడిట్ చేయడానికి <xliff:g id="APP_NAME_0">^1</xliff:g>‌ను అనుమతించాలా?}other{<xliff:g id="COUNT">^2</xliff:g> వీడియోలను ఎడిట్ చేయడానికి <xliff:g id="APP_NAME_1">^1</xliff:g>‌ను అనుమతించాలా?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"భద్రత రక్షణ"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"స్థానిక ట్రాన్స్‌కోడ్ అలర్ట్‌లు"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"స్థానిక ట్రాన్స్‌కోడ్ ప్రోగ్రెస్"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"కొన్ని ఫోటోలను లోడ్ చేయడం సాధ్యపడదు"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"సరే"</string>
</resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 10ee54691..8a0ebf5ee 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/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="picker_app_label" msgid="4254039089502164761">"สื่อ"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"เครื่องมือเลือกสื่อ"</string>
<string name="artist_label" msgid="8105600993099120273">"ศิลปิน"</string>
<string name="unknown" msgid="2059049215682829375">"ไม่ทราบ"</string>
<string name="root_images" msgid="5861633549189045666">"รูปภาพ"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"เข้าถึงสื่อในระบบคลาวด์จาก"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"ไม่มี"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"เปลี่ยนแอปสื่อบนระบบคลาวด์ไม่ได้ในขณะนี้"</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"เครื่องมือเลือกสื่อ"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"เครื่องมือเลือกสื่อ"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"กำลังซิงค์สื่อ…"</string>
<string name="add" msgid="2894574044585549298">"เพิ่ม"</string>
<string name="deselect" msgid="4297825044827769490">"ยกเลิกการเลือก"</string>
<string name="deselected" msgid="8488133193326208475">"ยกเลิกการเลือก"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"ตรวจสอบการเชื่อมต่ออินเทอร์เน็ตและลองอีกครั้ง"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"ลองใหม่"</string>
<string name="not_selected" msgid="2244008151669896758">"ไม่ได้เลือกไว้"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"กำลังเตรียมสื่อที่คุณเลือก"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"พร้อมแล้ว <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> จาก <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"รวมรูปภาพที่สำรองข้อมูลไว้แล้ว"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"คุณเลือกรูปภาพได้จากบัญชี <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> ของ \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"เลือกแอป"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"เลือกบัญชี"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"เปลี่ยนบัญชี"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"กำลังโหลดรูปภาพทั้งหมด"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{อนุญาตให้ <xliff:g id="APP_NAME_0">^1</xliff:g> แก้ไขไฟล์เสียงนี้ไหม}other{อนุญาตให้ <xliff:g id="APP_NAME_1">^1</xliff:g> แก้ไขไฟล์เสียง <xliff:g id="COUNT">^2</xliff:g> ไฟล์ไหม}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{กำลังแก้ไขไฟล์เสียง…}other{กำลังแก้ไขไฟล์เสียง <xliff:g id="COUNT">^1</xliff:g> ไฟล์…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{อนุญาตให้ <xliff:g id="APP_NAME_0">^1</xliff:g> แก้ไขวิดีโอนี้ไหม}other{อนุญาตให้ <xliff:g id="APP_NAME_1">^1</xliff:g> แก้ไขวิดีโอ <xliff:g id="COUNT">^2</xliff:g> รายการไหม}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"การปกป้องเพื่อความปลอดภัย"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Native Transcode Alerts"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Native Transcode Progress"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"โหลดรูปภาพบางรูปไม่ได้"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"รับทราบ"</string>
</resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 25f6d5302..fa6edae70 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Media"</string>
<string name="storage_description" msgid="4081716890357580107">"Lokal na storage"</string>
<string name="app_label" msgid="9035307001052716210">"Storage ng Media"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Media"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Tagapili ng media"</string>
<string name="artist_label" msgid="8105600993099120273">"Artist"</string>
<string name="unknown" msgid="2059049215682829375">"Hindi alam"</string>
<string name="root_images" msgid="5861633549189045666">"Mga Larawan"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"I-access ang cloud media sa"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Wala"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Hindi mapalitan ang cloud media app sa ngayon."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Tagapili ng media"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Tagapili ng media"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Sini-sync ang media…"</string>
<string name="add" msgid="2894574044585549298">"Magdagdag"</string>
<string name="deselect" msgid="4297825044827769490">"I-deselect"</string>
<string name="deselected" msgid="8488133193326208475">"Na-deselect"</string>
@@ -57,7 +60,7 @@
<string name="picker_album_media_empty_message" msgid="7061850698189881671">"Walang sinusuportahang larawan o video"</string>
<string name="picker_albums_empty_message" msgid="8341079772950966815">"Walang album"</string>
<string name="picker_view_selected" msgid="2266031384396143883">"Tingnan ang napili"</string>
- <string name="picker_photos" msgid="7415035516411087392">"Photos"</string>
+ <string name="picker_photos" msgid="7415035516411087392">"Mga Larawan"</string>
<string name="picker_albums" msgid="4822511902115299142">"Mga Album"</string>
<string name="picker_preview" msgid="6257414886055861039">"Preview"</string>
<string name="picker_work_profile" msgid="2083221066869141576">"Lumipat sa para sa trabaho"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Tingnan ang iyong koneksyon sa internet at subukan ulit"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Subukan ulit"</string>
<string name="not_selected" msgid="2244008151669896758">"hindi pinili"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Inihahanda ang napili mong media"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"Handa na ang <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> sa <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Kasama na ngayon ang mga na-back up na larawan"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Puwede kang pumili ng mga larawan mula sa <xliff:g id="APP_NAME">%1$s</xliff:g> account na <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Pumili ng app"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Pumili ng account"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Magpalit ng account"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Kinukuha ang lahat ng iyong larawan"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Payagan ang <xliff:g id="APP_NAME_0">^1</xliff:g> na baguhin ang audio file na ito?}one{Payagan ang <xliff:g id="APP_NAME_1">^1</xliff:g> na baguhin ang <xliff:g id="COUNT">^2</xliff:g> audio file?}other{Payagan ang <xliff:g id="APP_NAME_1">^1</xliff:g> na baguhin ang <xliff:g id="COUNT">^2</xliff:g> na audio file?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Binabago ang audio file…}one{Nagbabago ng <xliff:g id="COUNT">^1</xliff:g> audio file…}other{Nagbabago ng <xliff:g id="COUNT">^1</xliff:g> na audio file…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Payagan ang <xliff:g id="APP_NAME_0">^1</xliff:g> na baguhin ang video na ito?}one{Payagan ang <xliff:g id="APP_NAME_1">^1</xliff:g> na baguhin ang <xliff:g id="COUNT">^2</xliff:g> video?}other{Payagan ang <xliff:g id="APP_NAME_1">^1</xliff:g> na baguhin ang <xliff:g id="COUNT">^2</xliff:g> na video?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Proteksyon sa kaligtasan"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Native Transcode Alerts"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Native Transcode Progress"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Hindi ma-load ang ilang Larawan"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"OK"</string>
</resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 1a5101644..d7ff137b1 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Medya"</string>
<string name="storage_description" msgid="4081716890357580107">"Yerel depolama"</string>
<string name="app_label" msgid="9035307001052716210">"Medya Deposu"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Medya"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Medya seçme aracı"</string>
<string name="artist_label" msgid="8105600993099120273">"Sanatçı"</string>
<string name="unknown" msgid="2059049215682829375">"Bilinmiyor"</string>
<string name="root_images" msgid="5861633549189045666">"Resimler"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Şuradaki bulut medyasına erişin"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Yok"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Bulut medya uygulaması şu anda değiştirilemiyor."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Medya seçme aracı"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Medya seçme aracı"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Medya senkronize ediliyor…"</string>
<string name="add" msgid="2894574044585549298">"Ekle"</string>
<string name="deselect" msgid="4297825044827769490">"Seçimi kaldır"</string>
<string name="deselected" msgid="8488133193326208475">"Seçimi kaldırıldı"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"İnternet bağlantınızı kontrol edip tekrar deneyin"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Tekrar dene"</string>
<string name="not_selected" msgid="2244008151669896758">"seçili değil"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Seçtiğiniz medyalar hazırlanıyor"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> adetten <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> adedi hazır"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Yedeklenen fotoğraflar artık dahil ediliyor"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasındaki <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> hesabından fotoğraf seçebilirsiniz"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Uygulama seç"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Hesap seç"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Hesabı değiştir"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Tüm fotoğraflarınız alınıyor"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> uygulamasının bu ses dosyasını değiştirmesine izin verilsin mi?}other{<xliff:g id="APP_NAME_1">^1</xliff:g> uygulamasının <xliff:g id="COUNT">^2</xliff:g> ses dosyasını değiştirmesine izin verilsin mi?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Ses dosyası değiştiriliyor…}other{<xliff:g id="COUNT">^1</xliff:g> ses dosyası değiştiriliyor…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> uygulamasının bu videoyu değiştirmesine izin verilsin mi?}other{<xliff:g id="APP_NAME_1">^1</xliff:g> uygulamasının <xliff:g id="COUNT">^2</xliff:g> videoyu değiştirmesine izin verilsin mi?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Güvenlik koruması"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Yerel Kod Dönüştürme Uyarıları"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Yerel Kod Dönüştürme İlerleme Durumu"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Bazı fotoğraflar yüklenemiyor"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Anladım"</string>
</resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 6706539b2..cce673b45 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/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="picker_app_label" msgid="4254039089502164761">"Медіа"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Інструмент вибору медіаносія"</string>
<string name="artist_label" msgid="8105600993099120273">"Виконавець"</string>
<string name="unknown" msgid="2059049215682829375">"Невідомо"</string>
<string name="root_images" msgid="5861633549189045666">"Зображення"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Постачальник медіаконтенту з хмари"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Немає"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Не вдалося змінити хмарний мультимедійний додаток."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Інструмент вибору медіаносія"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Інструмент вибору медіаносія"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Синхронізація медіаносіїв…"</string>
<string name="add" msgid="2894574044585549298">"Додати"</string>
<string name="deselect" msgid="4297825044827769490">"Не вибирати"</string>
<string name="deselected" msgid="8488133193326208475">"Не вибрано"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Перевірте інтернет-з’єднання й повторіть спробу"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Повторити"</string>
<string name="not_selected" msgid="2244008151669896758">"не вибрано"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Підготовка вибраних медіафайлів"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"Готово: <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> з <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g>"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Резервні копії фотографій додано"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Ви можете вибрати фотографії з облікового запису <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> у додатку <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Вибрати додаток"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Вибрати обліковий запис"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Змінити обліковий запис"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Завантажуються всі ваші фото"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Дозволити додатку <xliff:g id="APP_NAME_0">^1</xliff:g> змінити цей аудіофайл?}one{Дозволити додатку <xliff:g id="APP_NAME_1">^1</xliff:g> змінити <xliff:g id="COUNT">^2</xliff:g> аудіофайл?}few{Дозволити додатку <xliff:g id="APP_NAME_1">^1</xliff:g> змінити <xliff:g id="COUNT">^2</xliff:g> аудіофайли?}many{Дозволити додатку <xliff:g id="APP_NAME_1">^1</xliff:g> змінити <xliff:g id="COUNT">^2</xliff:g> аудіофайлів?}other{Дозволити додатку <xliff:g id="APP_NAME_1">^1</xliff:g> змінити <xliff:g id="COUNT">^2</xliff:g> аудіофайлу?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Змінення аудіофайлу…}one{Змінення <xliff:g id="COUNT">^1</xliff:g> аудіофайлу…}few{Змінення <xliff:g id="COUNT">^1</xliff:g> аудіофайлів…}many{Змінення <xliff:g id="COUNT">^1</xliff:g> аудіофайлів…}other{Змінення <xliff:g id="COUNT">^1</xliff:g> аудіофайлу…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Дозволити додатку <xliff:g id="APP_NAME_0">^1</xliff:g> змінити це відео?}one{Дозволити додатку <xliff:g id="APP_NAME_1">^1</xliff:g> змінити <xliff:g id="COUNT">^2</xliff:g> відео?}few{Дозволити додатку <xliff:g id="APP_NAME_1">^1</xliff:g> змінити <xliff:g id="COUNT">^2</xliff:g> відео?}many{Дозволити додатку <xliff:g id="APP_NAME_1">^1</xliff:g> змінити <xliff:g id="COUNT">^2</xliff:g> відео?}other{Дозволити додатку <xliff:g id="APP_NAME_1">^1</xliff:g> змінити <xliff:g id="COUNT">^2</xliff:g> відео?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Захист"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Cповіщення про перекодування нативного коду"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Перебіг перекодування нативного коду"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Не вдається завантажити деякі фотографії"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"OK"</string>
</resources>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index 1206ef52a..fff4f4d4c 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/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="picker_app_label" msgid="4254039089502164761">"میڈیا"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"میڈیا منتخب کنندہ"</string>
<string name="artist_label" msgid="8105600993099120273">"فنکار"</string>
<string name="unknown" msgid="2059049215682829375">"نامعلوم"</string>
<string name="root_images" msgid="5861633549189045666">"تصاوير"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"اس سے کلاؤڈ میڈیا تک رسائی حاصل کریں"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"کوئی نہیں"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"کلاؤڈ میڈیا ایپ کو اس وقت تبدیل نہیں کیا جا سکا۔"</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"میڈیا منتخب کنندہ"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"میڈیا منتخب کنندہ"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"میڈیا کی مطابقت پذیری کی جا رہی ہے…"</string>
<string name="add" msgid="2894574044585549298">"شامل کریں"</string>
<string name="deselect" msgid="4297825044827769490">"غیر منتخب کریں"</string>
<string name="deselected" msgid="8488133193326208475">"غیر منتخب کردہ"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"اپنا انٹرنیٹ کنکشن چیک کریں اور دوبارہ کوشش کریں"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"پھر کوشش کریں"</string>
<string name="not_selected" msgid="2244008151669896758">"غیر منتخب کردہ"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"آپ کا منتخب کردہ میڈیا تیار کیا جا رہا ہے"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> میں سے <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> تیار ہیں"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"بیک اپ لی گئی تصاویر اب شامل ہیں"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"آپ <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> کے <xliff:g id="APP_NAME">%1$s</xliff:g> اکاؤنٹ سے تصاویر منتخب کر سکتے ہیں"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"ایپ منتخب کریں"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"اکاؤنٹ منتخب کریں"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"اکاؤنٹ تبدیل کریں"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"آپ کی تمام تصاویر حاصل کی جا رہی ہیں"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> کو اس آڈیو فائل میں ترمیم کرنے کی اجازت دیں؟}other{<xliff:g id="APP_NAME_1">^1</xliff:g> کو <xliff:g id="COUNT">^2</xliff:g> آڈیو فائلز میں ترمیم کرنے کی اجازت دیں؟}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{آڈیو فائل میں ترمیم کی جا رہی ہے…}other{<xliff:g id="COUNT">^1</xliff:g> آڈیو فائلز میں ترمیم کی جا رہی ہے…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> کو اس ویڈیو میں ترمیم کرنے کی اجازت دیں؟}other{<xliff:g id="APP_NAME_1">^1</xliff:g> کو <xliff:g id="COUNT">^2</xliff:g> ویڈیوز میں ترمیم کرنے کی اجازت دیں؟}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"سیفٹی پروٹیکشن"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"مقامی ٹرانسکوڈ کے الرٹس"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"مقامی ٹرانسکوڈ کی پیشرفت"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"کچھ تصاویر لوڈ نہیں کی جا سکتیں"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"سمجھ آ گئی"</string>
</resources>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 3f7f2d877..8287f989b 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Multimedia"</string>
<string name="storage_description" msgid="4081716890357580107">"Mahalliy xotira"</string>
<string name="app_label" msgid="9035307001052716210">"Multimedia xotirasi"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Media"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Rasm tanlash"</string>
<string name="artist_label" msgid="8105600993099120273">"Ijrochi"</string>
<string name="unknown" msgid="2059049215682829375">"Noaniq"</string>
<string name="root_images" msgid="5861633549189045666">"Rasmlar"</string>
@@ -46,12 +46,15 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Bulutli media kontentni ochish"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Hech qanday"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Hozirda bulutli media ilovasi oʻzgarmadi"</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Rasm tanlash"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Rasm tanlash"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Media sinxronlanmoqda…"</string>
<string name="add" msgid="2894574044585549298">"Kiritish"</string>
<string name="deselect" msgid="4297825044827769490">"Tanlovni bekor qilish"</string>
<string name="deselected" msgid="8488133193326208475">"Tanlovi yechilgan"</string>
<string name="select" msgid="2704765470563027689">"Tanlash"</string>
<string name="selected" msgid="9151797369975828124">"Tanlangan"</string>
- <string name="select_up_to" msgid="6994294169508439957">"{count,plural, =1{<xliff:g id="COUNT_0">^1</xliff:g> tagcha elementni tanlang}other{<xliff:g id="COUNT_1">^1</xliff:g> tagcha elementni tanlang}}"</string>
+ <string name="select_up_to" msgid="6994294169508439957">"{count,plural, =1{<xliff:g id="COUNT_0">^1</xliff:g> tagacha elementni tanlang}other{<xliff:g id="COUNT_1">^1</xliff:g> tagacha elementni tanlang}}"</string>
<string name="recent" msgid="6694613584743207874">"Oxirgi"</string>
<string name="picker_photos_empty_message" msgid="5980619500554575558">"Surat yoki video kiritilmagan"</string>
<string name="picker_album_media_empty_message" msgid="7061850698189881671">"Qabul qilinmaydigan rasm va videolar"</string>
@@ -60,8 +63,8 @@
<string name="picker_photos" msgid="7415035516411087392">"Suratlar"</string>
<string name="picker_albums" msgid="4822511902115299142">"Albomlar"</string>
<string name="picker_preview" msgid="6257414886055861039">"Razm solish"</string>
- <string name="picker_work_profile" msgid="2083221066869141576">"Ish profiliga oʻtish"</string>
- <string name="picker_personal_profile" msgid="639484258397758406">"Shaxsiy profilga oʻtish"</string>
+ <string name="picker_work_profile" msgid="2083221066869141576">"Ish profiliga almashish"</string>
+ <string name="picker_personal_profile" msgid="639484258397758406">"Shaxsiy profilga almashish"</string>
<string name="picker_profile_admin_title" msgid="4172022376418293777">"Administratoringiz tomonidan bloklangan"</string>
<string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"Shaxsiy ilovadan ishga oid maʼlumotlarga kirish taqiqlangan"</string>
<string name="picker_profile_admin_msg_from_work" msgid="8048524337462790110">"Ishga oid ilovadan shaxsiy maʼlumotlarga kirish taqiqlangan"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Internet aloqasini tekshiring va qayta urining"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Qayta urinish"</string>
<string name="not_selected" msgid="2244008151669896758">"tanlanmagan"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Tanlangan media tayyorlanmoqda"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g>/<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> tayyor"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Zaxiralangan suratlar qoʻshildi"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"<xliff:g id="USER_ACCOUNT">%2$s</xliff:g> hisobidagi <xliff:g id="APP_NAME">%1$s</xliff:g> rasmlarini tanlashingiz mumkin"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Ilovani tanlash"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Hisobni tanlang"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Hisobni almashtirish"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Barcha rasmlaringizni yuklab oling"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> ilovasiga bu audio faylni oʻzgartirishi uchun ruxsat berilsinmi?}other{<xliff:g id="APP_NAME_1">^1</xliff:g> ilovasiga <xliff:g id="COUNT">^2</xliff:g> ta audio faylni oʻzgartirishi uchun ruxsat berilsinmi?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Audio fayl oʻzgartirilmoqda…}other{<xliff:g id="COUNT">^1</xliff:g> ta audio fayl oʻzgartirilmoqda…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{<xliff:g id="APP_NAME_0">^1</xliff:g> ilovasiga bu videoni oʻzgartirishi uchun ruxsat berilsinmi?}other{<xliff:g id="APP_NAME_1">^1</xliff:g> ilovasiga <xliff:g id="COUNT">^2</xliff:g> ta videoni oʻzgartirishi uchun ruxsat berilsinmi?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Xavfsizlik himoyasi"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Nativ transkodlash signallari"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Nativ transkodlash jarayoni"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Ayrim suratlar yuklanmadi"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"OK"</string>
</resources>
diff --git a/res/values-v31/styles.xml b/res/values-v31/styles.xml
index 3dec1da72..85d3352e0 100644
--- a/res/values-v31/styles.xml
+++ b/res/values-v31/styles.xml
@@ -14,7 +14,8 @@
limitations under the License.
-->
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<style name="PickerMaterialTheme" parent="@style/Theme.Material3.DayNight.NoActionBar">
<item name="materialAlertDialogTheme">@style/ProfileDialogTheme</item>
@@ -40,6 +41,8 @@
<item name="pickerBannerPrimaryTextColor">?android:attr/textColorSecondary</item>
<item name="pickerBannerSecondaryTextColor">?android:attr/textColorPrimary</item>
<item name="pickerBannerButtonTextColor">@android:color/system_accent1_600</item>
+ <item name="categoryDefaultThumbnailColor">@android:color/system_accent1_300</item>
+ <item name="categoryDefaultThumbnailCircleColor">?androidprv:attr/materialColorSurfaceContainer</item>
</style>
</resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 471562e76..b2e077824 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Phương tiện"</string>
<string name="storage_description" msgid="4081716890357580107">"Bộ nhớ cục bộ"</string>
<string name="app_label" msgid="9035307001052716210">"Bộ nhớ phương tiện"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Nội dung nghe nhìn"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Công cụ chọn nội dung đa phương tiện"</string>
<string name="artist_label" msgid="8105600993099120273">"Nghệ sĩ"</string>
<string name="unknown" msgid="2059049215682829375">"Không xác định"</string>
<string name="root_images" msgid="5861633549189045666">"Hình ảnh"</string>
@@ -39,13 +39,16 @@
<string name="allow" msgid="8885707816848569619">"Cho phép"</string>
<string name="deny" msgid="6040983710442068936">"Từ chối"</string>
<string name="picker_browse" msgid="5554477454636075934">"Duyệt qua…"</string>
- <string name="picker_settings" msgid="6443463167344790260">"Ứng dụng đa phương tiện trên đám mây"</string>
- <string name="picker_settings_system_settings_menu_title" msgid="3055084757610063581">"Ứng dụng đa phương tiện trên đám mây"</string>
- <string name="picker_settings_title" msgid="5647700706470673258">"Ứng dụng nội dung phương tiện trên đám mây"</string>
- <string name="picker_settings_description" msgid="2916686824777214585">"Truy cập vào nội dung nghe nhìn trên đám mây của bạn khi ứng dụng hoặc trang web yêu cầu bạn chọn ảnh hoặc video"</string>
- <string name="picker_settings_selection_message" msgid="245453573086488596">"Truy cập nội dung phương tiện trên đám mây qua"</string>
+ <string name="picker_settings" msgid="6443463167344790260">"Ứng dụng nghe nhìn trên đám mây"</string>
+ <string name="picker_settings_system_settings_menu_title" msgid="3055084757610063581">"Ứng dụng nghe nhìn trên đám mây"</string>
+ <string name="picker_settings_title" msgid="5647700706470673258">"Ứng dụng nghe nhìn trên đám mây"</string>
+ <string name="picker_settings_description" msgid="2916686824777214585">"Truy cập vào nội dung nghe nhìn của bạn trên đám mây khi có ứng dụng hay trang web yêu cầu bạn chọn ảnh hoặc video"</string>
+ <string name="picker_settings_selection_message" msgid="245453573086488596">"Truy cập nội dung nghe nhìn trên đám mây qua"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Không có"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Hiện không thay đổi được ứng dụng đa phương tiện đám mây."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Công cụ chọn nội dung đa phương tiện"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Công cụ chọn nội dung đa phương tiện"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Đang đồng bộ hoá nội dung đa phương tiện…"</string>
<string name="add" msgid="2894574044585549298">"Thêm"</string>
<string name="deselect" msgid="4297825044827769490">"Bỏ chọn"</string>
<string name="deselected" msgid="8488133193326208475">"Đã bỏ chọn"</string>
@@ -55,14 +58,14 @@
<string name="recent" msgid="6694613584743207874">"Gần đây"</string>
<string name="picker_photos_empty_message" msgid="5980619500554575558">"Không có ảnh hoặc video nào"</string>
<string name="picker_album_media_empty_message" msgid="7061850698189881671">"Không có ảnh hoặc video nào được hỗ trợ"</string>
- <string name="picker_albums_empty_message" msgid="8341079772950966815">"Không có đĩa nhạc nào"</string>
+ <string name="picker_albums_empty_message" msgid="8341079772950966815">"Không có album nào"</string>
<string name="picker_view_selected" msgid="2266031384396143883">"Xem các mục được chọn"</string>
<string name="picker_photos" msgid="7415035516411087392">"Ảnh"</string>
<string name="picker_albums" msgid="4822511902115299142">"Album"</string>
<string name="picker_preview" msgid="6257414886055861039">"Xem trước"</string>
<string name="picker_work_profile" msgid="2083221066869141576">"Chuyển sang hồ sơ công việc"</string>
<string name="picker_personal_profile" msgid="639484258397758406">"Chuyển sang hồ sơ cá nhân"</string>
- <string name="picker_profile_admin_title" msgid="4172022376418293777">"Bị quản trị viên của bạn chặn"</string>
+ <string name="picker_profile_admin_title" msgid="4172022376418293777">"Quản trị viên của bạn đã chặn thao tác này"</string>
<string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"Bạn không được phép truy cập dữ liệu công việc từ một ứng dụng cá nhân"</string>
<string name="picker_profile_admin_msg_from_work" msgid="8048524337462790110">"Bạn không được phép truy cập dữ liệu cá nhân từ một ứng dụng công việc"</string>
<string name="picker_profile_work_paused_title" msgid="382212880704235925">"Ứng dụng công việc đã tạm dừng"</string>
@@ -93,8 +96,9 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Hãy kiểm tra kết nối Internet rồi thử lại"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Thử lại"</string>
<string name="not_selected" msgid="2244008151669896758">"chưa được chọn"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Đang chuẩn bị nội dung đa phương tiện mà bạn chọn"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g>/<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> mục đã sẵn sàng"</string>
- <string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Ảnh được sao lưu giờ đã xuất hiện"</string>
+ <string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Ảnh được sao lưu giờ đã có mặt"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Bạn có thể chọn ảnh của <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> trên <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="picker_banner_cloud_account_changed_title" msgid="4825058474378077327">"Đã cập nhật tài khoản <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="picker_banner_cloud_account_changed_desc" msgid="3433218869899792497">"Ảnh của <xliff:g id="USER_ACCOUNT">%1$s</xliff:g> giờ sẽ xuất hiện tại đây"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Chọn ứng dụng"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Chọn tài khoản"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Thay đổi tài khoản"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Tải tất cả các ảnh"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Cho phép <xliff:g id="APP_NAME_0">^1</xliff:g> sửa đổi tệp âm thanh này?}other{Cho phép <xliff:g id="APP_NAME_1">^1</xliff:g> sửa đổi <xliff:g id="COUNT">^2</xliff:g> tệp âm thanh?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Đang sửa đổi tệp âm thanh…}other{Đang sửa đổi <xliff:g id="COUNT">^1</xliff:g> tệp âm thanh…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Cho phép <xliff:g id="APP_NAME_0">^1</xliff:g> sửa đổi video này?}other{Cho phép <xliff:g id="APP_NAME_1">^1</xliff:g> sửa đổi <xliff:g id="COUNT">^2</xliff:g> video?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Bảo vệ an toàn"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Cảnh báo chuyển mã gốc"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Tiến trình chuyển mã gốc"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Không tải được một số ảnh"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Tôi hiểu"</string>
</resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 57feea139..ca8149e97 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/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="picker_app_label" msgid="4254039089502164761">"媒体"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"媒体选择工具"</string>
<string name="artist_label" msgid="8105600993099120273">"音乐人"</string>
<string name="unknown" msgid="2059049215682829375">"未知"</string>
<string name="root_images" msgid="5861633549189045666">"图片"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"从以下位置访问云端媒体:"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"无"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"目前无法更改云端媒体应用。"</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"媒体选择工具"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"媒体选择工具"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"正在同步媒体…"</string>
<string name="add" msgid="2894574044585549298">"添加"</string>
<string name="deselect" msgid="4297825044827769490">"取消选择"</string>
<string name="deselected" msgid="8488133193326208475">"已取消选中"</string>
@@ -93,19 +96,21 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"请检查互联网连接,然后重试"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"重试"</string>
<string name="not_selected" msgid="2244008151669896758">"未选择"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"正在准备您选择的媒体"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> 个已准备就绪,共 <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> 个"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"备份照片现已添加完成"</string>
- <string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"您可以选择来自<xliff:g id="APP_NAME">%1$s</xliff:g>帐号 <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> 的照片"</string>
- <string name="picker_banner_cloud_account_changed_title" msgid="4825058474378077327">"<xliff:g id="APP_NAME">%1$s</xliff:g>帐号已更新"</string>
+ <string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"您可以选择来自<xliff:g id="APP_NAME">%1$s</xliff:g>账号 <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> 的照片"</string>
+ <string name="picker_banner_cloud_account_changed_title" msgid="4825058474378077327">"<xliff:g id="APP_NAME">%1$s</xliff:g>账号已更新"</string>
<string name="picker_banner_cloud_account_changed_desc" msgid="3433218869899792497">"来自 <xliff:g id="USER_ACCOUNT">%1$s</xliff:g> 的照片已添加到此处"</string>
<string name="picker_banner_cloud_choose_app_title" msgid="3165966147547974251">"选择云端媒体应用"</string>
<string name="picker_banner_cloud_choose_app_desc" msgid="2359212653555524926">"如需将备份照片添加到此处,请在“设置”中选择一个云端媒体应用"</string>
- <string name="picker_banner_cloud_choose_account_title" msgid="5010901185639577685">"选择<xliff:g id="APP_NAME">%1$s</xliff:g>帐号"</string>
- <string name="picker_banner_cloud_choose_account_desc" msgid="8868134443673142712">"如需将来自<xliff:g id="APP_NAME">%1$s</xliff:g>的照片添加到此处,请在应用中选择一个帐号"</string>
+ <string name="picker_banner_cloud_choose_account_title" msgid="5010901185639577685">"选择<xliff:g id="APP_NAME">%1$s</xliff:g>账号"</string>
+ <string name="picker_banner_cloud_choose_account_desc" msgid="8868134443673142712">"如需将来自<xliff:g id="APP_NAME">%1$s</xliff:g>的照片添加到此处,请在应用中选择一个账号"</string>
<string name="picker_banner_cloud_dismiss_button" msgid="2935903078288463882">"关闭"</string>
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"选择应用"</string>
- <string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"选择帐号"</string>
- <string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"更改帐号"</string>
+ <string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"选择账号"</string>
+ <string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"更改账号"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"正在获取您的所有照片"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{要允许<xliff:g id="APP_NAME_0">^1</xliff:g>修改这个音频文件吗?}other{要允许<xliff:g id="APP_NAME_1">^1</xliff:g>修改这 <xliff:g id="COUNT">^2</xliff:g> 个音频文件吗?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{正在修改音频文件…}other{正在修改 <xliff:g id="COUNT">^1</xliff:g> 个音频文件…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{要允许<xliff:g id="APP_NAME_0">^1</xliff:g>修改这个视频吗?}other{要允许<xliff:g id="APP_NAME_1">^1</xliff:g>修改这 <xliff:g id="COUNT">^2</xliff:g> 个视频吗?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"安全保护"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"原生转码警报"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"原生转码进度"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"部分照片无法加载"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"知道了"</string>
</resources>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 089d6fca1..34a87d5f8 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/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="picker_app_label" msgid="4254039089502164761">"媒體"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"媒體選擇器"</string>
<string name="artist_label" msgid="8105600993099120273">"歌手"</string>
<string name="unknown" msgid="2059049215682829375">"不明"</string>
<string name="root_images" msgid="5861633549189045666">"相片"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"從以下位置存取雲端媒體:"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"無"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"目前無法變更雲端媒體應用程式。"</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"媒體選擇器"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"媒體選擇器"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"正在同步媒體…"</string>
<string name="add" msgid="2894574044585549298">"新增"</string>
<string name="deselect" msgid="4297825044827769490">"取消選取"</string>
<string name="deselected" msgid="8488133193326208475">"已取消選取"</string>
@@ -62,7 +65,7 @@
<string name="picker_preview" msgid="6257414886055861039">"預覽"</string>
<string name="picker_work_profile" msgid="2083221066869141576">"切換至工作設定檔"</string>
<string name="picker_personal_profile" msgid="639484258397758406">"切換至個人設定檔"</string>
- <string name="picker_profile_admin_title" msgid="4172022376418293777">"管理員已禁止此操作"</string>
+ <string name="picker_profile_admin_title" msgid="4172022376418293777">"管理員禁止此操作"</string>
<string name="picker_profile_admin_msg_from_personal" msgid="1941639895084555723">"個人應用程式不得存取工作資料"</string>
<string name="picker_profile_admin_msg_from_work" msgid="8048524337462790110">"工作應用程式不得存取個人資料"</string>
<string name="picker_profile_work_paused_title" msgid="382212880704235925">"已暫停工作應用程式"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"請檢查你的互聯網連線,然後再試一次"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"重試"</string>
<string name="not_selected" msgid="2244008151669896758">"未揀"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"正在準備你選取的媒體"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> 個項目已就緒,共 <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> 個"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"現在已納入備份相片"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"你可從「<xliff:g id="APP_NAME">%1$s</xliff:g>」帳戶 <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> 選取相片"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"選擇應用程式"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"選擇帳戶"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"變更帳戶"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"正在載入所有相片"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{允許 <xliff:g id="APP_NAME_0">^1</xliff:g> 修改此影片嗎?}other{允許 <xliff:g id="APP_NAME_1">^1</xliff:g> 修改 <xliff:g id="COUNT">^2</xliff:g> 部影片嗎?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{正在修改音訊檔案…}other{正在修改 <xliff:g id="COUNT">^1</xliff:g> 個音訊檔案…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{允許 <xliff:g id="APP_NAME_0">^1</xliff:g> 修改此影片嗎?}other{允許 <xliff:g id="APP_NAME_1">^1</xliff:g> 修改 <xliff:g id="COUNT">^2</xliff:g> 部影片嗎?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"安全保護"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"原生轉碼警示"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"原生轉碼進度"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"部分相片無法載入"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"知道了"</string>
</resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 0224634a4..05105779c 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/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="picker_app_label" msgid="4254039089502164761">"媒體"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"媒體選擇器"</string>
<string name="artist_label" msgid="8105600993099120273">"演出者"</string>
<string name="unknown" msgid="2059049215682829375">"不明"</string>
<string name="root_images" msgid="5861633549189045666">"圖片"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"從以下位置存取雲端媒體:"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"無"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"目前無法變更雲端媒體應用程式。"</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"媒體選擇器"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"媒體選擇器"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"正在同步媒體…"</string>
<string name="add" msgid="2894574044585549298">"新增"</string>
<string name="deselect" msgid="4297825044827769490">"取消選取"</string>
<string name="deselected" msgid="8488133193326208475">"已取消選取"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"請檢查網際網路連線,然後再試一次"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"重試"</string>
<string name="not_selected" msgid="2244008151669896758">"未選取"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"正在準備所選媒體"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"已備妥 <xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> 個項目,共 <xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> 個項目"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"現在已納入備份相片"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"你可以從「<xliff:g id="APP_NAME">%1$s</xliff:g>」帳戶 <xliff:g id="USER_ACCOUNT">%2$s</xliff:g> 選取相片"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"選擇應用程式"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"選擇帳戶"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"變更帳戶"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"正在載入所有相片"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{允許「<xliff:g id="APP_NAME_0">^1</xliff:g>」修改這個音訊檔案嗎?}other{允許「<xliff:g id="APP_NAME_1">^1</xliff:g>」修改這 <xliff:g id="COUNT">^2</xliff:g> 個音訊檔案嗎?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{正在修改音訊檔案…}other{正在修改 <xliff:g id="COUNT">^1</xliff:g> 個音訊檔案…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{允許「<xliff:g id="APP_NAME_0">^1</xliff:g>」修改這部影片嗎?}other{允許「<xliff:g id="APP_NAME_1">^1</xliff:g>」修改這 <xliff:g id="COUNT">^2</xliff:g> 部影片嗎?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"安全防護"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"原生轉碼警示"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"原生轉碼進度"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"無法載入部分相片"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"我知道了"</string>
</resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index ed066d83f..979d2b3a0 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -19,7 +19,7 @@
<string name="uid_label" msgid="8421971615411294156">"Abezind"</string>
<string name="storage_description" msgid="4081716890357580107">"Isitoreji sasendaweni"</string>
<string name="app_label" msgid="9035307001052716210">"Isitoreji Semidiya"</string>
- <string name="picker_app_label" msgid="4254039089502164761">"Imidiya"</string>
+ <string name="picker_app_label" msgid="1195424381053599122">"Isikhethi semidiya"</string>
<string name="artist_label" msgid="8105600993099120273">"Umculi"</string>
<string name="unknown" msgid="2059049215682829375">"Akwaziwa"</string>
<string name="root_images" msgid="5861633549189045666">"Izithombe"</string>
@@ -46,6 +46,9 @@
<string name="picker_settings_selection_message" msgid="245453573086488596">"Finyelela imidiya yacloud ukusuka"</string>
<string name="picker_settings_no_provider" msgid="2582311853680058223">"Lutho"</string>
<string name="picker_settings_toast_error" msgid="697274445512467469">"Ayikwazanga ukushintsha i-app yemidiya ye-cloud manje."</string>
+ <string name="picker_sync_notification_channel" msgid="1867105708912627993">"Isikhethi semidiya"</string>
+ <string name="picker_sync_notification_title" msgid="1122713382122055246">"Isikhethi semidiya"</string>
+ <string name="picker_sync_notification_text" msgid="8204423917712309382">"Ivumelanisa imidiya…"</string>
<string name="add" msgid="2894574044585549298">"Engeza"</string>
<string name="deselect" msgid="4297825044827769490">"Susa ukukhetha"</string>
<string name="deselected" msgid="8488133193326208475">"Okususwe ekukhethweni"</string>
@@ -93,6 +96,7 @@
<string name="picker_error_dialog_body" msgid="2515738446802971453">"Hlola ukuxhuma kwakho kwe-inthanethi uphinde uzame futhi"</string>
<string name="picker_error_dialog_positive_action" msgid="749544129082109232">"Zama futhi"</string>
<string name="not_selected" msgid="2244008151669896758">"akukhethiwe"</string>
+ <string name="preloading_dialog_title" msgid="4974348221848532887">"Ilungiselela imidiya yakho oyikhethile"</string>
<string name="preloading_progress_message" msgid="4741327138031980582">"U-<xliff:g id="NUMBER_PRELOADED">%1$d</xliff:g> wokungu-<xliff:g id="NUMBER_TOTAL">%2$d</xliff:g> ulungile"</string>
<string name="picker_banner_cloud_first_time_available_title" msgid="5912973744275711595">"Izithombe ezenziwe isipele sezifakiwe manje"</string>
<string name="picker_banner_cloud_first_time_available_desc" msgid="5570916598348187607">"Ungakhetha izithombe ezivela ku-akhawunti ye-<xliff:g id="APP_NAME">%1$s</xliff:g> ethi <xliff:g id="USER_ACCOUNT">%2$s</xliff:g>"</string>
@@ -106,6 +110,7 @@
<string name="picker_banner_cloud_choose_app_button" msgid="934085679890435479">"Khetha i-app"</string>
<string name="picker_banner_cloud_choose_account_button" msgid="7979484877116991631">"Khetha i-akhawunti"</string>
<string name="picker_banner_cloud_change_account_button" msgid="8361239765828471146">"Shintsha i-akhawunti"</string>
+ <string name="picker_loading_photos_message" msgid="6449180084857178949">"Ithola zonke izithombe zakho"</string>
<string name="permission_write_audio" msgid="8819694245323580601">"{count,plural, =1{Vumela i-<xliff:g id="APP_NAME_0">^1</xliff:g> ukuguqula leli fayela lomsindo?}one{Vumela i-<xliff:g id="APP_NAME_1">^1</xliff:g> ukuguqula amafayela omsindo angu-<xliff:g id="COUNT">^2</xliff:g>?}other{Vumela i-<xliff:g id="APP_NAME_1">^1</xliff:g> ukuguqula amafayela omsindo angu-<xliff:g id="COUNT">^2</xliff:g>?}}"</string>
<string name="permission_progress_write_audio" msgid="6029375427984180097">"{count,plural, =1{Ilungisa ifayela lomsindo…}one{Ilungisa amafayela womsindo angu-<xliff:g id="COUNT">^1</xliff:g>…}other{Ilungisa amafayela womsindo angu-<xliff:g id="COUNT">^1</xliff:g>…}}"</string>
<string name="permission_write_video" msgid="103902551603700525">"{count,plural, =1{Vumela i-<xliff:g id="APP_NAME_0">^1</xliff:g> ukuguqula le vidiyo?}one{Vumela i-<xliff:g id="APP_NAME_1">^1</xliff:g> ukuguqula amavidiyo angu-<xliff:g id="COUNT">^2</xliff:g>?}other{Vumela i-<xliff:g id="APP_NAME_1">^1</xliff:g> ukuguqula amavidiyo angu-<xliff:g id="COUNT">^2</xliff:g>?}}"</string>
@@ -149,4 +154,8 @@
<string name="safety_protection_icon_label" msgid="6714354052747723623">"Ukuvikeleka kokuphepha"</string>
<string name="transcode_alert_channel" msgid="997332371757680478">"Izexwayiso Zokudlulisela Ikhodi Yomdabu"</string>
<string name="transcode_progress_channel" msgid="6905136787933058387">"Inqubekela-phambili Yokudlulisela Ikhodi Yomdabu"</string>
+ <!-- no translation found for dialog_error_message (5120432204743681606) -->
+ <skip />
+ <string name="dialog_error_title" msgid="636349284077820636">"Ayikwazi ukulayisha ezinye Izithombe"</string>
+ <string name="dialog_button_text" msgid="351366485240852280">"Ngiyezwa"</string>
</resources>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 6f53ce1bf..c932084b8 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -78,4 +78,10 @@
<!-- Photo Picker Banner button text color. -->
<attr name="pickerBannerButtonTextColor" format="reference|color" />
+ <!-- Default thumbnail icon color for merged albums -->
+ <attr name="categoryDefaultThumbnailColor" format="reference|color"/>
+
+ <!-- Default thumbnail ellipse color for merged albums -->
+ <attr name="categoryDefaultThumbnailCircleColor" format="reference|color" />
+
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index de1540dfa..90013b745 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -19,6 +19,7 @@
<dimen name="permission_thumb_size">64dp</dimen>
<dimen name="permission_thumb_margin">6dp</dimen>
<dimen name="dialog_space">20dp</dimen>
+ <dimen name="button_touch_size">48dp</dimen>
<!-- PhotoPicker -->
<dimen name="picker_top_corner_radius">28dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b494869b5..53f3fa82c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -26,7 +26,7 @@
<string name="app_label">Media Storage</string>
<!-- Label to show to user for this package and for Photo picker. -->
- <string name="picker_app_label">Media</string>
+ <string name="picker_app_label">Media picker</string>
<!-- Description line for music artists in the search/suggestion results -->
<string name="artist_label">Artist</string>
@@ -107,6 +107,15 @@
<!-- Error message displayed to the user when the user is not able to change cloud media app preference in Picker Settings. [CHAR LIMIT=50] -->
<string name="picker_settings_toast_error">Could not change cloud media app at this time.</string>
+ <!-- PhotoPicker notification channel for sync updates [CHAR LIMIT=40] -->
+ <string name="picker_sync_notification_channel">Media picker</string>
+
+ <!-- PhotoPicker sync notification title [CHAR LIMIT=40] -->
+ <string name="picker_sync_notification_title">Media picker</string>
+
+ <!-- PhotoPicker sync notification text [CHAR LIMIT=60] -->
+ <string name="picker_sync_notification_text">Syncing media&#8230;</string>
+
<!-- Add button for PhotoPicker. [CHAR LIMIT=30] -->
<string name="add">Add</string>
@@ -138,7 +147,7 @@
<!-- The message for empty message on Albums tab in PhotoPicker when the item count is zero. [CHAR LIMIT=NONE] -->
<string name="picker_albums_empty_message">No albums</string>
- <!-- PhotoPicker view selected action text. [CHAR LIMIT=80] -->
+ <!-- PhotoPicker view selected action text. [CHAR LIMIT=17] -->
<string name="picker_view_selected">View selected</string>
<!-- The text of the photos tab for PhotoPicker. [CHAR LIMIT=30] -->
@@ -244,6 +253,8 @@
<!-- Default not selected text used by accessibility for an element that can be unselected. [CHAR LIMIT=NONE] -->
<string name="not_selected">not selected</string>
+ <!-- Title of the preloading progress dialog -->
+ <string name="preloading_dialog_title">"Preparing your selected media"</string>
<!-- A message for the Progress Dialog shown while preloading selected items before "closing" Photo Picker. [CHAR LIMIT=NONE] -->
<string name="preloading_progress_message"><xliff:g id="number_preloaded">%1$d</xliff:g> of <xliff:g id="number_total">%2$d</xliff:g> ready</string>
@@ -499,4 +510,13 @@
<!-- Transcode progress channel name. -->
<string name="transcode_progress_channel">Native Transcode Progress</string>
+
+ <!-- Dialog error message-->
+ <string name="dialog_error_message">Try again later. Your photos will be available once the issue is resolved.</string>
+
+ <!-- Dialog error title-->
+ <string name="dialog_error_title">Can\'t load some Photos</string>
+
+ <!-- Error dialog OK button text-->
+ <string name="dialog_button_text">Got it</string>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index d499105f7..179edf839 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -14,7 +14,8 @@
limitations under the License.
-->
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<style name="PickerDialogTheme"
parent="@android:style/Theme.DeviceDefault.Light.Dialog.Alert">
@@ -89,6 +90,7 @@
<style name="PickerDefaultTheme" parent="@android:style/Theme.DeviceDefault.DayNight">
<!-- System | Widget section -->
+ <item name="actionOverflowButtonStyle">@style/OverflowButtonStyle</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:navigationBarColor">@color/picker_background_color</item>
<item name="android:statusBarColor">@android:color/transparent</item>
@@ -127,6 +129,8 @@
<item name="pickerBannerPrimaryTextColor">?android:attr/textColorSecondary</item>
<item name="pickerBannerSecondaryTextColor">?android:attr/textColorPrimary</item>
<item name="pickerBannerButtonTextColor">?android:attr/colorAccent</item>
+ <item name="categoryDefaultThumbnailColor">?android:attr/colorAccent</item>
+ <item name="categoryDefaultThumbnailCircleColor">?androidprv:attr/materialColorSurfaceContainer</item>
</style>
<style name="PickerBannerButtonTheme"
@@ -138,4 +142,18 @@
<item name="android:textColor">?attr/pickerBannerButtonTextColor</item>
</style>
+ <style name="OverflowButtonStyle" parent="Widget.AppCompat.ActionButton.Overflow">
+ <item name="android:minWidth">@dimen/button_touch_size</item>
+ </style>
+
+ <style name="SelectedMediaPreloaderDialogTheme"
+ parent="@style/ThemeOverlay.MaterialComponents.MaterialAlertDialog.Centered">
+ <item name="android:textColor">?attr/colorOnSurfaceVariant</item>
+ <item name="materialAlertDialogTitleTextStyle">@style/AlertDialogTitleStyle</item>
+ </style>
+
+ <style name="AlertDialogTitleStyle"
+ parent="@style/MaterialAlertDialog.MaterialComponents.Title.Text.CenterStacked">
+ <item name="android:textColor">?attr/colorOnSurface</item>
+ </style>
</resources>
diff --git a/src/com/android/providers/media/ConfigStore.java b/src/com/android/providers/media/ConfigStore.java
index cceb73424..83955280b 100644
--- a/src/com/android/providers/media/ConfigStore.java
+++ b/src/com/android/providers/media/ConfigStore.java
@@ -67,6 +67,7 @@ public interface ConfigStore {
boolean DEFAULT_CLOUD_MEDIA_IN_PHOTO_PICKER_ENABLED = false;
boolean DEFAULT_ENFORCE_CLOUD_PROVIDER_ALLOWLIST = true;
+ boolean DEFAULT_PICKER_CHOICE_MANAGED_SELECTION_ENABLED = false;
/**
* @return if the Cloud-Media-in-Photo-Picker enabled (e.g. platform will recognize and
@@ -77,6 +78,14 @@ public interface ConfigStore {
}
/**
+ * @return if the Picker-Choice_Managed_selection is enabled.
+ */
+ default boolean isPickerChoiceManagedSelectionEnabled() {
+ return DEFAULT_PICKER_CHOICE_MANAGED_SELECTION_ENABLED;
+ }
+
+
+ /**
* @return package name of the pre-configured "system default"
* {@link android.provider.CloudMediaProvider}.
* @see #isCloudMediaInPhotoPickerEnabled()
@@ -242,7 +251,7 @@ public interface ConfigStore {
private static final String KEY_USER_SELECT_FOR_APP = "user_select_for_app";
@VisibleForTesting
- public static final String KEY_STABILIZE_VOLUME_INTERNAL = "stablize_volume_internal";
+ public static final String KEY_STABILIZE_VOLUME_INTERNAL = "stabilize_volume_internal";
@VisibleForTesting
public static final String KEY_STABILIZE_VOLUME_EXTERNAL = "stabilize_volume_external";
@@ -264,6 +273,8 @@ public interface ConfigStore {
"picker_pick_images_respect_preload_selected_arg";
private static final String KEY_CLOUD_MEDIA_FEATURE_ENABLED = "cloud_media_feature_enabled";
+ private static final String KEY_PICKER_CHOICE_MANAGED_SELECTION_ENABLED =
+ "picker_choice_managed_selection_enabled";
private static final String KEY_CLOUD_MEDIA_PROVIDER_ALLOWLIST = "allowed_cloud_providers";
private static final String KEY_CLOUD_MEDIA_ENFORCE_PROVIDER_ALLOWLIST =
"cloud_media_enforce_provider_allowlist";
@@ -279,8 +290,27 @@ public interface ConfigStore {
@Override
public boolean isCloudMediaInPhotoPickerEnabled() {
- return getBooleanDeviceConfig(NAMESPACE_MEDIAPROVIDER, KEY_CLOUD_MEDIA_FEATURE_ENABLED,
- DEFAULT_CLOUD_MEDIA_IN_PHOTO_PICKER_ENABLED);
+ Boolean isEnabled =
+ getBooleanDeviceConfig(
+ NAMESPACE_MEDIAPROVIDER,
+ KEY_CLOUD_MEDIA_FEATURE_ENABLED,
+ DEFAULT_CLOUD_MEDIA_IN_PHOTO_PICKER_ENABLED);
+
+ List<String> allowList =
+ getStringArrayDeviceConfig(
+ NAMESPACE_MEDIAPROVIDER, KEY_CLOUD_MEDIA_PROVIDER_ALLOWLIST);
+
+ // Only consider the feature enabled when the enabled flag is on AND when the allowlist
+ // of permitted cloud media providers is not empty.
+ return isEnabled && !allowList.isEmpty();
+ }
+
+ @Override
+ public boolean isPickerChoiceManagedSelectionEnabled() {
+ return getBooleanDeviceConfig(
+ NAMESPACE_MEDIAPROVIDER,
+ KEY_PICKER_CHOICE_MANAGED_SELECTION_ENABLED,
+ DEFAULT_PICKER_CHOICE_MANAGED_SELECTION_ENABLED);
}
@Nullable
diff --git a/src/com/android/providers/media/DatabaseBackupAndRecovery.java b/src/com/android/providers/media/DatabaseBackupAndRecovery.java
index 69df6a663..39039759d 100644
--- a/src/com/android/providers/media/DatabaseBackupAndRecovery.java
+++ b/src/com/android/providers/media/DatabaseBackupAndRecovery.java
@@ -132,11 +132,6 @@ public class DatabaseBackupAndRecovery {
};
/**
- * Wait time of 5 seconds in millis.
- */
- private static final long WAIT_TIME_5_SECONDS_IN_MILLIS = 5000;
-
- /**
* Wait time of 10 seconds in millis.
*/
private static final long WAIT_TIME_10_SECONDS_IN_MILLIS = 10000;
@@ -234,8 +229,7 @@ public class DatabaseBackupAndRecovery {
if (!new File(RECOVERY_DIRECTORY_PATH).exists()) {
new File(RECOVERY_DIRECTORY_PATH).mkdirs();
}
- FuseDaemon fuseDaemon = getFuseDaemonForFileWithWait(volumePath,
- WAIT_TIME_5_SECONDS_IN_MILLIS);
+ FuseDaemon fuseDaemon = getFuseDaemonForFileWithWait(volumePath);
Log.d(TAG, "Received db backup Fuse Daemon for: " + volumeName);
fuseDaemon.setupVolumeDbBackup();
mIsBackupSetupComplete.set(true);
@@ -261,9 +255,14 @@ public class DatabaseBackupAndRecovery {
return Optional.empty();
}
- final String fuseDaemonFilePath = getFuseDaemonFilePath(filePath);
+ final String fuseDaemonFilePath = getFilePathForFuseRequests(filePath);
try {
final String data = getFuseDaemonForPath(fuseDaemonFilePath).readBackedUpData(filePath);
+ if (data == null || data.isEmpty()) {
+ Log.w(TAG, "No backup found for path: " + filePath);
+ return Optional.empty();
+ }
+
return Optional.of(BackupIdRow.deserialize(data));
} catch (Exception e) {
Log.e(TAG, "Failure in getting backed up data for filePath: " + filePath, e);
@@ -325,8 +324,7 @@ public class DatabaseBackupAndRecovery {
FuseDaemon fuseDaemon;
try {
- fuseDaemon = getFuseDaemonForFileWithWait(new File(EXTERNAL_PRIMARY_ROOT_PATH),
- WAIT_TIME_5_SECONDS_IN_MILLIS);
+ fuseDaemon = getFuseDaemonForFileWithWait(new File(EXTERNAL_PRIMARY_ROOT_PATH));
} catch (FileNotFoundException e) {
Log.e(TAG,
"Fuse Daemon not found for primary external storage, skipping backing up of "
@@ -343,7 +341,7 @@ public class DatabaseBackupAndRecovery {
if (lastBackedGenerationNumber > 0) {
Log.i(TAG, "Last backed up generation number is " + lastBackedGenerationNumber);
}
- final String generationClause = MediaStore.Files.FileColumns.GENERATION_MODIFIED + " > "
+ final String generationClause = MediaStore.Files.FileColumns.GENERATION_MODIFIED + " >= "
+ lastBackedGenerationNumber;
final String volumeClause = MediaStore.Files.FileColumns.VOLUME_NAME + " = '"
+ MediaStore.VOLUME_EXTERNAL_PRIMARY + "'";
@@ -457,10 +455,9 @@ public class DatabaseBackupAndRecovery {
return;
}
- // For all internal file paths, redirect to external primary fuse daemon.
- final String fuseDaemonFilePath = getFuseDaemonFilePath(insertedRow.getPath());
try {
- FuseDaemon fuseDaemon = getFuseDaemonForPath(fuseDaemonFilePath);
+ FuseDaemon fuseDaemon = getFuseDaemonForPath(
+ getFilePathForFuseRequests(insertedRow.getPath()));
final BackupIdRow value = createBackupIdRow(fuseDaemon, insertedRow);
fuseDaemon.backupVolumeDbData(insertedRow.getPath(), BackupIdRow.serialize(value));
} catch (Exception e) {
@@ -468,8 +465,21 @@ public class DatabaseBackupAndRecovery {
}
}
- private String getFuseDaemonFilePath(String filePath) {
- return filePath.startsWith("/storage") ? filePath : EXTERNAL_PRIMARY_ROOT_PATH;
+ /**
+ * Creates a fuse daemon file path for a given path.
+ */
+ protected static String getFilePathForFuseRequests(String filePath) {
+ // For internal volume paths
+ if (!filePath.startsWith("/storage")) {
+ return EXTERNAL_PRIMARY_ROOT_PATH;
+ }
+
+ // For primary external and cloned app paths.
+ if (filePath.equalsIgnoreCase("/storage") || filePath.startsWith("/storage/emulated")) {
+ return EXTERNAL_PRIMARY_ROOT_PATH;
+ }
+
+ return filePath;
}
private BackupIdRow createBackupIdRow(FuseDaemon fuseDaemon, FileRow insertedRow)
@@ -599,10 +609,9 @@ public class DatabaseBackupAndRecovery {
return;
}
- // For all internal file paths, redirect to external primary fuse daemon.
- String fuseDaemonFilePath = getFuseDaemonFilePath(deletedFilePath);
try {
- getFuseDaemonForPath(fuseDaemonFilePath).deleteDbBackup(deletedFilePath);
+ getFuseDaemonForPath(getFilePathForFuseRequests(deletedFilePath)).deleteDbBackup(
+ deletedFilePath);
} catch (IOException e) {
Log.w(TAG, "Failure in deleting backup data for key: " + deletedFilePath, e);
}
@@ -637,10 +646,9 @@ public class DatabaseBackupAndRecovery {
}
final String updatedFilePath = updatedRow.getPath();
- // For all internal file paths, redirect to external primary fuse daemon.
- final String fuseDaemonFilePath = getFuseDaemonFilePath(updatedFilePath);
try {
- getFuseDaemonForPath(fuseDaemonFilePath).backupVolumeDbData(updatedFilePath,
+ getFuseDaemonForPath(getFilePathForFuseRequests(updatedFilePath)).backupVolumeDbData(
+ updatedFilePath,
BackupIdRow.serialize(BackupIdRow.newBuilder(updatedRow.getId()).setIsDirty(
true).build()));
} catch (IOException e) {
@@ -807,7 +815,7 @@ public class DatabaseBackupAndRecovery {
// Wait for external primary to be attached as we use same thread for internal volume.
// Maximum wait for 10s
try {
- getFuseDaemonForFileWithWait(new File(fuseFilePath), WAIT_TIME_10_SECONDS_IN_MILLIS);
+ getFuseDaemonForFileWithWait(new File(fuseFilePath));
} catch (FileNotFoundException e) {
Log.e(TAG, "Could not recover data as fuse daemon could not serve requests.", e);
return;
@@ -828,7 +836,7 @@ public class DatabaseBackupAndRecovery {
while (true) {
backedUpFilePaths = readBackedUpFilePaths(volumeName, lastReadValue,
LEVEL_DB_READ_LIMIT);
- if (backedUpFilePaths.length <= 0) {
+ if (backedUpFilePaths.length == 0) {
break;
}
@@ -868,10 +876,11 @@ public class DatabaseBackupAndRecovery {
return new File(RECOVERY_DIRECTORY_PATH).exists();
}
- protected FuseDaemon getFuseDaemonForFileWithWait(File fuseFilePath, long waitTime)
+ protected FuseDaemon getFuseDaemonForFileWithWait(File fuseFilePath)
throws FileNotFoundException {
pollForExternalStorageMountedState();
- return MediaProvider.getFuseDaemonForFileWithWait(fuseFilePath, mVolumeCache, waitTime);
+ return MediaProvider.getFuseDaemonForFileWithWait(fuseFilePath, mVolumeCache,
+ WAIT_TIME_10_SECONDS_IN_MILLIS);
}
private int getVolumeNameForStatsLog(String volumeName) {
@@ -912,7 +921,7 @@ public class DatabaseBackupAndRecovery {
FuseDaemon fuseDaemon;
try {
- fuseDaemon = getFuseDaemonForPath(EXTERNAL_PRIMARY_ROOT_PATH);
+ fuseDaemon = getFuseDaemonForPath(getFilePathForFuseRequests(oldRow.getPath()));
} catch (FileNotFoundException e) {
Log.e(TAG,
"Fuse Daemon not found for primary external storage, skipping update of "
@@ -927,7 +936,6 @@ public class DatabaseBackupAndRecovery {
null, null)) {
if (c.moveToFirst()) {
backupDataValues(fuseDaemon, c);
- Log.v(TAG, "Updated backed up row in leveldb");
String newPath = c.getString(1);
if (oldRow.getPath() != null && !oldRow.getPath().equalsIgnoreCase(newPath)) {
// If file path has changed, update leveldb backup to delete old path.
@@ -967,11 +975,14 @@ public class DatabaseBackupAndRecovery {
*/
protected void removeRecoveryDataExceptValidUsers(List<String> validUsers) {
List<String> xattrList = listXattr(DATA_MEDIA_XATTR_DIRECTORY_PATH);
+ Log.i(TAG, "Xattr list is " + xattrList);
if (xattrList.isEmpty()) {
return;
}
+ Log.i(TAG, "Valid users list is " + validUsers);
List<String> invalidUsers = getInvalidUsersList(xattrList, validUsers);
+ Log.i(TAG, "Invalid users list is " + invalidUsers);
for (String userIdToBeRemoved : invalidUsers) {
removeRecoveryDataForUserId(Integer.parseInt(userIdToBeRemoved));
}
diff --git a/src/com/android/providers/media/MediaGrants.java b/src/com/android/providers/media/MediaGrants.java
index b08bb63d8..bdeeb7485 100644
--- a/src/com/android/providers/media/MediaGrants.java
+++ b/src/com/android/providers/media/MediaGrants.java
@@ -16,10 +16,14 @@
package com.android.providers.media;
+import static android.provider.MediaStore.MediaColumns.DATA;
+
import static com.android.providers.media.LocalUriMatcher.PICKER_ID;
import android.content.ContentUris;
import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteConstraintException;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.provider.MediaStore;
@@ -29,7 +33,9 @@ import android.util.Log;
import androidx.annotation.NonNull;
import com.android.providers.media.photopicker.PickerSyncController;
+import com.android.providers.media.util.FileUtils;
+import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@@ -47,6 +53,9 @@ class MediaGrants {
public static final String OWNER_PACKAGE_NAME_COLUMN =
MediaStore.MediaColumns.OWNER_PACKAGE_NAME;
+ private static final String MEDIA_GRANTS_AND_FILES_JOIN_TABLE_NAME = "media_grants LEFT JOIN "
+ + "files ON media_grants.file_id = files._id";
+
private SQLiteQueryBuilder mQueryBuilder = new SQLiteQueryBuilder();
private DatabaseHelper mExternalDatabase;
private LocalUriMatcher mUriMatcher;
@@ -87,7 +96,15 @@ class MediaGrants {
values.put(FILE_ID_COLUMN, id);
values.put(PACKAGE_USER_ID_COLUMN, packageUserId);
- mQueryBuilder.insert(db, values);
+ try {
+ mQueryBuilder.insert(db, values);
+ } catch (SQLiteConstraintException exception) {
+ // no-op
+ // this may happen due to the presence of a foreign key between the
+ // media_grants and files table. An SQLiteConstraintException
+ // exception my occur if: while inserting the grant for a file, the
+ // file itself is deleted. In this situation no operation is required.
+ }
}
Log.d(
@@ -101,6 +118,41 @@ class MediaGrants {
}
/**
+ * Returns the file uris of items for which the passed package has READ_GRANTS.
+ *
+ * @param packageName the package name that has access.
+ * @param packageUserId the user_id of the package
+ */
+ List<Uri> getMediaGrantsForPackage(String packageName, int packageUserId)
+ throws IllegalArgumentException {
+ Objects.requireNonNull(packageName);
+ return mExternalDatabase.runWithoutTransaction((db) -> {
+ final List<Uri> filesUriList = new ArrayList<>();
+ final String selection = String.format(
+ "%s = '%s' AND %s = %s",
+ "media_grants." + MediaGrants.OWNER_PACKAGE_NAME_COLUMN,
+ packageName,
+ "media_grants." + MediaGrants.PACKAGE_USER_ID_COLUMN,
+ Integer.toString(packageUserId));
+ SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
+ queryBuilder.setDistinct(true);
+ queryBuilder.setTables(MEDIA_GRANTS_AND_FILES_JOIN_TABLE_NAME);
+ try (Cursor c = queryBuilder.query(db,
+ new String[]{DATA, FILE_ID_COLUMN},
+ selection,
+ null, null, null, null, null, null)) {
+ while (c.moveToNext()) {
+ final String file_path = c.getString(c.getColumnIndexOrThrow(DATA));
+ final Integer file_id = c.getInt(c.getColumnIndexOrThrow(FILE_ID_COLUMN));
+ filesUriList.add(FileUtils.getContentUriForPath(
+ file_path).buildUpon().appendPath(String.valueOf(file_id)).build());
+ }
+ return filesUriList;
+ }
+ });
+ }
+
+ /**
* Removes any existing media grants for the given package from the external database. This will
* not alter the files or file metadata themselves.
*
diff --git a/src/com/android/providers/media/MediaProvider.java b/src/com/android/providers/media/MediaProvider.java
index ced5445e4..1cd80b437 100644
--- a/src/com/android/providers/media/MediaProvider.java
+++ b/src/com/android/providers/media/MediaProvider.java
@@ -1311,7 +1311,7 @@ public class MediaProvider extends ContentProvider {
mPickerSyncController = PickerSyncController.initialize(context, mPickerDbFacade,
mConfigStore);
- mPickerDataLayer = new PickerDataLayer(context, mPickerDbFacade, mPickerSyncController,
+ mPickerDataLayer = PickerDataLayer.create(context, mPickerDbFacade, mPickerSyncController,
mConfigStore);
mPickerUriResolver = new PickerUriResolver(context, mPickerDbFacade, mProjectionHelper);
@@ -1321,9 +1321,6 @@ public class MediaProvider extends ContentProvider {
mTranscodeHelper = new TranscodeHelperNoOp();
}
- // Create dir for redacted and picker URI paths.
- buildPrimaryVolumeFile(uidToUserId(MY_UID), getRedactedRelativePath()).mkdirs();
-
final IntentFilter packageFilter = new IntentFilter();
packageFilter.setPriority(10);
packageFilter.addDataScheme("package");
@@ -6810,10 +6807,15 @@ public class MediaProvider extends ContentProvider {
return bundle;
}
case MediaStore.IS_CURRENT_CLOUD_PROVIDER_CALL: {
- final boolean isEnabled = mPickerSyncController.isProviderEnabled(arg,
- Binder.getCallingUid());
-
Bundle bundle = new Bundle();
+ boolean isEnabled = false;
+
+ if (mConfigStore.isCloudMediaInPhotoPickerEnabled()) {
+ isEnabled =
+ mPickerSyncController.isProviderEnabled(
+ arg, Binder.getCallingUid());
+ }
+
bundle.putBoolean(MediaStore.EXTRA_CLOUD_PROVIDER_RESULT, isEnabled);
return bundle;
}
@@ -10722,8 +10724,7 @@ public class MediaProvider extends ContentProvider {
ForegroundThread.getExecutor().execute(() -> {
mExternalDatabase.runWithTransaction((db) -> {
- ensureDefaultFolders(volume, db);
- ensureThumbnailsValid(volume, db);
+ ensureNecessaryFolders(volume, db);
return null;
});
@@ -10785,6 +10786,22 @@ public class MediaProvider extends ContentProvider {
if (LOGV) Log.v(TAG, "Detached volume: " + volumeName);
}
+ private void ensureNecessaryFolders(MediaVolume volume, SQLiteDatabase db) {
+ ensureDefaultFolders(volume, db);
+ ensureThumbnailsValid(volume, db);
+
+ // Create redacted directories
+ if (MediaStore.VOLUME_EXTERNAL_PRIMARY.equalsIgnoreCase(volume.getName())) {
+ // Create dir for redacted and picker URI paths.
+ File redactedRelativePath = buildPrimaryVolumeFile(uidToUserId(MY_UID),
+ getRedactedRelativePath());
+ if (!redactedRelativePath.exists() && !redactedRelativePath.mkdirs()) {
+ // We should always be able to create these directories from MediaProvider
+ Log.wtf(TAG, "Couldn't create redacted path for " + UserHandle.myUserId());
+ }
+ }
+ }
+
@GuardedBy("mAttachedVolumes")
private final ArraySet<MediaVolume> mAttachedVolumes = new ArraySet<>();
@GuardedBy("mCustomCollators")
diff --git a/src/com/android/providers/media/photopicker/DialogUtils.java b/src/com/android/providers/media/photopicker/DialogUtils.java
new file mode 100644
index 000000000..9f94aeff5
--- /dev/null
+++ b/src/com/android/providers/media/photopicker/DialogUtils.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.providers.media.photopicker;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.android.providers.media.R;
+
+/**
+ * Dialog box to display custom alert or error messages
+ */
+public class DialogUtils extends AppCompatActivity {
+ /**
+ * Custom dialog box with single button to display title and single error message
+ */
+ public static void showDialog(Context context, String title, String message) {
+ View customView =
+ LayoutInflater.from(context).inflate(R.layout.error_dialog, null);
+
+ TextView dialogTitle = customView.findViewById(R.id.title);
+ TextView dialogMessage = customView.findViewById(R.id.message);
+ Button gotItButton = customView.findViewById(R.id.okButton);
+ dialogTitle.setText(title);
+ dialogMessage.setText(message);
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setView(customView);
+ builder.setCancelable(false); // Prevent dismiss when clicking outside
+ final AlertDialog dialog = builder.create();
+
+ gotItButton.setOnClickListener(v -> {
+ dialog.dismiss(); // Close the dialog
+ });
+ dialog.show();
+ }
+}
diff --git a/src/com/android/providers/media/photopicker/PhotoPickerActivity.java b/src/com/android/providers/media/photopicker/PhotoPickerActivity.java
index b64ba1f8a..1cdc56c6f 100644
--- a/src/com/android/providers/media/photopicker/PhotoPickerActivity.java
+++ b/src/com/android/providers/media/photopicker/PhotoPickerActivity.java
@@ -65,6 +65,8 @@ import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.FragmentManager;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
@@ -73,6 +75,7 @@ import com.android.providers.media.R;
import com.android.providers.media.photopicker.data.PickerResult;
import com.android.providers.media.photopicker.data.Selection;
import com.android.providers.media.photopicker.data.UserIdManager;
+import com.android.providers.media.photopicker.data.model.Item;
import com.android.providers.media.photopicker.data.model.UserId;
import com.android.providers.media.photopicker.ui.TabContainerFragment;
import com.android.providers.media.photopicker.util.LayoutModeUtils;
@@ -115,6 +118,10 @@ public class PhotoPickerActivity extends AppCompatActivity {
private Toolbar mToolbar;
private CrossProfileListeners mCrossProfileListeners;
+ @NonNull
+ private final MutableLiveData<Boolean> mIsItemPhotoGridViewChanged =
+ new MutableLiveData<>(false);
+
@ColorInt
private int mDefaultBackgroundColor;
@@ -527,13 +534,17 @@ public class PhotoPickerActivity extends AppCompatActivity {
return getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
}
+ public LiveData<Boolean> isItemPhotoGridViewChanged() {
+ return mIsItemPhotoGridViewChanged;
+ }
+
public void setResultAndFinishSelf() {
logPickerSelectionConfirmed(mSelection.getSelectedItems().size());
-
if (shouldPreloadSelectedItems()) {
final var uris = PickerResult.getPickerUrisForItems(mSelection.getSelectedItems());
mPreloaderInstanceHolder.preloader =
SelectedMediaPreloader.preload(/* activity */ this, uris);
+ deSelectUnavailableMedia(mPreloaderInstanceHolder.preloader);
subscribeToSelectedMediaPreloader(mPreloaderInstanceHolder.preloader);
} else {
setResultAndFinishSelfInternal();
@@ -611,6 +622,30 @@ public class PhotoPickerActivity extends AppCompatActivity {
});
}
+ // This method is responsible for deselecting all unavailable items from selection list
+ // when user tries selecting unavailable could only media (not cached) while offline
+ private void deSelectUnavailableMedia(@NonNull SelectedMediaPreloader preloader) {
+ preloader.getUnavailableMediaIndexes().observe(
+ /* lifecycleOwner */ PhotoPickerActivity.this,
+ unavailableMediaIndexes -> {
+ if (unavailableMediaIndexes.size() > 0) {
+ // To notify the fragment to uncheck the unavailable items at UI those are
+ // no longer available in the selection list.
+ mIsItemPhotoGridViewChanged.postValue(true);
+ // Displaying error dialog with an error message when the user tries
+ // to add unavailable cloud only media (not cached) while offline.
+ DialogUtils.showDialog(this,
+ getResources().getString(R.string.dialog_error_title),
+ getResources().getString(R.string.dialog_error_message));
+
+ List<Item> selectedItems = mSelection.getSelectedItems();
+ for (var mediaIndex : unavailableMediaIndexes) {
+ mSelection.removeSelectedItem(selectedItems.get(mediaIndex));
+ }
+ }
+ });
+ }
+
/**
* NOTE: this may wrongly return {@code false} if called before {@link PickerViewModel} had a
* chance to fetch the authority and the account of the current
@@ -840,15 +875,32 @@ public class PhotoPickerActivity extends AppCompatActivity {
* Reset to Photo Picker initial launch state (Photos grid tab) in personal profile mode.
*/
private void resetToPersonalProfile() {
+ // Clear all the fragments in the FragmentManager
+ final FragmentManager fragmentManager = getSupportFragmentManager();
+ fragmentManager.popBackStackImmediate(/* name */ null,
+ FragmentManager.POP_BACK_STACK_INCLUSIVE);
+
+ // Reset all content to the personal profile
mPickerViewModel.resetToPersonalProfile();
+
+ // Set up the fragments same as the initial launch state
setupInitialLaunchState();
}
/**
* Reset to Photo Picker initial launch state (Photos grid tab) in the current profile mode.
*/
- private void resetInCurrentProfile() {
+ @VisibleForTesting
+ public void resetInCurrentProfile() {
+ // Clear all the fragments in the FragmentManager
+ final FragmentManager fragmentManager = getSupportFragmentManager();
+ fragmentManager.popBackStackImmediate(/* name */ null,
+ FragmentManager.POP_BACK_STACK_INCLUSIVE);
+
+ // Reset all content in the current profile
mPickerViewModel.resetAllContentInCurrentProfile();
+
+ // Set up the fragments same as the initial launch state
setupInitialLaunchState();
}
@@ -978,11 +1030,6 @@ public class PhotoPickerActivity extends AppCompatActivity {
}
private void switchToPersonalProfileInitialLaunchState() {
- final FragmentManager fragmentManager = getSupportFragmentManager();
- // Clear all back stacks in FragmentManager
- fragmentManager.popBackStackImmediate(/* name */ null,
- FragmentManager.POP_BACK_STACK_INCLUSIVE);
-
// We reset the state of the PhotoPicker as we do not want to make any
// assumptions on the state of the PhotoPicker when it was in Work Profile mode.
resetToPersonalProfile();
diff --git a/src/com/android/providers/media/photopicker/PickerDataLayer.java b/src/com/android/providers/media/photopicker/PickerDataLayer.java
index 51543917a..b479b45b1 100644
--- a/src/com/android/providers/media/photopicker/PickerDataLayer.java
+++ b/src/com/android/providers/media/photopicker/PickerDataLayer.java
@@ -26,6 +26,8 @@ import static android.provider.MediaStore.MY_UID;
import static com.android.providers.media.PickerUriResolver.getAlbumUri;
import static com.android.providers.media.PickerUriResolver.getMediaCollectionInfoUri;
+import static com.android.providers.media.photopicker.sync.PickerSyncManager.IMMEDIATE_ALBUM_SYNC_WORK_NAME;
+import static com.android.providers.media.photopicker.sync.PickerSyncManager.IMMEDIATE_LOCAL_SYNC_WORK_NAME;
import static java.util.Objects.requireNonNull;
@@ -55,6 +57,7 @@ import com.android.providers.media.photopicker.metrics.NonUiEventLogger;
import com.android.providers.media.photopicker.sync.PickerSyncManager;
import com.android.providers.media.photopicker.sync.SyncTracker;
import com.android.providers.media.photopicker.sync.SyncTrackerRegistry;
+import com.android.providers.media.util.ForegroundThread;
import java.util.ArrayList;
import java.util.Arrays;
@@ -64,6 +67,8 @@ import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -80,8 +85,18 @@ public class PickerDataLayer {
public static final String QUERY_DATE_TAKEN_BEFORE_MS = "android:query-date-taken-before-ms";
+ public static final String QUERY_LOCAL_ID_SELECTION = "android:query-local-id-selection";
+
public static final String QUERY_ROW_ID = "android:query-row-id";
+ // Thread pool size should be at least equal to the number of unique work requests in
+ // {@link PickerSyncManager} to ensure that any request type is not blocked on other request
+ // types. It is advisable to use unique work requests because in case the number of queued
+ // requests grows, they should not block other work requests.
+ private static final int WORK_MANAGER_THREAD_POOL_SIZE = 5;
+ @Nullable
+ private static volatile Executor sWorkManagerExecutor;
+
@NonNull
private final Context mContext;
@NonNull
@@ -95,22 +110,31 @@ public class PickerDataLayer {
@NonNull
private final ConfigStore mConfigStore;
- public PickerDataLayer(@NonNull Context context, @NonNull PickerDbFacade dbFacade,
- @NonNull PickerSyncController syncController, @NonNull ConfigStore configStore) {
- this(context, dbFacade, syncController, configStore, /* schedulePeriodicSyncs */ true);
- }
-
@VisibleForTesting
public PickerDataLayer(@NonNull Context context, @NonNull PickerDbFacade dbFacade,
@NonNull PickerSyncController syncController, @NonNull ConfigStore configStore,
- boolean schedulePeriodicSyncs) {
+ @NonNull PickerSyncManager syncManager) {
mContext = requireNonNull(context);
mDbFacade = requireNonNull(dbFacade);
mSyncController = requireNonNull(syncController);
mLocalProvider = requireNonNull(dbFacade.getLocalProvider());
mConfigStore = requireNonNull(configStore);
- mSyncManager = new PickerSyncManager(
- getWorkManager(), configStore, schedulePeriodicSyncs);
+ mSyncManager = syncManager;
+
+ // Add a subscriber to config store changes to monitor the allowlist.
+ mConfigStore.addOnChangeListener(
+ ForegroundThread.getExecutor(),
+ this::validateCurrentCloudProviderOnAllowlistChange);
+ }
+
+ /**
+ * Create a new instance of PickerDataLayer.
+ */
+ public static PickerDataLayer create(@NonNull Context context, @NonNull PickerDbFacade dbFacade,
+ @NonNull PickerSyncController syncController, @NonNull ConfigStore configStore) {
+ PickerSyncManager syncManager = new PickerSyncManager(
+ getWorkManager(context), context, configStore, /* schedulePeriodicSyncs */ true);
+ return new PickerDataLayer(context, dbFacade, syncController, configStore, syncManager);
}
/**
@@ -157,7 +181,8 @@ public class PickerDataLayer {
syncAllMedia(isLocalOnly);
} else {
// Wait for local sync to finish indefinitely
- waitForSync(SyncTrackerRegistry.getLocalSyncTracker());
+ waitForSync(SyncTrackerRegistry.getLocalSyncTracker(),
+ IMMEDIATE_LOCAL_SYNC_WORK_NAME);
Log.i(TAG, "Local sync is complete");
// Wait for on cloud sync with timeout
@@ -188,7 +213,8 @@ public class PickerDataLayer {
if (shouldSyncBeforePickerQuery()) {
mSyncController.syncAlbumMedia(albumId, isLocal(albumAuthority));
} else {
- waitForSync(SyncTrackerRegistry.getAlbumSyncTracker(isLocal(albumAuthority)));
+ waitForSync(SyncTrackerRegistry.getAlbumSyncTracker(isLocal(albumAuthority)),
+ IMMEDIATE_ALBUM_SYNC_WORK_NAME);
Log.i(TAG, "Album sync is complete");
}
@@ -220,10 +246,58 @@ public class PickerDataLayer {
}
}
- private void waitForSync(@NonNull SyncTracker syncTracker) {
- waitForSyncWithTimeout(syncTracker, /* timeout */ null);
+ /**
+ * Will try it's best to wait for the existing sync requests to complete. It may not wait for
+ * new sync requests received after this method starts running.
+ */
+ private void waitForSync(@NonNull SyncTracker syncTracker, String uniqueWorkName) {
+ try {
+ final CompletableFuture<Void> completableFuture =
+ CompletableFuture.allOf(
+ syncTracker.pendingSyncFutures().toArray(new CompletableFuture[0]));
+
+ waitForSync(completableFuture, uniqueWorkName, /* retryCount */ 30);
+ } catch (ExecutionException | InterruptedException e) {
+ Log.w(TAG, "Could not wait for the sync to finish: " + e);
+ }
+ }
+
+ /**
+ * Wait for sync tracked by the input future to complete. In case the future takes an unusually
+ * long time to complete, check the relevant unique work status from Work Manager.
+ */
+ @VisibleForTesting
+ public int waitForSync(@NonNull CompletableFuture<Void> completableFuture,
+ @NonNull String uniqueWorkName,
+ int retryCount) throws ExecutionException, InterruptedException {
+ for (; retryCount > 0; retryCount--) {
+ try {
+ completableFuture.get(/* timeout */ 3, TimeUnit.SECONDS);
+ return retryCount;
+ } catch (TimeoutException e) {
+ if (mSyncManager.isUniqueWorkPending(uniqueWorkName)) {
+ Log.i(TAG, "Waiting for the sync again."
+ + " Unique work name: " + uniqueWorkName
+ + " Retry count: " + retryCount);
+ } else {
+ Log.e(TAG, "Either immediate unique work is complete and the sync futures "
+ + "were not cleared, or a proactive sync might be blocking the query. "
+ + "Unblocking the query now for " + uniqueWorkName);
+ return retryCount;
+ }
+ }
+ }
+
+ if (retryCount == 0) {
+ Log.e(TAG, "Retry count exhausted, could not wait for sync anymore.");
+ }
+ return retryCount;
}
+ /**
+ * Will wait for the existing sync requests to complete till the provided timeout. It may
+ * not wait for new sync requests received after this method starts running.
+ */
private boolean waitForSyncWithTimeout(
@NonNull SyncTracker syncTracker,
@Nullable Long timeoutInMillis) {
@@ -231,14 +305,10 @@ public class PickerDataLayer {
final CompletableFuture<Void> completableFuture =
CompletableFuture.allOf(
syncTracker.pendingSyncFutures().toArray(new CompletableFuture[0]));
- if (timeoutInMillis == null) {
- completableFuture.get();
- } else {
- completableFuture.get(timeoutInMillis, TimeUnit.MILLISECONDS);
- }
+ completableFuture.get(timeoutInMillis, TimeUnit.MILLISECONDS);
return true;
} catch (ExecutionException | InterruptedException | TimeoutException e) {
- Log.w(TAG, "Could not wait for the sync to finish: " + e);
+ Log.w(TAG, "Could not wait for the sync with timeout to finish: " + e);
return false;
}
}
@@ -288,7 +358,8 @@ public class PickerDataLayer {
cursorExtra.putString(MediaStore.EXTRA_LOCAL_PROVIDER, mLocalProvider);
// Favorites and Videos are merged albums.
- final Cursor mergedAlbums = mDbFacade.getMergedAlbums(queryExtras.toQueryFilter());
+ final Cursor mergedAlbums = mDbFacade.getMergedAlbums(queryExtras.toQueryFilter(),
+ cloudProvider);
if (mergedAlbums != null) {
cursors.add(mergedAlbums);
}
@@ -445,7 +516,7 @@ public class PickerDataLayer {
if (!syncRequestExtras.shouldSyncMergedAlbum()) {
mSyncManager.syncAlbumMediaForProviderImmediately(
syncRequestExtras.getAlbumId(),
- isLocal(syncRequestExtras.getAlbumAuthority()));
+ syncRequestExtras.getAlbumAuthority());
}
}
}
@@ -473,7 +544,13 @@ public class PickerDataLayer {
* local providers.
*/
public void handleMediaEventNotification() {
- mSyncManager.syncAllMediaProactively();
+ try {
+ mSyncManager.syncAllMediaProactively();
+ } catch (RuntimeException e) {
+ // Catch any unchecked exceptions so that critical paths in MP that call this method are
+ // not affected by Picker related issues.
+ Log.e(TAG, "Could not handle media event notification ", e);
+ }
}
public static class AccountInfo {
@@ -589,7 +666,7 @@ public class PickerDataLayer {
* @return a {@link WorkManager} object that can be used to run work requests.
*/
@NonNull
- private WorkManager getWorkManager() {
+ private static WorkManager getWorkManager(Context mContext) {
if (!WorkManager.isInitialized()) {
Log.i(TAG, "Work manager not initialised. Attempting to initialise.");
WorkManager.initialize(mContext, getWorkManagerConfiguration());
@@ -599,11 +676,24 @@ public class PickerDataLayer {
@NonNull
private static Configuration getWorkManagerConfiguration() {
+ ensureWorkManagerExecutor();
return new Configuration.Builder()
.setMinimumLoggingLevel(Log.INFO)
+ .setExecutor(sWorkManagerExecutor)
.build();
}
+ private static void ensureWorkManagerExecutor() {
+ if (sWorkManagerExecutor == null) {
+ synchronized (PickerDataLayer.class) {
+ if (sWorkManagerExecutor == null) {
+ sWorkManagerExecutor = Executors
+ .newFixedThreadPool(WORK_MANAGER_THREAD_POOL_SIZE);
+ }
+ }
+ }
+ }
+
/**
* For cloud feature enabled scenarios, sync request is sent from the
* MediaStore.PICKER_MEDIA_INIT_CALL method call once when a fresh grid needs to be filled
@@ -614,4 +704,27 @@ public class PickerDataLayer {
private boolean shouldSyncBeforePickerQuery() {
return !mConfigStore.isCloudMediaInPhotoPickerEnabled();
}
+
+ /**
+ * Checks the current allowed list of Cloud Provider packages, and ensures that the currently
+ * set provider is a member of the allowlist. In the event the current Cloud Provider is not on
+ * the list, the current Cloud Provider is removed.
+ */
+ private void validateCurrentCloudProviderOnAllowlistChange() {
+
+ List<String> currentAllowlist = mConfigStore.getAllowedCloudProviderPackages();
+ String currentCloudProvider = mSyncController.getCurrentCloudProviderInfo().packageName;
+
+ if (!currentAllowlist.contains(currentCloudProvider)) {
+ Log.d(
+ TAG,
+ String.format(
+ "Cloud provider allowlist was changed, and the current cloud provider"
+ + " is no longer on the allowlist."
+ + " Allowlist: %s"
+ + " Current Provider: %s",
+ currentAllowlist.toString(), currentCloudProvider));
+ mSyncController.notifyPackageRemoval(currentCloudProvider);
+ }
+ }
}
diff --git a/src/com/android/providers/media/photopicker/PickerSyncController.java b/src/com/android/providers/media/photopicker/PickerSyncController.java
index 347be1fde..c12bdaa81 100644
--- a/src/com/android/providers/media/photopicker/PickerSyncController.java
+++ b/src/com/android/providers/media/photopicker/PickerSyncController.java
@@ -138,6 +138,9 @@ public class PickerSyncController {
private final String mLocalProvider;
private final Object mCloudSyncLock = new Object();
+ private final Object mCloudAlbumSyncLock = new Object();
+
+
// TODO(b/278562157): If there is a dependency on the sync process, always acquire the
// {@link mCloudSyncLock} before {@link mCloudProviderLock} to avoid deadlock.
private final Object mCloudProviderLock = new Object();
@@ -215,6 +218,8 @@ public class PickerSyncController {
mDbFacade = dbFacade;
mLocalProvider = localProvider;
+ // Listen to the device config, and try to enable cloud features when the config changes.
+ mConfigStore.addOnChangeListener(BackgroundThread.getExecutor(), this::initCloudProvider);
initCloudProvider();
}
@@ -256,6 +261,14 @@ public class PickerSyncController {
}
/**
+ * Returns the sync lock object for Cloud albums.
+ * @return the lock object for protecting synchronized code related to cloud albums.
+ */
+ public Object getCloudAlbumSyncLock() {
+ return mCloudAlbumSyncLock;
+ }
+
+ /**
* Syncs the local and currently enabled cloud {@link CloudMediaProvider} instances
*/
public void syncAllMedia() {
@@ -290,6 +303,7 @@ public class PickerSyncController {
* Syncs the cloud media
*/
public void syncAllMediaFromCloudProvider() {
+
synchronized (mCloudSyncLock) {
final String cloudProvider = getCloudProvider();
@@ -305,10 +319,6 @@ public class PickerSyncController {
+ ". The cloud provider may have changed during the sync, or only a"
+ " partial sync was completed.");
}
-
- // Reset the album_media table every time we sync all media
- // TODO(258765155): do we really need to reset for both providers?
- resetAlbumMedia();
}
}
@@ -318,8 +328,12 @@ public class PickerSyncController {
*/
public void syncAlbumMedia(String albumId, boolean isLocal) {
if (isLocal) {
+ executeSyncAlbumReset(getLocalProvider(), isLocal, albumId);
syncAlbumMediaFromLocalProvider(albumId);
} else {
+ synchronized (mCloudAlbumSyncLock) {
+ executeSyncAlbumReset(getCloudProvider(), isLocal, albumId);
+ }
syncAlbumMediaFromCloudProvider(albumId);
}
}
@@ -336,20 +350,12 @@ public class PickerSyncController {
* Syncs album media from the currently enabled cloud {@link CloudMediaProvider}.
*/
public void syncAlbumMediaFromCloudProvider(@NonNull String albumId) {
- synchronized (mCloudSyncLock) {
+ synchronized (mCloudAlbumSyncLock) {
syncAlbumMediaFromProvider(getCloudProvider(), /* isLocal */ false, albumId,
/* enforcePagedSync*/ true);
}
}
- private void resetAlbumMedia() {
- executeSyncAlbumReset(mLocalProvider, /* isLocal */ true, /* albumId */ null);
-
- synchronized (mCloudSyncLock) {
- executeSyncAlbumReset(getCloudProvider(), /* isLocal */ false, /* albumId */ null);
- }
- }
-
/**
* Resets media library previously synced from the current {@link CloudMediaProvider} as well
* as the {@link #mLocalProvider local provider}.
@@ -440,12 +446,6 @@ public class PickerSyncController {
Log.v(TAG, "Thread=" + Thread.currentThread() + "; Stacktrace:", new Throwable());
}
- if (!mConfigStore.isCloudMediaInPhotoPickerEnabled()) {
- Log.w(TAG, "Ignoring a request to set the CloudMediaProvider (" + authority + ") "
- + "since the Cloud-Media-in-Photo-Picker feature is disabled");
- return false;
- }
-
synchronized (mCloudProviderLock) {
if (Objects.equals(mCloudProviderInfo.authority, authority)) {
Log.w(TAG, "Cloud provider already set: " + authority);
@@ -618,8 +618,6 @@ public class PickerSyncController {
Trace.beginSection(traceSectionName("syncAlbumMediaFromProvider", isLocal));
try {
- executeSyncAlbumReset(authority, isLocal, albumId);
-
if (authority != null) {
executeSyncAddAlbum(authority, isLocal, albumId, queryArgs, instanceId);
}
@@ -628,6 +626,8 @@ public class PickerSyncController {
// occurred in fetching all the album_media since incremental sync is not supported.
// A full sync is therefore unlikely to resolve any issue
Log.e(TAG, "Failed to sync album media", e);
+ } catch (RequestObsoleteException e) {
+ Log.e(TAG, "Failed to sync all album media because authority has changed: ", e);
} finally {
Trace.endSection();
}
@@ -785,18 +785,29 @@ public class PickerSyncController {
}
/**
- * Queries the provider and writes the data returned to the db.
- *
- * <p> Also validates the cursor returned from provider has expected extras of not.
+ * Queries the provider and adds media to the picker database.
*
+ * @param authority Provider's authority
+ * @param isLocal Whether this is the local provider or not
+ * @param expectedMediaCollectionId The MediaCollectionId from the last sync point.
* @param isIncrementalSync If true, {@link CloudMediaProviderContract#EXTRA_SYNC_GENERATION}
- * should be honoured by the provider.
- * @param enforcePagedSync If true, {@link CloudMediaProviderContract#EXTRA_PAGE_SIZE} should
- * be honoured by the provider.
+ * should be honoured by the provider.
+ * @param enforcePagedSync If true, {@link CloudMediaProviderContract#EXTRA_PAGE_SIZE} should be
+ * honoured by the provider.
+ * @param queryArgs Query arguments to pass in query.
+ * @param instanceId Metrics related Picker session instance Id.
+ * @throws RequestObsoleteException When the sync is interrupted due to the provider
+ * changing.
*/
- private void executeSyncAdd(String authority, boolean isLocal,
- String expectedMediaCollectionId, boolean isIncrementalSync, boolean enforcePagedSync,
- Bundle queryArgs, InstanceId instanceId) {
+ private void executeSyncAdd(
+ String authority,
+ boolean isLocal,
+ String expectedMediaCollectionId,
+ boolean isIncrementalSync,
+ boolean enforcePagedSync,
+ Bundle queryArgs,
+ InstanceId instanceId)
+ throws RequestObsoleteException {
final Uri uri = getMediaUri(authority);
final List<String> expectedHonoredArgs = new ArrayList<>();
if (isIncrementalSync) {
@@ -821,7 +832,8 @@ public class PickerSyncController {
queryArgs,
resumeKey,
OPERATION_ADD_MEDIA,
- authority);
+ authority,
+ isLocal);
NonUiEventLogger.logPickerAddMediaSyncCompletion(instanceId, MY_UID, authority,
syncedItems);
} finally {
@@ -829,8 +841,24 @@ public class PickerSyncController {
}
}
- private void executeSyncAddAlbum(String authority, boolean isLocal,
- String albumId, Bundle queryArgs, InstanceId instanceId) {
+ /**
+ * Queries the provider to sync media from the given albumId into the picker database.
+ *
+ * @param authority Provider's authority
+ * @param isLocal Whether this is the local provider or not
+ * @param albumId the Id of the album to sync
+ * @param queryArgs Query arguments to pass in query.
+ * @param instanceId Metrics related Picker session instance Id.
+ * @throws RequestObsoleteException When the sync is interrupted due to the provider
+ * changing.
+ */
+ private void executeSyncAddAlbum(
+ String authority,
+ boolean isLocal,
+ String albumId,
+ Bundle queryArgs,
+ InstanceId instanceId)
+ throws RequestObsoleteException {
final Uri uri = getMediaUri(authority);
Log.i(TAG, "Executing SyncAddAlbum. "
@@ -843,9 +871,17 @@ public class PickerSyncController {
// We don't need to validate the mediaCollectionId for album_media sync since it's
// always a full sync
- int syncedItems = executePagedSync(uri, /* mediaCollectionId */ null,
- List.of(EXTRA_ALBUM_ID), queryArgs, resumeKey, OPERATION_ADD_ALBUM, authority,
- albumId);
+ int syncedItems =
+ executePagedSync(
+ uri, /* mediaCollectionId */
+ null,
+ List.of(EXTRA_ALBUM_ID),
+ queryArgs,
+ resumeKey,
+ OPERATION_ADD_ALBUM,
+ authority,
+ isLocal,
+ albumId);
NonUiEventLogger.logPickerAddAlbumMediaSyncCompletion(instanceId, MY_UID, authority,
syncedItems);
} finally {
@@ -853,8 +889,24 @@ public class PickerSyncController {
}
}
- private void executeSyncRemove(String authority, boolean isLocal,
- String mediaCollectionId, Bundle queryArgs, InstanceId instanceId) {
+ /**
+ * Queries the provider and syncs removed media with the picker database.
+ *
+ * @param authority Provider's authority
+ * @param isLocal Whether this is the local provider or not
+ * @param mediaCollectionId The last synced media collection id
+ * @param queryArgs Query arguments to pass in query.
+ * @param instanceId Metrics related Picker session instance Id.
+ * @throws RequestObsoleteException When the sync is interrupted due to the provider
+ * changing.
+ */
+ private void executeSyncRemove(
+ String authority,
+ boolean isLocal,
+ String mediaCollectionId,
+ Bundle queryArgs,
+ InstanceId instanceId)
+ throws RequestObsoleteException {
final Uri uri = getDeletedMediaUri(authority);
Log.i(TAG, "Executing SyncRemove. isLocal: " + isLocal + ". authority: " + authority);
@@ -863,9 +915,16 @@ public class PickerSyncController {
Trace.beginSection(traceSectionName("executeSyncRemove", isLocal));
try {
- int syncedItems = executePagedSync(uri, mediaCollectionId,
- List.of(EXTRA_SYNC_GENERATION), queryArgs, resumeKey, OPERATION_REMOVE_MEDIA,
- authority);
+ int syncedItems =
+ executePagedSync(
+ uri,
+ mediaCollectionId,
+ List.of(EXTRA_SYNC_GENERATION),
+ queryArgs,
+ resumeKey,
+ OPERATION_REMOVE_MEDIA,
+ authority,
+ isLocal);
NonUiEventLogger.logPickerRemoveMediaSyncCompletion(instanceId, MY_UID, authority,
syncedItems);
} finally {
@@ -1002,7 +1061,7 @@ public class PickerSyncController {
*/
private void rememberNextPageToken(@Nullable String token, String resumeKey) {
- synchronized (mCloudSyncLock) {
+ synchronized (mCloudProviderLock) {
final SharedPreferences.Editor editor = mSyncPrefs.edit();
if (token == null) {
Log.d(TAG, String.format("Clearing next page token for key: %s", resumeKey));
@@ -1176,6 +1235,8 @@ public class PickerSyncController {
* between pages.
* @param op The DbWriteOperation type. {@link OperationType}
* @param authority The authority string of the provider to sync with.
+ * @throws RequestObsoleteException When the sync is interrupted due to the provider
+ * changing.
* @return the total number of rows synced.
*/
private int executePagedSync(
@@ -1185,7 +1246,8 @@ public class PickerSyncController {
Bundle queryArgs,
@Nullable String resumeKey,
@OperationType int op,
- String authority) {
+ String authority,
+ Boolean isLocal) throws RequestObsoleteException {
return executePagedSync(
uri,
expectedMediaCollectionId,
@@ -1194,6 +1256,7 @@ public class PickerSyncController {
resumeKey,
op,
authority,
+ isLocal,
/* albumId=*/ null);
}
@@ -1212,6 +1275,8 @@ public class PickerSyncController {
* @param op The DbWriteOperation type. {@link OperationType}
* @param authority The authority string of the provider to sync with.
* @param albumId A {@link Nullable} albumId for album related operations.
+ * @throws RequestObsoleteException When the sync is interrupted due to the provider
+ * changing.
* @return the total number of rows synced.
*/
private int executePagedSync(
@@ -1222,7 +1287,8 @@ public class PickerSyncController {
@Nullable String resumeKey,
@OperationType int op,
String authority,
- @Nullable String albumId) {
+ Boolean isLocal,
+ @Nullable String albumId) throws RequestObsoleteException {
Trace.beginSection(traceSectionName("executePagedSync"));
try {
@@ -1241,33 +1307,55 @@ public class PickerSyncController {
do {
String updateDateTakenMs = null;
- try (PickerDbFacade.DbWriteOperation operation =
- beginPagedOperation(op, authority, albumId)) {
-
- if (nextPageToken != null) {
- queryArgs.putString(EXTRA_PAGE_TOKEN, nextPageToken);
- }
-
- try (Cursor cursor = query(uri, queryArgs)) {
- nextPageToken =
- validateCursor(
- cursor,
- expectedMediaCollectionId,
- expectedHonoredArgs,
- tokens);
+ if (nextPageToken != null) {
+ queryArgs.putString(EXTRA_PAGE_TOKEN, nextPageToken);
+ }
+ try (Cursor cursor = query(uri, queryArgs)) {
+ nextPageToken =
+ validateCursor(
+ cursor,
+ expectedMediaCollectionId,
+ expectedHonoredArgs,
+ tokens);
+ try (PickerDbFacade.DbWriteOperation operation =
+ beginPagedOperation(op, authority, albumId)) {
int writeCount = operation.execute(cursor);
+ if (!isLocal) {
+ // Ensure the cloud provider hasn't change out from underneath the
+ // running sync. If it has, we need to stop syncing.
+ String currentCloudProvider = getCloudProvider();
+ if (TextUtils.isEmpty(currentCloudProvider)
+ || !currentCloudProvider.equals(authority)) {
+
+ throw new RequestObsoleteException(
+ String.format(
+ "Aborting sync: the CloudProvider seems to have"
+ + " changed mid-sync. Old: %s Current: %s",
+ authority, currentCloudProvider));
+ }
+ }
+
+ operation.setSuccess();
totalRowcount += writeCount;
- // Before the cursor is closed pull the date taken ms for the first row.
- updateDateTakenMs = getFirstDateTakenMsInCursor(cursor);
+ if (cursor.getCount() > 0) {
+ // Before the cursor is closed pull the date taken ms for the first row.
+ updateDateTakenMs = getFirstDateTakenMsInCursor(cursor);
+
+ // If the cursor count is not null and the date taken field is not
+ // present in the cursor, fallback on the operation to provide the date
+ // taken.
+ if (updateDateTakenMs == null) {
+ updateDateTakenMs = getFirstDateTakenMsFromOperation(operation);
+ }
+ }
}
- operation.setSuccess();
-
} catch (IllegalArgumentException ex) {
- Log.e(TAG, String.format("Failed to open DbWriteOperation for op: %d", op), ex);
+ Log.e(TAG, String.format("Failed to open DbWriteOperation for op: %d", op),
+ ex);
return -1;
}
@@ -1307,14 +1395,25 @@ public class PickerSyncController {
*/
@Nullable
private String getFirstDateTakenMsInCursor(Cursor cursor) {
- if (cursor.getCount() > 0) {
- cursor.moveToFirst();
+ if (cursor.moveToFirst()) {
return getCursorString(cursor, MediaColumns.DATE_TAKEN_MILLIS);
}
return null;
}
/**
+ * Extracts the first row's date taken from the operation. Note that all functions may not
+ * implement this method.
+ */
+ private String getFirstDateTakenMsFromOperation(PickerDbFacade.DbWriteOperation op) {
+ final long firstDateTakenMillis = op.getFirstDateTakenMillis();
+
+ return firstDateTakenMillis == Long.MIN_VALUE
+ ? null
+ : Long.toString(firstDateTakenMillis);
+ }
+
+ /**
* Assembles a ContentObserver notification uri for the given operation.
*
* @param op {@link OperationType} the operation to notify has completed.
diff --git a/src/com/android/providers/media/photopicker/SelectedMediaPreloader.java b/src/com/android/providers/media/photopicker/SelectedMediaPreloader.java
index 661345bdb..7419f01cf 100644
--- a/src/com/android/providers/media/photopicker/SelectedMediaPreloader.java
+++ b/src/com/android/providers/media/photopicker/SelectedMediaPreloader.java
@@ -73,6 +73,9 @@ class SelectedMediaPreloader {
@NonNull
private final MutableLiveData<Boolean> mIsFinishedLiveData = new MutableLiveData<>(false);
@NonNull
+ private final MutableLiveData<List<Integer>> mUnavailableMediaIndexes =
+ new MutableLiveData<>(new ArrayList<>());
+ @NonNull
private final ContentResolver mContentResolver;
/**
@@ -107,24 +110,24 @@ class SelectedMediaPreloader {
Trace.beginAsyncSection(TRACE_SECTION_NAME, /* cookie */ preloader.hashCode());
- final var dialog = createProgressDialog(activity, items);
+ final var dialog = createProgressDialog(activity, items, context);
preloader.mIsFinishedLiveData.observeForever(new Observer<>() {
@Override
public void onChanged(Boolean isFinished) {
if (isFinished) {
preloader.mIsFinishedLiveData.removeObserver(this);
- dialog.dismiss();
-
Trace.endAsyncSection(TRACE_SECTION_NAME, /* cookie */ preloader.hashCode());
}
}
});
+
preloader.mFinishedCountLiveData.observeForever(new Observer<>() {
@Override
public void onChanged(Integer finishedCount) {
if (finishedCount == count) {
preloader.mFinishedCountLiveData.removeObserver(this);
+ dialog.dismiss();
}
// "X of Y ready"
final String message = context.getString(
@@ -155,18 +158,28 @@ class SelectedMediaPreloader {
return mIsFinishedLiveData;
}
+ @NonNull
+ LiveData<List<Integer>> getUnavailableMediaIndexes() {
+ return mUnavailableMediaIndexes;
+ }
+
/**
* This method is intentionally {@code private}: clients should use static
* {@link #preload(Context, List)} method.
*/
@UiThread
private void start(@NonNull Executor executor) {
- for (var item : mItems) {
+ List<Integer> unavailableMediaIndexes = new ArrayList<>();
+ for (int index = 0; index < mItems.size(); index++) {
+ int currIndex = index;
// Off-loading to an Executor (presumable backed up by a thread pool)
executor.execute(new Runnable() {
@Override
public void run() {
- openFileDescriptor(item);
+ boolean isOpenedSuccessfully = openFileDescriptor(mItems.get(currIndex));
+ if (!isOpenedSuccessfully) {
+ unavailableMediaIndexes.add(currIndex);
+ }
final int preloadedCount = mFinishedCount.incrementAndGet();
if (DEBUG) {
@@ -175,7 +188,12 @@ class SelectedMediaPreloader {
if (preloadedCount == mCount) {
// Don't need to "synchronize" here: mCount is our final value for
// preloadedCount, it won't be changing anymore.
- mIsFinishedLiveData.postValue(true);
+ if (unavailableMediaIndexes.size() == 0) {
+ mIsFinishedLiveData.postValue(true);
+ } else {
+ mUnavailableMediaIndexes.postValue(unavailableMediaIndexes);
+ mIsFinishedLiveData.postValue(false);
+ }
}
// In order to prevent race conditions where we may "post" a lower value after
@@ -190,7 +208,8 @@ class SelectedMediaPreloader {
}
@Nullable
- private void openFileDescriptor(@NonNull Uri uri) {
+ private Boolean openFileDescriptor(@NonNull Uri uri) {
+ Boolean isOpenedSuccessfully = true;
long start = 0;
if (DEBUG) {
Log.d(TAG, "openFileDescriptor() START, " + Thread.currentThread() + ", " + uri);
@@ -201,6 +220,7 @@ class SelectedMediaPreloader {
try {
mContentResolver.openAssetFileDescriptor(uri, "r");
} catch (FileNotFoundException e) {
+ isOpenedSuccessfully = false;
Log.w(TAG, "Could not open FileDescriptor for " + uri, e);
} finally {
Trace.endSection();
@@ -211,22 +231,27 @@ class SelectedMediaPreloader {
+ ", " + uri);
}
}
+ return isOpenedSuccessfully;
}
@NonNull
private static AlertDialog createProgressDialog(
- @NonNull Activity activity, @NonNull List<Uri> selectedMedia) {
- return ProgressDialog.show(activity,
- /* tile */ "Preparing your selected media",
- /* message */ "0 of " + selectedMedia.size() + " ready.",
- /* indeterminate */ true);
+ @NonNull Activity activity, @NonNull List<Uri> selectedMedia, Context context) {
+ ProgressDialog dialog = new ProgressDialog(activity,
+ R.style.SelectedMediaPreloaderDialogTheme);
+ dialog.setTitle(/* title */ context.getString(R.string.preloading_dialog_title));
+ dialog.setMessage(/* message */ context.getString(
+ R.string.preloading_progress_message, 0, selectedMedia.size()));
+ dialog.setIndeterminate(/* indeterminate */ true);
+ dialog.show();
+ return dialog;
}
private static void ensureExecutor() {
if (sExecutor == null) {
synchronized (SelectedMediaPreloader.class) {
if (sExecutor == null) {
- final ThreadFactory threadFactory = new ThreadFactory() {
+ sExecutor = Executors.newFixedThreadPool(2, new ThreadFactory() {
final AtomicInteger mCount = new AtomicInteger(1);
@@ -250,8 +275,7 @@ class SelectedMediaPreloader {
}
};
}
- };
- sExecutor = Executors.newCachedThreadPool(threadFactory);
+ });
}
}
}
diff --git a/src/com/android/providers/media/photopicker/data/CloudProviderQueryExtras.java b/src/com/android/providers/media/photopicker/data/CloudProviderQueryExtras.java
index b569f6953..48fd6040d 100644
--- a/src/com/android/providers/media/photopicker/data/CloudProviderQueryExtras.java
+++ b/src/com/android/providers/media/photopicker/data/CloudProviderQueryExtras.java
@@ -18,10 +18,12 @@ package com.android.providers.media.photopicker.data;
import static android.content.ContentResolver.QUERY_ARG_LIMIT;
import static com.android.providers.media.photopicker.PickerDataLayer.QUERY_DATE_TAKEN_BEFORE_MS;
+import static com.android.providers.media.photopicker.PickerDataLayer.QUERY_LOCAL_ID_SELECTION;
import static com.android.providers.media.photopicker.PickerDataLayer.QUERY_ROW_ID;
import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.BOOLEAN_DEFAULT;
import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.INT_DEFAULT;
import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.LIMIT_DEFAULT;
+import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.LIST_DEFAULT;
import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.LONG_DEFAULT;
import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.STRING_ARRAY_DEFAULT;
import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.STRING_DEFAULT;
@@ -34,6 +36,8 @@ import android.provider.MediaStore;
import com.android.providers.media.photopicker.PickerDataLayer;
+import java.util.List;
+
/**
* Represents the {@link CloudMediaProviderContract} extra filters from a {@link Bundle}.
*/
@@ -51,6 +55,8 @@ public class CloudProviderQueryExtras {
private final long mDateTakenBeforeMs;
private final int mRowId;
+ private final List<Integer> mLocalIdSelection;
+
private CloudProviderQueryExtras() {
mAlbumId = STRING_DEFAULT;
mAlbumAuthority = STRING_DEFAULT;
@@ -62,13 +68,15 @@ public class CloudProviderQueryExtras {
mIsVideo = BOOLEAN_DEFAULT;
mIsLocalOnly = BOOLEAN_DEFAULT;
mPageSize = INT_DEFAULT;
- mDateTakenBeforeMs = LONG_DEFAULT;
+ mDateTakenBeforeMs = Long.MIN_VALUE;
mRowId = INT_DEFAULT;
+ mLocalIdSelection = LIST_DEFAULT;
}
private CloudProviderQueryExtras(String albumId, String albumAuthority, String[] mimeTypes,
long sizeBytes, long generation, int limit, boolean isFavorite, boolean isVideo,
- boolean isLocalOnly, int pageSize, long dateTakenBeforeMs, int rowId) {
+ boolean isLocalOnly, int pageSize, long dateTakenBeforeMs, int rowId,
+ List<Integer> localIdSelection) {
mAlbumId = albumId;
mAlbumAuthority = albumAuthority;
mMimeTypes = mimeTypes;
@@ -81,6 +89,7 @@ public class CloudProviderQueryExtras {
mPageSize = pageSize;
mDateTakenBeforeMs = dateTakenBeforeMs;
mRowId = rowId;
+ mLocalIdSelection = localIdSelection;
}
/**
@@ -106,12 +115,13 @@ public class CloudProviderQueryExtras {
final boolean isLocalOnly = bundle.getBoolean(PickerDataLayer.QUERY_ARG_LOCAL_ONLY,
BOOLEAN_DEFAULT);
final int pageSize = INT_DEFAULT;
- final Long dateTakenBeforeMs = bundle.getLong(QUERY_DATE_TAKEN_BEFORE_MS, LONG_DEFAULT);
+ final long dateTakenBeforeMs = bundle.getLong(QUERY_DATE_TAKEN_BEFORE_MS, Long.MIN_VALUE);
final int rowId = bundle.getInt(QUERY_ROW_ID, INT_DEFAULT);
+ final List<Integer> localIdSelection = bundle.getIntegerArrayList(QUERY_LOCAL_ID_SELECTION);
return new CloudProviderQueryExtras(albumId, albumAuthority, mimeTypes, sizeBytes,
generation, limit, isFavorite, isVideo, isLocalOnly, pageSize, dateTakenBeforeMs,
- rowId);
+ rowId, localIdSelection);
}
public static CloudProviderQueryExtras fromCloudMediaBundle(Bundle bundle) {
@@ -133,14 +143,14 @@ public class CloudProviderQueryExtras {
final boolean isFavorite = BOOLEAN_DEFAULT;
final boolean isVideo = BOOLEAN_DEFAULT;
final boolean isLocalOnly = BOOLEAN_DEFAULT;
- final Long dateTakenBeforeMs = bundle.getLong(QUERY_DATE_TAKEN_BEFORE_MS, LONG_DEFAULT);
+ final long dateTakenBeforeMs = bundle.getLong(QUERY_DATE_TAKEN_BEFORE_MS, Long.MIN_VALUE);
final int rowId = bundle.getInt(QUERY_ROW_ID, INT_DEFAULT);
final int pageSize = bundle.getInt(CloudMediaProviderContract.EXTRA_PAGE_SIZE, INT_DEFAULT);
-
+ final List<Integer> localIdSelection = bundle.getIntegerArrayList(QUERY_LOCAL_ID_SELECTION);
return new CloudProviderQueryExtras(albumId, albumAuthority, mimeTypes, sizeBytes,
generation, limit, isFavorite, isVideo, isLocalOnly, pageSize, dateTakenBeforeMs,
- rowId);
+ rowId, localIdSelection);
}
public PickerDbFacade.QueryFilter toQueryFilter() {
@@ -153,6 +163,7 @@ public class CloudProviderQueryExtras {
qfb.setIsLocalOnly(mIsLocalOnly);
qfb.setDateTakenBeforeMs(mDateTakenBeforeMs);
qfb.setId(mRowId);
+ qfb.setLocalIdSelection(mLocalIdSelection);
return qfb.build();
}
diff --git a/src/com/android/providers/media/photopicker/data/ItemsProvider.java b/src/com/android/providers/media/photopicker/data/ItemsProvider.java
index bf640d46a..1c6f2c03b 100644
--- a/src/com/android/providers/media/photopicker/data/ItemsProvider.java
+++ b/src/com/android/providers/media/photopicker/data/ItemsProvider.java
@@ -22,6 +22,7 @@ import static android.provider.MediaStore.AUTHORITY;
import static com.android.providers.media.PickerUriResolver.PICKER_INTERNAL_URI;
import static com.android.providers.media.photopicker.PickerDataLayer.QUERY_DATE_TAKEN_BEFORE_MS;
+import static com.android.providers.media.photopicker.PickerDataLayer.QUERY_LOCAL_ID_SELECTION;
import static com.android.providers.media.photopicker.PickerDataLayer.QUERY_ROW_ID;
import static com.android.providers.media.photopicker.util.CloudProviderUtils.sendInitPhotoPickerDataNotification;
@@ -50,14 +51,17 @@ import com.android.providers.media.PickerUriResolver;
import com.android.providers.media.photopicker.data.model.Category;
import com.android.providers.media.photopicker.data.model.UserId;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
/**
* Provides image and video items from {@link MediaStore} collection to the Photo Picker.
*/
public class ItemsProvider {
private static final String TAG = ItemsProvider.class.getSimpleName();
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = true;
private static final boolean DEBUG_DUMP_CURSORS = false;
private final Context mContext;
@@ -109,14 +113,6 @@ public class ItemsProvider {
@Nullable String[] mimeTypes,
@Nullable UserId userId,
@Nullable CancellationSignal cancellationSignal) throws IllegalArgumentException {
- if (DEBUG) {
- Log.d(TAG, "getAllItems() userId=" + userId + " cat=" + category
- + " mimeTypes=" + Arrays.toString(mimeTypes) + " limit="
- + pagingParameters.getPageSize() + " dateTakenBeforeMs="
- + pagingParameters.getDateBeforeMs() + " rowId=" + pagingParameters.getRowId());
- Log.v(TAG, "Thread=" + Thread.currentThread() + "; Stacktrace:", new Throwable());
- }
-
Trace.beginSection("ItemsProvider.getAllItems");
try {
return queryMedia(URI_MEDIA_ALL, pagingParameters, mimeTypes, category, userId,
@@ -155,14 +151,6 @@ public class ItemsProvider {
@Nullable String[] mimeTypes,
@Nullable UserId userId,
@Nullable CancellationSignal cancellationSignal) throws IllegalArgumentException {
- if (DEBUG) {
- Log.d(TAG, "getLocalItems() userId=" + userId + " cat=" + category
- + " mimeTypes=" + Arrays.toString(mimeTypes) + " limit="
- + pagingParameters.getPageSize() + " dateTakenBeforeMs="
- + pagingParameters.getDateBeforeMs() + " rowId=" + pagingParameters.getRowId());
- Log.v(TAG, "Thread=" + Thread.currentThread() + "; Stacktrace:", new Throwable());
- }
-
Trace.beginSection("ItemsProvider.getLocalItems");
try {
return queryMedia(URI_MEDIA_LOCAL, pagingParameters, mimeTypes, category, userId,
@@ -173,6 +161,26 @@ public class ItemsProvider {
}
/**
+ * Gets cursor for items corresponding to the ids passed as an argument.
+ *
+ * @param category the category of items to return.
+ * @param mimeTypes the mime type of item. {@code null} returns all images/videos that are
+ * scanned by {@link MediaStore}.
+ * @param userId the {@link UserId} of the user to get items as.
+ * {@code null} defaults to {@link UserId#CURRENT_USER}
+ * @param localIdSelection list of ids for which the item objects are required
+ */
+ public Cursor getLocalItemsForSelection(Category category,
+ @NonNull List<Integer> localIdSelection,
+ @Nullable String[] mimeTypes,
+ @Nullable UserId userId,
+ @Nullable CancellationSignal cancellationSignal) throws IllegalArgumentException {
+ Objects.requireNonNull(localIdSelection);
+ return queryMedia(URI_MEDIA_LOCAL, new PaginationParameters(), mimeTypes, category, userId,
+ localIdSelection, cancellationSignal);
+ }
+
+ /**
* Returns a {@link Cursor} to all non-empty categories in which images/videos are categorised.
* This includes:
* * A constant list of local categories for on-device images/videos: {@link Category}
@@ -189,12 +197,6 @@ public class ItemsProvider {
@Nullable
public Cursor getAllCategories(@Nullable String[] mimeTypes, @Nullable UserId userId,
@Nullable CancellationSignal cancellationSignal) {
- if (DEBUG) {
- Log.d(TAG, "getAllCategories() userId=" + userId
- + " mimeTypes=" + Arrays.toString(mimeTypes));
- Log.v(TAG, "Thread=" + Thread.currentThread() + "; Stacktrace:", new Throwable());
- }
-
Trace.beginSection("ItemsProvider.getAllCategories");
try {
return queryAlbums(URI_ALBUMS_ALL, mimeTypes, userId, cancellationSignal);
@@ -218,12 +220,6 @@ public class ItemsProvider {
@Nullable
public Cursor getLocalCategories(@Nullable String[] mimeTypes, @Nullable UserId userId,
@Nullable CancellationSignal cancellationSignal) {
- if (DEBUG) {
- Log.d(TAG, "getLocalCategories() userId=" + userId
- + " mimeTypes=" + Arrays.toString(mimeTypes));
- Log.v(TAG, "Thread=" + Thread.currentThread() + "; Stacktrace:", new Throwable());
- }
-
Trace.beginSection("ItemsProvider.getLocalCategories");
try {
return queryAlbums(URI_ALBUMS_LOCAL, mimeTypes, userId, cancellationSignal);
@@ -235,6 +231,15 @@ public class ItemsProvider {
@Nullable
private Cursor queryMedia(@NonNull Uri uri, PaginationParameters paginationParameters,
String[] mimeTypes, @NonNull Category category, @Nullable UserId userId,
+ @Nullable CancellationSignal cancellationSignal) {
+ return queryMedia(uri, paginationParameters, mimeTypes, category, userId, null,
+ cancellationSignal);
+ }
+
+ @Nullable
+ private Cursor queryMedia(@NonNull Uri uri, PaginationParameters paginationParameters,
+ String[] mimeTypes, @NonNull Category category, @Nullable UserId userId,
+ List<Integer> localIdSelection,
@Nullable CancellationSignal cancellationSignal)
throws IllegalStateException {
if (userId == null) {
@@ -242,12 +247,12 @@ public class ItemsProvider {
}
if (DEBUG) {
- Log.d(TAG, "queryMedia() userId=" + userId + " uri=" + uri + " cat=" + category
- + " mimeTypes=" + Arrays.toString(mimeTypes) + " limit="
- + paginationParameters.getPageSize() + " date_taken_before_ms = "
- + paginationParameters.getDateBeforeMs() + " row_id = "
- + paginationParameters.getRowId());
- Log.v(TAG, "Thread=" + Thread.currentThread() + "; Stacktrace:", new Throwable());
+ Log.d(TAG, "queryMedia() uri=" + uri
+ + " cat=" + category
+ + " mimeTypes=" + Arrays.toString(mimeTypes)
+ + " limit=" + paginationParameters.getPageSize()
+ + " date_taken_before_ms = " + paginationParameters.getDateBeforeMs()
+ + " row_id = " + paginationParameters.getRowId());
}
Trace.beginSection("ItemsProvider.queryMedia");
@@ -266,11 +271,16 @@ public class ItemsProvider {
}
extras.putString(MediaStore.QUERY_ARG_ALBUM_ID, category.getId());
extras.putString(MediaStore.QUERY_ARG_ALBUM_AUTHORITY, category.getAuthority());
+
if (paginationParameters.getRowId() >= 0
- && paginationParameters.getDateBeforeMs() >= 0) {
+ && paginationParameters.getDateBeforeMs() > Long.MIN_VALUE) {
extras.putInt(QUERY_ROW_ID, paginationParameters.getRowId());
extras.putLong(QUERY_DATE_TAKEN_BEFORE_MS, paginationParameters.getDateBeforeMs());
}
+ if (localIdSelection != null) {
+ extras.putIntegerArrayList(QUERY_LOCAL_ID_SELECTION,
+ (ArrayList<Integer>) localIdSelection);
+ }
result = client.query(uri, /* projection */ null, extras,
/* cancellationSignal */ cancellationSignal);
@@ -303,9 +313,8 @@ public class ItemsProvider {
}
if (DEBUG) {
- Log.d(TAG, "queryAlbums() userId=" + userId + " uri=" + uri
+ Log.d(TAG, "queryAlbums() uri=" + uri
+ " mimeTypes=" + Arrays.toString(mimeTypes));
- Log.v(TAG, "Thread=" + Thread.currentThread() + "; Stacktrace:", new Throwable());
}
Trace.beginSection("ItemsProvider.queryAlbums");
diff --git a/src/com/android/providers/media/photopicker/data/PaginationParameters.java b/src/com/android/providers/media/photopicker/data/PaginationParameters.java
index 3df947e49..2d05eb447 100644
--- a/src/com/android/providers/media/photopicker/data/PaginationParameters.java
+++ b/src/com/android/providers/media/photopicker/data/PaginationParameters.java
@@ -17,7 +17,6 @@
package com.android.providers.media.photopicker.data;
import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.INT_DEFAULT;
-import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.LONG_DEFAULT;
/**
* Holder for parameters required for pagination of photos and category items grid recyclerView in
@@ -25,7 +24,7 @@ import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryF
*/
public class PaginationParameters {
private int mPageSize = INT_DEFAULT;
- private long mDateBeforeMs = LONG_DEFAULT;
+ private long mDateBeforeMs = Long.MIN_VALUE;
private int mRowId = INT_DEFAULT;
public static final int PAGINATION_PAGE_SIZE_ITEMS = 600;
@@ -87,7 +86,7 @@ public class PaginationParameters {
* <b>Note: This parameter is only used in the query if the row id is set. Else it is
* ignored.</b>
*/
- public long getDateBeforeMs() {
+ public Long getDateBeforeMs() {
return mDateBeforeMs;
}
diff --git a/src/com/android/providers/media/photopicker/data/PickerDbFacade.java b/src/com/android/providers/media/photopicker/data/PickerDbFacade.java
index 248574bd4..7c0985815 100644
--- a/src/com/android/providers/media/photopicker/data/PickerDbFacade.java
+++ b/src/com/android/providers/media/photopicker/data/PickerDbFacade.java
@@ -49,11 +49,13 @@ import androidx.annotation.VisibleForTesting;
import com.android.providers.media.photopicker.PickerSyncController;
import com.android.providers.media.photopicker.data.model.Item;
+import com.android.providers.media.photopicker.sync.SyncTrackerRegistry;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.stream.Collectors;
/**
* This is a facade that hides the complexities of executing some SQL statements on the picker db.
@@ -151,6 +153,7 @@ public class PickerDbFacade {
String.format("%s < ? OR (%s = ? AND %s < ?)",
KEY_DATE_TAKEN_MS, KEY_DATE_TAKEN_MS, KEY_ID);
private static final String WHERE_ALBUM_ID = KEY_ALBUM_ID + " = ?";
+ private static final String WHERE_LOCAL_ID_IN = KEY_LOCAL_ID + " IN ";
// This where clause returns all rows for media items that are local-only and are marked as
// favorite.
@@ -396,6 +399,16 @@ public class PickerDbFacade {
return null;
}
+
+ /**
+ * Returns the first date taken present in the columns affected by the DB write operation
+ * when this method is overridden. Otherwise, it returns Long.MIN_VALUE.
+ */
+ public long getFirstDateTakenMillis() {
+ Log.e(TAG, "Method getFirstDateTakenMillis() is not overridden. "
+ + "It will always return Long.MIN_VALUE");
+ return Long.MIN_VALUE;
+ }
}
/**
@@ -526,6 +539,8 @@ public class PickerDbFacade {
}
private static final class RemoveMediaOperation extends DbWriteOperation {
+ private static final String[] sDateTakenProjection = new String[] {KEY_DATE_TAKEN_MS};
+ private long mFirstDateTakenMillis = Long.MIN_VALUE;
private RemoveMediaOperation(SQLiteDatabase database, boolean isLocal) {
super(database, isLocal);
@@ -539,6 +554,10 @@ public class PickerDbFacade {
int counter = 0;
while (cursor.moveToNext()) {
+ if (cursor.isFirst()) {
+ updateFirstDateTakenMillis(cursor, isLocal);
+ }
+
// Need to fetch the local_id before delete because for cloud items
// we need a db query to fetch the local_id matching the id received from
// cursor (cloud_id).
@@ -558,6 +577,11 @@ public class PickerDbFacade {
return counter;
}
+ @Override
+ public long getFirstDateTakenMillis() {
+ return mFirstDateTakenMillis;
+ }
+
private void promoteCloudMediaToVisible(@Nullable String localId) {
if (localId == null) {
return;
@@ -594,6 +618,34 @@ public class PickerDbFacade {
/* columnIndex */ 0);
}
}
+
+ private void updateFirstDateTakenMillis(Cursor inputCursor, boolean isLocal) {
+ final int idIndex = inputCursor
+ .getColumnIndex(CloudMediaProviderContract.MediaColumns.ID);
+ if (idIndex < 0) {
+ Log.e(TAG, "Id is not present in the cursor");
+ return;
+ }
+
+ final String id = inputCursor.getString(idIndex);
+ if (TextUtils.isEmpty((id))) {
+ Log.e(TAG, "Input id is empty");
+ return;
+ }
+
+ final SQLiteQueryBuilder qb = isLocal ? QB_MATCH_LOCAL_ONLY : QB_MATCH_CLOUD;
+ final String[] queryArgs = new String[]{id};
+
+ try (Cursor outputCursor = qb.query(getDatabase(), sDateTakenProjection,
+ /* selection */ null, queryArgs, /* groupBy */ null, /* having */ null,
+ /* orderBy */ null)) {
+ if (outputCursor.moveToFirst()) {
+ mFirstDateTakenMillis = outputCursor.getLong(/* columnIndex */ 0);
+ } else {
+ Log.e(TAG, "Could not get first date taken millis for media id: " + id);
+ }
+ }
+ }
}
private static final class ResetMediaOperation extends DbWriteOperation {
@@ -641,9 +693,11 @@ public class PickerDbFacade {
private final boolean mIsVideo;
public boolean mIsLocalOnly;
+ private List<Integer> mLocalIdSelection;
+
private QueryFilter(int limit, long dateTakenBeforeMs, long dateTakenAfterMs, long id,
String albumId, long sizeBytes, String[] mimeTypes, boolean isFavorite,
- boolean isVideo, boolean isLocalOnly) {
+ boolean isVideo, boolean isLocalOnly, List<Integer> localIdSelection) {
this.mLimit = limit;
this.mDateTakenBeforeMs = dateTakenBeforeMs;
this.mDateTakenAfterMs = dateTakenAfterMs;
@@ -654,6 +708,7 @@ public class PickerDbFacade {
this.mIsFavorite = isFavorite;
this.mIsVideo = isVideo;
this.mIsLocalOnly = isLocalOnly;
+ this.mLocalIdSelection = localIdSelection;
}
}
@@ -665,11 +720,12 @@ public class PickerDbFacade {
public static final String[] STRING_ARRAY_DEFAULT = null;
public static final boolean BOOLEAN_DEFAULT = false;
+ public static final List LIST_DEFAULT = null;
public static final int LIMIT_DEFAULT = 1000;
private final int limit;
- private long dateTakenBeforeMs = LONG_DEFAULT;
- private long dateTakenAfterMs = LONG_DEFAULT;
+ private long mDateTakenBeforeMs = Long.MIN_VALUE;
+ private long mDateTakenAfterMs = Long.MIN_VALUE;
private long id = LONG_DEFAULT;
private String albumId = STRING_DEFAULT;
private long sizeBytes = LONG_DEFAULT;
@@ -678,17 +734,19 @@ public class PickerDbFacade {
private boolean mIsVideo = BOOLEAN_DEFAULT;
private boolean mIsLocalOnly = BOOLEAN_DEFAULT;
+ private List<Integer> mLocalIdSelection = LIST_DEFAULT;
+
public QueryFilterBuilder(int limit) {
this.limit = limit;
}
public QueryFilterBuilder setDateTakenBeforeMs(long dateTakenBeforeMs) {
- this.dateTakenBeforeMs = dateTakenBeforeMs;
+ this.mDateTakenBeforeMs = dateTakenBeforeMs;
return this;
}
public QueryFilterBuilder setDateTakenAfterMs(long dateTakenAfterMs) {
- this.dateTakenAfterMs = dateTakenAfterMs;
+ this.mDateTakenAfterMs = dateTakenAfterMs;
return this;
}
@@ -724,6 +782,14 @@ public class PickerDbFacade {
}
/**
+ * Sets the local id selection filter.
+ */
+ public QueryFilterBuilder setLocalIdSelection(List<Integer> localIdSelection) {
+ this.mLocalIdSelection = localIdSelection;
+ return this;
+ }
+
+ /**
* If {@code isFavorite} is {@code true}, the {@link QueryFilter} returns only
* favorited items, however, if it is {@code false}, it returns all items including
* favorited and non-favorited items.
@@ -753,8 +819,8 @@ public class PickerDbFacade {
}
public QueryFilter build() {
- return new QueryFilter(limit, dateTakenBeforeMs, dateTakenAfterMs, id, albumId,
- sizeBytes, mimeTypes, isFavorite, mIsVideo, mIsLocalOnly);
+ return new QueryFilter(limit, mDateTakenBeforeMs, mDateTakenAfterMs, id, albumId,
+ sizeBytes, mimeTypes, isFavorite, mIsVideo, mIsLocalOnly, mLocalIdSelection);
}
}
@@ -793,7 +859,7 @@ public class PickerDbFacade {
* The result is sorted in reverse chronological order, i.e. newest first, up to a maximum of
* {@code limit}. They can also be filtered with {@code query}.
*/
- public Cursor queryAlbumMediaForUi(QueryFilter query, String authority) {
+ public Cursor queryAlbumMediaForUi(@NonNull QueryFilter query, @NonNull String authority) {
final SQLiteQueryBuilder qb = createAlbumMediaQueryBuilder(isLocal(authority));
final String[] selectionArgs = buildSelectionArgs(qb, query);
@@ -841,7 +907,7 @@ public class PickerDbFacade {
* Returns empty {@link Cursor} if there are no items matching merged album constraints {@code
* query}
*/
- public Cursor getMergedAlbums(QueryFilter query) {
+ public Cursor getMergedAlbums(QueryFilter query, String cloudProvider) {
final MatrixCursor c = new MatrixCursor(AlbumColumns.ALL_PROJECTION);
List<String> mergedAlbums = List.of(ALBUM_ID_FAVORITES, ALBUM_ID_VIDEOS);
for (String albumId : mergedAlbums) {
@@ -869,7 +935,9 @@ public class PickerDbFacade {
}
long count = getCursorLong(cursor, CloudMediaProviderContract.AlbumColumns.MEDIA_COUNT);
- if (count == 0) {
+
+ // We want to always display empty merged folder in case of cloud picker.
+ if (count == 0 && (query.mIsLocalOnly || cloudProvider == null)) {
continue;
}
@@ -907,6 +975,9 @@ public class PickerDbFacade {
return mLocalProvider.equals(authority);
}
+ /**
+ * Returns sorted and deduped cloud and local media or album content items from the picker db.
+ */
private Cursor queryMediaForUi(SQLiteQueryBuilder qb, String[] selectionArgs,
int limit, String tableName, String authority) {
// Use the <table>.<column> form to order _id to avoid ordering against the projection '_id'
@@ -1188,6 +1259,22 @@ public class PickerDbFacade {
selectArgs.add(query.mAlbumId);
}
+ if (query.mLocalIdSelection != null && !query.mLocalIdSelection.isEmpty()) {
+ StringBuilder localIdSelectionPlaceholder = new StringBuilder("(");
+ for (int itr = 0; itr < query.mLocalIdSelection.size(); itr++) {
+ localIdSelectionPlaceholder.append("?,");
+ }
+ localIdSelectionPlaceholder.deleteCharAt(localIdSelectionPlaceholder.length() - 1);
+ localIdSelectionPlaceholder.append(")");
+
+ // Append the where clause for local id selection to the query builder.
+ qb.appendWhereStandalone(WHERE_LOCAL_ID_IN + localIdSelectionPlaceholder);
+
+ // Add local ids to the selection args.
+ selectArgs.addAll(query.mLocalIdSelection.stream().map(
+ String::valueOf).collect(Collectors.toList()));
+ }
+
if (selectArgs.isEmpty()) {
return null;
}
@@ -1361,6 +1448,7 @@ public class PickerDbFacade {
final boolean isLocal = isLocal();
final String albumId = getAlbumId();
final SQLiteQueryBuilder qb = createAlbumMediaQueryBuilder(isLocal);
+ final SQLiteQueryBuilder qbMedia = createMediaQueryBuilder();
int counter = 0;
if (cursor.getCount() > PAGE_SIZE) {
@@ -1406,11 +1494,46 @@ public class PickerDbFacade {
} catch (SQLiteConstraintException e) {
Log.v(TAG, "Failed to insert album_media. ContentValues: " + values, e);
}
+
+ // Check if a Cloud sync is running, and additionally insert this row to media table
+ // if true.
+ maybeInsertFileToMedia(qbMedia, cursor, isLocal);
}
return counter;
}
+ /**
+ * Will (possibly) insert this file to the Picker database's media table if there's an
+ * existing Cloud Sync running.
+ *
+ * <p>This is necessary to guarantee it exists in case it is selected by the user. (So that
+ * the pre-loader can load it to the device before the session is closed.)
+ *
+ * @param queryBuilder The media table query builder to use for the insert
+ * @param cursor The current cursor being processed (this method does not advance the
+ * cursor).
+ * @param isLocal Whether this is the local provider sync or not.
+ */
+ private void maybeInsertFileToMedia(
+ SQLiteQueryBuilder queryBuilder, Cursor cursor, boolean isLocal) {
+ if (SyncTrackerRegistry.getCloudSyncTracker().pendingSyncFutures().size() > 0) {
+ ContentValues values = cursorToContentValue(cursor, isLocal);
+ Log.d(
+ TAG,
+ String.format(
+ "Encountered running Cloud sync during AddAlbumMediaOperation while"
+ + " processing row. Will additional insert to media table: %s",
+ values));
+ try {
+ queryBuilder.insert(getDatabase(), values);
+ } catch (SQLiteConstraintException ignored) {
+ // If we hit a constraint exception it means this row is already in media,
+ // so nothing to do here.
+ }
+ }
+ }
+
private void updateContentValues(ContentValues values, Cursor cursor) {
if (cursor.moveToFirst()) {
for (int columnIndex = 0; columnIndex < cursor.getColumnCount(); columnIndex++) {
diff --git a/src/com/android/providers/media/photopicker/data/Selection.java b/src/com/android/providers/media/photopicker/data/Selection.java
index 4894977ea..7176aaded 100644
--- a/src/com/android/providers/media/photopicker/data/Selection.java
+++ b/src/com/android/providers/media/photopicker/data/Selection.java
@@ -27,6 +27,7 @@ import androidx.lifecycle.MutableLiveData;
import com.android.providers.media.photopicker.data.model.Item;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -36,6 +37,16 @@ import java.util.Map;
* A class that tracks Selection
*/
public class Selection {
+ /**
+ * Contains positions of checked Item at UI. {@link #mCheckedItemIndexes} may have more number
+ * of indexes , from the number of items present in {@link #mSelectedItems}. The index in
+ * {@link #mCheckedItemIndexes} is a potential index that needs to be rechecked in
+ * notifyItemChanged() at the time of deselecting the unavailable item at UI when user is
+ * offline and tries adding unavailable non cached items. the item corresponding to the index in
+ * {@link #mCheckedItemIndexes} may no longer be selected.
+ */
+ private final Map<Item, Integer> mCheckedItemIndexes = new HashMap<>();
+
// The list of selected items.
private Map<Uri, Item> mSelectedItems = new HashMap<>();
private MutableLiveData<Integer> mSelectedItemSize = new MutableLiveData<>();
@@ -55,6 +66,13 @@ public class Selection {
}
/**
+ * @return Indexes - A {@link List} of checked {@link Item} positions.
+ */
+ public Collection<Integer> getCheckedItemsIndexes() {
+ return mCheckedItemIndexes.values();
+ }
+
+ /**
* @return {@link LiveData} of count of selected items in {@link #mSelectedItems}
*/
public LiveData<Integer> getSelectedItemCount() {
@@ -74,6 +92,13 @@ public class Selection {
}
/**
+ * Add the checked {@code item} index into {@link #mCheckedItemIndexes}.
+ */
+ public void addCheckedItemIndex(Item item, Integer index) {
+ mCheckedItemIndexes.put(item, index);
+ }
+
+ /**
* Clears {@link #mSelectedItems} and sets the selected item as given {@code item}
*/
public void setSelectedItem(Item item) {
@@ -84,7 +109,7 @@ public class Selection {
}
/**
- * Remove the {@code item} from the selected item list {@link #mSelectedItems}.
+ * Remove the {@code item} from the selected item list {@link #mSelectedItems}
*
* @param item the item to be removed from the selected item list
*/
@@ -95,15 +120,32 @@ public class Selection {
}
/**
- * Clear all selected items
+ * Remove the {@code item} index from the checked item index list {@link #mCheckedItemIndexes}.
+ *
+ * @param item the item to be removed from the selected item list
+ */
+ public void removeCheckedItemIndex(Item item) {
+ mCheckedItemIndexes.remove(item);
+ }
+
+ /**
+ * Clear all selected items and checked positions
*/
public void clearSelectedItems() {
mSelectedItems.clear();
+ mCheckedItemIndexes.clear();
mSelectedItemSize.postValue(mSelectedItems.size());
updateSelectionAllowed();
}
/**
+ * Clear all checked items
+ */
+ public void clearCheckedItemList() {
+ mCheckedItemIndexes.clear();
+ }
+
+ /**
* @return {@code true} if give {@code item} is present in selected items
* {@link #mSelectedItems}, {@code false} otherwise
*/
diff --git a/src/com/android/providers/media/photopicker/data/model/Category.java b/src/com/android/providers/media/photopicker/data/model/Category.java
index 7ccda79f7..487a39c26 100644
--- a/src/com/android/providers/media/photopicker/data/model/Category.java
+++ b/src/com/android/providers/media/photopicker/data/model/Category.java
@@ -40,6 +40,7 @@ import androidx.annotation.VisibleForTesting;
import com.android.providers.media.R;
import com.android.providers.media.photopicker.data.ItemsProvider;
+import java.util.List;
import java.util.Locale;
/**
@@ -49,6 +50,8 @@ public class Category {
public static final String TAG = "PhotoPicker";
public static final Category DEFAULT = new Category();
public static final Category EMPTY_VIEW = new Category("EMPTY_VIEW");
+ private static final List<String> TRANSLATABLE_CATEGORIES = List.of(ALBUM_ID_VIDEOS,
+ ALBUM_ID_CAMERA, ALBUM_ID_SCREENSHOTS, ALBUM_ID_DOWNLOADS, ALBUM_ID_FAVORITES);
private final String mId;
private final String mAuthority;
@@ -91,7 +94,7 @@ public class Category {
}
public String getDisplayName(Context context) {
- if (mIsLocal) {
+ if (TRANSLATABLE_CATEGORIES.contains(mId)) {
return getLocalizedDisplayName(context, mId);
}
return mDisplayName;
@@ -163,7 +166,7 @@ public class Category {
return new Category(getCursorString(cursor, AlbumColumns.ID),
authority,
getCursorString(cursor, AlbumColumns.DISPLAY_NAME),
- coverUri,
+ getCursorString(cursor, AlbumColumns.MEDIA_COVER_ID) != null ? coverUri : null,
getCursorInt(cursor, AlbumColumns.MEDIA_COUNT),
isLocal);
}
diff --git a/src/com/android/providers/media/photopicker/data/model/Item.java b/src/com/android/providers/media/photopicker/data/model/Item.java
index e618386f2..11dbc643d 100644
--- a/src/com/android/providers/media/photopicker/data/model/Item.java
+++ b/src/com/android/providers/media/photopicker/data/model/Item.java
@@ -41,6 +41,8 @@ import com.android.providers.media.photopicker.data.ItemsProvider;
import com.android.providers.media.photopicker.util.DateTimeUtils;
import com.android.providers.media.util.MimeUtils;
+import java.util.Objects;
+
/**
* Base class for representing a single media item (a picture, a video, etc.) in the PhotoPicker.
*/
@@ -225,4 +227,17 @@ public class Item {
public boolean isLocal() {
return LOCAL_PICKER_PROVIDER_AUTHORITY.equals(mUri.getAuthority());
}
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null || !(obj instanceof Item)) return false;
+
+ Item other = (Item) obj;
+ return mUri.equals(other.mUri);
+ }
+
+ @Override public int hashCode() {
+ return Objects.hash(mUri);
+ }
} \ No newline at end of file
diff --git a/src/com/android/providers/media/photopicker/sync/ImmediateAlbumSyncWorker.java b/src/com/android/providers/media/photopicker/sync/ImmediateAlbumSyncWorker.java
index dea21f3fd..bc896d59d 100644
--- a/src/com/android/providers/media/photopicker/sync/ImmediateAlbumSyncWorker.java
+++ b/src/com/android/providers/media/photopicker/sync/ImmediateAlbumSyncWorker.java
@@ -29,11 +29,13 @@ import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.work.ForegroundInfo;
import androidx.work.ListenableWorker;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
import com.android.providers.media.photopicker.PickerSyncController;
+import com.android.providers.media.photopicker.util.exceptions.RequestObsoleteException;
/**
* This is a {@link Worker} class responsible for syncing album media with the correct sync source.
@@ -41,6 +43,7 @@ import com.android.providers.media.photopicker.PickerSyncController;
public class ImmediateAlbumSyncWorker extends Worker {
private static final String TAG = "IASyncWorker";
private static final int INVALID_SYNC_SOURCE = -1;
+ private final Context mContext;
/**
* Creates an instance of the {@link Worker}.
@@ -52,6 +55,7 @@ public class ImmediateAlbumSyncWorker extends Worker {
@NonNull Context context,
@NonNull WorkerParameters workerParams) {
super(context, workerParams);
+ mContext = context;
}
@NonNull
@@ -71,6 +75,7 @@ public class ImmediateAlbumSyncWorker extends Worker {
// No need to instantiate a work request tracker for immediate syncs in the worker.
// For immediate syncs, the work request tracker is initiated before enqueueing the
// request in WorkManager.
+ checkIsWorkerStopped();
if (syncSource == SYNC_LOCAL_ONLY) {
PickerSyncController.getInstanceOrThrow().syncAlbumMediaFromLocalProvider(albumId);
} else {
@@ -81,7 +86,7 @@ public class ImmediateAlbumSyncWorker extends Worker {
"Completed picker immediate album sync from sync source: %s album id: %s",
syncSource, albumId));
return ListenableWorker.Result.success();
- } catch (IllegalArgumentException | IllegalStateException e) {
+ } catch (IllegalArgumentException | IllegalStateException | RequestObsoleteException e) {
Log.e(TAG, String.format("Could not complete picker immediate album sync from "
+ "sync source: %s album id: %s",
syncSource, albumId), e);
@@ -105,4 +110,25 @@ public class ImmediateAlbumSyncWorker extends Worker {
throw new IllegalArgumentException("Invalid album id " + albumId);
}
}
+
+ private void checkIsWorkerStopped() throws RequestObsoleteException {
+ if (isStopped()) {
+ throw new RequestObsoleteException("Work is stopped " + getId());
+ }
+ }
+
+ @Override
+ @NonNull
+ public ForegroundInfo getForegroundInfo() {
+ return PickerSyncNotificationHelper.getForegroundInfo(mContext);
+ }
+
+ @Override
+ public void onStopped() {
+ Log.w(TAG, "Worker is stopped. Clearing all pending futures. It's possible that the sync "
+ + "will continue to run if it has started already.");
+ final int syncSource = getInputData()
+ .getInt(SYNC_WORKER_INPUT_SYNC_SOURCE, /* defaultValue */ SYNC_LOCAL_ONLY);
+ markAlbumMediaSyncAsComplete(syncSource, getId());
+ }
}
diff --git a/src/com/android/providers/media/photopicker/sync/ImmediateSyncWorker.java b/src/com/android/providers/media/photopicker/sync/ImmediateSyncWorker.java
index 9ea5a9afc..f4ad8d4ba 100644
--- a/src/com/android/providers/media/photopicker/sync/ImmediateSyncWorker.java
+++ b/src/com/android/providers/media/photopicker/sync/ImmediateSyncWorker.java
@@ -29,17 +29,20 @@ import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
+import androidx.work.ForegroundInfo;
import androidx.work.ListenableWorker;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
import com.android.providers.media.photopicker.PickerSyncController;
+import com.android.providers.media.photopicker.util.exceptions.RequestObsoleteException;
/**
* This is a {@link Worker} class responsible for syncing with the correct sync source.
*/
public class ImmediateSyncWorker extends Worker {
private static final String TAG = "ISyncWorker";
+ private final Context mContext;
/**
* Creates an instance of the {@link Worker}.
@@ -49,13 +52,14 @@ public class ImmediateSyncWorker extends Worker {
*/
public ImmediateSyncWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
+ mContext = context;
}
@NonNull
@Override
public ListenableWorker.Result doWork() {
final int syncSource = getInputData()
- .getInt(SYNC_WORKER_INPUT_SYNC_SOURCE, /* defaultValue */ SYNC_LOCAL_AND_CLOUD);
+ .getInt(SYNC_WORKER_INPUT_SYNC_SOURCE, /* defaultValue */ SYNC_LOCAL_ONLY);
Log.i(TAG, String.format(
"Starting immediate picker sync from sync source: %s", syncSource));
@@ -65,17 +69,19 @@ public class ImmediateSyncWorker extends Worker {
// For immediate syncs, the work request tracker is initiated before enqueueing the
// request in WorkManager.
if (syncSource == SYNC_LOCAL_AND_CLOUD || syncSource == SYNC_LOCAL_ONLY) {
+ checkIsWorkerStopped();
PickerSyncController.getInstanceOrThrow().syncAllMediaFromLocalProvider();
getLocalSyncTracker().markSyncCompleted(getId());
Log.i(TAG, "Completed immediate picker sync from local provider.");
}
if (syncSource == SYNC_LOCAL_AND_CLOUD || syncSource == SYNC_CLOUD_ONLY) {
+ checkIsWorkerStopped();
PickerSyncController.getInstanceOrThrow().syncAllMediaFromCloudProvider();
getCloudSyncTracker().markSyncCompleted(getId());
Log.i(TAG, "Completed immediate picker sync from cloud provider.");
}
return ListenableWorker.Result.success();
- } catch (IllegalStateException e) {
+ } catch (IllegalStateException | RequestObsoleteException e) {
Log.i(TAG, String.format(
"Could not complete immediate sync from sync source: %s", syncSource), e);
@@ -84,4 +90,25 @@ public class ImmediateSyncWorker extends Worker {
return ListenableWorker.Result.failure();
}
}
+
+ private void checkIsWorkerStopped() throws RequestObsoleteException {
+ if (isStopped()) {
+ throw new RequestObsoleteException("Work is stopped " + getId());
+ }
+ }
+
+ @Override
+ @NonNull
+ public ForegroundInfo getForegroundInfo() {
+ return PickerSyncNotificationHelper.getForegroundInfo(mContext);
+ }
+
+ @Override
+ public void onStopped() {
+ Log.w(TAG, "Worker is stopped. Clearing all pending futures. It's possible that the sync "
+ + "still finishes running if it has started already.");
+ final int syncSource = getInputData()
+ .getInt(SYNC_WORKER_INPUT_SYNC_SOURCE, /* defaultValue */ SYNC_LOCAL_AND_CLOUD);
+ markSyncAsComplete(syncSource, getId());
+ }
}
diff --git a/src/com/android/providers/media/photopicker/sync/MediaResetWorker.java b/src/com/android/providers/media/photopicker/sync/MediaResetWorker.java
new file mode 100644
index 000000000..47c745583
--- /dev/null
+++ b/src/com/android/providers/media/photopicker/sync/MediaResetWorker.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.providers.media.photopicker.sync;
+
+import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_CLOUD_ONLY;
+import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_LOCAL_ONLY;
+import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_RESET_ALBUM;
+import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_RESET_MEDIA;
+import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_WORKER_INPUT_ALBUM_ID;
+import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_WORKER_INPUT_AUTHORITY;
+import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_WORKER_INPUT_RESET_TYPE;
+import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_WORKER_INPUT_SYNC_SOURCE;
+import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_WORKER_TAG_IS_PERIODIC;
+import static com.android.providers.media.photopicker.sync.SyncTrackerRegistry.markAlbumMediaSyncAsComplete;
+import static com.android.providers.media.photopicker.sync.SyncTrackerRegistry.trackNewAlbumMediaSyncRequests;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteException;
+import android.os.Trace;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.work.ForegroundInfo;
+import androidx.work.ListenableWorker;
+import androidx.work.Worker;
+import androidx.work.WorkerParameters;
+
+import com.android.providers.media.photopicker.PickerSyncController;
+import com.android.providers.media.photopicker.data.PickerDbFacade;
+import com.android.providers.media.photopicker.sync.PickerSyncManager.SyncResetType;
+
+/**
+ * This is a {@link Worker} class responsible for handling table reset operations in the picker
+ * database.
+ */
+public class MediaResetWorker extends Worker {
+
+ private static final String TAG = "MediaResetWorker";
+ private static final int UNDEFINED_RESET_TYPE = -1;
+
+ @Nullable private final String mAlbumId;
+ @NonNull private final Context mContext;
+ @NonNull private final int mResetType;
+ @NonNull private final int mSyncSource;
+
+ @Nullable private String mAuthority;
+
+ public MediaResetWorker(@NonNull Context context, @NonNull WorkerParameters workerParameters) {
+ super(context, workerParameters);
+ mContext = context;
+
+ mAuthority = getInputData().getString(SYNC_WORKER_INPUT_AUTHORITY);
+ mAlbumId = getInputData().getString(SYNC_WORKER_INPUT_ALBUM_ID);
+ mResetType = getInputData().getInt(SYNC_WORKER_INPUT_RESET_TYPE, UNDEFINED_RESET_TYPE);
+ mSyncSource = getInputData().getInt(SYNC_WORKER_INPUT_SYNC_SOURCE, -1);
+ }
+
+ @Override
+ public ListenableWorker.Result doWork() {
+ Log.i(
+ TAG,
+ String.format(
+ "MediaReset has been requested. Authority: %s AlbumId: %s",
+ mAuthority, mAlbumId));
+
+ PickerSyncController controller;
+ PickerDbFacade dBFacade;
+ try {
+ controller = PickerSyncController.getInstanceOrThrow();
+ dBFacade = new PickerDbFacade(mContext);
+ } catch (IllegalStateException ex) {
+ Log.e(TAG, "Unable to obtain PickerSyncController", ex);
+ return ListenableWorker.Result.failure();
+ } catch (SQLiteException ex) {
+ Log.e(TAG, "Unable to get writeable database", ex);
+ return ListenableWorker.Result.failure();
+ }
+
+ if (getTags().contains(SYNC_WORKER_TAG_IS_PERIODIC)) {
+ // If this worker is being run as part of periodic work, it needs to register
+ // its own sync with the sync tracker.
+ trackNewAlbumMediaSyncRequests(mSyncSource, getId());
+
+ // Since this is a periodic worker, we'll use the cloud authority, if it exists.
+ // Using the cloud authority will reset files for all providers. If the local
+ // authority is used, it will limit the query to only files with a local_id, but
+ // the cloud authority does not have such a limitation.
+ // (This is not intuitive, it's just how it works.)
+ mAuthority = controller.getCloudProvider();
+ if (mAuthority == null) {
+ mAuthority = controller.getLocalProvider();
+ }
+ // If the authority is still null, end the operation.
+ if (mAuthority == null) {
+ Log.e(TAG, "Unable to set authority for periodic worker");
+ return ListenableWorker.Result.failure();
+ }
+ }
+
+ try {
+
+ if (mSyncSource == SYNC_LOCAL_ONLY) {
+ return start(dBFacade);
+ } else {
+ // SyncSource is either CLOUD_ONLY or LOCAL_AND_CLOUD, either way we need the
+ // cloud lock.
+ final Object cloudAlbumSyncLock = controller.getCloudAlbumSyncLock();
+ synchronized (cloudAlbumSyncLock) {
+ return start(dBFacade);
+ }
+ }
+ } finally {
+ markAlbumMediaSyncAsComplete(mSyncSource, getId());
+ }
+ }
+
+ private ListenableWorker.Result start(@NonNull PickerDbFacade dbFacade) {
+
+ Trace.beginSection("MediaResetWorker:BeginOperation");
+
+ int deleteCount = 0;
+ try (PickerDbFacade.DbWriteOperation operation =
+ beginResetOperation(dbFacade, mResetType)) {
+
+ deleteCount = operation.execute(/* cursor= */ null);
+
+ // Just ensure the worker hasn't been stopped before allowing the commit.
+ if (isStopped()) {
+ Log.i(TAG, "Worker was stopped before operation was completed");
+ return ListenableWorker.Result.failure();
+ }
+ operation.setSuccess();
+
+ } catch (UnsupportedOperationException | IllegalStateException ex) {
+ Log.e(TAG, "Operation failed.", ex);
+ return ListenableWorker.Result.failure();
+ } finally {
+ Trace.endSection();
+ }
+
+ Log.i(TAG, String.format("Reset operation complete. Deleted rows: %d", deleteCount));
+ return ListenableWorker.Result.success();
+ }
+
+ private PickerDbFacade.DbWriteOperation beginResetOperation(
+ @NonNull PickerDbFacade dbFacade, @NonNull @SyncResetType int resetType) {
+
+ switch (resetType) {
+ case SYNC_RESET_ALBUM:
+ if (mAuthority == null) {
+ throw new IllegalStateException(
+ String.format(
+ "Failed to begin SYNC_RESET_ALBUM. Unknown provider authority:"
+ + " %s",
+ mAuthority));
+ }
+
+ if (mSyncSource == SYNC_CLOUD_ONLY && mAlbumId == null) {
+ Log.w(
+ TAG,
+ "Sync Source is set to SYNC_CLOUD_ONLY with no albumId, but the reset"
+ + " operation will still remove cloud+local files.");
+ }
+ return dbFacade.beginResetAlbumMediaOperation(mAuthority, mAlbumId);
+ case SYNC_RESET_MEDIA:
+ default:
+ throw new UnsupportedOperationException(
+ String.format(
+ "Requested Reset operation not (yet) supported. ResetType: %d",
+ resetType));
+ }
+ }
+
+ @Override
+ @NonNull
+ public ForegroundInfo getForegroundInfo() {
+ return PickerSyncNotificationHelper.getForegroundInfo(mContext);
+ }
+
+ @Override
+ public void onStopped() {
+ Log.w(
+ TAG,
+ "Worker is stopped. Clearing all pending futures. It's possible that the worker "
+ + "still finishes running if it has started already.");
+ markAlbumMediaSyncAsComplete(mSyncSource, getId());
+ }
+}
diff --git a/src/com/android/providers/media/photopicker/sync/PickerSyncManager.java b/src/com/android/providers/media/photopicker/sync/PickerSyncManager.java
index ab4cb2c02..ab94d2072 100644
--- a/src/com/android/providers/media/photopicker/sync/PickerSyncManager.java
+++ b/src/com/android/providers/media/photopicker/sync/PickerSyncManager.java
@@ -21,6 +21,9 @@ import static com.android.providers.media.photopicker.sync.SyncTrackerRegistry.m
import static com.android.providers.media.photopicker.sync.SyncTrackerRegistry.trackNewAlbumMediaSyncRequests;
import static com.android.providers.media.photopicker.sync.SyncTrackerRegistry.trackNewSyncRequests;
+import static java.util.Objects.requireNonNull;
+
+import android.content.Context;
import android.util.Log;
import androidx.annotation.IntDef;
@@ -33,20 +36,25 @@ import androidx.work.OneTimeWorkRequest;
import androidx.work.Operation;
import androidx.work.OutOfQuotaPolicy;
import androidx.work.PeriodicWorkRequest;
+import androidx.work.WorkInfo;
import androidx.work.WorkManager;
+import androidx.work.Worker;
+import com.android.modules.utils.BackgroundThread;
import com.android.providers.media.ConfigStore;
+import com.android.providers.media.photopicker.PickerSyncController;
+
+import com.google.common.util.concurrent.ListenableFuture;
import org.jetbrains.annotations.NotNull;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.Collections;
+import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
-
/**
* This class manages all the triggers for Picker syncs.
* <p></p>
@@ -68,21 +76,102 @@ public class PickerSyncManager {
@IntDef(value = { SYNC_LOCAL_ONLY, SYNC_CLOUD_ONLY, SYNC_LOCAL_AND_CLOUD })
@Retention(RetentionPolicy.SOURCE)
public @interface SyncSource {}
+
+ public static final int SYNC_RESET_MEDIA = 1;
+ public static final int SYNC_RESET_ALBUM = 2;
+
+ @IntDef(value = {SYNC_RESET_MEDIA, SYNC_RESET_ALBUM})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SyncResetType {}
+
+ static final String SYNC_WORKER_INPUT_AUTHORITY = "INPUT_AUTHORITY";
static final String SYNC_WORKER_INPUT_SYNC_SOURCE = "INPUT_SYNC_TYPE";
+ static final String SYNC_WORKER_INPUT_RESET_TYPE = "INPUT_RESET_TYPE";
static final String SYNC_WORKER_INPUT_ALBUM_ID = "INPUT_ALBUM_ID";
+ static final String SYNC_WORKER_TAG_IS_PERIODIC = "PERIODIC";
private static final int SYNC_MEDIA_PERIODIC_WORK_INTERVAL = 4; // Time unit is hours.
- private static final String SYNC_MEDIA_PERIODIC_SYNC_PREFIX = "SYNC_MEDIA_PERIODIC_";
- private static final String SYNC_MEDIA_PROACTIVE_WORK_PREFIX = "SYNC_MEDIA_PROACTIVE_";
- private static final String SYNC_ALL_WORK_SUFFIX = "ALL";
+ private static final int RESET_ALBUM_MEDIA_PERIODIC_WORK_INTERVAL = 12; // Time unit is hours.
+
+ private static final String PERIODIC_SYNC_WORK_NAME;
+ private static final String PROACTIVE_SYNC_WORK_NAME;
+ public static final String IMMEDIATE_LOCAL_SYNC_WORK_NAME;
+ private static final String IMMEDIATE_CLOUD_SYNC_WORK_NAME;
+ public static final String IMMEDIATE_ALBUM_SYNC_WORK_NAME;
+ private static final String PERIODIC_ALBUM_RESET_WORK_NAME;
+
+ static {
+ final String syncPeriodicPrefix = "SYNC_MEDIA_PERIODIC_";
+ final String syncProactivePrefix = "SYNC_MEDIA_PROACTIVE_";
+ final String syncImmediatePrefix = "SYNC_MEDIA_IMMEDIATE_";
+ final String syncAllSuffix = "ALL";
+ final String syncLocalSuffix = "LOCAL";
+ final String syncCloudSuffix = "CLOUD";
+
+ PERIODIC_ALBUM_RESET_WORK_NAME = "RESET_ALBUM_MEDIA_PERIODIC";
+ PERIODIC_SYNC_WORK_NAME = syncPeriodicPrefix + syncAllSuffix;
+ PROACTIVE_SYNC_WORK_NAME = syncProactivePrefix + syncAllSuffix;
+ IMMEDIATE_LOCAL_SYNC_WORK_NAME = syncImmediatePrefix + syncLocalSuffix;
+ IMMEDIATE_CLOUD_SYNC_WORK_NAME = syncImmediatePrefix + syncCloudSuffix;
+ IMMEDIATE_ALBUM_SYNC_WORK_NAME = "SYNC_ALBUM_MEDIA_IMMEDIATE";
+ }
+
private final WorkManager mWorkManager;
+ private final ConfigStore mConfigStore;
+ private final Context mContext;
public PickerSyncManager(@NonNull WorkManager workManager,
+ @NonNull Context context,
@NonNull ConfigStore configStore,
- boolean schedulePeriodicSyncs) {
- mWorkManager = workManager;
+ boolean shouldSchedulePeriodicSyncs) {
+ mWorkManager = requireNonNull(workManager);
+ mConfigStore = requireNonNull(configStore);
+ mContext = requireNonNull(context);
+
+ if (shouldSchedulePeriodicSyncs) {
+ setUpPeriodicWork();
+ }
+
+ // Subscribe to device config changes so we can enable periodic workers if Cloud
+ // Photopicker is enabled.
+ mConfigStore.addOnChangeListener(BackgroundThread.getExecutor(), this::setUpPeriodicWork);
+ }
+
+ /**
+ * Will register new unique {@link Worker} for periodic sync and picker database maintenance if
+ * the cloud photopicker experiment is currently enabled.
+ */
+ private void setUpPeriodicWork() {
+
+ if (mConfigStore.isCloudMediaInPhotoPickerEnabled()) {
+ PickerSyncNotificationHelper.createNotificationChannel(mContext);
- if (schedulePeriodicSyncs && configStore.isCloudMediaInPhotoPickerEnabled()) {
schedulePeriodicSyncs();
+ schedulePeriodicAlbumReset();
+ } else {
+ // Disable any scheduled ongoing work if the feature is disabled.
+ mWorkManager.cancelUniqueWork(PERIODIC_SYNC_WORK_NAME);
+ mWorkManager.cancelUniqueWork(PERIODIC_ALBUM_RESET_WORK_NAME);
+ }
+ }
+
+ /**
+ * Returns true if the given unique work is pending. In case the unique work is complete or
+ * there was an error in getting the work state, it returns false.
+ */
+ public boolean isUniqueWorkPending(String uniqueWorkName) {
+ ListenableFuture<List<WorkInfo>> future =
+ mWorkManager.getWorkInfosForUniqueWork(uniqueWorkName);
+ try {
+ List<WorkInfo> workInfos = future.get();
+ for (WorkInfo workInfo : workInfos) {
+ if (!workInfo.getState().isFinished()) {
+ return true;
+ }
+ }
+ return false;
+ } catch (InterruptedException | ExecutionException e) {
+ Log.e(TAG, "Error occurred in fetching work info - ignore pending work");
+ return false;
}
}
@@ -96,9 +185,9 @@ public class PickerSyncManager {
try {
// Note that the first execution of periodic work happens immediately or as soon as the
// given Constraints are met.
- Operation enqueueOperation = mWorkManager
+ final Operation enqueueOperation = mWorkManager
.enqueueUniquePeriodicWork(
- SYNC_MEDIA_PERIODIC_SYNC_PREFIX + SYNC_ALL_WORK_SUFFIX,
+ PERIODIC_SYNC_WORK_NAME,
ExistingPeriodicWorkPolicy.KEEP,
periodicSyncRequest
);
@@ -110,6 +199,35 @@ public class PickerSyncManager {
}
}
+ private void schedulePeriodicAlbumReset() {
+ Log.i(TAG, "Scheduling periodic picker album data resets");
+
+ final Data inputData =
+ new Data(
+ Map.of(
+ SYNC_WORKER_INPUT_SYNC_SOURCE,
+ SYNC_LOCAL_AND_CLOUD,
+ SYNC_WORKER_INPUT_RESET_TYPE,
+ SYNC_RESET_ALBUM));
+ final PeriodicWorkRequest periodicAlbumResetRequest =
+ getPeriodicAlbumResetRequest(inputData);
+
+ try {
+ // Note that the first execution of periodic work happens immediately or as soon
+ // as the given Constraints are met.
+ Operation enqueueOperation =
+ mWorkManager.enqueueUniquePeriodicWork(
+ PERIODIC_ALBUM_RESET_WORK_NAME,
+ ExistingPeriodicWorkPolicy.KEEP,
+ periodicAlbumResetRequest);
+
+ // Check that the request has been successfully enqueued.
+ enqueueOperation.getResult().get();
+ } catch (InterruptedException | ExecutionException e) {
+ Log.e(TAG, "Could not enqueue periodic picker album resets request", e);
+ }
+ }
+
/**
* Use this method for proactive syncs. The sync might take a while to start. Some device state
* conditions may apply before the sync can start like battery level etc.
@@ -119,16 +237,10 @@ public class PickerSyncManager {
new Data(Map.of(SYNC_WORKER_INPUT_SYNC_SOURCE, SYNC_LOCAL_AND_CLOUD));
final OneTimeWorkRequest syncRequest = getOneTimeProactiveSyncRequest(inputData);
- final String workName = SYNC_MEDIA_PROACTIVE_WORK_PREFIX + SYNC_ALL_WORK_SUFFIX;
- try {
- Operation enqueueOperation = mWorkManager
- .enqueueUniqueWork(workName, ExistingWorkPolicy.KEEP, syncRequest);
-
- // Check that the request has been successfully enqueued.
- enqueueOperation.getResult().get();
- } catch (InterruptedException | ExecutionException e) {
- Log.e(TAG, "Could not enqueue proactive picker sync request", e);
- }
+ // Don't wait for the sync operation to enqueue so that Picker sync enqueue requests in
+ // order to avoid adding latency to critical MP code paths.
+ mWorkManager.enqueueUniqueWork(PROACTIVE_SYNC_WORK_NAME, ExistingWorkPolicy.KEEP,
+ syncRequest);
}
/**
@@ -139,27 +251,27 @@ public class PickerSyncManager {
* local and cloud provider.
*/
public void syncMediaImmediately(boolean shouldSyncLocalOnlyData) {
- if (shouldSyncLocalOnlyData) {
- syncMediaImmediately(PickerSyncManager.SYNC_LOCAL_ONLY);
- } else {
- syncMediaImmediately(PickerSyncManager.SYNC_LOCAL_AND_CLOUD);
+ syncMediaImmediately(PickerSyncManager.SYNC_LOCAL_ONLY, IMMEDIATE_LOCAL_SYNC_WORK_NAME);
+ if (!shouldSyncLocalOnlyData) {
+ syncMediaImmediately(PickerSyncManager.SYNC_CLOUD_ONLY, IMMEDIATE_CLOUD_SYNC_WORK_NAME);
}
}
/**
* Use this method for reactive syncs with either, local and cloud providers, or both.
*/
- private void syncMediaImmediately(@SyncSource int syncSource) {
+ private void syncMediaImmediately(@SyncSource int syncSource, @NonNull String workName) {
final Data inputData = new Data(Map.of(SYNC_WORKER_INPUT_SYNC_SOURCE, syncSource));
- final OneTimeWorkRequest syncRequest = getImmediateSyncRequest(inputData);
+ final OneTimeWorkRequest syncRequest =
+ buildOneTimeWorkerRequest(ImmediateSyncWorker.class, inputData);
// Track the new sync request(s)
trackNewSyncRequests(syncSource, syncRequest.getId());
- // Enqueue local sync then cloud sync requests
+ // Enqueue local or cloud sync request
try {
final Operation enqueueOperation = mWorkManager
- .enqueue(Collections.singletonList(syncRequest));
+ .enqueueUniqueWork(workName, ExistingWorkPolicy.APPEND_OR_REPLACE, syncRequest);
// Check that the request has been successfully enqueued.
enqueueOperation.getResult().get();
@@ -173,69 +285,92 @@ public class PickerSyncManager {
* Use this method for reactive syncs which are user action triggered.
*
* @param albumId is the id of the album that needs to be synced.
- * @param isLocal is true when the authority when the sync type is local.
- * For cloud syncs, this is false.
+ * @param authority The authority of the album media.
*/
public void syncAlbumMediaForProviderImmediately(
- @NonNull String albumId,
- boolean isLocal) {
- syncAlbumMediaForProviderImmediately(albumId, getSyncSource(isLocal));
+ @NonNull String albumId, @NonNull String authority) {
+ boolean isLocal = PickerSyncController.LOCAL_PICKER_PROVIDER_AUTHORITY.equals(authority);
+ syncAlbumMediaForProviderImmediately(albumId, getSyncSource(isLocal), authority);
}
/**
* Use this method for reactive syncs which are user action triggered.
*
* @param albumId is the id of the album that needs to be synced.
- * @param syncSource indicates if the sync is required with local provider or cloud provider
- * or both.
+ * @param syncSource indicates if the sync is required with local provider or cloud provider or
+ * both.
*/
private void syncAlbumMediaForProviderImmediately(
- @NonNull String albumId,
- @SyncSource int syncSource) {
- final Data inputData = new Data(Map.of(
- SYNC_WORKER_INPUT_SYNC_SOURCE, syncSource,
- SYNC_WORKER_INPUT_ALBUM_ID, albumId));
- final OneTimeWorkRequest syncRequest = getImmediateAlbumSyncRequest(inputData);
+ @NonNull String albumId, @SyncSource int syncSource, String authority) {
+ final Data inputData =
+ new Data(
+ Map.of(
+ SYNC_WORKER_INPUT_AUTHORITY, authority,
+ SYNC_WORKER_INPUT_SYNC_SOURCE, syncSource,
+ SYNC_WORKER_INPUT_RESET_TYPE, SYNC_RESET_ALBUM,
+ SYNC_WORKER_INPUT_ALBUM_ID, albumId));
+ final OneTimeWorkRequest resetRequest =
+ buildOneTimeWorkerRequest(MediaResetWorker.class, inputData);
+ final OneTimeWorkRequest syncRequest =
+ buildOneTimeWorkerRequest(ImmediateAlbumSyncWorker.class, inputData);
// Track the new sync request(s)
+ trackNewAlbumMediaSyncRequests(syncSource, resetRequest.getId());
trackNewAlbumMediaSyncRequests(syncSource, syncRequest.getId());
-
- // Enqueue local sync then cloud sync requests
+ // Enqueue local or cloud sync requests
try {
- final Operation enqueueOperation = mWorkManager
- .enqueue(Collections.singletonList(syncRequest));
+ final Operation enqueueOperation =
+ mWorkManager
+ .beginUniqueWork(
+ IMMEDIATE_ALBUM_SYNC_WORK_NAME,
+ ExistingWorkPolicy.APPEND_OR_REPLACE,
+ resetRequest)
+ .then(syncRequest).enqueue();
// Check that the request has been successfully enqueued.
enqueueOperation.getResult().get();
} catch (Exception e) {
Log.e(TAG, "Could not enqueue expedited picker sync request", e);
+ markAlbumMediaSyncAsComplete(syncSource, resetRequest.getId());
markAlbumMediaSyncAsComplete(syncSource, syncRequest.getId());
}
}
@NotNull
- private OneTimeWorkRequest getImmediateSyncRequest(@NotNull Data inputData) {
- return new OneTimeWorkRequest.Builder(ImmediateSyncWorker.class)
+ private OneTimeWorkRequest buildOneTimeWorkerRequest(
+ @NotNull Class<? extends Worker> workerClass, @NonNull Data inputData) {
+ return new OneTimeWorkRequest.Builder(workerClass)
.setInputData(inputData)
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
.build();
}
@NotNull
- private OneTimeWorkRequest getImmediateAlbumSyncRequest(@NotNull Data inputData) {
- return new OneTimeWorkRequest.Builder(ImmediateAlbumSyncWorker.class)
+ private PeriodicWorkRequest getPeriodicProactiveSyncRequest(@NotNull Data inputData) {
+ return new PeriodicWorkRequest.Builder(
+ ProactiveSyncWorker.class, SYNC_MEDIA_PERIODIC_WORK_INTERVAL, TimeUnit.HOURS)
.setInputData(inputData)
- .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
+ .setConstraints(getProactiveSyncConstraints())
.build();
}
@NotNull
- private PeriodicWorkRequest getPeriodicProactiveSyncRequest(@NotNull Data inputData) {
+ private PeriodicWorkRequest getPeriodicAlbumResetRequest(@NotNull Data inputData) {
+
+ Constraints constraints =
+ new Constraints.Builder()
+ .setRequiresBatteryNotLow(true)
+ .setRequiresDeviceIdle(true)
+ .build();
+
return new PeriodicWorkRequest.Builder(
- ProactiveSyncWorker.class, SYNC_MEDIA_PERIODIC_WORK_INTERVAL, TimeUnit.HOURS)
+ MediaResetWorker.class,
+ RESET_ALBUM_MEDIA_PERIODIC_WORK_INTERVAL,
+ TimeUnit.HOURS)
.setInputData(inputData)
- .setConstraints(getProactiveSyncConstraints())
+ .setConstraints(constraints)
+ .addTag(SYNC_WORKER_TAG_IS_PERIODIC)
.build();
}
@@ -249,7 +384,6 @@ public class PickerSyncManager {
@NotNull
private static Constraints getProactiveSyncConstraints() {
- // TODO these constraints are not finalised.
return new Constraints.Builder()
.setRequiresBatteryNotLow(true)
.build();
diff --git a/src/com/android/providers/media/photopicker/sync/PickerSyncNotificationHelper.java b/src/com/android/providers/media/photopicker/sync/PickerSyncNotificationHelper.java
new file mode 100644
index 000000000..e30f2eb49
--- /dev/null
+++ b/src/com/android/providers/media/photopicker/sync/PickerSyncNotificationHelper.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.providers.media.photopicker.sync;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.core.app.NotificationCompat;
+import androidx.work.ForegroundInfo;
+
+import com.android.modules.utils.build.SdkLevel;
+import com.android.providers.media.R;
+
+/**
+ * Helper functions for Picker sync notifications.
+ */
+public class PickerSyncNotificationHelper {
+ private static final String TAG = "SyncNotifHelper";
+ private static final String NOTIFICATION_CHANNEL_ID = "PhotoPickerSyncChannel";
+ private static final int NOTIFICATION_ID = 0;
+ private static final int NOTIFICATION_TIMEOUT_MILLIS = 1000;
+
+
+ /**
+ * Created notification channel for Picker Sync notifications.
+ * Recreating an existing notification channel with its original values performs no operation,
+ * so it's safe to call this code when starting an app.
+ */
+ public static void createNotificationChannel(@NonNull Context context) {
+ final String contentTitle = context.getResources()
+ .getString(R.string.picker_sync_notification_channel);
+
+ final NotificationChannel channel = new NotificationChannel(
+ NOTIFICATION_CHANNEL_ID, contentTitle, NotificationManager.IMPORTANCE_LOW);
+ channel.enableLights(false);
+ channel.enableVibration(false);
+
+ final NotificationManager notificationManager =
+ context.getSystemService(NotificationManager.class);
+ if (notificationManager != null) {
+ notificationManager.createNotificationChannel(channel);
+ }
+ }
+
+ /**
+ * Return Foreground info. This object contains a Notification and notification id that should
+ * be displayed in the context of a foreground service.
+ * This method should not be invoked by WorkManager in Android S+ devices.
+ */
+ @NonNull
+ public static ForegroundInfo getForegroundInfo(@NonNull Context context) {
+ if (SdkLevel.isAtLeastS()) {
+ Log.w(TAG, "Picker Sync notifications should not be displayed in S+ devices.");
+ }
+ return new ForegroundInfo(NOTIFICATION_ID, getNotification(context));
+ }
+
+ /**
+ * Create a notification to display when Picker sync is happening.
+ */
+ private static Notification getNotification(@NonNull Context context) {
+ final Resources resources = context.getResources();
+ final String contentTitle = resources.getString(R.string.picker_sync_notification_title);
+ final String contentText = resources.getString(R.string.picker_sync_notification_text);
+
+ return new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
+ .setSmallIcon(R.drawable.picker_app_icon)
+ .setContentTitle(contentTitle)
+ .setContentText(contentText)
+ .setPriority(NotificationCompat.PRIORITY_MIN)
+ .setVisibility(NotificationCompat.VISIBILITY_SECRET)
+ .setSilent(true)
+ .setTimeoutAfter(NOTIFICATION_TIMEOUT_MILLIS)
+ .build();
+ }
+}
diff --git a/src/com/android/providers/media/photopicker/sync/ProactiveSyncWorker.java b/src/com/android/providers/media/photopicker/sync/ProactiveSyncWorker.java
index 8a9297f82..dff247677 100644
--- a/src/com/android/providers/media/photopicker/sync/ProactiveSyncWorker.java
+++ b/src/com/android/providers/media/photopicker/sync/ProactiveSyncWorker.java
@@ -28,11 +28,13 @@ import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
+import androidx.work.ForegroundInfo;
import androidx.work.ListenableWorker;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
import com.android.providers.media.photopicker.PickerSyncController;
+import com.android.providers.media.photopicker.util.exceptions.RequestObsoleteException;
/**
* This is a {@link Worker} class responsible for proactively syncing media with the correct sync
@@ -40,6 +42,7 @@ import com.android.providers.media.photopicker.PickerSyncController;
*/
public class ProactiveSyncWorker extends Worker {
private static final String TAG = "PSyncWorker";
+ private final Context mContext;
/**
* Creates an instance of the {@link Worker}.
@@ -49,6 +52,7 @@ public class ProactiveSyncWorker extends Worker {
*/
public ProactiveSyncWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
+ mContext = context;
}
@NonNull
@@ -67,6 +71,7 @@ public class ProactiveSyncWorker extends Worker {
localSyncTracker.createSyncFuture(getId());
// Complete sync and mark work tracker as finished.
+ checkIsWorkerStopped();
PickerSyncController.getInstanceOrThrow().syncAllMediaFromLocalProvider();
localSyncTracker.markSyncCompleted(getId());
Log.i(TAG, "Completed picker proactive sync complete from local provider.");
@@ -77,12 +82,13 @@ public class ProactiveSyncWorker extends Worker {
cloudSyncTracker.createSyncFuture(getId());
// Complete sync and mark work tracker as finished.
+ checkIsWorkerStopped();
PickerSyncController.getInstanceOrThrow().syncAllMediaFromCloudProvider();
cloudSyncTracker.markSyncCompleted(getId());
Log.i(TAG, "Completed picker proactive sync complete from cloud provider.");
}
return ListenableWorker.Result.success();
- } catch (IllegalStateException e) {
+ } catch (IllegalStateException | RequestObsoleteException e) {
Log.e(TAG, "Could not complete proactive sync for sync source: " + syncSource, e);
// Mark all pending syncs as finished and set failure result.
@@ -90,4 +96,26 @@ public class ProactiveSyncWorker extends Worker {
return ListenableWorker.Result.failure();
}
}
+
+ private void checkIsWorkerStopped() throws RequestObsoleteException {
+ if (isStopped()) {
+ throw new RequestObsoleteException("Work is stopped " + getId());
+ }
+ }
+
+ @Override
+ @NonNull
+ public ForegroundInfo getForegroundInfo() {
+ Log.e(TAG, "Proactive Sync Worker should not run as an expedited task");
+ return PickerSyncNotificationHelper.getForegroundInfo(mContext);
+ }
+
+ @Override
+ public void onStopped() {
+ Log.w(TAG, "Worker is stopped. Clearing all pending futures. It's possible that the sync "
+ + "still finishes running if it has started already.");
+ final int syncSource = getInputData()
+ .getInt(SYNC_WORKER_INPUT_SYNC_SOURCE, /* defaultValue */ SYNC_LOCAL_AND_CLOUD);
+ markSyncAsComplete(syncSource, getId());
+ }
}
diff --git a/src/com/android/providers/media/photopicker/ui/AlbumGridHolder.java b/src/com/android/providers/media/photopicker/ui/AlbumGridHolder.java
index a9d42d6d2..a90f6388b 100644
--- a/src/com/android/providers/media/photopicker/ui/AlbumGridHolder.java
+++ b/src/com/android/providers/media/photopicker/ui/AlbumGridHolder.java
@@ -16,6 +16,7 @@
package com.android.providers.media.photopicker.ui;
+import android.provider.CloudMediaProviderContract;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
@@ -38,6 +39,7 @@ class AlbumGridHolder extends RecyclerView.ViewHolder {
private final ImageLoader mImageLoader;
private final ImageView mIconThumb;
+ private final ImageView mIconDefaultThumb;
private final TextView mAlbumName;
private final TextView mItemCount;
private final boolean mHasMimeTypeFilter;
@@ -50,6 +52,7 @@ class AlbumGridHolder extends RecyclerView.ViewHolder {
super(itemView);
mIconThumb = itemView.findViewById(R.id.icon_thumbnail);
+ mIconDefaultThumb = itemView.findViewById(R.id.icon_default_thumbnail);
mAlbumName = itemView.findViewById(R.id.album_name);
mItemCount = itemView.findViewById(R.id.item_count);
mImageLoader = imageLoader;
@@ -60,7 +63,16 @@ class AlbumGridHolder extends RecyclerView.ViewHolder {
void bind(@NonNull Category category) {
int position = getAbsoluteAdapterPosition();
itemView.setOnClickListener(v -> mOnAlbumClickListener.onAlbumClick(category, position));
- mImageLoader.loadAlbumThumbnail(category, mIconThumb);
+
+ // Show default thumbnail icons if merged album is empty.
+ int defaultResId = -1;
+ if (CloudMediaProviderContract.AlbumColumns.ALBUM_ID_FAVORITES.equals(category.getId())) {
+ defaultResId = R.drawable.thumbnail_favorites;
+ } else if (CloudMediaProviderContract.AlbumColumns.ALBUM_ID_VIDEOS
+ .equals(category.getId())) {
+ defaultResId = R.drawable.thumbnail_videos;
+ }
+ mImageLoader.loadAlbumThumbnail(category, mIconThumb, defaultResId, mIconDefaultThumb);
mAlbumName.setText(category.getDisplayName(itemView.getContext()));
// Check whether there is a mime type filter or not. If yes, hide the item count. Otherwise,
// show the item count and update the count.
diff --git a/src/com/android/providers/media/photopicker/ui/AlbumsTabFragment.java b/src/com/android/providers/media/photopicker/ui/AlbumsTabFragment.java
index b973c3bc5..7d67abfbe 100644
--- a/src/com/android/providers/media/photopicker/ui/AlbumsTabFragment.java
+++ b/src/com/android/providers/media/photopicker/ui/AlbumsTabFragment.java
@@ -15,8 +15,6 @@
*/
package com.android.providers.media.photopicker.ui;
-import static com.android.providers.media.photopicker.DataLoaderThread.TOKEN;
-
import android.content.Context;
import android.os.Bundle;
import android.view.View;
@@ -27,7 +25,6 @@ import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import com.android.providers.media.R;
-import com.android.providers.media.photopicker.DataLoaderThread;
import com.android.providers.media.photopicker.util.LayoutModeUtils;
import java.util.ArrayList;
@@ -106,11 +103,4 @@ public class AlbumsTabFragment extends TabFragment {
ft.replace(R.id.fragment_container, fragment);
ft.commitAllowingStateLoss();
}
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- // Clear queued tasks in handler.
- DataLoaderThread.getHandler().removeCallbacksAndMessages(TOKEN);
- }
} \ No newline at end of file
diff --git a/src/com/android/providers/media/photopicker/ui/ImageLoader.java b/src/com/android/providers/media/photopicker/ui/ImageLoader.java
index 0d77b8287..08f25d98a 100644
--- a/src/com/android/providers/media/photopicker/ui/ImageLoader.java
+++ b/src/com/android/providers/media/photopicker/ui/ImageLoader.java
@@ -26,6 +26,7 @@ import android.net.Uri;
import android.provider.CloudMediaProviderContract;
import android.provider.MediaStore;
import android.util.Log;
+import android.view.View;
import android.widget.ImageView;
import androidx.annotation.NonNull;
@@ -71,12 +72,24 @@ public class ImageLoader {
* @param category the album
* @param imageView the imageView shows the thumbnail
*/
- public void loadAlbumThumbnail(@NonNull Category category, @NonNull ImageView imageView) {
+ public void loadAlbumThumbnail(@NonNull Category category, @NonNull ImageView imageView,
+ int defaultThumbnailRes, @NonNull ImageView defaultIcon) {
// Always show all thumbnails as bitmap images instead of drawables
// This is to ensure that we do not animate any thumbnail (for eg GIF)
// TODO(b/194285082): Use drawable instead of bitmap, as it saves memory.
- loadWithGlide(getBitmapRequestBuilder(category.getCoverUri()), THUMBNAIL_OPTION,
- /* signature */ null, imageView);
+ if (category.getCoverUri() != null || defaultThumbnailRes == -1) {
+ defaultIcon.setVisibility(View.GONE);
+ imageView.setVisibility(View.VISIBLE);
+
+ loadWithGlide(getBitmapRequestBuilder(category.getCoverUri()), THUMBNAIL_OPTION,
+ /* signature */ null, imageView);
+ } else {
+ imageView.setVisibility(View.INVISIBLE);
+ defaultIcon.setVisibility(View.VISIBLE);
+
+ loadWithGlide(getDrawableRequestBuilder(mContext.getDrawable(defaultThumbnailRes)),
+ THUMBNAIL_OPTION, /* signature */ null, defaultIcon);
+ }
}
/**
diff --git a/src/com/android/providers/media/photopicker/ui/PhotosTabAdapter.java b/src/com/android/providers/media/photopicker/ui/PhotosTabAdapter.java
index 3588fc378..5f518646a 100644
--- a/src/com/android/providers/media/photopicker/ui/PhotosTabAdapter.java
+++ b/src/com/android/providers/media/photopicker/ui/PhotosTabAdapter.java
@@ -103,6 +103,10 @@ class PhotosTabAdapter extends TabAdapter {
final boolean isSelected = mSelection.canSelectMultiple()
&& mSelection.isItemSelected(item);
+ if (isSelected) {
+ mSelection.addCheckedItemIndex(item, position);
+ }
+
mediaItemVH.bind(item, isSelected);
// We also need to set Item as a tag so that OnClick/OnLongClickListeners can then
@@ -191,4 +195,4 @@ class PhotosTabAdapter extends TabAdapter {
boolean onItemLongClick(@NonNull View view, int position);
}
-}
+} \ No newline at end of file
diff --git a/src/com/android/providers/media/photopicker/ui/PhotosTabFragment.java b/src/com/android/providers/media/photopicker/ui/PhotosTabFragment.java
index 2050cae0e..d8421325f 100644
--- a/src/com/android/providers/media/photopicker/ui/PhotosTabFragment.java
+++ b/src/com/android/providers/media/photopicker/ui/PhotosTabFragment.java
@@ -15,7 +15,6 @@
*/
package com.android.providers.media.photopicker.ui;
-import static com.android.providers.media.photopicker.DataLoaderThread.TOKEN;
import static com.android.providers.media.photopicker.ui.ItemsAction.ACTION_LOAD_NEXT_PAGE;
import static com.android.providers.media.photopicker.ui.ItemsAction.ACTION_REFRESH_ITEMS;
import static com.android.providers.media.photopicker.ui.ItemsAction.ACTION_VIEW_CREATED;
@@ -44,7 +43,6 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.android.providers.media.R;
-import com.android.providers.media.photopicker.DataLoaderThread;
import com.android.providers.media.photopicker.data.PaginationParameters;
import com.android.providers.media.photopicker.data.model.Category;
import com.android.providers.media.photopicker.data.model.Item;
@@ -87,7 +85,6 @@ public class PhotosTabFragment extends TabFragment {
private final Object mHideProgressBarToken = new Object();
-
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -133,6 +130,7 @@ public class PhotosTabFragment extends TabFragment {
if (savedInstanceState == null) {
initProgressBar(view);
}
+ mSelection.clearCheckedItemList();
final PhotosTabAdapter adapter = new PhotosTabAdapter(showRecentSection, mSelection,
mImageLoader, mOnMediaItemClickListener, /* lifecycleOwner */ this,
@@ -153,7 +151,7 @@ public class PhotosTabFragment extends TabFragment {
ACTION_VIEW_CREATED,
new PaginationParameters(
mPageSize,
- /* dateBeforeMs */ -1,
+ /* dateBeforeMs */ Long.MIN_VALUE,
/* rowId */ -1))
.observe(this, itemListResult -> {
onChangeMediaItems(itemListResult, adapter);
@@ -170,7 +168,7 @@ public class PhotosTabFragment extends TabFragment {
ACTION_VIEW_CREATED,
new PaginationParameters(
mPageSize,
- /* dateBeforeMs */ -1,
+ /* dateBeforeMs */ Long.MIN_VALUE,
/* rowId */ -1))
.observe(this, itemListResult -> {
onChangeMediaItems(itemListResult, adapter);
@@ -190,8 +188,21 @@ public class PhotosTabFragment extends TabFragment {
if (mIsCloudMediaInPhotoPickerEnabled) {
setOnScrollListenerForRecyclerView();
}
- }
+ // uncheck the unavailable items at UI those are no longer available in the selection list
+ getPickerActivity().isItemPhotoGridViewChanged()
+ .observe(this, isItemViewChanged -> {
+ if (isItemViewChanged) {
+ // To re-bind the view just to uncheck the unavailable media items at UI
+ // Size of mCheckItems is going to be constant ( Iterating over mCheckItems
+ // is not a heavy operation)
+ for (Integer index : mSelection.getCheckedItemsIndexes()) {
+ adapter.notifyItemChanged(index);
+ }
+ }
+ }
+ );
+ }
private void initProgressBar(@NonNull View view) {
// Check feature flag for cloud media and if it is not true then hide progress bar and
@@ -281,7 +292,6 @@ public class PhotosTabFragment extends TabFragment {
@Override
public void onResume() {
super.onResume();
-
final String title;
final LayoutModeUtils.Mode layoutMode;
final boolean shouldHideProfileButton;
@@ -311,7 +321,8 @@ public class PhotosTabFragment extends TabFragment {
mPickerViewModel.getPaginatedItemsForAction(
ACTION_REFRESH_ITEMS,
new PaginationParameters(firstVisibleItemPosition
- + PaginationParameters.PAGINATION_PAGE_SIZE_ITEMS, -1, -1));
+ + PaginationParameters.PAGINATION_PAGE_SIZE_ITEMS,
+ /*dateBeforeMs*/ Long.MIN_VALUE, -1));
}
}
}
@@ -325,7 +336,11 @@ public class PhotosTabFragment extends TabFragment {
} else {
adapter.setMediaItems(itemList.getItems(), itemList.getAction());
// Handle emptyView's visibility
- updateVisibilityForEmptyView(/* shouldShowEmptyView */ itemList.getItems().size() == 0);
+ boolean shouldShowEmptyView = (itemList.getItems().size() == 0);
+ updateVisibilityForEmptyView(shouldShowEmptyView);
+ if (shouldShowEmptyView) {
+ mPickerViewModel.setEmptyPageDisplayed(true);
+ }
}
mIsCurrentPageLoading = false;
mAtLeastOnePageLoaded = true;
@@ -342,12 +357,15 @@ public class PhotosTabFragment extends TabFragment {
new PhotosTabAdapter.OnMediaItemClickListener() {
@Override
public void onItemClick(@NonNull View view, int position) {
+
if (mSelection.canSelectMultiple()) {
final boolean isSelectedBefore = view.isSelected();
if (isSelectedBefore) {
mSelection.removeSelectedItem((Item) view.getTag());
+ mSelection.removeCheckedItemIndex((Item) view.getTag());
} else {
+ mSelection.addCheckedItemIndex((Item) view.getTag(), position);
if (!mSelection.isSelectionAllowed()) {
final int maxCount = mSelection.getMaxSelectionLimit();
final CharSequence quantityText =
@@ -366,6 +384,7 @@ public class PhotosTabFragment extends TabFragment {
}
}
view.setSelected(!isSelectedBefore);
+
// There is an issue b/223695510 about not selected in Accessibility mode.
// It only says selected state, but it doesn't say not selected state.
// Add the not selected only to avoid that it says selected twice.
@@ -487,11 +506,10 @@ public class PhotosTabFragment extends TabFragment {
mProgressBar.setVisibility(View.VISIBLE);
}
}
+
@Override
public void onDestroy() {
super.onDestroy();
mMainThreadHandler.removeCallbacksAndMessages(mHideProgressBarToken);
- // Clear queued tasks in handler.
- DataLoaderThread.getHandler().removeCallbacksAndMessages(TOKEN);
}
-}
+} \ No newline at end of file
diff --git a/src/com/android/providers/media/photopicker/ui/TabAdapter.java b/src/com/android/providers/media/photopicker/ui/TabAdapter.java
index 9b2c6efb7..35db5801e 100644
--- a/src/com/android/providers/media/photopicker/ui/TabAdapter.java
+++ b/src/com/android/providers/media/photopicker/ui/TabAdapter.java
@@ -317,7 +317,7 @@ public abstract class TabAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
mDismissButton.setOnClickListener(v -> onBannerEventListener.onDismissButtonClick());
- if (banner.mActionButtonText != -1) {
+ if (banner.mActionButtonText != -1 && onBannerEventListener.shouldShowActionButton()) {
mActionButton.setText(banner.mActionButtonText);
mActionButton.setVisibility(View.VISIBLE);
mActionButton.setOnClickListener(v -> onBannerEventListener.onActionButtonClick());
@@ -328,18 +328,14 @@ public abstract class TabAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
}
private enum Banner {
- // TODO(b/274426228): Replace `CLOUD_MEDIA_AVAILABLE` `mActionButtonText` from `-1` to
- // `R.string.picker_banner_cloud_change_account_button`, post change cloud account
- // functionality implementation from the Picker settings (b/261999521).
CLOUD_MEDIA_AVAILABLE(R.string.picker_banner_cloud_first_time_available_title,
- R.string.picker_banner_cloud_first_time_available_desc, /* no action button */ -1),
+ R.string.picker_banner_cloud_first_time_available_desc,
+ R.string.picker_banner_cloud_change_account_button),
ACCOUNT_UPDATED(R.string.picker_banner_cloud_account_changed_title,
R.string.picker_banner_cloud_account_changed_desc, /* no action button */ -1),
- // TODO(b/274426228): Replace `CHOOSE_ACCOUNT` `mActionButtonText` from `-1` to
- // `R.string.picker_banner_cloud_choose_account_button`, post change cloud account
- // functionality implementation from the Picker settings (b/261999521).
CHOOSE_ACCOUNT(R.string.picker_banner_cloud_choose_account_title,
- R.string.picker_banner_cloud_choose_account_desc, /* no action button */ -1),
+ R.string.picker_banner_cloud_choose_account_desc,
+ R.string.picker_banner_cloud_choose_account_button),
CHOOSE_APP(R.string.picker_banner_cloud_choose_app_title,
R.string.picker_banner_cloud_choose_app_desc,
R.string.picker_banner_cloud_choose_app_button);
@@ -395,5 +391,9 @@ public abstract class TabAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
}
void onBannerAdded();
+
+ default boolean shouldShowActionButton() {
+ return true;
+ }
}
}
diff --git a/src/com/android/providers/media/photopicker/ui/TabFragment.java b/src/com/android/providers/media/photopicker/ui/TabFragment.java
index 820993e31..159a97ce2 100644
--- a/src/com/android/providers/media/photopicker/ui/TabFragment.java
+++ b/src/com/android/providers/media/photopicker/ui/TabFragment.java
@@ -24,6 +24,7 @@ import static com.android.providers.media.photopicker.ui.TabAdapter.ITEM_TYPE_SE
import android.app.admin.DevicePolicyManager;
import android.content.Context;
+import android.content.Intent;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
@@ -468,7 +469,15 @@ public abstract class TabFragment extends Fragment {
@Override
public void onActionButtonClick() {
dismissBanner();
- getPickerActivity().startSettingsActivity();
+
+ final Intent accountChangeIntent =
+ mPickerViewModel.getChooseCloudMediaAccountActivityIntent();
+
+ if (accountChangeIntent != null) {
+ getPickerActivity().startActivity(accountChangeIntent);
+ } else {
+ getPickerActivity().startSettingsActivity();
+ }
}
@Override
@@ -513,6 +522,11 @@ public abstract class TabFragment extends Fragment {
void dismissBanner() {
mPickerViewModel.onUserDismissedCloudMediaAvailableBanner();
}
+
+ @Override
+ public boolean shouldShowActionButton() {
+ return mPickerViewModel.getChooseCloudMediaAccountActivityIntent() != null;
+ }
};
protected final OnBannerEventListener mOnAccountUpdatedBannerEventListener =
@@ -529,5 +543,10 @@ public abstract class TabFragment extends Fragment {
void dismissBanner() {
mPickerViewModel.onUserDismissedChooseAccountBanner();
}
+
+ @Override
+ public boolean shouldShowActionButton() {
+ return mPickerViewModel.getChooseCloudMediaAccountActivityIntent() != null;
+ }
};
}
diff --git a/src/com/android/providers/media/photopicker/ui/remotepreview/RemotePreviewSession.java b/src/com/android/providers/media/photopicker/ui/remotepreview/RemotePreviewSession.java
index 7536f6e21..cac25f587 100644
--- a/src/com/android/providers/media/photopicker/ui/remotepreview/RemotePreviewSession.java
+++ b/src/com/android/providers/media/photopicker/ui/remotepreview/RemotePreviewSession.java
@@ -268,6 +268,12 @@ final class RemotePreviewSession {
case PLAYBACK_STATE_BUFFERING:
mPreviewVideoHolder.getCircularProgressIndicator().setVisibility(View.VISIBLE);
return;
+ case PLAYBACK_STATE_COMPLETED:
+ // TODO(b/296543163): Investigate CloudMediaProviderContract for future OEM
+ // implementers. Should the provider be expected to loop the video themselves
+ // instead of ending the playback state?
+ requestPlayMedia();
+ return;
default:
}
}
@@ -375,7 +381,8 @@ final class RemotePreviewSession {
// media size, then we hide the thumbnail view.
mPreviewVideoHolder.getPlayerContainer().setVisibility(View.INVISIBLE);
mPreviewVideoHolder.getThumbnailView().setVisibility(View.VISIBLE);
- mPreviewVideoHolder.getPlayerControlsRoot().setVisibility(View.GONE);
+ updatePlayerControlsVisibilityState(
+ mPlayerControlsVisibilityStatus.shouldShowPlayerControls());
mPreviewVideoHolder.getCircularProgressIndicator().setVisibility(View.GONE);
updatePlayPauseButtonState(false /* isPlaying */);
@@ -450,7 +457,11 @@ final class RemotePreviewSession {
mIsAccessibilityEnabled = enabled;
mPreviewVideoHolder.getPlayerContainer().setOnClickListener(
mIsAccessibilityEnabled ? null : mPlayerContainerClickListener);
- updatePlayerControlsVisibilityState(mIsAccessibilityEnabled);
+ if (mIsAccessibilityEnabled) {
+ updatePlayerControlsVisibilityState(/* visible= */ true);
+ } else {
+ hidePlayerControlsWithDelay();
+ }
}
private void updatePlayPauseButtonState(boolean isPlaying) {
diff --git a/src/com/android/providers/media/photopicker/ui/settings/SettingsCloudMediaViewModel.java b/src/com/android/providers/media/photopicker/ui/settings/SettingsCloudMediaViewModel.java
index 346eed309..ca9be634f 100644
--- a/src/com/android/providers/media/photopicker/ui/settings/SettingsCloudMediaViewModel.java
+++ b/src/com/android/providers/media/photopicker/ui/settings/SettingsCloudMediaViewModel.java
@@ -56,6 +56,7 @@ import java.util.List;
public class SettingsCloudMediaViewModel extends ViewModel {
static final String NONE_PREF_KEY = "none";
private static final String TAG = "SettingsFragVM";
+ private static final long GET_ACCOUNT_NAME_TIMEOUT_IN_MILLIS = 10000L;
@NonNull
private final Context mContext;
@@ -196,7 +197,8 @@ public class SettingsCloudMediaViewModel extends ViewModel {
} else {
try {
final String accountName = getCloudMediaAccountName(
- mUserId.getContentResolver(mContext), currentProviderAuthority);
+ mUserId.getContentResolver(mContext), currentProviderAuthority,
+ GET_ACCOUNT_NAME_TIMEOUT_IN_MILLIS);
return new CloudMediaProviderAccount(currentProviderAuthority, accountName);
} catch (Exception e) {
Log.w(TAG, "Failed to fetch account name from the cloud media provider.", e);
diff --git a/src/com/android/providers/media/photopicker/util/CloudProviderUtils.java b/src/com/android/providers/media/photopicker/util/CloudProviderUtils.java
index 741755bdf..a859ba304 100644
--- a/src/com/android/providers/media/photopicker/util/CloudProviderUtils.java
+++ b/src/com/android/providers/media/photopicker/util/CloudProviderUtils.java
@@ -28,8 +28,12 @@ import static android.provider.MediaStore.GET_CLOUD_PROVIDER_RESULT;
import static android.provider.MediaStore.PICKER_MEDIA_INIT_CALL;
import static android.provider.MediaStore.SET_CLOUD_PROVIDER_CALL;
+import static com.android.providers.media.PickerUriResolver.getMediaCollectionInfoUri;
+
import static java.util.Collections.emptyList;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import android.annotation.DurationMillisLong;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context;
@@ -55,6 +59,9 @@ import com.android.providers.media.photopicker.data.model.UserId;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
/**
* Utility methods for retrieving available and/or allowlisted Cloud Providers.
@@ -248,23 +255,48 @@ public class CloudProviderUtils {
}
/**
+ * @param resolver {@link ContentResolver} for the related user
+ * @param cloudMediaProviderAuthority authority {@link String} of the {@link CloudMediaProvider}
+ * @param timeout timeout in milliseconds for this query (<= 0 for timeout)
* @return the current cloud media account name for the {@link CloudMediaProvider} with the
* given {@code cloudMediaProviderAuthority}.
*/
@Nullable
public static String getCloudMediaAccountName(@NonNull ContentResolver resolver,
- @Nullable String cloudMediaProviderAuthority) {
+ @Nullable String cloudMediaProviderAuthority, @DurationMillisLong long timeout)
+ throws ExecutionException, InterruptedException, TimeoutException {
if (cloudMediaProviderAuthority == null) {
return null;
}
- try (ContentProviderClient client =
- resolver.acquireContentProviderClient(cloudMediaProviderAuthority)) {
- final Bundle out = client.call(METHOD_GET_MEDIA_COLLECTION_INFO, /* arg */ null,
- /* extras */ null);
- return out.getString(ACCOUNT_NAME);
- } catch (RemoteException e) {
- throw e.rethrowAsRuntimeException();
+ CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
+ final Bundle out = resolver.call(getMediaCollectionInfoUri(cloudMediaProviderAuthority),
+ METHOD_GET_MEDIA_COLLECTION_INFO, /* arg */ null, /* extras */ null);
+ return (out == null) ? null : out.getString(ACCOUNT_NAME);
+ });
+
+ return (timeout > 0) ? future.get(timeout, MILLISECONDS) : future.get();
+ }
+
+ /**
+ * @param resolver {@link ContentResolver} for the related user
+ * @param cloudMediaProviderAuthority authority {@link String} of the {@link CloudMediaProvider}
+ * @param timeout timeout in milliseconds for this query (<= 0 for timeout)
+ * @return the current cloud media collection info for the {@link CloudMediaProvider} with the
+ * given {@code cloudMediaProviderAuthority}.
+ */
+ @Nullable
+ public static Bundle getCloudMediaCollectionInfo(@NonNull ContentResolver resolver,
+ @Nullable String cloudMediaProviderAuthority, @DurationMillisLong long timeout)
+ throws ExecutionException, InterruptedException, TimeoutException {
+ if (cloudMediaProviderAuthority == null) {
+ return null;
}
+
+ CompletableFuture<Bundle> future = CompletableFuture.supplyAsync(() ->
+ resolver.call(getMediaCollectionInfoUri(cloudMediaProviderAuthority),
+ METHOD_GET_MEDIA_COLLECTION_INFO, /* arg */ null, /* extras */ null));
+
+ return (timeout > 0) ? future.get(timeout, MILLISECONDS) : future.get();
}
}
diff --git a/src/com/android/providers/media/photopicker/viewmodel/BannerController.java b/src/com/android/providers/media/photopicker/viewmodel/BannerController.java
index 5b070a3c8..5d8afe99e 100644
--- a/src/com/android/providers/media/photopicker/viewmodel/BannerController.java
+++ b/src/com/android/providers/media/photopicker/viewmodel/BannerController.java
@@ -19,14 +19,17 @@ package com.android.providers.media.photopicker.viewmodel;
import static android.provider.MediaStore.getCurrentCloudProvider;
import static com.android.providers.media.photopicker.util.CloudProviderUtils.getAvailableCloudProviders;
-import static com.android.providers.media.photopicker.util.CloudProviderUtils.getCloudMediaAccountName;
+import static com.android.providers.media.photopicker.util.CloudProviderUtils.getCloudMediaCollectionInfo;
import static com.android.providers.media.photopicker.util.CloudProviderUtils.getProviderLabelForUser;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.PackageManager;
+import android.os.Bundle;
import android.os.Looper;
import android.os.UserHandle;
+import android.provider.CloudMediaProviderContract.MediaCollectionInfo;
import android.text.TextUtils;
import android.util.AtomicFile;
import android.util.Log;
@@ -44,6 +47,8 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
/**
* Banner Controller to store and handle the banner data per user for
@@ -64,6 +69,7 @@ class BannerController {
* {@link android.provider.CloudMediaProvider}.
*/
private static final String ACCOUNT_NAME = "account_name";
+ private static final long GET_CLOUD_MEDIA_COLLECTION_INFO_TIMEOUT_IN_MILLIS = 100L;
private final Context mContext;
private final UserHandle mUserHandle;
@@ -83,6 +89,9 @@ class BannerController {
// Label of the current cloud media provider
private String mCmpLabel;
+ // Account selection activity intent of the current cloud media provider
+ private Intent mChooseCloudMediaAccountActivityIntent;
+
// Boolean 'Choose App' banner visibility
private boolean mShowChooseAppBanner;
@@ -130,7 +139,9 @@ class BannerController {
* block the UI thread on the heavy Binder calls to fetch the cloud media provider info.
*/
private void initialise() {
- final String cmpAuthority, cmpAccountName;
+ String cmpAuthority = null, cmpAccountName = null;
+ mCmpLabel = null;
+ mChooseCloudMediaAccountActivityIntent = null;
// TODO(b/245746037): Remove try-catch for the RuntimeException.
// Under the hood MediaStore.getCurrentCloudProvider() makes an IPC call to the primary
// MediaProvider process, where we currently perform a UID check (making sure that
@@ -149,14 +160,23 @@ class BannerController {
UserId.of(mUserHandle).getContentResolver(mContext);
cmpAuthority = getCurrentCloudProvider(contentResolver);
mCmpLabel = getProviderLabelForUser(mContext, mUserHandle, cmpAuthority);
- cmpAccountName = getCloudMediaAccountName(contentResolver, cmpAuthority);
+ final Bundle cloudMediaCollectionInfo = getCloudMediaCollectionInfo(contentResolver,
+ cmpAuthority, GET_CLOUD_MEDIA_COLLECTION_INFO_TIMEOUT_IN_MILLIS);
+ if (cloudMediaCollectionInfo != null) {
+ cmpAccountName = cloudMediaCollectionInfo.getString(
+ MediaCollectionInfo.ACCOUNT_NAME);
+ mChooseCloudMediaAccountActivityIntent = cloudMediaCollectionInfo.getParcelable(
+ MediaCollectionInfo.ACCOUNT_CONFIGURATION_INTENT);
+ }
// Not logging the account name due to privacy concerns
Log.d(TAG, "Current CloudMediaProvider authority: " + cmpAuthority + ", label: "
+ mCmpLabel);
- } catch (PackageManager.NameNotFoundException | RuntimeException e) {
+ } catch (PackageManager.NameNotFoundException | RuntimeException | ExecutionException
+ | InterruptedException | TimeoutException e) {
Log.w(TAG, "Could not fetch the current CloudMediaProvider", e);
- resetToDefault();
+ updateCloudProviderDataMap(cmpAuthority, cmpAccountName);
+ clearBanners();
return;
}
@@ -213,15 +233,6 @@ class BannerController {
}
/**
- * Reset all the controller data to their default values.
- */
- private void resetToDefault() {
- mCloudProviderDataMap.clear();
- mCmpLabel = null;
- clearBanners();
- }
-
- /**
* Clear all banners
*
* Reset all should show banner {@code boolean} values to {@code false}.
@@ -263,6 +274,15 @@ class BannerController {
}
/**
+ * @return the account selection activity {@link Intent} of the current
+ * {@link android.provider.CloudMediaProvider}.
+ */
+ @Nullable
+ Intent getChooseCloudMediaAccountActivityIntent() {
+ return mChooseCloudMediaAccountActivityIntent;
+ }
+
+ /**
* @return the 'Choose App' banner visibility {@link #mShowChooseAppBanner}.
*/
boolean shouldShowChooseAppBanner() {
@@ -385,6 +405,12 @@ class BannerController {
private void persistCloudProviderInfo(@Nullable String cmpAuthority,
@Nullable String cmpAccountName) {
+ updateCloudProviderDataMap(cmpAuthority, cmpAccountName);
+ updateCloudProviderDataFile();
+ }
+
+ private void updateCloudProviderDataMap(@Nullable String cmpAuthority,
+ @Nullable String cmpAccountName) {
mCloudProviderDataMap.clear();
if (cmpAuthority != null) {
mCloudProviderDataMap.put(AUTHORITY, cmpAuthority);
@@ -392,8 +418,6 @@ class BannerController {
if (cmpAccountName != null) {
mCloudProviderDataMap.put(ACCOUNT_NAME, cmpAccountName);
}
-
- updateCloudProviderDataFile();
}
@VisibleForTesting
diff --git a/src/com/android/providers/media/photopicker/viewmodel/BannerManager.java b/src/com/android/providers/media/photopicker/viewmodel/BannerManager.java
index b871cbff3..a726d0bf1 100644
--- a/src/com/android/providers/media/photopicker/viewmodel/BannerManager.java
+++ b/src/com/android/providers/media/photopicker/viewmodel/BannerManager.java
@@ -20,6 +20,7 @@ import static com.android.providers.media.photopicker.DataLoaderThread.TOKEN;
import android.annotation.UserIdInt;
import android.content.Context;
+import android.content.Intent;
import android.os.UserHandle;
import android.util.Log;
@@ -46,6 +47,8 @@ class BannerManager {
private final MutableLiveData<String> mCloudMediaProviderLabel = new MutableLiveData<>();
// Account name of the current CloudMediaProvider of the current user
private final MutableLiveData<String> mCloudMediaAccountName = new MutableLiveData<>();
+ // Account selection activity intent of the current CloudMediaProvider of the current user
+ private Intent mChooseCloudMediaAccountActivityIntent = null;
// Boolean Choose App Banner visibility
private final MutableLiveData<Boolean> mShowChooseAppBanner = new MutableLiveData<>(false);
@@ -101,6 +104,24 @@ class BannerManager {
}
/**
+ * @return the account selection activity {@link Intent} of the current
+ * {@link android.provider.CloudMediaProvider}.
+ */
+ @Nullable
+ Intent getChooseCloudMediaAccountActivityIntent() {
+ return mChooseCloudMediaAccountActivityIntent;
+ }
+
+
+ /**
+ * Update the account selection activity {@link Intent} of the current
+ * {@link android.provider.CloudMediaProvider}.
+ */
+ void setChooseCloudMediaAccountActivityIntent(Intent intent) {
+ mChooseCloudMediaAccountActivityIntent = intent;
+ }
+
+ /**
* @return a {@link LiveData} that holds the value (once it's fetched) of the account name
* of the current {@link android.provider.CloudMediaProvider}.
*/
@@ -291,6 +312,8 @@ class BannerManager {
.postValue(bannerController.getCloudMediaProviderLabel());
getCloudMediaAccountNameLiveData()
.postValue(bannerController.getCloudMediaProviderAccountName());
+ setChooseCloudMediaAccountActivityIntent(
+ bannerController.getChooseCloudMediaAccountActivityIntent());
shouldShowChooseAppBannerLiveData()
.postValue(bannerController.shouldShowChooseAppBanner());
shouldShowCloudMediaAvailableBannerLiveData()
diff --git a/src/com/android/providers/media/photopicker/viewmodel/PickerViewModel.java b/src/com/android/providers/media/photopicker/viewmodel/PickerViewModel.java
index b4bfb24bd..5e1e05dd8 100644
--- a/src/com/android/providers/media/photopicker/viewmodel/PickerViewModel.java
+++ b/src/com/android/providers/media/photopicker/viewmodel/PickerViewModel.java
@@ -43,9 +43,12 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
import android.database.ContentObserver;
import android.database.Cursor;
import android.os.CancellationSignal;
+import android.os.Handler;
+import android.os.Looper;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
@@ -61,6 +64,7 @@ import androidx.lifecycle.Observer;
import com.android.internal.logging.InstanceId;
import com.android.internal.logging.InstanceIdSequence;
+import com.android.modules.utils.BackgroundThread;
import com.android.modules.utils.build.SdkLevel;
import com.android.providers.media.ConfigStore;
import com.android.providers.media.MediaApplication;
@@ -96,12 +100,16 @@ public class PickerViewModel extends AndroidViewModel {
private static final int INSTANCE_ID_MAX = 1 << 15;
private static final int DELAY_MILLIS = 0;
+ // Token for the tasks to load the category items in the data loader thread's queue
+ private final Object mLoadCategoryItemsThreadToken = new Object();
+
@NonNull
@SuppressLint("StaticFieldLeak")
private final Context mAppContext;
private final Selection mSelection;
private final MuteStatus mMuteStatus;
+ public boolean mEmptyPageDisplayed = false;
// TODO(b/193857982): We keep these four data sets now, we may need to find a way to reduce the
// data set to reduce memories.
@@ -146,7 +154,6 @@ public class PickerViewModel extends AndroidViewModel {
// Note - Must init banner manager on mIsUserSelectForApp / mIsLocalOnly updates
private boolean mIsUserSelectForApp;
private boolean mIsLocalOnly;
- private boolean mIsAllItemsLoaded = false;
private boolean mIsAllCategoryItemsLoaded = false;
private boolean mIsNotificationForUpdateReceived = false;
private CancellationSignal mCancellationSignal = new CancellationSignal();
@@ -188,13 +195,20 @@ public class PickerViewModel extends AndroidViewModel {
// Signal ContentProvider to cancel currently running task.
mCancellationSignal.cancel();
- // Clear queued tasks in handler.
- DataLoaderThread.getHandler().removeCallbacksAndMessages(TOKEN);
+ clearQueuedTasksInDataLoaderThread();
}
private void onNotificationReceived() {
Log.d(TAG, "Notification for media update has been received");
mIsNotificationForUpdateReceived = true;
+ if (mEmptyPageDisplayed && mConfigStore.isCloudMediaInPhotoPickerEnabled()) {
+ (new Handler(Looper.getMainLooper())).post(() -> {
+ Log.d(TAG, "Refreshing UI to display new items.");
+ mEmptyPageDisplayed = false;
+ getPaginatedItemsForAction(ACTION_REFRESH_ITEMS,
+ new PaginationParameters(mItemsPageSize, -1, -1));
+ });
+ }
}
@VisibleForTesting
@@ -232,6 +246,10 @@ public class PickerViewModel extends AndroidViewModel {
mConfigStore = configStore;
}
+ public void setEmptyPageDisplayed(boolean emptyPageDisplayed) {
+ mEmptyPageDisplayed = emptyPageDisplayed;
+ }
+
/**
* @return the {@link ConfigStore} for this context.
*/
@@ -298,6 +316,15 @@ public class PickerViewModel extends AndroidViewModel {
}
/**
+ * @return the account selection activity {@link Intent} of the current
+ * {@link android.provider.CloudMediaProvider}.
+ */
+ @Nullable
+ public Intent getChooseCloudMediaAccountActivityIntent() {
+ return mBannerManager.getChooseCloudMediaAccountActivityIntent();
+ }
+
+ /**
* Reset to personal profile mode.
*/
@UiThread
@@ -325,8 +352,7 @@ public class PickerViewModel extends AndroidViewModel {
// Post 'should refresh UI live data' value as false to avoid unnecessary repetitive resets
mShouldRefreshUiLiveData.postValue(false);
- // Clear queued tasks in handler.
- DataLoaderThread.getHandler().removeCallbacksAndMessages(TOKEN);
+ clearQueuedTasksInDataLoaderThread();
initPhotoPickerData();
@@ -392,8 +418,8 @@ public class PickerViewModel extends AndroidViewModel {
// number of items. This will be equal to page size for pagination if cloud
// picker feature flag is enabled, else it will be -1 implying that the complete
// list should be loaded.
- updatePaginatedItems(new PaginationParameters(mItemsPageSize, -1,
- -1), /* isReset */ true, action);
+ updatePaginatedItems(new PaginationParameters(mItemsPageSize,
+ /*dateBeforeMs*/ Long.MIN_VALUE, /*rowId*/ -1), /* isReset */ true, action);
break;
}
case ACTION_REFRESH_ITEMS: {
@@ -438,9 +464,6 @@ public class PickerViewModel extends AndroidViewModel {
final UserId userId = mUserIdManager.getCurrentUserProfileId();
DataLoaderThread.getHandler().postDelayed(() -> {
- if (action == ACTION_LOAD_NEXT_PAGE && mIsAllItemsLoaded) {
- return;
- }
// Load the items as per the pagination parameters passed as params to this method.
List<Item> newPageItemList = loadItems(Category.DEFAULT, userId, pagingParameters);
@@ -451,13 +474,8 @@ public class PickerViewModel extends AndroidViewModel {
mItemsResult.getValue() == null || isReset ? new ArrayList<>()
: mItemsResult.getValue().getItems();
updatedList.addAll(newPageItemList);
-
- if (isReset) {
- mIsAllItemsLoaded = false;
- }
Log.d(TAG, "Next page for photos items have been loaded.");
if (newPageItemList.isEmpty()) {
- mIsAllItemsLoaded = true;
Log.d(TAG, "All photos items have been loaded.");
}
@@ -525,7 +543,10 @@ public class PickerViewModel extends AndroidViewModel {
switch (action) {
case ACTION_VIEW_CREATED: {
// This call is made only for loading the first page of album media,
- // hence the category and category item list should be refreshed each time.
+ // so the existing data loader thread tasks for updating the category items should
+ // be cleared and the category and category item list should be refreshed each time.
+ DataLoaderThread.getHandler().removeCallbacksAndMessages(
+ mLoadCategoryItemsThreadToken);
mCategoryItemsResult = new MutableLiveData<>();
mCurrentCategory = category;
assert paginationParameters != null;
@@ -588,13 +609,14 @@ public class PickerViewModel extends AndroidViewModel {
private void loadCategoryItemsAsync(PaginationParameters pagingParameters, boolean isReset,
@ItemsAction.Type int action) {
final UserId userId = mUserIdManager.getCurrentUserProfileId();
+ final Category category = mCurrentCategory;
DataLoaderThread.getHandler().postDelayed(() -> {
if (action == ACTION_LOAD_NEXT_PAGE && mIsAllCategoryItemsLoaded) {
return;
}
// Load the items as per the pagination parameters passed as params to this method.
- List<Item> newPageItemList = loadItems(mCurrentCategory, userId, pagingParameters);
+ List<Item> newPageItemList = loadItems(category, userId, pagingParameters);
// Based on if it is a reset case or not, create an updated list.
// If it is a reset case, assign an empty list else use the contents of the pre-existing
@@ -607,13 +629,15 @@ public class PickerViewModel extends AndroidViewModel {
mIsAllCategoryItemsLoaded = false;
}
Log.d(TAG, "Next page for category items have been loaded. Category: "
- + mCurrentCategory + " " + updatedList.size());
+ + category + " " + updatedList.size());
if (newPageItemList.isEmpty()) {
mIsAllCategoryItemsLoaded = true;
Log.d(TAG, "All items have been loaded for category: " + mCurrentCategory);
}
- mCategoryItemsResult.postValue(new PaginatedItemsResult(updatedList, action));
- }, TOKEN, DELAY_MILLIS);
+ if (Objects.equals(category, mCurrentCategory)) {
+ mCategoryItemsResult.postValue(new PaginatedItemsResult(updatedList, action));
+ }
+ }, mLoadCategoryItemsThreadToken, DELAY_MILLIS);
}
/**
@@ -799,8 +823,6 @@ public class PickerViewModel extends AndroidViewModel {
maybeLogPickerOpenedWithCloudProvider();
}
- // TODO(b/245745412): Fix log params (uid & package name)
- // TODO(b/245745424): Solve for active cloud provider without a logged in account
private void maybeLogPickerOpenedWithCloudProvider() {
if (shouldShowOnlyLocalFeatures()) {
return;
@@ -815,8 +837,8 @@ public class PickerViewModel extends AndroidViewModel {
+ ", log=" + (providerAuthority != null));
if (providerAuthority != null) {
- mLogger.logPickerOpenWithActiveCloudProvider(
- mInstanceId, /* cloudProviderUid */ -1, providerAuthority);
+ BackgroundThread.getExecutor().execute(() ->
+ logPickerOpenedWithCloudProvider(providerAuthority));
}
// We only need to get the value once.
cloudMediaProviderAuthorityLiveData.removeObserver(this);
@@ -824,6 +846,27 @@ public class PickerViewModel extends AndroidViewModel {
});
}
+ private void logPickerOpenedWithCloudProvider(@NonNull String providerAuthority) {
+ String cloudProviderPackage = providerAuthority;
+ int cloudProviderUid = -1;
+
+ try {
+ final PackageManager packageManager =
+ UserId.CURRENT_USER.getPackageManager(mAppContext);
+ final ProviderInfo providerInfo = packageManager.resolveContentProvider(
+ providerAuthority, /* flags= */ 0);
+
+ cloudProviderPackage = providerInfo.applicationInfo.packageName;
+ cloudProviderUid = providerInfo.applicationInfo.uid;
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.d(TAG, "Logging the ui event 'picker open with an active cloud provider' with its "
+ + "authority in place of the package name and a default uid.", e);
+ }
+
+ mLogger.logPickerOpenWithActiveCloudProvider(
+ mInstanceId, cloudProviderUid, cloudProviderPackage);
+ }
+
/**
* Log metrics to notify that the user has clicked Browse to open DocumentsUi
*/
@@ -1209,4 +1252,9 @@ public class PickerViewModel extends AndroidViewModel {
}, TOKEN, DELAY_MILLIS);
}
}
+
+ private void clearQueuedTasksInDataLoaderThread() {
+ DataLoaderThread.getHandler().removeCallbacksAndMessages(TOKEN);
+ DataLoaderThread.getHandler().removeCallbacksAndMessages(mLoadCategoryItemsThreadToken);
+ }
}
diff --git a/src/com/android/providers/media/stableuris/dao/BackupIdRow.java b/src/com/android/providers/media/stableuris/dao/BackupIdRow.java
index 27060d5d7..0bd03906d 100644
--- a/src/com/android/providers/media/stableuris/dao/BackupIdRow.java
+++ b/src/com/android/providers/media/stableuris/dao/BackupIdRow.java
@@ -20,13 +20,8 @@ import android.provider.MediaStore.MediaColumns;
import com.android.providers.media.util.StringUtils;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
import java.io.Serializable;
-import java.util.Base64;
import java.util.Objects;
/**
@@ -248,24 +243,35 @@ public final class BackupIdRow implements Serializable {
/**
* Serializes the given {@link BackupIdRow} object to a string
+ * Format is
+ * "is_dirty::_id::is_fav::is_pending::is_trashed::media_type::user_id::owner_id::date_expires"
*/
public static String serialize(BackupIdRow backupIdRow) throws IOException {
- ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
- ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
- objectOutputStream.writeObject(backupIdRow);
- objectOutputStream.close();
- return Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
+ return String.format("%s::%s::%s::%s::%s::%s::%s::%s::%s",
+ backupIdRow.getIsDirty() ? "1" : "0", backupIdRow.getId(),
+ backupIdRow.getIsFavorite(), backupIdRow.getIsPending(), backupIdRow.getIsTrashed(),
+ backupIdRow.getMediaType(), backupIdRow.getUserId(),
+ backupIdRow.getOwnerPackageId(), backupIdRow.getDateExpires());
}
/**
* Deserializes the given string to {@link BackupIdRow} object
*/
public static BackupIdRow deserialize(String s) throws IOException, ClassNotFoundException {
- byte[] bytes = Base64.getDecoder().decode(s);
- ObjectInputStream objectInputStream = new ObjectInputStream(
- new ByteArrayInputStream(bytes));
- BackupIdRow backupIdRow = (BackupIdRow) objectInputStream.readObject();
- objectInputStream.close();
- return backupIdRow;
+ if (s == null || s.isEmpty()) {
+ return null;
+ }
+
+ String[] fields = s.split("::");
+ BackupIdRow.Builder builder = BackupIdRow.newBuilder(Long.parseLong(fields[1]));
+ builder.setIsDirty(Objects.equals(fields[0], "1"));
+ builder.setIsFavorite(Integer.parseInt(fields[2]));
+ builder.setIsPending(Integer.parseInt(fields[3]));
+ builder.setIsTrashed(Integer.parseInt(fields[4]));
+ builder.setMediaType(Integer.parseInt(fields[5]));
+ builder.setUserId(Integer.parseInt(fields[6]));
+ builder.setOwnerPackagedId(Integer.parseInt(fields[7]));
+ builder.setDateExpires(fields[8]);
+ return builder.build();
}
}
diff --git a/tests/Android.bp b/tests/Android.bp
index 2bb5f3766..4dbaf16e7 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -229,3 +229,10 @@ filegroup {
name: "mediaprovider-testutils",
srcs: ["utils/**/*.java"],
}
+
+filegroup {
+ name: "mediaprovider-library",
+ srcs: [
+ "src/com/android/providers/media/library/RunOnlyOnPostsubmit.java",
+ ],
+}
diff --git a/tests/client/Android.bp b/tests/client/Android.bp
index 7e5182870..ca3687d7c 100644
--- a/tests/client/Android.bp
+++ b/tests/client/Android.bp
@@ -16,6 +16,7 @@ android_test {
srcs: [
"src/**/*.java",
":mediaprovider-testutils",
+ ":mediaprovider-library",
],
libs: [
diff --git a/tests/client/src/com/android/providers/media/client/ClientPlaylistTest.java b/tests/client/src/com/android/providers/media/client/ClientPlaylistTest.java
index e9b9cbf26..dc86aae55 100644
--- a/tests/client/src/com/android/providers/media/client/ClientPlaylistTest.java
+++ b/tests/client/src/com/android/providers/media/client/ClientPlaylistTest.java
@@ -41,6 +41,8 @@ import android.util.Pair;
import androidx.test.InstrumentationRegistry;
+import com.android.providers.media.library.RunOnlyOnPostsubmit;
+
import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
@@ -63,6 +65,7 @@ import java.util.concurrent.TimeUnit;
* external client app. Exercises all supported playlist formats.
*/
@RunWith(Parameterized.class)
+@RunOnlyOnPostsubmit
public class ClientPlaylistTest {
private static final String TAG = "ClientPlaylistTest";
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 b792ee22c..f7f5c27ad 100644
--- a/tests/client/src/com/android/providers/media/client/PerformanceTest.java
+++ b/tests/client/src/com/android/providers/media/client/PerformanceTest.java
@@ -36,6 +36,7 @@ import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import androidx.test.uiautomator.UiDevice;
+import com.android.providers.media.library.RunOnlyOnPostsubmit;
import com.android.providers.media.tests.utils.Timer;
import org.junit.Test;
@@ -62,6 +63,7 @@ import java.util.concurrent.TimeUnit;
*/
@RunWith(AndroidJUnit4.class)
@LargeTest
+@RunOnlyOnPostsubmit
public class PerformanceTest {
private static final String TAG = "PerformanceTest";
diff --git a/tests/client/src/com/android/providers/media/client/PlaylistPerformanceTest.java b/tests/client/src/com/android/providers/media/client/PlaylistPerformanceTest.java
index e76181420..c7739785d 100644
--- a/tests/client/src/com/android/providers/media/client/PlaylistPerformanceTest.java
+++ b/tests/client/src/com/android/providers/media/client/PlaylistPerformanceTest.java
@@ -37,6 +37,7 @@ import androidx.annotation.NonNull;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import com.android.providers.media.library.RunOnlyOnPostsubmit;
import com.android.providers.media.tests.utils.Timer;
import org.junit.After;
@@ -49,6 +50,7 @@ import java.io.IOException;
import java.io.OutputStream;
@RunWith(AndroidJUnit4.class)
+@RunOnlyOnPostsubmit
public class PlaylistPerformanceTest {
private static final Uri AUDIO_URI = MediaStore.Audio.Media
.getContentUri(VOLUME_EXTERNAL_PRIMARY);
diff --git a/tests/client/src/com/android/providers/media/client/PublicVolumePlaylistTest.java b/tests/client/src/com/android/providers/media/client/PublicVolumePlaylistTest.java
index af17d50c9..6f0d33dd4 100644
--- a/tests/client/src/com/android/providers/media/client/PublicVolumePlaylistTest.java
+++ b/tests/client/src/com/android/providers/media/client/PublicVolumePlaylistTest.java
@@ -40,6 +40,8 @@ import android.provider.MediaStore;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import com.android.providers.media.library.RunOnlyOnPostsubmit;
+
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Ignore;
@@ -49,6 +51,7 @@ import org.junit.runner.RunWith;
import java.io.OutputStream;
@RunWith(AndroidJUnit4.class)
+@RunOnlyOnPostsubmit
public class PublicVolumePlaylistTest {
@BeforeClass
public static void setUp() throws Exception {
diff --git a/tests/client/src/com/android/providers/media/client/PublicVolumeTest.java b/tests/client/src/com/android/providers/media/client/PublicVolumeTest.java
index e5181d5b0..da80f4181 100644
--- a/tests/client/src/com/android/providers/media/client/PublicVolumeTest.java
+++ b/tests/client/src/com/android/providers/media/client/PublicVolumeTest.java
@@ -36,6 +36,8 @@ import android.provider.MediaStore;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import com.android.providers.media.library.RunOnlyOnPostsubmit;
+
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Ignore;
@@ -45,6 +47,7 @@ import org.junit.runner.RunWith;
import java.io.OutputStream;
@RunWith(AndroidJUnit4.class)
+@RunOnlyOnPostsubmit
public class PublicVolumeTest {
@BeforeClass
public static void setUp() throws Exception {
diff --git a/tests/src/com/android/providers/media/DatabaseBackupAndRecoveryTest.java b/tests/src/com/android/providers/media/DatabaseBackupAndRecoveryTest.java
index 6b459933b..447a98fa0 100644
--- a/tests/src/com/android/providers/media/DatabaseBackupAndRecoveryTest.java
+++ b/tests/src/com/android/providers/media/DatabaseBackupAndRecoveryTest.java
@@ -25,6 +25,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertTrue;
import android.content.Context;
+import android.os.UserHandle;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.runner.AndroidJUnit4;
@@ -77,4 +78,16 @@ public class DatabaseBackupAndRecoveryTest {
assertThat(DatabaseBackupAndRecovery.getInvalidUsersList(xattrData, /* validUserIds */
Arrays.asList("0", "13"))).containsExactly("10", "11", "12");
}
+
+ @Test
+ public void testGetFilePathForFuseRequests() {
+ assertThat(DatabaseBackupAndRecovery.getFilePathForFuseRequests("/storage")).isEqualTo(
+ "/storage/emulated/" + UserHandle.myUserId());
+ assertThat(DatabaseBackupAndRecovery.getFilePathForFuseRequests(
+ "/storage/emulated/" + UserHandle.myUserId() + "/Android/media")).isEqualTo(
+ "/storage/emulated/" + UserHandle.myUserId());
+ assertThat(
+ DatabaseBackupAndRecovery.getFilePathForFuseRequests("/storage/ABC-DEF")).isEqualTo(
+ "/storage/ABC-DEF");
+ }
}
diff --git a/tests/src/com/android/providers/media/IsolatedContext.java b/tests/src/com/android/providers/media/IsolatedContext.java
index 8a87eb5ad..dc52fcd3d 100644
--- a/tests/src/com/android/providers/media/IsolatedContext.java
+++ b/tests/src/com/android/providers/media/IsolatedContext.java
@@ -31,8 +31,10 @@ import android.test.mock.MockContentProvider;
import android.test.mock.MockContentResolver;
import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
import com.android.providers.media.cloudproviders.CloudProviderPrimary;
+import com.android.providers.media.cloudproviders.FlakyCloudProvider;
import com.android.providers.media.photopicker.PhotoPickerProvider;
import com.android.providers.media.photopicker.PickerSyncController;
import com.android.providers.media.util.FileUtils;
@@ -48,6 +50,7 @@ public class IsolatedContext extends ContextWrapper {
private final MockContentResolver mResolver;
private final MediaProvider mMediaProvider;
private final UserHandle mUserHandle;
+ private final FlakyCloudProvider mFlakyCloudProvider;
public IsolatedContext(Context base, String tag, boolean asFuseThread) {
this(base, tag, asFuseThread, base.getUser());
@@ -88,6 +91,9 @@ public class IsolatedContext extends ContextWrapper {
final CloudMediaProvider cmp = new CloudProviderPrimary();
attachInfoAndAddProvider(base, cmp, CloudProviderPrimary.AUTHORITY);
+ mFlakyCloudProvider = new FlakyCloudProvider();
+ attachInfoAndAddProvider(base, mFlakyCloudProvider, FlakyCloudProvider.AUTHORITY);
+
MediaStore.waitForIdle(mResolver);
}
@@ -162,4 +168,13 @@ public class IsolatedContext extends ContextWrapper {
}
}
+ @VisibleForTesting
+ public void setFlakyCloudProviderToFlakeInTheNextRequest() {
+ mFlakyCloudProvider.setToFlakeInTheNextRequest();
+ }
+
+ @VisibleForTesting
+ public void resetFlakyCloudProviderToNotFlakeInTheNextRequest() {
+ mFlakyCloudProvider.resetToNotFlakeInTheNextRequest();
+ }
}
diff --git a/tests/src/com/android/providers/media/MediaGrantsTest.java b/tests/src/com/android/providers/media/MediaGrantsTest.java
index aae4f8454..66346fbfb 100644
--- a/tests/src/com/android/providers/media/MediaGrantsTest.java
+++ b/tests/src/com/android/providers/media/MediaGrantsTest.java
@@ -25,6 +25,7 @@ import static org.junit.Assert.assertTrue;
import android.Manifest;
import android.content.ContentResolver;
+import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
@@ -51,6 +52,7 @@ public class MediaGrantsTest {
private MediaGrants mGrants;
private static final String TEST_OWNER_PACKAGE_NAME = "com.android.test.package";
+ private static final String TEST_OWNER_PACKAGE_NAME2 = "com.android.test.package2";
private static final int TEST_USER_ID = UserHandle.myUserId();
@BeforeClass
@@ -96,6 +98,46 @@ public class MediaGrantsTest {
}
@Test
+ public void testGetMediaGrantsForPackage() throws Exception {
+ Long fileId1 = insertFileInResolver(mIsolatedResolver, "test_file1");
+ Long fileId2 = insertFileInResolver(mIsolatedResolver, "test_file2");
+ Long fileId3 = insertFileInResolver(mIsolatedResolver, "test_file3");
+ List<Uri> uris1 = List.of(buildValidPickerUri(fileId1), buildValidPickerUri(fileId2));
+ List<Uri> uris2 = List.of(buildValidPickerUri(fileId3));
+
+ mGrants.addMediaGrantsForPackage(TEST_OWNER_PACKAGE_NAME, uris1, TEST_USER_ID);
+ mGrants.addMediaGrantsForPackage(TEST_OWNER_PACKAGE_NAME2, uris2, TEST_USER_ID);
+
+
+ List<Uri> fileUris = mGrants.getMediaGrantsForPackage(
+ TEST_OWNER_PACKAGE_NAME, TEST_USER_ID);
+
+ List<Long> expectedFileIdsList = List.of(fileId1, fileId2);
+
+ assertEquals(fileUris.size(), expectedFileIdsList.size());
+ for (Uri uri: fileUris) {
+ assertTrue(expectedFileIdsList.contains(Long.valueOf(ContentUris.parseId(uri))));
+ }
+
+ List<Uri> fileUrisForTestPackage2 = mGrants.getMediaGrantsForPackage(
+ TEST_OWNER_PACKAGE_NAME2, TEST_USER_ID);
+
+ List<Long> expectedFileIdsList2 = List.of(fileId3);
+
+ assertEquals(fileUrisForTestPackage2.size(), expectedFileIdsList2.size());
+ for (Uri uri: fileUrisForTestPackage2) {
+ assertTrue(expectedFileIdsList2.contains(Long.valueOf(ContentUris.parseId(uri))));
+ }
+
+ List<Uri> fileUrisForTestPackage3 = mGrants.getMediaGrantsForPackage(
+ "non.existent.package", TEST_USER_ID);
+
+ // assert no items are returned for an invalid package.
+ assertEquals(/* expected= */fileUrisForTestPackage3.size(), /* actual= */0);
+
+ }
+
+ @Test
public void testAddDuplicateMediaGrants() throws Exception {
Long fileId1 = insertFileInResolver(mIsolatedResolver, "test_file1");
diff --git a/tests/src/com/android/providers/media/PublicVolumeTest.java b/tests/src/com/android/providers/media/PublicVolumeTest.java
index e2a272f2b..aaed1f9de 100644
--- a/tests/src/com/android/providers/media/PublicVolumeTest.java
+++ b/tests/src/com/android/providers/media/PublicVolumeTest.java
@@ -30,6 +30,7 @@ import android.provider.MediaStore;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import com.android.providers.media.library.RunOnlyOnPostsubmit;
import com.android.providers.media.tests.utils.PublicVolumeSetupHelper;
import com.android.providers.media.util.FileUtils;
@@ -43,6 +44,7 @@ import java.io.File;
import java.util.List;
@RunWith(AndroidJUnit4.class)
+@RunOnlyOnPostsubmit
public class PublicVolumeTest {
static final int POLL_DELAY_MS = 500;
static final int WAIT_FOR_DEFAULT_FOLDERS_MS = 30000;
diff --git a/tests/src/com/android/providers/media/TestConfigStore.java b/tests/src/com/android/providers/media/TestConfigStore.java
index 038be6269..a19360320 100644
--- a/tests/src/com/android/providers/media/TestConfigStore.java
+++ b/tests/src/com/android/providers/media/TestConfigStore.java
@@ -18,9 +18,12 @@ package com.android.providers.media;
import static java.util.Objects.requireNonNull;
+import android.util.Pair;
+
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -32,36 +35,49 @@ import java.util.concurrent.Executor;
*/
public class TestConfigStore implements ConfigStore {
private boolean mCloudMediaInPhotoPickerEnabled = false;
- private @Nullable List<String> mAllowedCloudProviderPackages = null;
+ private List<String> mAllowedCloudProviderPackages = Collections.emptyList();
private @Nullable String mDefaultCloudProviderPackage = null;
+ private List<Pair<Executor, Runnable>> mObservers = new ArrayList<>();
public void enableCloudMediaFeatureAndSetAllowedCloudProviderPackages(String... providers) {
mAllowedCloudProviderPackages = Arrays.asList(providers);
- enableCloudMediaFeature();
+ mCloudMediaInPhotoPickerEnabled = true;
+ notifyObservers();
}
public void enableCloudMediaFeature() {
mCloudMediaInPhotoPickerEnabled = true;
+ notifyObservers();
}
public void clearAllowedCloudProviderPackagesAndDisableCloudMediaFeature() {
- mAllowedCloudProviderPackages = null;
+ mAllowedCloudProviderPackages = Collections.emptyList();
disableCloudMediaFeature();
+ notifyObservers();
}
public void disableCloudMediaFeature() {
mCloudMediaInPhotoPickerEnabled = false;
+ notifyObservers();
}
@Override
public @NonNull List<String> getAllowedCloudProviderPackages() {
- return mAllowedCloudProviderPackages != null ? mAllowedCloudProviderPackages
- : Collections.emptyList();
+ return mAllowedCloudProviderPackages;
+ }
+
+ public void setAllowedCloudProviderPackages(String... providers) {
+ if (providers.length == 0) {
+ mAllowedCloudProviderPackages = Collections.emptyList();
+ } else {
+ mAllowedCloudProviderPackages = Arrays.asList(providers);
+ }
+ notifyObservers();
}
@Override
public boolean isCloudMediaInPhotoPickerEnabled() {
- return mCloudMediaInPhotoPickerEnabled;
+ return mCloudMediaInPhotoPickerEnabled && !mAllowedCloudProviderPackages.isEmpty();
}
public void setDefaultCloudProviderPackage(@NonNull String packageName) {
@@ -94,6 +110,19 @@ public class TestConfigStore implements ConfigStore {
@Override
public void addOnChangeListener(@NonNull Executor executor, @NonNull Runnable listener) {
- // No-op.
+ Pair p = Pair.create(executor, listener);
+ mObservers.add(p);
+ }
+
+
+ /**
+ * Runs all subscribers to the TestConfigStore.
+ */
+ private void notifyObservers() {
+ for (Pair<Executor, Runnable> observer: mObservers) {
+ Executor exec = observer.first;
+ Runnable listener = observer.second;
+ exec.execute(listener);
+ }
}
}
diff --git a/tests/src/com/android/providers/media/TestDatabaseBackupAndRecovery.java b/tests/src/com/android/providers/media/TestDatabaseBackupAndRecovery.java
index 63af35780..fc2dc77a4 100644
--- a/tests/src/com/android/providers/media/TestDatabaseBackupAndRecovery.java
+++ b/tests/src/com/android/providers/media/TestDatabaseBackupAndRecovery.java
@@ -75,7 +75,7 @@ public class TestDatabaseBackupAndRecovery extends DatabaseBackupAndRecovery {
}
@Override
- protected FuseDaemon getFuseDaemonForFileWithWait(File fuseFilePath, long waitTime)
+ protected FuseDaemon getFuseDaemonForFileWithWait(File fuseFilePath)
throws FileNotFoundException {
return null;
}
diff --git a/tests/src/com/android/providers/media/cloudproviders/CloudProviderSecondary.java b/tests/src/com/android/providers/media/cloudproviders/CloudProviderSecondary.java
index ac7cef0d5..5c3df94d8 100644
--- a/tests/src/com/android/providers/media/cloudproviders/CloudProviderSecondary.java
+++ b/tests/src/com/android/providers/media/cloudproviders/CloudProviderSecondary.java
@@ -38,7 +38,7 @@ import java.io.FileNotFoundException;
* {@link MediaGenerator}
*/
public class CloudProviderSecondary extends CloudMediaProvider {
- private static final String AUTHORITY =
+ public static final String AUTHORITY =
"com.android.providers.media.photopicker.tests.cloud_secondary";
private final MediaGenerator mMediaGenerator =
diff --git a/tests/src/com/android/providers/media/cloudproviders/FlakyCloudProvider.java b/tests/src/com/android/providers/media/cloudproviders/FlakyCloudProvider.java
index d4c3dec30..2d20574b8 100644
--- a/tests/src/com/android/providers/media/cloudproviders/FlakyCloudProvider.java
+++ b/tests/src/com/android/providers/media/cloudproviders/FlakyCloudProvider.java
@@ -20,6 +20,8 @@ import static android.provider.CloudMediaProviderContract.EXTRA_PAGE_TOKEN;
import static com.android.providers.media.PickerProviderMediaGenerator.MediaGenerator;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.graphics.Point;
@@ -27,6 +29,9 @@ import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.provider.CloudMediaProvider;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
import com.android.providers.media.PickerProviderMediaGenerator;
import com.android.providers.media.photopicker.data.CloudProviderQueryExtras;
@@ -41,24 +46,28 @@ import java.io.FileNotFoundException;
* out of every three requests.
*/
public class FlakyCloudProvider extends CloudMediaProvider {
+ private static final String TAG = "FlakyCloudProvider";
public static final String AUTHORITY =
"com.android.providers.media.photopicker.tests.cloud_flaky";
+ public static final String ACCOUNT_NAME = "test_account@flakyCloudProvider";
+ private static final int INITIAL_REQUEST_COUNT = 0;
+ private static final int REQUEST_COUNT_FOR_NEXT_ONE_TO_FLAKE = 2;
private final MediaGenerator mMediaGenerator =
PickerProviderMediaGenerator.getMediaGenerator(AUTHORITY);
- private int mRequestCount = 0;
+ private int mRequestCount = INITIAL_REQUEST_COUNT;
/** Determines if the current request should flake. */
private boolean shouldFlake() {
// Always succeed on the first request.
- if (++mRequestCount < 2) {
+ if (++mRequestCount < REQUEST_COUNT_FOR_NEXT_ONE_TO_FLAKE) {
return false;
}
- if (mRequestCount >= 3) {
- mRequestCount = 0;
+ if (mRequestCount > REQUEST_COUNT_FOR_NEXT_ONE_TO_FLAKE) {
+ mRequestCount = INITIAL_REQUEST_COUNT;
}
return true;
@@ -66,6 +75,7 @@ public class FlakyCloudProvider extends CloudMediaProvider {
@Override
public boolean onCreate() {
+ mMediaGenerator.setAccountInfo(ACCOUNT_NAME, /* configIntent= */ null);
return true;
}
@@ -137,6 +147,24 @@ public class FlakyCloudProvider extends CloudMediaProvider {
@Override
public Bundle onGetMediaCollectionInfo(Bundle extras) {
+ if (shouldFlake()) {
+ try {
+ MILLISECONDS.sleep(/* timeout= */ 200L);
+ } catch (InterruptedException e) {
+ Log.d(TAG, "Error while sleep when should flake on get media collection info.", e);
+ }
+ }
+
return mMediaGenerator.getMediaCollectionInfo();
}
+
+ @VisibleForTesting
+ public void resetToNotFlakeInTheNextRequest() {
+ mRequestCount = INITIAL_REQUEST_COUNT;
+ }
+
+ @VisibleForTesting
+ public void setToFlakeInTheNextRequest() {
+ mRequestCount = REQUEST_COUNT_FOR_NEXT_ONE_TO_FLAKE;
+ }
}
diff --git a/tests/src/com/android/providers/media/photopicker/ItemsProviderTest.java b/tests/src/com/android/providers/media/photopicker/ItemsProviderTest.java
index 1dd565b9e..5de28d31a 100644
--- a/tests/src/com/android/providers/media/photopicker/ItemsProviderTest.java
+++ b/tests/src/com/android/providers/media/photopicker/ItemsProviderTest.java
@@ -32,12 +32,14 @@ import static com.android.providers.media.util.MimeUtils.isVideoMimeType;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.Manifest;
import android.app.Instrumentation;
import android.app.UiAutomation;
import android.content.ContentResolver;
+import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
@@ -81,6 +83,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
+import java.util.stream.Collectors;
public class ItemsProviderTest {
/**
@@ -662,7 +665,7 @@ public class ItemsProviderTest {
try {
// Set the limit and ensure that only that number of items are returned.
final Cursor res = mItemsProvider.getAllItems(Category.DEFAULT,
- new PaginationParameters(/* limit */ 5, -1, -1),
+ new PaginationParameters(/* limit */ 5, /*dateBeforeMs*/ Long.MIN_VALUE, -1),
/* mimeType */ null, /* userId */ null, /* cancellationSignal */ null);
assertThat(res).isNotNull();
@@ -961,6 +964,72 @@ public class ItemsProviderTest {
}
/**
+ * Tests {@link ItemsProvider#getLocalItemsForSelection(Category, List, String[],
+ * UserId, CancellationSignal)} to return only selected items from the media table for ids
+ * defined in the localId selection list.
+ */
+ @Test
+ public void testGetItemsImages_withLocalIdSelection() throws Exception {
+ List<Uri> imageFilesUris = assertCreateNewImagesWithSameDateModifiedTimesAndReturnUri(10);
+ // Put the id of random items from the inserted set. say 4th and 6th item.
+ ArrayList<Long> inputIds = new ArrayList<>(1);
+ inputIds.add(ContentUris.parseId(imageFilesUris.get(4)));
+ inputIds.add(ContentUris.parseId(imageFilesUris.get(6)));
+ ArrayList<Integer> inputIdsAsIntegers =
+ (ArrayList<Integer>) inputIds.stream().map(
+ (Long id) -> Integer.valueOf(Math.toIntExact(id))).collect(
+ Collectors.toList());
+ try {
+ // get the item objects for the provided ids.
+ final Cursor res = mItemsProvider.getLocalItemsForSelection(Category.DEFAULT,
+ /* local id selection list */ inputIdsAsIntegers,
+ /* mimeType */ new String[]{"image/*"}, /* userId */ null,
+ /* cancellationSignal */ null);
+
+ // verify that the correct number of items are returned and that they have the correct
+ // ids.
+ assertThat(res).isNotNull();
+ assertThat(res.getCount()).isEqualTo(2);
+ res.moveToPosition(0);
+ while (res.moveToNext()) {
+ Item item = Item.fromCursor(res, UserId.CURRENT_USER);
+ assertTrue(inputIds.contains(Long.parseLong(item.getId())));
+ }
+ assertThatOnlyImages(res);
+ } finally {
+ // clean up.
+ deleteAllFilesNoThrow();
+ }
+ }
+
+ /**
+ * Tests {@link ItemsProvider#getLocalItemsForSelection(Category, List, String[],
+ * UserId, CancellationSignal)} to return only selected items from the media table for ids
+ * defined in the localId selection list. Here the list is empty so the parameter is ignored and
+ * the list is returned without any selection.
+ */
+ @Test
+ public void testGetItemsImages_withLocalIdSelectionEmpty() throws Exception {
+ assertCreateNewImagesWithSameDateModifiedTimesAndReturnUri(10);
+ try {
+ // get the item objects for the empty list.
+ final Cursor res = mItemsProvider.getLocalItemsForSelection(Category.DEFAULT,
+ /* local id selection list */ new ArrayList<>(),
+ /* mimeType */ new String[]{"image/*"}, /* userId */ null,
+ /* cancellationSignal */ null);
+
+ assertThat(res).isNotNull();
+ // All images are returned and selection is ignored.
+ assertThat(res.getCount()).isEqualTo(10);
+ assertThatOnlyImages(res);
+ } finally {
+ // clean up.
+ deleteAllFilesNoThrow();
+ }
+ }
+
+
+ /**
* Tests
* {@link ItemsProvider#getAllItems(Category, PaginationParameters, String[], UserId)}
* (Category, PaginationParameters, String[], UserId)} (Category, int, String[], UserId)}
@@ -1172,6 +1241,7 @@ public class ItemsProviderTest {
try (Cursor c = mItemsProvider.getAllCategories(/* mimeType */ null,
/* userId */ null, /* cancellationSignal*/ null)) {
assertGetCategoriesMatchMultiple(c, Arrays.asList(
+ Pair.create(ALBUM_ID_FAVORITES, 0),
Pair.create(ALBUM_ID_VIDEOS, 2),
Pair.create(ALBUM_ID_SCREENSHOTS, 1),
Pair.create(cloudAlbum, 1)
@@ -1404,6 +1474,19 @@ public class ItemsProviderTest {
return imageFiles;
}
+
+ private List<Uri> assertCreateNewImagesWithSameDateModifiedTimesAndReturnUri(int numberOfImages)
+ throws Exception {
+ List<Uri> imageFiles = new ArrayList<>();
+ long currentTime = System.nanoTime() / 1000;
+ for (int itr = 0; itr < numberOfImages; itr++) {
+ String fileName = TAG + "_file_" + String.valueOf(System.nanoTime()) + ".jpg";
+ imageFiles.add(assertCreateNewFileWithLastModifiedTimeAndReturnUri(
+ getDownloadsDir(), fileName, currentTime));
+ }
+ return imageFiles;
+ }
+
private File assertCreateNewVideo(File dir) throws Exception {
return assertCreateNewFile(dir, VIDEO_FILE_NAME);
}
@@ -1433,6 +1516,11 @@ public class ItemsProviderTest {
prepareFileAndGetUri(file, lastModifiedTime);
return file;
}
+ private Uri assertCreateNewFileWithLastModifiedTimeAndReturnUri(File parentDir, String fileName,
+ long lastModifiedTime) throws Exception {
+ final File file = new File(parentDir, fileName);
+ return prepareFileAndGetUri(file, lastModifiedTime);
+ }
private Uri prepareFileAndGetUri(File file, long lastModifiedTime) throws IOException {
diff --git a/tests/src/com/android/providers/media/photopicker/PickerDataLayerTest.java b/tests/src/com/android/providers/media/photopicker/PickerDataLayerTest.java
index a8d3dd4fc..8395b1bd9 100644
--- a/tests/src/com/android/providers/media/photopicker/PickerDataLayerTest.java
+++ b/tests/src/com/android/providers/media/photopicker/PickerDataLayerTest.java
@@ -22,11 +22,15 @@ import static android.provider.CloudMediaProviderContract.AlbumColumns.ALBUM_ID_
import static com.android.providers.media.PickerProviderMediaGenerator.MediaGenerator;
import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.LONG_DEFAULT;
import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.STRING_DEFAULT;
+import static com.android.providers.media.photopicker.sync.SyncWorkerTestUtils.initializeTestWorkManager;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
import android.content.Context;
import android.content.Intent;
@@ -40,13 +44,17 @@ import android.util.Pair;
import androidx.annotation.NonNull;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import androidx.work.WorkManager;
import com.android.modules.utils.BackgroundThread;
import com.android.providers.media.PickerProviderMediaGenerator;
import com.android.providers.media.TestConfigStore;
+import com.android.providers.media.photopicker.data.CloudProviderInfo;
import com.android.providers.media.photopicker.data.PickerDatabaseHelper;
import com.android.providers.media.photopicker.data.PickerDbFacade;
import com.android.providers.media.photopicker.data.PickerSyncRequestExtras;
+import com.android.providers.media.photopicker.sync.PickerSyncManager;
+import com.android.providers.media.util.ForegroundThread;
import org.junit.After;
import org.junit.Before;
@@ -55,8 +63,11 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.File;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
@RunWith(AndroidJUnit4.class)
public class PickerDataLayerTest {
@@ -108,6 +119,7 @@ public class PickerDataLayerTest {
private PickerDbFacade mFacade;
private PickerDataLayer mDataLayer;
private PickerSyncController mController;
+ private TestConfigStore mConfigStore;
@Before
public void setUp() {
@@ -128,13 +140,17 @@ public class PickerDataLayerTest {
mDbHelper = new PickerDatabaseHelper(mContext, DB_NAME, DB_VERSION_1);
mFacade = new PickerDbFacade(mContext, LOCAL_PROVIDER_AUTHORITY, mDbHelper);
- final TestConfigStore configStore = new TestConfigStore();
- configStore.enableCloudMediaFeatureAndSetAllowedCloudProviderPackages(PACKAGE_NAME);
+ mConfigStore = new TestConfigStore();
+ mConfigStore.enableCloudMediaFeatureAndSetAllowedCloudProviderPackages(PACKAGE_NAME);
mController = PickerSyncController.initialize(
- mContext, mFacade, configStore, LOCAL_PROVIDER_AUTHORITY);
- mDataLayer = new PickerDataLayer(mContext, mFacade, mController, configStore,
- /* schedulePeriodicSyncs */ false);
+ mContext, mFacade, mConfigStore, LOCAL_PROVIDER_AUTHORITY);
+
+ initializeTestWorkManager(mContext);
+ final WorkManager workManager = WorkManager.getInstance(mContext);
+ final PickerSyncManager syncManager = new PickerSyncManager(
+ workManager, mContext, mConfigStore, /* schedulePeriodicSyncs */ false);
+ mDataLayer = new PickerDataLayer(mContext, mFacade, mController, mConfigStore, syncManager);
// Set cloud provider to null to discard
mFacade.setCloudProvider(null);
@@ -703,6 +719,83 @@ public class PickerDataLayerTest {
() -> mDataLayer.initMediaData(syncExtras));
}
+ @Test
+ public void testCloudPackageAllowlistListenerRemovesActiveThatIsNowInvalid() {
+ mController.setCloudProvider(CLOUD_PRIMARY_PROVIDER_AUTHORITY);
+ assertThat(mController.getCurrentCloudProviderInfo().packageName).isEqualTo(PACKAGE_NAME);
+
+ // Simulate a DeviceConfig change where the Allowlist is set to empty.
+ mConfigStore.setAllowedCloudProviderPackages(new String[] {});
+
+
+ // The listener uses the ForegroundThread to run the listener, so wait for the
+ // ForegroundThread to complete.
+ ForegroundThread.waitForIdle();
+
+ assertThat(mController.getCurrentCloudProviderInfo()).isEqualTo(CloudProviderInfo.EMPTY);
+ }
+
+ @Test
+ public void testCloudPackageAllowlistListenerDoesNotChangeAllowedProvider() {
+ mController.setCloudProvider(CLOUD_PRIMARY_PROVIDER_AUTHORITY);
+ assertThat(mController.getCurrentCloudProviderInfo().packageName).isEqualTo(PACKAGE_NAME);
+
+ // Simulate a DeviceConfig change where the Allowlist adds a new provider, but the current
+ // provider is still permitted.
+ final String newlyAddedProviderPackage = "com.hooli.super.awesome.cloud.provider";
+ mConfigStore.setAllowedCloudProviderPackages(
+ new String[] {PACKAGE_NAME, newlyAddedProviderPackage});
+
+ // The listener uses the ForegroundThread to run the listener, so wait for the
+ // ForegroundThread to complete.
+ ForegroundThread.waitForIdle();
+
+ // Ensure nothing was changed.
+ assertThat(mController.getCurrentCloudProviderInfo().packageName).isEqualTo(PACKAGE_NAME);
+ }
+
+ @Test
+ public void testWaitForSyncWhenSyncFutureIsComplete()
+ throws ExecutionException, InterruptedException {
+ final CompletableFuture<Void> completableFuture = new CompletableFuture<>();
+ completableFuture.complete(null);
+
+ final int inputRetryCount = 3;
+ assertThat(mDataLayer
+ .waitForSync(completableFuture, "work-name", inputRetryCount))
+ .isEqualTo(inputRetryCount);
+ }
+
+ @Test
+ public void testWaitForSyncWhenSyncFutureNeverCompletes()
+ throws ExecutionException, InterruptedException, TimeoutException {
+ final PickerSyncManager mockSyncManager = mock(PickerSyncManager.class);
+ final PickerDataLayer dataLayer = new PickerDataLayer(mContext, mFacade, mController,
+ mConfigStore, mockSyncManager);
+ final CompletableFuture<Void> completableFuture = new CompletableFuture<>();
+ doReturn(true).when(mockSyncManager).isUniqueWorkPending(any());
+
+ final int inputRetryCount = 3;
+ assertThat(dataLayer
+ .waitForSync(completableFuture, "work-name", inputRetryCount))
+ .isEqualTo(0);
+ }
+
+ @Test
+ public void testWaitForSyncWhenWorkerFails()
+ throws ExecutionException, InterruptedException, TimeoutException {
+ final PickerSyncManager mockSyncManager = mock(PickerSyncManager.class);
+ final PickerDataLayer dataLayer = new PickerDataLayer(mContext, mFacade, mController,
+ mConfigStore, mockSyncManager);
+ final CompletableFuture<Void> completableFuture = new CompletableFuture<>();
+ doReturn(false).when(mockSyncManager).isUniqueWorkPending(any());
+
+ final int inputRetryCount = 3;
+ assertThat(dataLayer
+ .waitForSync(completableFuture, "work-name", inputRetryCount))
+ .isEqualTo(inputRetryCount);
+ }
+
private static void waitForIdle() {
final CountDownLatch latch = new CountDownLatch(1);
BackgroundThread.getExecutor().execute(() -> {
diff --git a/tests/src/com/android/providers/media/photopicker/PickerSyncControllerTest.java b/tests/src/com/android/providers/media/photopicker/PickerSyncControllerTest.java
index 4869b8a22..1ff22ce3b 100644
--- a/tests/src/com/android/providers/media/photopicker/PickerSyncControllerTest.java
+++ b/tests/src/com/android/providers/media/photopicker/PickerSyncControllerTest.java
@@ -22,8 +22,10 @@ import static com.android.providers.media.photopicker.NotificationContentObserve
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -185,6 +187,78 @@ public class PickerSyncControllerTest {
}
@Test
+ public void testInitCloudProviderOnDeviceConfigChange() {
+
+ TestConfigStore configStore = new TestConfigStore();
+ configStore.disableCloudMediaFeature();
+
+ PickerSyncController controller =
+ PickerSyncController.initialize(mContext, mFacade, configStore);
+ assertThat(controller.getCurrentCloudProviderInfo()).isEqualTo(CloudProviderInfo.EMPTY);
+ configStore.setDefaultCloudProviderPackage(PACKAGE_NAME);
+ configStore.enableCloudMediaFeatureAndSetAllowedCloudProviderPackages(PACKAGE_NAME);
+ waitForIdle();
+
+ // Ensure the cloud provider is set to something. (The test package name here actually
+ // has multiple cloud providers in it, so just ensure something got set.)
+ assertThat(controller.getCurrentCloudProviderInfo().authority).isNotNull();
+
+ configStore.clearAllowedCloudProviderPackagesAndDisableCloudMediaFeature();
+ waitForIdle();
+
+ // Ensure the cloud provider is correctly nulled out when the config changes again.
+ assertThat(controller.getCurrentCloudProviderInfo().authority).isNull();
+ }
+
+ @Test
+ public void testSyncIsCancelledIfCloudProviderIsChanged() {
+
+ PickerSyncController controller = spy(mController);
+
+ // Ensure we return the appropriate authority until we actually enter the sync process,
+ // and then return a different authority than what the sync was started with to simulate
+ // a cloud provider changing.
+ doReturn(CLOUD_PRIMARY_PROVIDER_AUTHORITY,
+ CLOUD_SECONDARY_PROVIDER_AUTHORITY)
+ .when(controller)
+ .getCloudProvider();
+
+ // Add local only media, we expect these to be successfully sync'd from the local provider.
+ addMedia(mLocalMediaGenerator, LOCAL_ONLY_1);
+ addMedia(mLocalMediaGenerator, LOCAL_ONLY_2);
+ mLocalMediaGenerator.setNextCursorExtras(
+ /* queryCount */ 2,
+ /* mediaCollectionId */ COLLECTION_1,
+ /* honoredSyncGeneration */ true,
+ /* honoredAlbumId */ false,
+ /* honoredPageSize */ true);
+
+ // Add cloud media, we should try to sync these, but not actually commit them since the
+ // cloud provider will be changed before the transaction can be committed.
+ addMedia(mCloudPrimaryMediaGenerator, CLOUD_ONLY_1);
+ addMedia(mCloudPrimaryMediaGenerator, CLOUD_ONLY_2);
+ mCloudPrimaryMediaGenerator.setNextCursorExtras(
+ /* queryCount */ 2,
+ /* mediaCollectionId */ COLLECTION_1,
+ /* honoredSyncGeneration */ true,
+ /* honoredAlbumId */ false,
+ /* honoredPageSize */ true);
+
+ controller.setCloudProvider(CLOUD_PRIMARY_PROVIDER_AUTHORITY);
+ controller.syncAllMedia();
+
+ // The cursor should only contain the items from the local provider. (Even though we've
+ // aded a total of 4 items to the linked providers.)
+ try (Cursor cr = queryMedia()) {
+ assertThat(cr.getCount()).isEqualTo(2);
+
+ assertCursor(cr, LOCAL_ID_2, LOCAL_PROVIDER_AUTHORITY);
+ assertCursor(cr, LOCAL_ID_1, LOCAL_PROVIDER_AUTHORITY);
+ }
+
+ }
+
+ @Test
public void testSyncAllMediaNoCloud() {
// 1. Do nothing
mController.syncAllMedia();
@@ -354,29 +428,6 @@ public class PickerSyncControllerTest {
}
@Test
- public void testSyncAllMediaResetsAlbumMedia() {
- // 1. Set primary cloud provider
- setCloudProviderAndSyncAllMedia(CLOUD_PRIMARY_PROVIDER_AUTHORITY);
- assertEmptyCursorFromAlbumMediaQuery(ALBUM_ID_1, false);
-
- // 2. Add album_media
- addAlbumMedia(mCloudPrimaryMediaGenerator, CLOUD_ONLY_1.first, CLOUD_ONLY_1.second,
- ALBUM_ID_1);
- addAlbumMedia(mCloudPrimaryMediaGenerator, CLOUD_ONLY_2.first, CLOUD_ONLY_2.second,
- ALBUM_ID_1);
- mController.syncAlbumMedia(ALBUM_ID_1, false);
-
- // 3. Assert non-empty album_media
- try (Cursor cr = queryAlbumMedia(ALBUM_ID_1, false)) {
- assertThat(cr.getCount()).isEqualTo(2);
- }
-
- // 4. Sync all media and assert empty album_media
- mController.syncAllMedia();
- assertEmptyCursorFromAlbumMediaQuery(ALBUM_ID_1, false);
- }
-
- @Test
public void testSyncAllAlbumMediaCloudOnly() {
// 1. Add media before setting primary cloud provider
addAlbumMedia(mCloudPrimaryMediaGenerator, CLOUD_ONLY_1.first, CLOUD_ONLY_1.second,
@@ -1245,7 +1296,7 @@ public class PickerSyncControllerTest {
}
@Test
- public void testContentNotifications() throws Exception {
+ public void testContentAddNotifications() throws Exception {
NotificationContentObserver observer = new NotificationContentObserver(null);
observer.register(mContext.getContentResolver());
@@ -1280,6 +1331,36 @@ public class PickerSyncControllerTest {
}
@Test
+ public void testContentDeleteNotifications() throws Exception {
+ NotificationContentObserver observer = new NotificationContentObserver(null);
+ observer.register(mContext.getContentResolver());
+
+ setCloudProviderAndSyncAllMedia(CLOUD_PRIMARY_PROVIDER_AUTHORITY);
+
+ CountDownLatch latch = new CountDownLatch(1);
+ NotificationContentObserver.ContentObserverCallback callback =
+ spy(new TestableContentObserverCallback(latch));
+ observer.registerKeysToObserverCallback(Arrays.asList(MEDIA), callback);
+
+ addMedia(mCloudPrimaryMediaGenerator, CLOUD_ONLY_1);
+ mCloudPrimaryMediaGenerator.setMediaCollectionId(COLLECTION_1);
+ mController.syncAllMedia();
+ latch.await(2, TimeUnit.SECONDS);
+ verify(callback).onNotificationReceived(any(), any());
+
+ latch = new CountDownLatch(1);
+ callback = spy(new TestableContentObserverCallback(latch));
+ observer.registerKeysToObserverCallback(Arrays.asList(MEDIA), callback);
+
+ deleteMedia(mCloudPrimaryMediaGenerator, CLOUD_ONLY_1);
+ mController.syncAllMedia();
+ latch.await(2, TimeUnit.SECONDS);
+ verify(callback).onNotificationReceived(any(), any());
+
+ observer.unregister(mContext.getContentResolver());
+ }
+
+ @Test
public void testRefreshUiNotifications() throws InterruptedException {
final ContentResolver contentResolver = mContext.getContentResolver();
final TestContentObserver refreshUiNotificationObserver = new TestContentObserver(null);
diff --git a/tests/src/com/android/providers/media/photopicker/data/PickerDbFacadeTest.java b/tests/src/com/android/providers/media/photopicker/data/PickerDbFacadeTest.java
index f38afe83b..cff210b9c 100644
--- a/tests/src/com/android/providers/media/photopicker/data/PickerDbFacadeTest.java
+++ b/tests/src/com/android/providers/media/photopicker/data/PickerDbFacadeTest.java
@@ -24,6 +24,8 @@ import static com.android.providers.media.util.MimeUtils.getExtensionFromMimeTyp
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.MockitoAnnotations.initMocks;
import android.content.ContentValues;
import android.content.Context;
@@ -39,13 +41,18 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import com.android.providers.media.ProjectionHelper;
+import com.android.providers.media.photopicker.sync.SyncTracker;
+import com.android.providers.media.photopicker.sync.SyncTrackerRegistry;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
import java.io.File;
+import java.util.Collections;
+import java.util.concurrent.CompletableFuture;
@RunWith(AndroidJUnit4.class)
public class PickerDbFacadeTest {
@@ -86,14 +93,25 @@ public class PickerDbFacadeTest {
private Context mContext;
private ProjectionHelper mProjectionHelper;
+ @Mock
+ private SyncTracker mMockLocalSyncTracker;
+ @Mock
+ private SyncTracker mMockCloudSyncTracker;
+
@Before
public void setUp() {
+ initMocks(this);
mContext = InstrumentationRegistry.getTargetContext();
File dbPath = mContext.getDatabasePath(PickerDatabaseHelper.PICKER_DATABASE_NAME);
dbPath.delete();
mFacade = new PickerDbFacade(mContext, LOCAL_PROVIDER);
mFacade.setCloudProvider(CLOUD_PROVIDER);
mProjectionHelper = new ProjectionHelper(Column.class, ExportedSince.class);
+
+
+ // Inject mock trackers
+ SyncTrackerRegistry.setLocalSyncTracker(mMockLocalSyncTracker);
+ SyncTrackerRegistry.setCloudSyncTracker(mMockCloudSyncTracker);
}
@After
@@ -101,6 +119,10 @@ public class PickerDbFacadeTest {
if (mFacade != null) {
mFacade.setCloudProvider(null);
}
+
+ // Reset mock trackers
+ SyncTrackerRegistry.setLocalSyncTracker(new SyncTracker());
+ SyncTrackerRegistry.setCloudSyncTracker(new SyncTracker());
}
@Test
@@ -241,6 +263,33 @@ public class PickerDbFacadeTest {
}
@Test
+ public void testAddCloudAlbumMediaWhileCloudSyncIsRunning() {
+
+
+ doReturn(Collections.singletonList(new CompletableFuture<>()))
+ .when(mMockCloudSyncTracker)
+ .pendingSyncFutures();
+
+ Cursor cursor1 = getAlbumMediaCursor(/* local id */ null, CLOUD_ID, DATE_TAKEN_MS + 1);
+
+ assertAddAlbumMediaOperation(CLOUD_PROVIDER, cursor1, 1, ALBUM_ID);
+
+ try (Cursor cr = queryAlbumMedia(ALBUM_ID, false)) {
+ assertThat(cr.getCount()).isEqualTo(1);
+ cr.moveToFirst();
+ assertCloudMediaCursor(cr, CLOUD_ID, DATE_TAKEN_MS + 1);
+ }
+
+ // These files should also be in the media table since we're pretending that
+ // we have a cloud sync running.
+ try (Cursor cr = queryMediaAll()) {
+ assertThat(cr.getCount()).isEqualTo(1);
+ cr.moveToFirst();
+ assertCloudMediaCursor(cr, CLOUD_ID, DATE_TAKEN_MS + 1);
+ }
+ }
+
+ @Test
public void testAddCloudAlbumMediaAvailableOnDevice() {
// Add local row for a media item in media table.
final Cursor localCursor = getLocalMediaCursor(LOCAL_ID, DATE_TAKEN_MS);
@@ -463,6 +512,39 @@ public class PickerDbFacadeTest {
}
@Test
+ public void testRemoveMedia_withLatestDateTakenMillis() {
+ Cursor localCursor = getLocalMediaCursor(LOCAL_ID, DATE_TAKEN_MS);
+ Cursor cloudCursor1 = getCloudMediaCursor(CLOUD_ID, LOCAL_ID, DATE_TAKEN_MS + 1);
+
+ assertAddMediaOperation(LOCAL_PROVIDER, localCursor, 1);
+ assertAddMediaOperation(CLOUD_PROVIDER, cloudCursor1, 1);
+
+ try (Cursor cr = queryMediaAll()) {
+ assertThat(cr.getCount()).isEqualTo(1);
+ cr.moveToFirst();
+ assertCloudMediaCursor(cr, LOCAL_ID, DATE_TAKEN_MS);
+ }
+
+ try (PickerDbFacade.DbWriteOperation operation =
+ mFacade.beginRemoveMediaOperation(CLOUD_PROVIDER)) {
+ assertWriteOperation(operation, getDeletedMediaCursor(CLOUD_ID), /* writeCount */ 1);
+ assertThat(operation.getFirstDateTakenMillis()).isEqualTo(DATE_TAKEN_MS + 1);
+ operation.setSuccess();
+ }
+
+ try (PickerDbFacade.DbWriteOperation operation =
+ mFacade.beginRemoveMediaOperation(LOCAL_PROVIDER)) {
+ assertWriteOperation(operation, getDeletedMediaCursor(LOCAL_ID), /* writeCount */ 1);
+ assertThat(operation.getFirstDateTakenMillis()).isEqualTo(DATE_TAKEN_MS);
+ operation.setSuccess();
+ }
+
+ try (Cursor cr = queryMediaAll()) {
+ assertThat(cr.getCount()).isEqualTo(0);
+ }
+ }
+
+ @Test
public void testResetLocal() throws Exception {
Cursor localCursor = getLocalMediaCursor(LOCAL_ID, DATE_TAKEN_MS);
// Add two cloud_ids mapping to the same local_id to verify that
@@ -1216,7 +1298,7 @@ public class PickerDbFacadeTest {
assertThat(cr.getCount()).isEqualTo(4);
}
- try (Cursor cr = mFacade.getMergedAlbums(qfb.build())) {
+ try (Cursor cr = mFacade.getMergedAlbums(qfb.build(), CLOUD_PROVIDER)) {
assertThat(cr.getCount()).isEqualTo(2);
cr.moveToFirst();
assertCloudAlbumCursor(cr,
@@ -1269,7 +1351,7 @@ public class PickerDbFacadeTest {
assertThat(cr.getCount()).isEqualTo(4);
}
- try (Cursor cr = mFacade.getMergedAlbums(qfb.build())) {
+ try (Cursor cr = mFacade.getMergedAlbums(qfb.build(), CLOUD_PROVIDER)) {
assertThat(cr.getCount()).isEqualTo(2);
cr.moveToFirst();
assertCloudAlbumCursor(cr,
@@ -1288,7 +1370,7 @@ public class PickerDbFacadeTest {
}
qfb.setMimeTypes(IMAGE_MIME_TYPES_QUERY);
- try (Cursor cr = mFacade.getMergedAlbums(qfb.build())) {
+ try (Cursor cr = mFacade.getMergedAlbums(qfb.build(), /* cloudProvider*/ null)) {
assertThat(cr.getCount()).isEqualTo(1);
cr.moveToFirst();
assertCloudAlbumCursor(cr,
@@ -1299,8 +1381,19 @@ public class PickerDbFacadeTest {
/* count */ 1);
}
+ try (Cursor cr = mFacade.getMergedAlbums(qfb.build(), CLOUD_PROVIDER)) {
+ assertThat(cr.getCount()).isEqualTo(2);
+ cr.moveToFirst();
+ assertCloudAlbumCursor(cr,
+ ALBUM_ID_FAVORITES,
+ ALBUM_ID_FAVORITES,
+ CLOUD_ID + "1",
+ DATE_TAKEN_MS,
+ /* count */ 1);
+ }
+
qfb.setMimeTypes(VIDEO_MIME_TYPES_QUERY);
- try (Cursor cr = mFacade.getMergedAlbums(qfb.build())) {
+ try (Cursor cr = mFacade.getMergedAlbums(qfb.build(), CLOUD_PROVIDER)) {
assertThat(cr.getCount()).isEqualTo(2);
cr.moveToFirst();
assertCloudAlbumCursor(cr,
@@ -1319,8 +1412,8 @@ public class PickerDbFacadeTest {
}
qfb.setMimeTypes(new String[]{"foo"});
- try (Cursor cr = mFacade.getMergedAlbums(qfb.build())) {
- assertThat(cr.getCount()).isEqualTo(0);
+ try (Cursor cr = mFacade.getMergedAlbums(qfb.build(), CLOUD_PROVIDER)) {
+ assertThat(cr.getCount()).isEqualTo(2);
}
}
@@ -1378,7 +1471,7 @@ public class PickerDbFacadeTest {
// Verify that we see all available merged albums and their respective media count
qfb.setIsLocalOnly(false);
- try (Cursor cr = mFacade.getMergedAlbums(qfb.build())) {
+ try (Cursor cr = mFacade.getMergedAlbums(qfb.build(), CLOUD_PROVIDER)) {
assertThat(cr.getCount()).isEqualTo(2);
cr.moveToFirst();
assertCloudAlbumCursor(cr,
@@ -1398,7 +1491,7 @@ public class PickerDbFacadeTest {
qfb.setIsLocalOnly(true);
// Verify that with isLocalOnly=true, we only see one album with only one local item.
- try (Cursor cr = mFacade.getMergedAlbums(qfb.build())) {
+ try (Cursor cr = mFacade.getMergedAlbums(qfb.build(), /* cloudProvider */ null)) {
assertThat(cr.getCount()).isEqualTo(1);
cr.moveToFirst();
assertCloudAlbumCursor(cr,
@@ -1789,4 +1882,4 @@ public class PickerDbFacadeTest {
assertThat(cursor.getInt(cursor.getColumnIndex(PickerMediaColumns.ORIENTATION)))
.isEqualTo(ORIENTATION);
}
-} \ No newline at end of file
+}
diff --git a/tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerActivityTest.java b/tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerActivityTest.java
index 92043fb90..a7a54126f 100644
--- a/tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerActivityTest.java
+++ b/tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerActivityTest.java
@@ -319,7 +319,11 @@ public class PhotoPickerActivityTest extends PhotoPickerBaseTest {
@Test
public void testResetOnCloudProviderChange() throws InterruptedException {
// Enable cloud media feature for the activity through the test config store
- mScenario.onActivity(activity -> activity.getConfigStore().enableCloudMediaFeature());
+ mScenario.onActivity(
+ activity ->
+ activity.getConfigStore()
+ .enableCloudMediaFeatureAndSetAllowedCloudProviderPackages(
+ "com.hooli.super.awesome.cloud.provider"));
// Switch to the albums tab
onView(allOf(withText(PICKER_ALBUMS_STRING_ID), isDescendantOfA(withId(TAB_LAYOUT_ID))))
diff --git a/tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerBaseTest.java b/tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerBaseTest.java
index 30b6efdda..965f3f33f 100644
--- a/tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerBaseTest.java
+++ b/tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerBaseTest.java
@@ -54,10 +54,10 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class PhotoPickerBaseTest {
- protected static final int PICKER_TAB_RECYCLERVIEW_ID = R.id.picker_tab_recyclerview;
- protected static final int TAB_LAYOUT_ID = R.id.tab_layout;
+ public static final int PICKER_TAB_RECYCLERVIEW_ID = R.id.picker_tab_recyclerview;
+ public static final int TAB_LAYOUT_ID = R.id.tab_layout;
protected static final int PICKER_PHOTOS_STRING_ID = R.string.picker_photos;
- protected static final int PICKER_ALBUMS_STRING_ID = R.string.picker_albums;
+ public static final int PICKER_ALBUMS_STRING_ID = R.string.picker_albums;
protected static final int PREVIEW_VIEW_PAGER_ID = R.id.preview_viewPager;
protected static final int ICON_CHECK_ID = R.id.icon_check;
protected static final int ICON_THUMBNAIL_ID = R.id.icon_thumbnail;
@@ -133,7 +133,7 @@ public class PhotoPickerBaseTest {
private static final long POLLING_SLEEP_MILLIS = 200;
private static IsolatedContext sIsolatedContext;
- private static UserIdManager sUserIdManager;
+ static UserIdManager sUserIdManager;
public static Intent getSingleSelectMimeTypeFilterIntent(String mimeTypeFilter) {
final Intent intent = new Intent(sSingleSelectIntent);
diff --git a/tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerTestActivity.java b/tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerTestActivity.java
index c279abb77..242ad58b2 100644
--- a/tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerTestActivity.java
+++ b/tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerTestActivity.java
@@ -32,16 +32,18 @@ public class PhotoPickerTestActivity extends PhotoPickerActivity {
private final UiEventLogger mLogger = mock(UiEventLogger.class, RETURNS_SMART_NULLS);
private InstanceId mInstanceId;
+ private PickerViewModel mPickerViewModel;
+
@Override
protected PickerViewModel getOrCreateViewModel() {
- PickerViewModel pickerViewModel = super.getOrCreateViewModel();
- pickerViewModel.setConfigStore(mConfigStore);
- pickerViewModel.setItemsProvider(new ItemsProvider(
+ mPickerViewModel = super.getOrCreateViewModel();
+ mPickerViewModel.setConfigStore(mConfigStore);
+ mPickerViewModel.setItemsProvider(new ItemsProvider(
PhotoPickerBaseTest.getIsolatedContext()));
- pickerViewModel.setUserIdManager(PhotoPickerBaseTest.getMockUserIdManager());
- pickerViewModel.setLogger(new PhotoPickerUiEventLogger(mLogger));
- mInstanceId = pickerViewModel.getInstanceId();
- return pickerViewModel;
+ mPickerViewModel.setUserIdManager(PhotoPickerBaseTest.getMockUserIdManager());
+ mPickerViewModel.setLogger(new PhotoPickerUiEventLogger(mLogger));
+ mInstanceId = mPickerViewModel.getInstanceId();
+ return mPickerViewModel;
}
TestConfigStore getConfigStore() {
@@ -55,4 +57,12 @@ public class PhotoPickerTestActivity extends PhotoPickerActivity {
InstanceId getInstanceId() {
return mInstanceId;
}
+
+ void setItemsProvider(ItemsProvider itemsProvider) {
+ mPickerViewModel.setItemsProvider(itemsProvider);
+ }
+
+ void initSyncForPhotosGrid() {
+ mPickerViewModel.initPhotoPickerData();
+ }
}
diff --git a/tests/src/com/android/providers/media/photopicker/espresso/ProgressBarTest.java b/tests/src/com/android/providers/media/photopicker/espresso/ProgressBarTest.java
new file mode 100644
index 000000000..a59ac46f5
--- /dev/null
+++ b/tests/src/com/android/providers/media/photopicker/espresso/ProgressBarTest.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.providers.media.photopicker.espresso;
+
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.hamcrest.Matchers.allOf;
+
+import android.content.Context;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiSelector;
+import android.text.format.DateUtils;
+
+import androidx.annotation.Nullable;
+import androidx.test.core.app.ActivityScenario;
+import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner;
+
+import com.android.providers.media.R;
+import com.android.providers.media.library.RunOnlyOnPostsubmit;
+import com.android.providers.media.photopicker.DataLoaderThread;
+import com.android.providers.media.photopicker.data.ItemsProvider;
+import com.android.providers.media.photopicker.data.model.UserId;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunOnlyOnPostsubmit
+@RunWith(AndroidJUnit4ClassRunner.class)
+public class ProgressBarTest extends PhotoPickerBaseTest {
+ public ActivityScenario<PhotoPickerTestActivity> mScenario;
+ protected static final UiDevice sDevice = UiDevice.getInstance(getInstrumentation());
+
+ @Before
+ public void setup() {
+ startPhotoPickerActivityAndEnableCloudFlag();
+ }
+
+ @Ignore("Enable progress bar and pagination tests after fixing the flaky behaviour b/296520260")
+ @Test
+ public void test_progressBarPhotosItems_isVisible() {
+ // To recreate the fragments with the new config.
+ mScenario.onActivity((PhotoPickerTestActivity::resetInCurrentProfile));
+ DataLoaderThread.waitForIdle();
+
+ setItemsProviderWithDelayInActivity();
+
+ // Re-initiate sync to ensure that the progress bar comes into view.
+ mScenario.onActivity((PhotoPickerTestActivity::initSyncForPhotosGrid));
+
+ // Verify that the progress bar and loading text is visible.
+ assertProgressBarAndLoadingTextAppears();
+ }
+
+
+ @Ignore("Enable progress bar and pagination tests after fixing the flaky behaviour b/296520260")
+ @Test
+ public void test_progressBarAlbumItems_isVisible() {
+ // Navigate to Albums tab
+ onView(allOf(withText(PICKER_ALBUMS_STRING_ID), isDescendantOfA(withId(TAB_LAYOUT_ID))))
+ .perform(click());
+
+ setItemsProviderWithDelayInActivity();
+ // Navigate to photos in Camera album
+ final int cameraStringId = R.string.picker_category_camera;
+ onView(allOf(withText(cameraStringId),
+ isDescendantOfA(withId(PICKER_TAB_RECYCLERVIEW_ID)))).perform(click());
+
+ // Verify that the progress bar and loading text is visible.
+ assertProgressBarAndLoadingTextAppears();
+ }
+
+ @Test
+ public void test_progressBarAlbumsTab_isNotVisible() {
+
+ // Navigate to albums tab.
+ onView(allOf(withText(PICKER_ALBUMS_STRING_ID), isDescendantOfA(withId(TAB_LAYOUT_ID))))
+ .perform(click());
+
+ // Verify that the progress bar and loading text is not visible.
+ assertProgressBarAndLoadingTextDoesNotAppears();
+ }
+
+ private void startPhotoPickerActivityAndEnableCloudFlag() {
+ sDevice.waitForIdle();
+ launchPhotosActivity();
+ mScenario.onActivity(
+ (activity -> {
+ activity.getConfigStore()
+ .enableCloudMediaFeatureAndSetAllowedCloudProviderPackages(
+ getInstrumentation().getTargetContext().getPackageName());
+ }));
+ }
+
+ private void launchPhotosActivity() {
+ mScenario = ActivityScenario.launchActivityForResult(
+ PhotoPickerBaseTest.getSingleSelectionIntent());
+ }
+
+ private void setItemsProviderWithDelayInActivity() {
+ FakeItemsProvider itemsProvider = new FakeItemsProvider(getIsolatedContext());
+ itemsProvider.delaySync();
+ mScenario.onActivity(
+ (activity -> {
+ activity.setItemsProvider(itemsProvider);
+ }));
+ }
+
+ private void assertProgressBarAndLoadingTextAppears() {
+ final UiSelector progressBar = new UiSelector().resourceId(
+ getIsolatedContext().getPackageName()
+ + ":id/progress_bar");
+ assertWithMessage("Waiting for progressBar to appear on photos grid").that(
+ new UiObject(progressBar).waitForExists(DateUtils.SECOND_IN_MILLIS)).isTrue();
+
+ final UiSelector loadingText = new UiSelector().resourceId(
+ getIsolatedContext().getPackageName()
+ + ":id/loading_text_view");
+ assertWithMessage("Waiting for progressBar to appear on photos grid").that(
+ new UiObject(loadingText).waitForExists(DateUtils.SECOND_IN_MILLIS)).isTrue();
+ }
+
+ private void assertProgressBarAndLoadingTextDoesNotAppears() {
+ final UiSelector progressBar = new UiSelector().resourceId(
+ getIsolatedContext().getPackageName()
+ + ":id/progress_bar");
+ assertWithMessage("Waiting for progressBar to appear on photos grid").that(
+ new UiObject(progressBar).waitForExists(DateUtils.SECOND_IN_MILLIS / 2)).isFalse();
+
+ final UiSelector loadingText = new UiSelector().resourceId(
+ getIsolatedContext().getPackageName()
+ + ":id/loading_text_view");
+ assertWithMessage("Waiting for progressBar to appear on photos grid").that(
+ new UiObject(loadingText).waitForExists(DateUtils.SECOND_IN_MILLIS / 2)).isFalse();
+ }
+
+ @After
+ public void tearDown() {
+ if (mScenario != null) {
+ mScenario.close();
+ }
+ }
+
+ public static class FakeItemsProvider extends ItemsProvider {
+
+ private boolean mShouldDelaySync = false;
+
+ public FakeItemsProvider(Context context) {
+ super(context);
+ }
+
+ public void delaySync() {
+ mShouldDelaySync = true;
+ }
+
+ @Override
+ public void initPhotoPickerData(@Nullable String albumId,
+ @Nullable String albumAuthority,
+ boolean initLocalOnlyData,
+ @Nullable UserId userId) {
+ if (mShouldDelaySync) {
+ try {
+ Thread.sleep(DateUtils.SECOND_IN_MILLIS);
+ } catch (Exception e) {
+ // no-op
+ }
+ } else {
+ super.initPhotoPickerData(albumId, albumAuthority, initLocalOnlyData, userId);
+ }
+ }
+ }
+}
diff --git a/tests/src/com/android/providers/media/photopicker/sync/MediaResetWorkerTest.java b/tests/src/com/android/providers/media/photopicker/sync/MediaResetWorkerTest.java
new file mode 100644
index 000000000..62ee3377c
--- /dev/null
+++ b/tests/src/com/android/providers/media/photopicker/sync/MediaResetWorkerTest.java
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.providers.media.photopicker.sync;
+
+import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_LOCAL_AND_CLOUD;
+import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_RESET_ALBUM;
+import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_WORKER_INPUT_AUTHORITY;
+import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_WORKER_INPUT_RESET_TYPE;
+import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_WORKER_INPUT_SYNC_SOURCE;
+import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_WORKER_TAG_IS_PERIODIC;
+import static com.android.providers.media.photopicker.sync.SyncWorkerTestUtils.getAlbumResetInputData;
+import static com.android.providers.media.photopicker.sync.SyncWorkerTestUtils.initializeTestWorkManager;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.os.Build;
+import android.provider.CloudMediaProviderContract.MediaColumns;
+
+import androidx.test.filters.SdkSuppress;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.work.Data;
+import androidx.work.OneTimeWorkRequest;
+import androidx.work.WorkInfo;
+import androidx.work.WorkManager;
+
+import com.android.providers.media.photopicker.PickerSyncController;
+import com.android.providers.media.photopicker.data.PickerDatabaseHelper;
+import com.android.providers.media.photopicker.data.PickerDbFacade;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+
+import java.io.File;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+
+// TODO enable tests in Android R after fixing b/293390235
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
+public class MediaResetWorkerTest {
+
+ private PickerSyncController mExistingPickerSyncController;
+
+ @Mock private PickerSyncController mMockPickerSyncController;
+ @Mock private SyncTracker mMockLocalAlbumSyncTracker;
+ @Mock private SyncTracker mMockCloudAlbumSyncTracker;
+
+ private PickerDbFacade mDbFacade;
+ private Context mContext;
+
+ private static final String TEST_ALBUM_ID_1 = "test-album-id-1";
+ private static final String TEST_ALBUM_ID_2 = "test-album-id-2";
+ private static final String TEST_ALBUM_ID_3 = "test-album-id-3";
+ private static final String TEST_ALBUM_ID_4 = "test-album-id-4";
+ private static final String TEST_LOCAL_AUTHORITY = "com.android.media.photopicker";
+ private static final String TEST_CLOUD_AUTHORITY = "com.hooli.super.awesome.cloud.provider";
+
+ @Before
+ public void setup() {
+ initMocks(this);
+
+ try {
+ mExistingPickerSyncController = PickerSyncController.getInstanceOrThrow();
+ } catch (IllegalStateException ignored) {
+ }
+
+ // Inject mock trackers
+ SyncTrackerRegistry.setLocalAlbumSyncTracker(mMockLocalAlbumSyncTracker);
+ SyncTrackerRegistry.setCloudAlbumSyncTracker(mMockCloudAlbumSyncTracker);
+
+ doReturn(new Object()).when(mMockPickerSyncController).getCloudAlbumSyncLock();
+ doReturn(TEST_CLOUD_AUTHORITY).when(mMockPickerSyncController).getCloudProvider();
+ doReturn(TEST_LOCAL_AUTHORITY).when(mMockPickerSyncController).getLocalProvider();
+
+ mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+
+ // Cleanup previous test run databases.
+ File dbPath = mContext.getDatabasePath(PickerDatabaseHelper.PICKER_DATABASE_NAME);
+ dbPath.delete();
+
+ mDbFacade = new PickerDbFacade(mContext, TEST_LOCAL_AUTHORITY);
+ mDbFacade.setCloudProvider(TEST_CLOUD_AUTHORITY);
+
+ initializeTestWorkManager(mContext);
+ PickerSyncController.setInstance(mMockPickerSyncController);
+ }
+
+ @After
+ public void teardown() {
+ if (mExistingPickerSyncController != null) {
+ PickerSyncController.setInstance(mExistingPickerSyncController);
+ }
+
+ // Reset mock trackers
+ SyncTrackerRegistry.setLocalAlbumSyncTracker(new SyncTracker());
+ SyncTrackerRegistry.setCloudAlbumSyncTracker(new SyncTracker());
+ }
+
+ @Test
+ public void testResetCloudAlbumMediaForAlbumId()
+ throws ExecutionException, InterruptedException {
+
+ assertAddAlbumMediaWithAlbumId(TEST_ALBUM_ID_1, TEST_CLOUD_AUTHORITY);
+ assertAddAlbumMediaWithAlbumId(TEST_ALBUM_ID_2, TEST_CLOUD_AUTHORITY);
+ assertAddAlbumMediaWithAlbumId(TEST_ALBUM_ID_3, TEST_LOCAL_AUTHORITY);
+ assertAddAlbumMediaWithAlbumId(TEST_ALBUM_ID_4, TEST_LOCAL_AUTHORITY);
+
+ final OneTimeWorkRequest request =
+ new OneTimeWorkRequest.Builder(MediaResetWorker.class)
+ .setInputData(
+ getAlbumResetInputData(
+ TEST_ALBUM_ID_1, TEST_CLOUD_AUTHORITY, false))
+ .build();
+
+ final WorkManager workManager = WorkManager.getInstance(mContext);
+ workManager.enqueue(request).getResult().get();
+
+ // Verify
+ final WorkInfo workInfo = workManager.getWorkInfoById(request.getId()).get();
+ assertThat(workInfo.getState()).isEqualTo(WorkInfo.State.SUCCEEDED);
+
+ // We should have deleted just the rows related to the TEST_ALBUM_ID_1 album.
+ Cursor cursor = queryAlbumMediaAll(TEST_CLOUD_AUTHORITY);
+ assertThat(cursor.getCount()).isEqualTo(60);
+ cursor.close();
+
+ cursor = queryAlbumMediaAll(TEST_ALBUM_ID_1, TEST_CLOUD_AUTHORITY);
+ assertThat(cursor.getCount()).isEqualTo(0);
+ cursor.close();
+
+ cursor = queryAlbumMediaAll(TEST_ALBUM_ID_2, TEST_CLOUD_AUTHORITY);
+ assertThat(cursor.getCount()).isEqualTo(20);
+ cursor.close();
+
+ cursor = queryAlbumMediaAll(TEST_ALBUM_ID_3, TEST_LOCAL_AUTHORITY);
+ assertThat(cursor.getCount()).isEqualTo(20);
+ cursor.close();
+
+ cursor = queryAlbumMediaAll(TEST_ALBUM_ID_4, TEST_LOCAL_AUTHORITY);
+ assertThat(cursor.getCount()).isEqualTo(20);
+ cursor.close();
+
+ // The sync future is created by the PickerSyncManager before the request is
+ // enqueued.
+ verify(mMockCloudAlbumSyncTracker, times(/* wantedNumberOfInvocations */ 0))
+ .createSyncFuture(any());
+
+ // The worker should resolve its own sync future.
+ verify(mMockCloudAlbumSyncTracker, times(/* wantedNumberOfInvocations */ 1))
+ .markSyncCompleted(any());
+ }
+
+ @Test
+ public void testResetLocalAlbumMediaForAlbumId()
+ throws ExecutionException, InterruptedException {
+
+ assertAddAlbumMediaWithAlbumId(TEST_ALBUM_ID_1, TEST_LOCAL_AUTHORITY);
+ assertAddAlbumMediaWithAlbumId(TEST_ALBUM_ID_2, TEST_CLOUD_AUTHORITY);
+
+ final OneTimeWorkRequest request =
+ new OneTimeWorkRequest.Builder(MediaResetWorker.class)
+ .setInputData(
+ getAlbumResetInputData(TEST_ALBUM_ID_1, TEST_CLOUD_AUTHORITY, true))
+ .build();
+
+ final WorkManager workManager = WorkManager.getInstance(mContext);
+ workManager.enqueue(request).getResult().get();
+
+ // Verify
+ final WorkInfo workInfo = workManager.getWorkInfoById(request.getId()).get();
+ assertThat(workInfo.getState()).isEqualTo(WorkInfo.State.SUCCEEDED);
+
+
+ // We should have deleted just the rows related to the TEST_ALBUM_ID_1 album.
+ Cursor cursor = queryAlbumMediaAll(TEST_CLOUD_AUTHORITY);
+ assertThat(cursor.getCount()).isEqualTo(20);
+ cursor.close();
+
+ cursor = queryAlbumMediaAll(TEST_ALBUM_ID_1, TEST_LOCAL_AUTHORITY);
+ assertThat(cursor.getCount()).isEqualTo(0);
+ cursor.close();
+
+ cursor = queryAlbumMediaAll(TEST_ALBUM_ID_2, TEST_CLOUD_AUTHORITY);
+ assertThat(cursor.getCount()).isEqualTo(20);
+ cursor.close();
+
+ // The sync future is created by the PickerSyncManager before the request is
+ // enqueued.
+ verify(mMockLocalAlbumSyncTracker, times(/* wantedNumberOfInvocations */ 0))
+ .createSyncFuture(any());
+
+ // The worker should resolve its own sync future.
+ verify(mMockLocalAlbumSyncTracker, times(/* wantedNumberOfInvocations */ 1))
+ .markSyncCompleted(any());
+ }
+
+ @Test
+ public void testResetAllAlbumMedia() throws ExecutionException, InterruptedException {
+
+ assertAddAlbumMediaWithAlbumId(TEST_ALBUM_ID_1, TEST_CLOUD_AUTHORITY);
+ assertAddAlbumMediaWithAlbumId(TEST_ALBUM_ID_2, TEST_CLOUD_AUTHORITY);
+
+ final Data requestData =
+ new Data(
+ Map.of(
+ SYNC_WORKER_INPUT_AUTHORITY,
+ TEST_CLOUD_AUTHORITY,
+ SYNC_WORKER_INPUT_RESET_TYPE,
+ SYNC_RESET_ALBUM,
+ SYNC_WORKER_INPUT_SYNC_SOURCE,
+ SYNC_LOCAL_AND_CLOUD));
+
+ final OneTimeWorkRequest request =
+ new OneTimeWorkRequest.Builder(MediaResetWorker.class)
+ .setInputData(requestData)
+ .build();
+
+ final WorkManager workManager = WorkManager.getInstance(mContext);
+ workManager.enqueue(request).getResult().get();
+
+ // Verify
+ final WorkInfo workInfo = workManager.getWorkInfoById(request.getId()).get();
+ assertThat(workInfo.getState()).isEqualTo(WorkInfo.State.SUCCEEDED);
+
+ Cursor cursor = queryAlbumMediaAll(TEST_CLOUD_AUTHORITY);
+ assertThat(cursor.getCount()).isEqualTo(0);
+ cursor.close();
+
+ cursor = queryAlbumMediaAll(TEST_LOCAL_AUTHORITY);
+ assertThat(cursor.getCount()).isEqualTo(0);
+ cursor.close();
+
+ // The sync future is created by the PickerSyncManager before the request is
+ // enqueued.
+ verify(mMockCloudAlbumSyncTracker, times(/* wantedNumberOfInvocations */ 0))
+ .createSyncFuture(any());
+
+ // The worker should resolve its own sync future.
+ verify(mMockLocalAlbumSyncTracker, times(/* wantedNumberOfInvocations */ 1))
+ .markSyncCompleted(any());
+ verify(mMockCloudAlbumSyncTracker, times(/* wantedNumberOfInvocations */ 1))
+ .markSyncCompleted(any());
+ }
+
+ @Test
+ public void testPeriodicWorkerAlbumReset_WithCloudProvider()
+ throws ExecutionException, InterruptedException {
+
+ assertAddAlbumMediaWithAlbumId(TEST_ALBUM_ID_1, TEST_LOCAL_AUTHORITY);
+ assertAddAlbumMediaWithAlbumId(TEST_ALBUM_ID_2, TEST_CLOUD_AUTHORITY);
+
+ final Data requestData =
+ new Data(
+ Map.of(
+ SYNC_WORKER_INPUT_RESET_TYPE,
+ SYNC_RESET_ALBUM,
+ SYNC_WORKER_INPUT_SYNC_SOURCE,
+ SYNC_LOCAL_AND_CLOUD));
+
+ final OneTimeWorkRequest request =
+ new OneTimeWorkRequest.Builder(MediaResetWorker.class)
+ .setInputData(requestData)
+ .addTag(SYNC_WORKER_TAG_IS_PERIODIC)
+ .build();
+
+ final WorkManager workManager = WorkManager.getInstance(mContext);
+ workManager.enqueue(request).getResult().get();
+
+ // Verify
+ final WorkInfo workInfo = workManager.getWorkInfoById(request.getId()).get();
+ assertThat(workInfo.getState()).isEqualTo(WorkInfo.State.SUCCEEDED);
+
+ // The sync future is created by the PickerSyncManager before the request is
+ // enqueued.
+ verify(mMockCloudAlbumSyncTracker, times(/* wantedNumberOfInvocations */ 1))
+ .createSyncFuture(any());
+ verify(mMockLocalAlbumSyncTracker, times(/* wantedNumberOfInvocations */ 1))
+ .createSyncFuture(any());
+ verify(mMockCloudAlbumSyncTracker, times(/* wantedNumberOfInvocations */ 1))
+ .markSyncCompleted(any());
+ verify(mMockLocalAlbumSyncTracker, times(/* wantedNumberOfInvocations */ 1))
+ .markSyncCompleted(any());
+
+ Cursor cursor = queryAlbumMediaAll(TEST_CLOUD_AUTHORITY);
+ assertThat(cursor.getCount()).isEqualTo(0);
+ cursor.close();
+
+ cursor = queryAlbumMediaAll(TEST_LOCAL_AUTHORITY);
+ assertThat(cursor.getCount()).isEqualTo(0);
+ cursor.close();
+ }
+
+ @Test
+ public void testPeriodicWorkerAlbumReset_WithLocalProvider()
+ throws ExecutionException, InterruptedException {
+
+ doReturn(null).when(mMockPickerSyncController).getCloudProvider();
+
+ assertAddAlbumMediaWithAlbumId(TEST_ALBUM_ID_1, TEST_LOCAL_AUTHORITY);
+ assertAddAlbumMediaWithAlbumId(TEST_ALBUM_ID_2, TEST_LOCAL_AUTHORITY);
+
+ final Data requestData =
+ new Data(
+ Map.of(
+ SYNC_WORKER_INPUT_RESET_TYPE,
+ SYNC_RESET_ALBUM,
+ SYNC_WORKER_INPUT_SYNC_SOURCE,
+ SYNC_LOCAL_AND_CLOUD));
+
+ final OneTimeWorkRequest request =
+ new OneTimeWorkRequest.Builder(MediaResetWorker.class)
+ .setInputData(requestData)
+ .addTag(SYNC_WORKER_TAG_IS_PERIODIC)
+ .build();
+
+ final WorkManager workManager = WorkManager.getInstance(mContext);
+ workManager.enqueue(request).getResult().get();
+
+ // Verify
+ final WorkInfo workInfo = workManager.getWorkInfoById(request.getId()).get();
+ assertThat(workInfo.getState()).isEqualTo(WorkInfo.State.SUCCEEDED);
+
+ // The sync future is created by the PickerSyncManager before the request is
+ // enqueued.
+ verify(mMockCloudAlbumSyncTracker, times(/* wantedNumberOfInvocations */ 1))
+ .createSyncFuture(any());
+ verify(mMockLocalAlbumSyncTracker, times(/* wantedNumberOfInvocations */ 1))
+ .createSyncFuture(any());
+ verify(mMockCloudAlbumSyncTracker, times(/* wantedNumberOfInvocations */ 1))
+ .markSyncCompleted(any());
+ verify(mMockLocalAlbumSyncTracker, times(/* wantedNumberOfInvocations */ 1))
+ .markSyncCompleted(any());
+
+ Cursor cursor = queryAlbumMediaAll(TEST_LOCAL_AUTHORITY);
+ assertThat(cursor.getCount()).isEqualTo(0);
+ cursor.close();
+ }
+
+ /**
+ * Builds a suitible mock Album media cursor that could be returned from a provider.
+ *
+ * @param id a base id for each file. will be appended with the current loop count.
+ */
+ private static Cursor getAlbumMediaCursor(String id) {
+ String[] projectionKey =
+ new String[] {
+ MediaColumns.ID,
+ MediaColumns.MEDIA_STORE_URI,
+ MediaColumns.DATE_TAKEN_MILLIS,
+ MediaColumns.SYNC_GENERATION,
+ MediaColumns.SIZE_BYTES,
+ MediaColumns.MIME_TYPE,
+ MediaColumns.STANDARD_MIME_TYPE_EXTENSION,
+ MediaColumns.DURATION_MILLIS,
+ };
+
+ MatrixCursor c = new MatrixCursor(projectionKey);
+ int counter = 0;
+
+ while (++counter <= 20) {
+
+ String[] projectionValue =
+ new String[] {
+ id + counter,
+ "content://media/external/file/1234" + counter,
+ String.valueOf(System.nanoTime()),
+ String.valueOf(1),
+ String.valueOf(1234),
+ "image/png",
+ String.valueOf(MediaColumns.STANDARD_MIME_TYPE_EXTENSION_NONE),
+ String.valueOf(1234),
+ };
+
+ c.addRow(projectionValue);
+ }
+ return c;
+ }
+
+ /**
+ * Query all records in the Album media table.
+ *
+ * @param authority provider's authority
+ */
+ private Cursor queryAlbumMediaAll(String authority) {
+ return mDbFacade.queryAlbumMediaForUi(
+ new PickerDbFacade.QueryFilterBuilder(1000).build(), authority);
+ }
+
+ /**
+ * @param albumId limit the results to just files present in this album
+ * @param authority provider's authority
+ */
+ private Cursor queryAlbumMediaAll(String albumId, String authority) {
+ return mDbFacade.queryAlbumMediaForUi(
+ new PickerDbFacade.QueryFilterBuilder(1000).setAlbumId(albumId).build(), authority);
+ }
+
+ /**
+ * Creates a fake Album with the given Album ID and adds 20 fake files to it.
+ *
+ * @param albumId the id to use in creating the fake album
+ * @param authority the provider that owns the fake album.
+ */
+ private void assertAddAlbumMediaWithAlbumId(String albumId, String authority) {
+
+ try (PickerDbFacade.DbWriteOperation operation =
+ mDbFacade.beginAddAlbumMediaOperation(authority, albumId)) {
+ operation.execute(getAlbumMediaCursor("1234-" + albumId));
+ operation.setSuccess();
+ }
+
+ Cursor cr = queryAlbumMediaAll(albumId, authority);
+ assertThat(cr.getCount()).isEqualTo(20);
+ }
+}
diff --git a/tests/src/com/android/providers/media/photopicker/sync/PickerSyncManagerTest.java b/tests/src/com/android/providers/media/photopicker/sync/PickerSyncManagerTest.java
index d066d7788..3cd2858c6 100644
--- a/tests/src/com/android/providers/media/photopicker/sync/PickerSyncManagerTest.java
+++ b/tests/src/com/android/providers/media/photopicker/sync/PickerSyncManagerTest.java
@@ -25,22 +25,31 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.MockitoAnnotations.initMocks;
+import android.content.Context;
+import android.content.res.Resources;
+
import androidx.work.ExistingPeriodicWorkPolicy;
import androidx.work.ExistingWorkPolicy;
import androidx.work.OneTimeWorkRequest;
import androidx.work.Operation;
import androidx.work.PeriodicWorkRequest;
+import androidx.work.WorkContinuation;
+import androidx.work.WorkInfo;
import androidx.work.WorkManager;
import androidx.work.WorkRequest;
+import com.android.modules.utils.BackgroundThread;
import com.android.providers.media.TestConfigStore;
+import com.android.providers.media.photopicker.PickerSyncController;
import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
import org.junit.Before;
import org.junit.Test;
@@ -48,7 +57,12 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
+import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
public class PickerSyncManagerTest {
private PickerSyncManager mPickerSyncManager;
@@ -58,32 +72,40 @@ public class PickerSyncManagerTest {
@Mock
private Operation mMockOperation;
@Mock
+ private WorkContinuation mMockWorkContinuation;
+ @Mock
private ListenableFuture<Operation.State.SUCCESS> mMockFuture;
+ @Mock
+ private Context mMockContext;
+ @Mock
+ private Resources mResources;
@Captor
ArgumentCaptor<PeriodicWorkRequest> mPeriodicWorkRequestArgumentCaptor;
@Captor
ArgumentCaptor<OneTimeWorkRequest> mOneTimeWorkRequestArgumentCaptor;
@Captor
- ArgumentCaptor<List<WorkRequest>> mWorkRequestListArgumentCaptor;
+ ArgumentCaptor<List<OneTimeWorkRequest>> mOneTimeWorkRequestListArgumentCaptor;
@Before
public void setUp() {
initMocks(this);
+ doReturn(mResources).when(mMockContext).getResources();
mConfigStore = new TestConfigStore();
- mConfigStore.enableCloudMediaFeature();
+ mConfigStore.enableCloudMediaFeatureAndSetAllowedCloudProviderPackages(
+ "com.hooli.super.awesome.cloudpicker");
}
@Test
public void testSchedulePeriodicSyncs() {
setupPickerSyncManager(/* schedulePeriodicSyncs */ true);
- verify(mMockWorkManager, times(1))
+ verify(mMockWorkManager, times(2))
.enqueueUniquePeriodicWork(anyString(),
any(),
mPeriodicWorkRequestArgumentCaptor.capture());
final PeriodicWorkRequest periodicWorkRequest =
- mPeriodicWorkRequestArgumentCaptor.getValue();
+ mPeriodicWorkRequestArgumentCaptor.getAllValues().get(0);
assertThat(periodicWorkRequest.getWorkSpec().workerClassName)
.isEqualTo(ProactiveSyncWorker.class.getName());
assertThat(periodicWorkRequest.getWorkSpec().expedited).isFalse();
@@ -93,6 +115,77 @@ public class PickerSyncManagerTest {
assertThat(periodicWorkRequest.getWorkSpec().input
.getInt(SYNC_WORKER_INPUT_SYNC_SOURCE, -1))
.isEqualTo(SYNC_LOCAL_AND_CLOUD);
+
+ final PeriodicWorkRequest periodicResetRequest =
+ mPeriodicWorkRequestArgumentCaptor.getAllValues().get(1);
+ assertThat(periodicResetRequest.getWorkSpec().workerClassName)
+ .isEqualTo(MediaResetWorker.class.getName());
+ assertThat(periodicResetRequest.getWorkSpec().expedited).isFalse();
+ assertThat(periodicResetRequest.getWorkSpec().isPeriodic()).isTrue();
+ assertThat(periodicResetRequest.getWorkSpec().id).isNotNull();
+ assertThat(periodicResetRequest.getWorkSpec().constraints.requiresBatteryNotLow()).isTrue();
+ assertThat(periodicResetRequest.getWorkSpec().constraints.requiresDeviceIdle()).isTrue();
+ assertThat(periodicResetRequest.getWorkSpec().input
+ .getInt(SYNC_WORKER_INPUT_SYNC_SOURCE, -1))
+ .isEqualTo(SYNC_LOCAL_AND_CLOUD);
+ }
+
+ @Test
+ public void testPeriodicWorkIsScheduledOnDeviceConfigChanges() {
+
+ mConfigStore.disableCloudMediaFeature();
+
+
+ setupPickerSyncManager(true);
+
+ // Ensure no syncs have been scheduled yet.
+ verify(mMockWorkManager, times(0))
+ .enqueueUniquePeriodicWork(anyString(),
+ any(),
+ mPeriodicWorkRequestArgumentCaptor.capture());
+
+ mConfigStore.enableCloudMediaFeatureAndSetAllowedCloudProviderPackages(
+ "com.hooli.some.cloud.provider");
+
+ waitForIdle();
+
+ // Ensure the syncs are now scheduled.
+ verify(mMockWorkManager, times(2))
+ .enqueueUniquePeriodicWork(anyString(),
+ any(),
+ mPeriodicWorkRequestArgumentCaptor.capture());
+
+ final PeriodicWorkRequest periodicWorkRequest =
+ mPeriodicWorkRequestArgumentCaptor.getAllValues().get(0);
+ assertThat(periodicWorkRequest.getWorkSpec().workerClassName)
+ .isEqualTo(ProactiveSyncWorker.class.getName());
+ assertThat(periodicWorkRequest.getWorkSpec().expedited).isFalse();
+ assertThat(periodicWorkRequest.getWorkSpec().isPeriodic()).isTrue();
+ assertThat(periodicWorkRequest.getWorkSpec().id).isNotNull();
+ assertThat(periodicWorkRequest.getWorkSpec().constraints.requiresBatteryNotLow()).isTrue();
+ assertThat(periodicWorkRequest.getWorkSpec().input
+ .getInt(SYNC_WORKER_INPUT_SYNC_SOURCE, -1))
+ .isEqualTo(SYNC_LOCAL_AND_CLOUD);
+
+ final PeriodicWorkRequest periodicResetRequest =
+ mPeriodicWorkRequestArgumentCaptor.getAllValues().get(1);
+ assertThat(periodicResetRequest.getWorkSpec().workerClassName)
+ .isEqualTo(MediaResetWorker.class.getName());
+ assertThat(periodicResetRequest.getWorkSpec().expedited).isFalse();
+ assertThat(periodicResetRequest.getWorkSpec().isPeriodic()).isTrue();
+ assertThat(periodicResetRequest.getWorkSpec().id).isNotNull();
+ assertThat(periodicResetRequest.getWorkSpec().constraints.requiresBatteryNotLow()).isTrue();
+ assertThat(periodicResetRequest.getWorkSpec().constraints.requiresDeviceIdle()).isTrue();
+ assertThat(periodicResetRequest.getWorkSpec().input
+ .getInt(SYNC_WORKER_INPUT_SYNC_SOURCE, -1))
+ .isEqualTo(SYNC_LOCAL_AND_CLOUD);
+
+ clearInvocations(mMockWorkManager);
+
+ mConfigStore.disableCloudMediaFeature();
+ waitForIdle();
+
+ verify(mMockWorkManager, times(2)).cancelUniqueWork(anyString());
}
@Test
@@ -123,11 +216,9 @@ public class PickerSyncManagerTest {
mPickerSyncManager.syncMediaImmediately(true);
verify(mMockWorkManager, times(1))
- .enqueue(mWorkRequestListArgumentCaptor.capture());
+ .enqueueUniqueWork(anyString(), any(), mOneTimeWorkRequestArgumentCaptor.capture());
- final List<WorkRequest> workRequestList = mWorkRequestListArgumentCaptor.getValue();
- assertThat(workRequestList.size()).isEqualTo(1);
- WorkRequest workRequest = workRequestList.get(0);
+ final OneTimeWorkRequest workRequest = mOneTimeWorkRequestArgumentCaptor.getValue();
assertThat(workRequest.getWorkSpec().workerClassName)
.isEqualTo(ImmediateSyncWorker.class.getName());
assertThat(workRequest.getWorkSpec().expedited).isTrue();
@@ -144,42 +235,71 @@ public class PickerSyncManagerTest {
setupPickerSyncManager(/* schedulePeriodicSyncs */ false);
mPickerSyncManager.syncMediaImmediately(false);
- verify(mMockWorkManager, times(1))
- .enqueue(mWorkRequestListArgumentCaptor.capture());
+ verify(mMockWorkManager, times(2))
+ .enqueueUniqueWork(anyString(), any(), mOneTimeWorkRequestArgumentCaptor.capture());
- final List<WorkRequest> workRequestList = mWorkRequestListArgumentCaptor.getValue();
- assertThat(workRequestList.size()).isEqualTo(1);
- WorkRequest workRequest = workRequestList.get(0);
- assertThat(workRequest.getWorkSpec().workerClassName)
+ final List<OneTimeWorkRequest> workRequestList =
+ mOneTimeWorkRequestArgumentCaptor.getAllValues();
+ assertThat(workRequestList.size()).isEqualTo(2);
+
+ WorkRequest localWorkRequest = workRequestList.get(0);
+ assertThat(localWorkRequest.getWorkSpec().workerClassName)
.isEqualTo(ImmediateSyncWorker.class.getName());
- assertThat(workRequest.getWorkSpec().expedited).isTrue();
- assertThat(workRequest.getWorkSpec().isPeriodic()).isFalse();
- assertThat(workRequest.getWorkSpec().id).isNotNull();
- assertThat(workRequest.getWorkSpec().constraints.requiresBatteryNotLow()).isFalse();
- assertThat(workRequest.getWorkSpec().input
+ assertThat(localWorkRequest.getWorkSpec().expedited).isTrue();
+ assertThat(localWorkRequest.getWorkSpec().isPeriodic()).isFalse();
+ assertThat(localWorkRequest.getWorkSpec().id).isNotNull();
+ assertThat(localWorkRequest.getWorkSpec().constraints.requiresBatteryNotLow()).isFalse();
+ assertThat(localWorkRequest.getWorkSpec().input
.getInt(SYNC_WORKER_INPUT_SYNC_SOURCE, -1))
- .isEqualTo(SYNC_LOCAL_AND_CLOUD);
+ .isEqualTo(SYNC_LOCAL_ONLY);
+
+ WorkRequest cloudWorkRequest = workRequestList.get(1);
+ assertThat(cloudWorkRequest.getWorkSpec().workerClassName)
+ .isEqualTo(ImmediateSyncWorker.class.getName());
+ assertThat(cloudWorkRequest.getWorkSpec().expedited).isTrue();
+ assertThat(cloudWorkRequest.getWorkSpec().isPeriodic()).isFalse();
+ assertThat(cloudWorkRequest.getWorkSpec().id).isNotNull();
+ assertThat(cloudWorkRequest.getWorkSpec().constraints.requiresBatteryNotLow()).isFalse();
+ assertThat(cloudWorkRequest.getWorkSpec().input
+ .getInt(SYNC_WORKER_INPUT_SYNC_SOURCE, -1))
+ .isEqualTo(SYNC_CLOUD_ONLY);
}
@Test
public void testImmediateLocalAlbumSync() {
setupPickerSyncManager(/* schedulePeriodicSyncs */ false);
- mPickerSyncManager.syncAlbumMediaForProviderImmediately("Not_null", true);
+ mPickerSyncManager.syncAlbumMediaForProviderImmediately(
+ "Not_null", PickerSyncController.LOCAL_PICKER_PROVIDER_AUTHORITY);
verify(mMockWorkManager, times(1))
- .enqueue(mWorkRequestListArgumentCaptor.capture());
+ .beginUniqueWork(
+ anyString(),
+ any(ExistingWorkPolicy.class),
+ mOneTimeWorkRequestListArgumentCaptor.capture());
+ verify(mMockWorkContinuation, times(1))
+ .then(mOneTimeWorkRequestListArgumentCaptor.capture());
+ verify(mMockWorkContinuation).enqueue();
- final List<WorkRequest> workRequestList = mWorkRequestListArgumentCaptor.getValue();
- assertThat(workRequestList.size()).isEqualTo(1);
- WorkRequest workRequest = workRequestList.get(0);
+ final OneTimeWorkRequest resetRequest =
+ mOneTimeWorkRequestListArgumentCaptor.getAllValues().get(0).get(0);
+ assertThat(resetRequest.getWorkSpec().workerClassName)
+ .isEqualTo(MediaResetWorker.class.getName());
+ assertThat(resetRequest.getWorkSpec().expedited).isTrue();
+ assertThat(resetRequest.getWorkSpec().isPeriodic()).isFalse();
+ assertThat(resetRequest.getWorkSpec().id).isNotNull();
+ assertThat(resetRequest.getWorkSpec().constraints.requiresBatteryNotLow()).isFalse();
+ assertThat(resetRequest.getWorkSpec().input.getInt(SYNC_WORKER_INPUT_SYNC_SOURCE, -1))
+ .isEqualTo(SYNC_LOCAL_ONLY);
+
+ final OneTimeWorkRequest workRequest =
+ mOneTimeWorkRequestListArgumentCaptor.getAllValues().get(1).get(0);
assertThat(workRequest.getWorkSpec().workerClassName)
.isEqualTo(ImmediateAlbumSyncWorker.class.getName());
assertThat(workRequest.getWorkSpec().expedited).isTrue();
assertThat(workRequest.getWorkSpec().isPeriodic()).isFalse();
assertThat(workRequest.getWorkSpec().id).isNotNull();
assertThat(workRequest.getWorkSpec().constraints.requiresBatteryNotLow()).isFalse();
- assertThat(workRequest.getWorkSpec().input
- .getInt(SYNC_WORKER_INPUT_SYNC_SOURCE, -1))
+ assertThat(workRequest.getWorkSpec().input.getInt(SYNC_WORKER_INPUT_SYNC_SOURCE, -1))
.isEqualTo(SYNC_LOCAL_ONLY);
}
@@ -187,24 +307,75 @@ public class PickerSyncManagerTest {
public void testImmediateCloudAlbumSync() {
setupPickerSyncManager(/* schedulePeriodicSyncs */ false);
- mPickerSyncManager.syncAlbumMediaForProviderImmediately("Not_null", false);
+ mPickerSyncManager.syncAlbumMediaForProviderImmediately(
+ "Not_null", "com.hooli.cloudpicker");
verify(mMockWorkManager, times(1))
- .enqueue(mWorkRequestListArgumentCaptor.capture());
+ .beginUniqueWork(
+ anyString(),
+ any(ExistingWorkPolicy.class),
+ mOneTimeWorkRequestListArgumentCaptor.capture());
+ verify(mMockWorkContinuation, times(1))
+ .then(mOneTimeWorkRequestListArgumentCaptor.capture());
+ verify(mMockWorkContinuation).enqueue();
- final List<WorkRequest> workRequestList = mWorkRequestListArgumentCaptor.getValue();
- assertThat(workRequestList.size()).isEqualTo(1);
- WorkRequest workRequest = workRequestList.get(0);
+ final OneTimeWorkRequest resetRequest =
+ mOneTimeWorkRequestListArgumentCaptor.getAllValues().get(0).get(0);
+ assertThat(resetRequest.getWorkSpec().workerClassName)
+ .isEqualTo(MediaResetWorker.class.getName());
+ assertThat(resetRequest.getWorkSpec().expedited).isTrue();
+ assertThat(resetRequest.getWorkSpec().isPeriodic()).isFalse();
+ assertThat(resetRequest.getWorkSpec().id).isNotNull();
+ assertThat(resetRequest.getWorkSpec().constraints.requiresBatteryNotLow()).isFalse();
+ assertThat(resetRequest.getWorkSpec().input.getInt(SYNC_WORKER_INPUT_SYNC_SOURCE, -1))
+ .isEqualTo(SYNC_CLOUD_ONLY);
+
+ final OneTimeWorkRequest workRequest =
+ mOneTimeWorkRequestListArgumentCaptor.getAllValues().get(1).get(0);
assertThat(workRequest.getWorkSpec().workerClassName)
.isEqualTo(ImmediateAlbumSyncWorker.class.getName());
assertThat(workRequest.getWorkSpec().expedited).isTrue();
assertThat(workRequest.getWorkSpec().isPeriodic()).isFalse();
assertThat(workRequest.getWorkSpec().id).isNotNull();
assertThat(workRequest.getWorkSpec().constraints.requiresBatteryNotLow()).isFalse();
- assertThat(workRequest.getWorkSpec().input
- .getInt(SYNC_WORKER_INPUT_SYNC_SOURCE, -1))
+ assertThat(workRequest.getWorkSpec().input.getInt(SYNC_WORKER_INPUT_SYNC_SOURCE, -1))
.isEqualTo(SYNC_CLOUD_ONLY);
}
+ @Test
+ public void testUniqueWorkStatusForPendingWork() {
+ setupPickerSyncManager(/* schedulePeriodicSyncs */ false);
+ final String workName = "testWorkName";
+ final SettableFuture<List<WorkInfo>> future = SettableFuture.create();
+ final List<WorkInfo> futureResult = new ArrayList<>();
+ futureResult.add(getWorkInfo(WorkInfo.State.SUCCEEDED));
+ futureResult.add(getWorkInfo(WorkInfo.State.ENQUEUED));
+ future.set(futureResult);
+ doReturn(future).when(mMockWorkManager)
+ .getWorkInfosForUniqueWork(workName);
+
+ assertThat(mPickerSyncManager.isUniqueWorkPending(workName)).isTrue();
+ }
+
+ @Test
+ public void testUniqueWorkStatusForCompletedWork() {
+ setupPickerSyncManager(/* schedulePeriodicSyncs */ false);
+ final String workName = "testWorkName";
+ final SettableFuture<List<WorkInfo>> future = SettableFuture.create();
+ final List<WorkInfo> futureResult = new ArrayList<>();
+ futureResult.add(getWorkInfo(WorkInfo.State.SUCCEEDED));
+ futureResult.add(getWorkInfo(WorkInfo.State.FAILED));
+ futureResult.add(getWorkInfo(WorkInfo.State.CANCELLED));
+ future.set(futureResult);
+ doReturn(future).when(mMockWorkManager)
+ .getWorkInfosForUniqueWork(workName);
+
+ assertThat(mPickerSyncManager.isUniqueWorkPending(workName)).isFalse();
+ }
+
+ private WorkInfo getWorkInfo(WorkInfo.State state) {
+ return new WorkInfo(UUID.randomUUID(), state, new HashSet<>());
+ }
+
private void setupPickerSyncManager(boolean schedulePeriodicSyncs) {
doReturn(mMockOperation).when(mMockWorkManager)
.enqueueUniquePeriodicWork(anyString(),
@@ -214,9 +385,31 @@ public class PickerSyncManagerTest {
.enqueueUniqueWork(anyString(),
any(ExistingWorkPolicy.class),
any(OneTimeWorkRequest.class));
+ doReturn(mMockWorkContinuation)
+ .when(mMockWorkManager)
+ .beginUniqueWork(
+ anyString(), any(ExistingWorkPolicy.class), any(List.class));
+ // Handle .then chaining
+ doReturn(mMockWorkContinuation)
+ .when(mMockWorkContinuation)
+ .then(any(List.class));
+ doReturn(mMockOperation).when(mMockWorkContinuation).enqueue();
doReturn(mMockFuture).when(mMockOperation).getResult();
mPickerSyncManager =
- new PickerSyncManager(mMockWorkManager, mConfigStore, schedulePeriodicSyncs);
+ new PickerSyncManager(mMockWorkManager, mMockContext,
+ mConfigStore, schedulePeriodicSyncs);
}
+
+ private static void waitForIdle() {
+ final CountDownLatch latch = new CountDownLatch(1);
+ BackgroundThread.getExecutor().execute(latch::countDown);
+ try {
+ latch.await(30, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ throw new IllegalStateException(e);
+ }
+
+ }
+
}
diff --git a/tests/src/com/android/providers/media/photopicker/sync/SyncWorkerTestUtils.java b/tests/src/com/android/providers/media/photopicker/sync/SyncWorkerTestUtils.java
index 24408e104..de621d9f3 100644
--- a/tests/src/com/android/providers/media/photopicker/sync/SyncWorkerTestUtils.java
+++ b/tests/src/com/android/providers/media/photopicker/sync/SyncWorkerTestUtils.java
@@ -19,7 +19,10 @@ package com.android.providers.media.photopicker.sync;
import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_CLOUD_ONLY;
import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_LOCAL_AND_CLOUD;
import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_LOCAL_ONLY;
+import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_RESET_ALBUM;
import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_WORKER_INPUT_ALBUM_ID;
+import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_WORKER_INPUT_AUTHORITY;
+import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_WORKER_INPUT_RESET_TYPE;
import static com.android.providers.media.photopicker.sync.PickerSyncManager.SYNC_WORKER_INPUT_SYNC_SOURCE;
import android.content.Context;
@@ -63,6 +66,19 @@ public class SyncWorkerTestUtils {
}
@NonNull
+ public static Data getAlbumResetInputData(
+ @NonNull String albumId, String authority, boolean isLocal) {
+ Objects.requireNonNull(albumId);
+ Objects.requireNonNull(authority);
+ return new Data(
+ Map.of(
+ SYNC_WORKER_INPUT_AUTHORITY, authority,
+ SYNC_WORKER_INPUT_SYNC_SOURCE, isLocal ? SYNC_LOCAL_ONLY : SYNC_CLOUD_ONLY,
+ SYNC_WORKER_INPUT_RESET_TYPE, SYNC_RESET_ALBUM,
+ SYNC_WORKER_INPUT_ALBUM_ID, albumId));
+ }
+
+ @NonNull
public static Data getCloudAlbumSyncInputData(@NonNull String albumId) {
Objects.requireNonNull(albumId);
return new Data(Map.of(SYNC_WORKER_INPUT_SYNC_SOURCE, SYNC_CLOUD_ONLY,
diff --git a/tests/src/com/android/providers/media/photopicker/util/CloudProviderUtilsTest.java b/tests/src/com/android/providers/media/photopicker/util/CloudProviderUtilsTest.java
new file mode 100644
index 000000000..8649d4d56
--- /dev/null
+++ b/tests/src/com/android/providers/media/photopicker/util/CloudProviderUtilsTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.providers.media.photopicker.util;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import androidx.test.InstrumentationRegistry;
+
+import com.android.providers.media.IsolatedContext;
+import com.android.providers.media.TestConfigStore;
+import com.android.providers.media.cloudproviders.CloudProviderPrimary;
+import com.android.providers.media.cloudproviders.CloudProviderSecondary;
+import com.android.providers.media.cloudproviders.FlakyCloudProvider;
+import com.android.providers.media.photopicker.data.CloudProviderInfo;
+
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Set;
+
+
+public class CloudProviderUtilsTest {
+
+ @Test
+ public void getAllAvailableCloudProvidersTest() {
+ final Context context = InstrumentationRegistry.getTargetContext();
+ final Context isolatedContext =
+ new IsolatedContext(context, "CloudProviderUtilsTest", /*asFuseThread*/ false);
+ final Set<String> testCloudProviders = Set.of(
+ FlakyCloudProvider.AUTHORITY,
+ CloudProviderPrimary.AUTHORITY,
+ CloudProviderSecondary.AUTHORITY);
+ final TestConfigStore configStore = new TestConfigStore();
+ configStore.enableCloudMediaFeatureAndSetAllowedCloudProviderPackages(
+ testCloudProviders.toArray(new String[0]));
+
+ List<CloudProviderInfo> availableProviders =
+ CloudProviderUtils.getAllAvailableCloudProviders(isolatedContext, configStore);
+
+ assertThat(availableProviders.size()).isEqualTo(testCloudProviders.size());
+ for (CloudProviderInfo info : availableProviders) {
+ assertThat(testCloudProviders.contains(info.authority)).isTrue();
+ }
+ }
+}
diff --git a/tests/src/com/android/providers/media/photopicker/viewmodel/BannerControllerTest.java b/tests/src/com/android/providers/media/photopicker/viewmodel/BannerControllerTest.java
index d1f8a5899..05ccbbe4f 100644
--- a/tests/src/com/android/providers/media/photopicker/viewmodel/BannerControllerTest.java
+++ b/tests/src/com/android/providers/media/photopicker/viewmodel/BannerControllerTest.java
@@ -16,19 +16,30 @@
package com.android.providers.media.photopicker.viewmodel;
+import static android.provider.MediaStore.AUTHORITY;
+import static android.provider.MediaStore.getCurrentCloudProvider;
+
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+import static com.android.providers.media.photopicker.util.CloudProviderUtils.persistSelectedProvider;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
import android.content.Context;
+import android.os.RemoteException;
+import androidx.annotation.Nullable;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.providers.media.IsolatedContext;
import com.android.providers.media.TestConfigStore;
+import com.android.providers.media.cloudproviders.FlakyCloudProvider;
import org.junit.Before;
import org.junit.Test;
@@ -36,37 +47,37 @@ import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class BannerControllerTest {
- private BannerController mBannerController;
+ private static final Context sTargetContext = getInstrumentation().getTargetContext();
+ private static final String TEST_PACKAGE_NAME = "com.android.providers.media.tests";
private static final String CMP_AUTHORITY = "authority";
private static final String CMP_ACCOUNT_NAME = "account_name";
- private static final String TAG = "BannerControllerTest";
+
+ private IsolatedContext mIsolatedContext;
+ private ContentResolver mContentResolver;
+ private BannerController mBannerController;
@Before
- public void setUp() {
- final Context context = new IsolatedContext(
- getInstrumentation().getTargetContext(), TAG, /* asFuseThread= */ false);
+ public void setUp() throws RemoteException {
final TestConfigStore configStore = new TestConfigStore();
+ configStore.enableCloudMediaFeatureAndSetAllowedCloudProviderPackages(TEST_PACKAGE_NAME);
- mBannerController = new BannerController(context, context.getUser(), configStore) {
- @Override
- void updateCloudProviderDataFile() {
- // No-op
- }
+ mIsolatedContext = new IsolatedContext(sTargetContext, /* tag= */ "databases",
+ /* asFuseThread= */ false, sTargetContext.getUser(), configStore);
+ mContentResolver = mIsolatedContext.getContentResolver();
- @Override
- boolean areCloudProviderOptionsAvailable() {
- return true;
- }
- };
+ setCloudProvider(/* authority= */ null);
+
+ mBannerController =
+ new BannerController(mIsolatedContext, mIsolatedContext.getUser(), configStore) {
+ @Override
+ void updateCloudProviderDataFile() {
+ // No-op
+ }
+ };
assertNull(mBannerController.getCloudMediaProviderAuthority());
assertNull(mBannerController.getCloudMediaProviderLabel());
assertNull(mBannerController.getCloudMediaProviderAccountName());
-
- assertFalse(mBannerController.shouldShowCloudMediaAvailableBanner());
- assertFalse(mBannerController.shouldShowAccountUpdatedBanner());
- assertFalse(mBannerController.shouldShowChooseAccountBanner());
- assertFalse(mBannerController.shouldShowChooseAppBanner());
}
@Test
@@ -150,4 +161,51 @@ public class BannerControllerTest {
assertFalse(mBannerController.shouldShowChooseAccountBanner());
assertFalse(mBannerController.shouldShowChooseAppBanner());
}
+
+ @Test
+ public void testCloudProviderSlowQueryFallback() throws RemoteException {
+ setCloudProvider(FlakyCloudProvider.AUTHORITY);
+
+ // Test for fast query
+ mIsolatedContext.resetFlakyCloudProviderToNotFlakeInTheNextRequest();
+ mBannerController.onChangeCloudMediaInfo(
+ /* cmpAuthority */ null, /* cmpAccountName */ null);
+ mBannerController.reset();
+
+ assertEquals(FlakyCloudProvider.AUTHORITY,
+ mBannerController.getCloudMediaProviderAuthority());
+ assertEquals(FlakyCloudProvider.ACCOUNT_NAME,
+ mBannerController.getCloudMediaProviderAccountName());
+
+ assertTrue(mBannerController.shouldShowCloudMediaAvailableBanner());
+ assertFalse(mBannerController.shouldShowAccountUpdatedBanner());
+ assertFalse(mBannerController.shouldShowChooseAccountBanner());
+ assertFalse(mBannerController.shouldShowChooseAppBanner());
+
+ // Test for slow query
+ mIsolatedContext.setFlakyCloudProviderToFlakeInTheNextRequest();
+ mBannerController.onChangeCloudMediaInfo(
+ /* cmpAuthority */ null, /* cmpAccountName */ null);
+ mBannerController.reset();
+
+ assertEquals(FlakyCloudProvider.AUTHORITY,
+ mBannerController.getCloudMediaProviderAuthority());
+ assertNull(mBannerController.getCloudMediaProviderAccountName());
+
+ assertFalse(mBannerController.shouldShowCloudMediaAvailableBanner());
+ assertFalse(mBannerController.shouldShowAccountUpdatedBanner());
+ assertFalse(mBannerController.shouldShowChooseAccountBanner());
+ assertFalse(mBannerController.shouldShowChooseAppBanner());
+ }
+
+ private void setCloudProvider(@Nullable String authority) throws RemoteException {
+ final ContentProviderClient client =
+ mContentResolver.acquireContentProviderClient(AUTHORITY);
+ assertNotNull(client);
+
+ persistSelectedProvider(client, authority);
+
+ final String actualAuthority = getCurrentCloudProvider(mContentResolver);
+ assertEquals(authority, actualAuthority);
+ }
}
diff --git a/tests/src/com/android/providers/media/photopicker/viewmodel/PickerViewModelPaginationTest.java b/tests/src/com/android/providers/media/photopicker/viewmodel/PickerViewModelPaginationTest.java
index d9385b455..44b0cb83e 100644
--- a/tests/src/com/android/providers/media/photopicker/viewmodel/PickerViewModelPaginationTest.java
+++ b/tests/src/com/android/providers/media/photopicker/viewmodel/PickerViewModelPaginationTest.java
@@ -58,6 +58,7 @@ import com.android.providers.media.photopicker.data.model.Item;
import com.android.providers.media.photopicker.data.model.UserId;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -134,8 +135,8 @@ public class PickerViewModelPaginationTest {
// Get live data for items, this also loads the first page.
LiveData<PickerViewModel.PaginatedItemsResult> testItems =
mPickerViewModel.getPaginatedItemsForAction(
- ACTION_VIEW_CREATED, new
- PaginationParameters(pageSize, -1, -1));
+ ACTION_VIEW_CREATED, new PaginationParameters(
+ pageSize, /*dateBeforeMs*/ Long.MIN_VALUE, /* rowId*/ -1));
DataLoaderThread.waitForIdle();
// Empty list should be returned.
@@ -169,7 +170,8 @@ public class PickerViewModelPaginationTest {
LiveData<PickerViewModel.PaginatedItemsResult> testItems =
mPickerViewModel.getPaginatedCategoryItemsForAction(
downloadsAlbum, ACTION_VIEW_CREATED,
- new PaginationParameters(pageSize, -1, -1));
+ new PaginationParameters(
+ pageSize, /*dateBeforeMs*/ Long.MIN_VALUE, /* rowId*/ -1));
DataLoaderThread.waitForIdle();
// Empty list should be returned.
@@ -201,8 +203,8 @@ public class PickerViewModelPaginationTest {
// Get live data for items, this also loads the first page.
LiveData<PickerViewModel.PaginatedItemsResult> testItems =
mPickerViewModel.getPaginatedItemsForAction(
- ACTION_VIEW_CREATED, new
- PaginationParameters(pageSize, -1, -1));
+ ACTION_VIEW_CREATED, new PaginationParameters(
+ pageSize, /*dateBeforeMs*/ Long.MIN_VALUE, /* rowId*/ -1));
DataLoaderThread.waitForIdle();
// Page 1: Since the page size is set to 4, only 4 images should be returned.
@@ -237,6 +239,7 @@ public class PickerViewModelPaginationTest {
}
}
+ @Ignore("Enable progress bar and pagination tests after fixing the flaky behaviour b/296520260")
@Test
public void test_differentCategories_getCategoryItems() throws Exception {
int pageSize = 4;
@@ -260,7 +263,8 @@ public class PickerViewModelPaginationTest {
LiveData<PickerViewModel.PaginatedItemsResult> testItems =
mPickerViewModel.getPaginatedCategoryItemsForAction(
cameraAlbum, ACTION_VIEW_CREATED,
- new PaginationParameters(pageSize, -1, -1));
+ new PaginationParameters(
+ pageSize, /*dateBeforeMs*/ Long.MIN_VALUE, /* rowId*/ -1));
DataLoaderThread.waitForIdle();
// Page 1: Since the page size is set to 4, only 4 images should be returned.
@@ -296,7 +300,8 @@ public class PickerViewModelPaginationTest {
LiveData<PickerViewModel.PaginatedItemsResult> testItemsDownloads =
mPickerViewModel.getPaginatedCategoryItemsForAction(
downloadsAlbum, ACTION_VIEW_CREATED,
- new PaginationParameters(pageSize, -1, -1));
+ new PaginationParameters(
+ pageSize, /*dateBeforeMs*/ Long.MIN_VALUE, /* rowId*/ -1));
DataLoaderThread.waitForIdle();
// Page 1: Since the page size is set to 4, only 4 images should be returned.
@@ -349,7 +354,8 @@ public class PickerViewModelPaginationTest {
// Get live data for items, this also loads the first page.
LiveData<PickerViewModel.PaginatedItemsResult> testItems =
mPickerViewModel.getPaginatedItemsForAction(
- ACTION_VIEW_CREATED, new PaginationParameters(pageSize, -1, -1));
+ ACTION_VIEW_CREATED, new PaginationParameters(pageSize,
+ /*dateBeforeMs*/ Long.MIN_VALUE, /* rowId*/ -1));
DataLoaderThread.waitForIdle();
// Page 1: Since the page size is set to 4, only 4 images should be returned.
@@ -392,7 +398,8 @@ public class PickerViewModelPaginationTest {
// loaded.
LiveData<PickerViewModel.PaginatedItemsResult> testItems =
mPickerViewModel.getPaginatedItemsForAction(
- ACTION_VIEW_CREATED, new PaginationParameters(pageSize, -1, -1));
+ ACTION_VIEW_CREATED, new PaginationParameters(pageSize,
+ /*dateBeforeMs*/ Long.MIN_VALUE, /* rowId*/ -1));
DataLoaderThread.waitForIdle();
assertThat(testItems.getValue().getItems().size()).isEqualTo(pageSize);
@@ -409,7 +416,8 @@ public class PickerViewModelPaginationTest {
// Call updateItems which is usually called on profile switch or reset.
// This should clear out the list and load the first page.
mPickerViewModel.getPaginatedItemsForAction(ACTION_REFRESH_ITEMS,
- new PaginationParameters(pageSize, -1, -1));
+ new PaginationParameters(
+ pageSize, /*dateBeforeMs*/ Long.MIN_VALUE, /* rowId*/ -1));
DataLoaderThread.waitForIdle();
// Assert that only one page of items are present now.
diff --git a/tests/src/com/android/providers/media/photopicker/viewmodel/PickerViewModelTest.java b/tests/src/com/android/providers/media/photopicker/viewmodel/PickerViewModelTest.java
index 817e5af19..947154c55 100644
--- a/tests/src/com/android/providers/media/photopicker/viewmodel/PickerViewModelTest.java
+++ b/tests/src/com/android/providers/media/photopicker/viewmodel/PickerViewModelTest.java
@@ -89,6 +89,8 @@ import java.util.concurrent.TimeUnit;
public class PickerViewModelTest {
private static final String FAKE_CATEGORY_NAME = "testCategoryName";
private static final String FAKE_ID = "5";
+ private static final String FAKE_CLOUD_MEDIA_PROVIDER_PACKAGE_NAME =
+ "com.hooli.super.awesome.cloud.provider";
private static final Context sTargetContext = getInstrumentation().getTargetContext();
@Rule
@@ -111,6 +113,8 @@ public class PickerViewModelTest {
when(mApplication.getApplicationContext()).thenReturn(sTargetContext);
mConfigStore = new TestConfigStore();
mConfigStore.enableCloudMediaFeature();
+ mConfigStore.setAllowedCloudProviderPackages(
+ new String[]{FAKE_CLOUD_MEDIA_PROVIDER_PACKAGE_NAME});
getInstrumentation().runOnMainSync(() -> {
mPickerViewModel = new PickerViewModel(mApplication) {
@Override
diff --git a/tests/src/com/android/providers/media/stableuris/dao/BackupIdRowTest.java b/tests/src/com/android/providers/media/stableuris/dao/BackupIdRowTest.java
index bfadf87af..f0087355b 100644
--- a/tests/src/com/android/providers/media/stableuris/dao/BackupIdRowTest.java
+++ b/tests/src/com/android/providers/media/stableuris/dao/BackupIdRowTest.java
@@ -44,8 +44,9 @@ public class BackupIdRowTest {
.setIsTrashed(0)
.setOwnerPackagedId(1)
.setUserId(1)
- .setDateExpires("10")
+ .setDateExpires(null)
.setIsDirty(true)
+ .setMediaType(1)
.build();
String s = BackupIdRow.serialize(row);
@@ -59,6 +60,7 @@ public class BackupIdRowTest {
.setUserId(1)
.setDateExpires("10")
.setIsDirty(false)
+ .setMediaType(0)
.build();
assertThat(BackupIdRow.deserialize(s)).isNotEqualTo(row2);