diff options
| author | Xin Li <delphij@google.com> | 2021-10-06 22:53:54 +0000 |
|---|---|---|
| committer | Xin Li <delphij@google.com> | 2021-10-06 22:53:54 +0000 |
| commit | 8c348c41a50cb3fe83e9d2403cc34db5d5ddcb70 (patch) | |
| tree | 2ba30a68b1e5a2246c7e071219139cea61cab0e6 | |
| parent | 4bc189377da5f3cb27fb439d677cb89f3390a7a6 (diff) | |
| parent | 84af7ecf6ae45a2ab3aba9b0019baa191b430af5 (diff) | |
| download | platform_packages_apps_DocumentsUI-master.tar.gz platform_packages_apps_DocumentsUI-master.tar.bz2 platform_packages_apps_DocumentsUI-master.zip | |
Bug: 202323961
Merged-In: I64e7be8bd815a3f3bf84277ffb9ea801a5dceb24
Change-Id: Ib2ecaa196b974cec584f6ae5c1e8b4092818d73a
210 files changed, 1795 insertions, 716 deletions
diff --git a/Android.bp b/Android.bp index fde741ac3..a1e4f0d77 100644 --- a/Android.bp +++ b/Android.bp @@ -56,6 +56,7 @@ java_defaults { }, sdk_version: "system_current", + target_sdk_version: "30", min_sdk_version: "29", plugins: [ @@ -110,6 +111,7 @@ android_library { ], sdk_version: "system_current", + target_sdk_version: "30", min_sdk_version: "29", } @@ -137,6 +139,7 @@ android_library { ], sdk_version: "system_current", + target_sdk_version: "30", min_sdk_version: "29", } @@ -162,5 +165,6 @@ android_app { required: ["privapp_whitelist_com.android.documentsui"], + target_sdk_version: "30", min_sdk_version: "29", } diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 6fa0971cc..8b86febcf 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -19,7 +19,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.documentsui"> - <uses-sdk android:minSdkVersion="29" /> + <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="30"/> <uses-permission android:name="android.permission.MANAGE_DOCUMENTS" /> <uses-permission android:name="android.permission.REMOVE_TASKS" /> @@ -36,6 +36,8 @@ <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE"/> <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"/> + <uses-permission android:name="android.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND"/> + <application android:name=".DocumentsApplication" android:label="@string/app_label" diff --git a/app-perf-tests/Android.bp b/app-perf-tests/Android.bp index 95ed43a9f..f753ac5b5 100644 --- a/app-perf-tests/Android.bp +++ b/app-perf-tests/Android.bp @@ -18,12 +18,15 @@ android_test { static_libs: [ "androidx.legacy_legacy-support-v4", + "collector-device-lib", "mockito-target", "ub-uiautomator", ], platform_apis: true, + data: [":perfetto_artifacts"], + instrumentation_for: "DocumentsUI", certificate: "platform", diff --git a/app-perf-tests/AndroidManifest.xml b/app-perf-tests/AndroidManifest.xml index 0013b6b7b..0ed5e4540 100644 --- a/app-perf-tests/AndroidManifest.xml +++ b/app-perf-tests/AndroidManifest.xml @@ -13,7 +13,7 @@ <!-- This package instrumentates itself, so the DocumentsUI process can be killed without killing the testing package. --> - <instrumentation android:name="android.test.InstrumentationTestRunner" + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" android:targetPackage="com.android.documentsui.appperftests" android:label="App performance tests for DocumentsUI" /> diff --git a/app-perf-tests/AndroidTest.xml b/app-perf-tests/AndroidTest.xml index c8dd9a105..a55322673 100644 --- a/app-perf-tests/AndroidTest.xml +++ b/app-perf-tests/AndroidTest.xml @@ -22,7 +22,7 @@ </target_preparer> <test class="com.android.tradefed.testtype.AndroidJUnitTest" > - <option name="runner" value="android.test.InstrumentationTestRunner" /> + <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> <option name="package" value="com.android.documentsui.appperftests" /> </test> </configuration> diff --git a/app-perf-tests/src/com/android/documentsui/FilesAppPerfTest.java b/app-perf-tests/src/com/android/documentsui/FilesAppPerfTest.java index d39b49cb9..be8fd9852 100644 --- a/app-perf-tests/src/com/android/documentsui/FilesAppPerfTest.java +++ b/app-perf-tests/src/com/android/documentsui/FilesAppPerfTest.java @@ -28,12 +28,19 @@ import android.support.test.uiautomator.UiDevice; import android.test.InstrumentationTestCase; import android.test.suitebuilder.annotation.LargeTest; +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + import java.util.Arrays; import java.util.List; import java.util.concurrent.CountDownLatch; -@LargeTest -public class FilesAppPerfTest extends InstrumentationTestCase { +@RunWith(AndroidJUnit4.class) +public class FilesAppPerfTest { // Keys used to report metrics to APCT. private static final String KEY_FILES_COLD_START_PERFORMANCE_MEDIAN = @@ -46,17 +53,19 @@ public class FilesAppPerfTest extends InstrumentationTestCase { private static final int NUM_MEASUREMENTS = 10; private LauncherActivity mActivity; - private UiDevice mDevice; + private static UiDevice mDevice; - @Override - public void setUp() { - mDevice = UiDevice.getInstance(getInstrumentation()); + @BeforeClass + public static void setUp() { + mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); } + @Test public void testFilesColdStartPerformance() throws Exception { runFilesStartPerformanceTest(true); } + @Test public void testFilesWarmStartPerformance() throws Exception { runFilesStartPerformanceTest(false); } @@ -72,7 +81,9 @@ public class FilesAppPerfTest extends InstrumentationTestCase { mDevice.waitForIdle(); LauncherActivity.testCaseLatch = new CountDownLatch(1); - mActivity = launchActivity(getInstrumentation().getTargetContext().getPackageName(), + mActivity = launchActivity( + InstrumentationRegistry.getInstrumentation().getTargetContext() + .getPackageName(), LauncherActivity.class, null); LauncherActivity.testCaseLatch.await(); measurements[i] = LauncherActivity.measurement; @@ -88,11 +99,11 @@ public class FilesAppPerfTest extends InstrumentationTestCase { final long median = measurements[NUM_MEASUREMENTS / 2 - 1]; status.putDouble(key, median); - getInstrumentation().sendStatus(Activity.RESULT_OK, status); + InstrumentationRegistry.getInstrumentation().sendStatus(Activity.RESULT_OK, status); } private void killProviders() throws Exception { - final Context context = getInstrumentation().getContext(); + final Context context = InstrumentationRegistry.getInstrumentation().getContext(); final PackageManager pm = context.getPackageManager(); final ActivityManager am = (ActivityManager) context.getSystemService( Context.ACTIVITY_SERVICE); @@ -103,4 +114,26 @@ public class FilesAppPerfTest extends InstrumentationTestCase { am.killBackgroundProcesses(packageName); } } + + private final <T extends Activity> T launchActivity( + String pkg, + Class<T> activityCls, + Bundle extras) { + Intent intent = new Intent(Intent.ACTION_MAIN); + if (extras != null) { + intent.putExtras(extras); + } + return launchActivityWithIntent(pkg, activityCls, intent); + } + + private final <T extends Activity> T launchActivityWithIntent( + String pkg, + Class<T> activityCls, + Intent intent) { + intent.setClassName(pkg, activityCls.getName()); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + T activity = (T) InstrumentationRegistry.getInstrumentation().startActivitySync(intent); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); + return activity; + } } diff --git a/proguard.flags b/proguard.flags index 1d253261b..a9483308c 100644 --- a/proguard.flags +++ b/proguard.flags @@ -17,6 +17,11 @@ public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat obtain(); } +# This method is marked @hide in DocumentsProvider but we need to implement it for managed mode. +-keep public class com.android.documentsui.archives.ArchivesProvider { + public android.database.Cursor queryChildDocumentsForManage(java.lang.String, java.lang.String[], java.lang.String); +} + # To prevent class not found exception in org.brotli.dec.Dictionary -keep final class org.brotli.dec.DictionaryData diff --git a/res/color/horizontal_breadcrumb_color.xml b/res/color/horizontal_breadcrumb_color.xml new file mode 100644 index 000000000..d5a852c0a --- /dev/null +++ b/res/color/horizontal_breadcrumb_color.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2016 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_enabled="true" + android:color="?android:colorAccent" /> + <item android:color="?android:attr/colorControlNormal" /> +</selector> diff --git a/res/color/item_doc_grid_border.xml b/res/color/item_doc_grid_border.xml index b535aedc3..592d07634 100644 --- a/res/color/item_doc_grid_border.xml +++ b/res/color/item_doc_grid_border.xml @@ -18,10 +18,10 @@ <item android:state_focused="true" android:state_selected="false" - android:color="?android:attr/colorPrimary"/> + android:color="?android:attr/colorAccent"/> <item android:state_selected="true" - android:color="?android:attr/colorPrimary"/> + android:color="?android:attr/colorAccent"/> <item android:color="@android:color/transparent"/> </selector> diff --git a/res/color/item_doc_grid_tint.xml b/res/color/item_doc_grid_tint.xml index 2c48e9658..878afb175 100644 --- a/res/color/item_doc_grid_tint.xml +++ b/res/color/item_doc_grid_tint.xml @@ -17,7 +17,7 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_activated="true" - android:color="?android:colorPrimary" + android:color="?android:colorAccent" android:alpha=".15" /> <item android:color="@android:color/transparent" /> diff --git a/res/color/item_root_secondary_text.xml b/res/color/item_root_secondary_text.xml index 44086ef88..632135ce8 100644 --- a/res/color/item_root_secondary_text.xml +++ b/res/color/item_root_secondary_text.xml @@ -16,8 +16,10 @@ --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_focused="true" android:state_activated="true" android:color="?android:colorPrimary" /> - <item android:state_focused="false" android:state_activated="true" android:color="?android:colorPrimary" /> + <item android:state_focused="true" android:state_activated="true" + android:color="?android:colorControlActivated" /> + <item android:state_focused="false" android:state_activated="true" + android:color="?android:colorControlActivated" /> <item android:state_enabled="false" android:alpha="0.5" android:color="?android:textColorSecondary" /> <item android:color="?android:textColorSecondary" /> </selector> diff --git a/res/color/search_chip_ripple_color.xml b/res/color/search_chip_ripple_color.xml index 985b6cc7d..0f78a0722 100644 --- a/res/color/search_chip_ripple_color.xml +++ b/res/color/search_chip_ripple_color.xml @@ -18,15 +18,15 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Selected. --> <item android:state_pressed="true" android:state_selected="true" - android:alpha="0.16" android:color="?android:colorPrimary"/> + android:alpha="0.16" android:color="?android:colorSecondary"/> <item android:state_focused="true" android:state_hovered="true" android:state_selected="true" - android:alpha="0.16" android:color="?android:colorPrimary"/> + android:alpha="0.16" android:color="?android:colorSecondary"/> <item android:state_focused="true" android:state_selected="true" - android:alpha="0.12" android:color="?android:colorPrimary"/> + android:alpha="0.12" android:color="?android:colorSecondary"/> <item android:state_hovered="true" android:state_selected="true" - android:alpha="0.04" android:color="?android:colorPrimary"/> + android:alpha="0.04" android:color="?android:colorSecondary"/> <item android:state_selected="true" - android:alpha="0.00" android:color="?android:colorPrimary"/> + android:alpha="0.00" android:color="?android:colorSecondary"/> <!-- Unselected. --> <item android:state_pressed="true" android:alpha="0.16" android:color="?android:textColorSecondary"/> diff --git a/res/color/search_chip_text_color.xml b/res/color/search_chip_text_color.xml index 0457ba25a..262bede41 100644 --- a/res/color/search_chip_text_color.xml +++ b/res/color/search_chip_text_color.xml @@ -16,7 +16,7 @@ --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_selected="true" android:color="?android:colorPrimary"/> + <item android:state_selected="true" android:color="?android:colorControlActivated"/> <item android:state_enabled="true" android:color="?android:textColorSecondary"/> <item android:state_enabled="false" android:color="?android:textColorSecondary" android:alpha="0.3"/> </selector>
\ No newline at end of file diff --git a/res/color/sort_list_text.xml b/res/color/sort_list_text.xml index 16f16a24d..cbe8da6fe 100644 --- a/res/color/sort_list_text.xml +++ b/res/color/sort_list_text.xml @@ -16,7 +16,7 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_checked="true" - android:color="?android:attr/colorPrimary"/> + android:color="?android:attr/colorAccent"/> <item android:color="?android:attr/textColorPrimary"/> </selector>
\ No newline at end of file diff --git a/res/drawable/ic_briefcase.xml b/res/drawable/ic_briefcase.xml index cf979ac1c..64efd18d9 100644 --- a/res/drawable/ic_briefcase.xml +++ b/res/drawable/ic_briefcase.xml @@ -20,6 +20,6 @@ android:viewportWidth="24" android:viewportHeight="24"> <path - android:fillColor="@color/briefcase_icon_color" + android:fillColor="?android:attr/colorAccent" android:pathData="M20,6h-4L16,4c0,-1.11 -0.89,-2 -2,-2h-4c-1.11,0 -2,0.89 -2,2v2L4,6c-1.11,0 -1.99,0.89 -1.99,2L2,19c0,1.11 0.89,2 2,2h16c1.11,0 2,-0.89 2,-2L22,8c0,-1.11 -0.89,-2 -2,-2zM12,15c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2zM14,6h-4L10,4h4v2z"/> </vector> diff --git a/res/drawable/ic_check.xml b/res/drawable/ic_check.xml index a6df08a93..2f02c9a6c 100644 --- a/res/drawable/ic_check.xml +++ b/res/drawable/ic_check.xml @@ -18,7 +18,7 @@ Copyright (C) 2018 The Android Open Source Project android:height="24dp" android:viewportWidth="24.0" android:viewportHeight="24.0" - android:tint="?android:attr/colorPrimary"> + android:tint="?android:colorControlActivated"> <path android:fillColor="@android:color/white" android:pathData="vM9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/> diff --git a/res/drawable/ic_check_circle.xml b/res/drawable/ic_check_circle.xml index 13b45bd8e..62a4e34b4 100644 --- a/res/drawable/ic_check_circle.xml +++ b/res/drawable/ic_check_circle.xml @@ -19,6 +19,6 @@ Copyright (C) 2016 The Android Open Source Project android:viewportWidth="24.0" android:viewportHeight="24.0"> <path - android:fillColor="?android:attr/colorPrimary" + android:fillColor="?android:attr/colorAccent" android:pathData="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10,-4.48 10,-10S17.52 2 12 2zm-2 15l-5,-5 1.41,-1.41L10 14.17l7.59,-7.59L19 8l-9 9z"/> </vector> diff --git a/res/drawable/ic_dialog_info.xml b/res/drawable/ic_dialog_info.xml index 2e2447b69..968bb67dd 100644 --- a/res/drawable/ic_dialog_info.xml +++ b/res/drawable/ic_dialog_info.xml @@ -19,7 +19,7 @@ android:height="24dp" android:viewportWidth="24.0" android:viewportHeight="24.0" - android:tint="?android:attr/colorPrimary"> + android:tint="?android:attr/colorAccent"> <path android:fillColor="?android:attr/colorBackground" android:pathData="M11 15h2v2h-2v-2zm0-8h2v6h-2V7zm0.99-5C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z" /> diff --git a/res/drawable/ic_done.xml b/res/drawable/ic_done.xml index f8f66b692..299bd177f 100644 --- a/res/drawable/ic_done.xml +++ b/res/drawable/ic_done.xml @@ -19,6 +19,6 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> <path - android:fillColor="?android:colorPrimary" + android:fillColor="?android:colorAccent" android:pathData="M9,16.2L4.8,12l-1.4,1.4L9,19 21,7l-1.4,-1.4L9,16.2z"/> </vector> diff --git a/res/drawable/launcher_screen.xml b/res/drawable/launcher_screen.xml index 485160615..c0d814632 100644 --- a/res/drawable/launcher_screen.xml +++ b/res/drawable/launcher_screen.xml @@ -3,7 +3,7 @@ <item android:drawable="@android:color/white"/> <item - android:drawable="@drawable/app_icon" + android:drawable="@drawable/splash_screen" android:height="150dp" android:width="150dp" android:gravity="center"/> diff --git a/res/drawable/launcher_screen_night.xml b/res/drawable/launcher_screen_night.xml index 8a9ffd3a6..983c4977d 100644 --- a/res/drawable/launcher_screen_night.xml +++ b/res/drawable/launcher_screen_night.xml @@ -3,7 +3,7 @@ <item android:drawable="@color/app_background_color"/> <item - android:drawable="@drawable/app_icon" + android:drawable="@drawable/splash_screen" android:height="150dp" android:width="150dp" android:gravity="center"/> diff --git a/res/drawable/list_divider.xml b/res/drawable/list_divider.xml index 5768aff8a..5067af08e 100644 --- a/res/drawable/list_divider.xml +++ b/res/drawable/list_divider.xml @@ -16,7 +16,7 @@ <shape xmlns:android="http://schemas.android.com/apk/res/android" android:tint="?android:attr/colorForeground"> - <solid android:color="#1f000000" /> + <solid android:color="@color/list_divider_color" /> <size android:height="1dp" android:width="1dp" /> diff --git a/res/drawable/list_item_background.xml b/res/drawable/list_item_background.xml index afbeecd27..a73ae2e2a 100644 --- a/res/drawable/list_item_background.xml +++ b/res/drawable/list_item_background.xml @@ -16,16 +16,16 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_focused="true" > - <color android:color="?android:colorSecondary"/> + <color android:color="@color/list_item_selected_background_color"/> </item> <item android:state_selected="true"> - <color android:color="?android:colorSecondary"/> + <color android:color="@color/list_item_selected_background_color"/> </item> <item android:state_drag_hovered="true"> <color android:color="?android:strokeColor"/> </item> <item android:state_selected="false" android:state_focused="false"> - <color android:color="@color/app_background_color"/> + <color android:color="?android:attr/colorBackground"/> </item> </selector>
\ No newline at end of file diff --git a/res/drawable/splash_screen.xml b/res/drawable/splash_screen.xml new file mode 100644 index 000000000..3f0c48b6b --- /dev/null +++ b/res/drawable/splash_screen.xml @@ -0,0 +1,64 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:aapt="http://schemas.android.com/aapt" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:pathData="M12,12m-11,0a11,11 0,1 1,22 0a11,11 0,1 1,-22 0" + android:fillColor="#4285F4"/> + <path + android:pathData="M23,12c0,6.1 -4.9,11 -11,11S1,18.1 1,12c0,0 0,0 0,-0.1c0,6 4.9,10.9 11,10.9S23,18 23,12C23,12 23,12 23,12z" + android:strokeAlpha="0.2" + android:fillColor="#263238" + android:fillAlpha="0.2"/> + <path + android:pathData="M23,12C23,12 23,12 23,12c0,-6 -4.9,-10.9 -11,-10.9S1,6 1,12.1c0,0 0,0 0,-0.1C1,5.9 5.9,1 12,1S23,5.9 23,12z" + android:strokeAlpha="0.2" + android:fillColor="#FFFFFF" + android:fillAlpha="0.2"/> + <path + android:pathData="M22.8,14.2c-1,4.8 -5,8.4 -9.9,8.8l-6.4,-6.4L17.6,9C17.6,9 22.8,14.2 22.8,14.2z" + android:fillColor="#4285F4"/> + <path + android:pathData="M22.8,14.2c-1,4.8 -5,8.4 -9.9,8.8l-6.4,-6.4L17.6,9C17.6,9 22.8,14.2 22.8,14.2z"> + <aapt:attr name="android:fillColor"> + <gradient + android:startY="12.203438" + android:startX="11.452812" + android:endY="20.219812" + android:endX="19.469187" + android:type="linear"> + <item android:offset="0" android:color="#33263238"/> + <item android:offset="1" android:color="#05263238"/> + </gradient> + </aapt:attr> + </path> + <path + android:pathData="M16.5,8.5H12L10.8,7H7.5C6.7,7 6,7.7 6,8.5v7C6,16.3 6.7,17 7.5,17h9c0.8,0 1.5,-0.7 1.5,-1.5V10C18,9.2 17.3,8.5 16.5,8.5z" + android:fillColor="#F5F5F5"/> + <path + android:pathData="M18,10v0.1c0,-0.8 -0.7,-1.5 -1.5,-1.5H12l-1.2,-1.5H7.5C6.7,7.1 6,7.8 6,8.6V8.5C6,7.7 6.7,7 7.5,7h3.2L12,8.5h4.5C17.3,8.5 18,9.2 18,10z" + android:strokeAlpha="0.4" + android:fillColor="#FFFFFF" + android:fillAlpha="0.4"/> + <path + android:pathData="M18,15.5v0.1c0,0.8 -0.7,1.5 -1.5,1.5h-9c-0.8,0 -1.5,-0.7 -1.5,-1.5v-0.1C6,16.3 6.7,17 7.5,17h9C17.3,17 18,16.3 18,15.5z" + android:strokeAlpha="0.2" + android:fillColor="#263238" + android:fillAlpha="0.2"/> + <path + android:pathData="M12,12m-11,0a11,11 0,1 1,22 0a11,11 0,1 1,-22 0" + android:fillAlpha="0.1"> + <aapt:attr name="android:fillColor"> + <gradient + android:gradientRadius="22.333876" + android:centerX="3.238875" + android:centerY="5.0445" + android:type="radial"> + <item android:offset="0" android:color="#FFFFFFFF"/> + <item android:offset="1" android:color="#00FFFFFF"/> + </gradient> + </aapt:attr> + </path> +</vector> diff --git a/res/layout-sw720dp/item_doc_list.xml b/res/layout-sw720dp/item_doc_list.xml index c19e69750..cf74909e9 100644 --- a/res/layout-sw720dp/item_doc_list.xml +++ b/res/layout-sw720dp/item_doc_list.xml @@ -16,9 +16,12 @@ --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="?android:attr/selectableItemBackground" + android:background="@drawable/list_item_background" + android:foreground="?android:attr/selectableItemBackground" + android:clickable="true" android:focusable="true" android:orientation="horizontal" > @@ -40,31 +43,39 @@ android:paddingEnd="16dp" android:paddingStart="@dimen/list_item_padding" > - <ImageView - android:id="@+id/icon_mime" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:contentDescription="@null" - android:scaleType="centerInside" /> - - <ImageView - android:id="@+id/icon_thumb" + <com.google.android.material.card.MaterialCardView + app:cardElevation="0dp" + app:cardBackgroundColor="@android:color/transparent" android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_gravity="center" - android:contentDescription="@null" - android:scaleType="centerCrop" /> - - <ImageView - android:id="@+id/icon_check" - android:layout_width="@dimen/check_icon_size" - android:layout_height="@dimen/check_icon_size" - android:layout_gravity="center" - android:alpha="0" - android:contentDescription="@null" - android:scaleType="fitCenter" - android:src="@drawable/ic_check_circle" /> + android:layout_height="match_parent"> + + <ImageView + android:id="@+id/icon_mime" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:contentDescription="@null" + android:scaleType="centerInside" /> + + <ImageView + android:id="@+id/icon_thumb" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_gravity="center" + android:contentDescription="@null" + android:scaleType="centerCrop" /> + + <ImageView + android:id="@+id/icon_check" + android:layout_width="@dimen/check_icon_size" + android:layout_height="@dimen/check_icon_size" + android:layout_gravity="center" + android:alpha="0" + android:contentDescription="@null" + android:scaleType="fitCenter" + android:src="@drawable/ic_check_circle" /> + + </com.google.android.material.card.MaterialCardView> </FrameLayout> @@ -99,7 +110,7 @@ android:ellipsize="middle" android:singleLine="true" android:textAlignment="viewStart" - android:textAppearance="@android:style/TextAppearance.Material.Subhead" + android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead" android:textColor="?android:attr/textColorPrimary"/> </LinearLayout> @@ -112,7 +123,7 @@ android:ellipsize="end" android:singleLine="true" android:textAlignment="viewStart" - android:textAppearance="@android:style/TextAppearance.Material.Body1" + android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1" android:textColor="?android:attr/textColorSecondary" /> <TextView @@ -125,7 +136,7 @@ android:minWidth="70dp" android:singleLine="true" android:textAlignment="viewEnd" - android:textAppearance="@android:style/TextAppearance.Material.Body1" + android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1" android:textColor="?android:attr/textColorSecondary" /> <TextView @@ -138,7 +149,7 @@ android:minWidth="70dp" android:singleLine="true" android:textAlignment="viewEnd" - android:textAppearance="@android:style/TextAppearance.Material.Body1" + android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1" android:textColor="?android:attr/textColorSecondary" /> </LinearLayout> diff --git a/res/layout-sw720dp/shared_cell_content.xml b/res/layout-sw720dp/shared_cell_content.xml index 2a811f94e..dc37f2cfe 100644 --- a/res/layout-sw720dp/shared_cell_content.xml +++ b/res/layout-sw720dp/shared_cell_content.xml @@ -23,7 +23,7 @@ android:ellipsize="end" android:singleLine="true" android:textAlignment="viewStart" - android:textAppearance="@style/android:TextAppearance.Material.Subhead" + android:textAppearance="@*style/android:TextAppearance.DeviceDefault.Subhead" android:textColor="?android:attr/textColorSecondary"/> <ImageView diff --git a/res/layout/dialog_delete_confirmation.xml b/res/layout/dialog_delete_confirmation.xml index 501736cec..d5b133ee8 100644 --- a/res/layout/dialog_delete_confirmation.xml +++ b/res/layout/dialog_delete_confirmation.xml @@ -21,5 +21,5 @@ android:paddingTop="24dp" android:paddingStart="24dp" android:paddingEnd="24dp" - android:textAppearance="@android:style/TextAppearance.Material.Subhead"> + android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"> </TextView> diff --git a/res/layout/dialog_file_name.xml b/res/layout/dialog_file_name.xml index 0ebd936d0..7f2a9592b 100644 --- a/res/layout/dialog_file_name.xml +++ b/res/layout/dialog_file_name.xml @@ -35,6 +35,7 @@ android:id="@android:id/text1" android:layout_width="match_parent" android:layout_height="wrap_content" + android:maxLength="255" android:inputType="textCapSentences"/> </com.google.android.material.textfield.TextInputLayout> diff --git a/res/layout/directory_app_bar.xml b/res/layout/directory_app_bar.xml index 3225ce599..ad80ec201 100644 --- a/res/layout/directory_app_bar.xml +++ b/res/layout/directory_app_bar.xml @@ -34,17 +34,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> - <include layout="@layout/directory_header"/> + <include layout="@layout/directory_header" /> </androidx.core.widget.NestedScrollView> - <View - android:id="@+id/toolbar_background_layout" - android:layout_width="match_parent" - android:layout_height="@dimen/action_bar_space_height" - android:background="?android:attr/colorBackground" - app:layout_collapseMode="pin"/> - <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" @@ -53,7 +46,7 @@ android:background="?android:attr/colorBackground" android:theme="?actionBarTheme" android:popupTheme="?actionBarPopupTheme" - android:elevation="3dp" + android:elevation="@dimen/search_bar_elevation" app:collapseContentDescription="@string/button_back" app:titleTextAppearance="@style/ToolbarTitle" app:layout_collapseMode="pin"> @@ -64,7 +57,7 @@ android:layout_height="?android:attr/actionBarSize" android:gravity="center_vertical" android:text="@string/search_bar_hint" - android:textAppearance="@style/SearchBarTitle"/> + android:textAppearance="@style/SearchBarTitle" /> </androidx.appcompat.widget.Toolbar> diff --git a/res/layout/directory_header.xml b/res/layout/directory_header.xml index 94c52e978..791af999e 100644 --- a/res/layout/directory_header.xml +++ b/res/layout/directory_header.xml @@ -18,7 +18,6 @@ android:id="@+id/directory_header" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="@dimen/action_bar_space_margin" android:orientation="vertical"> <com.android.documentsui.HorizontalBreadcrumb @@ -47,8 +46,8 @@ app:tabMaxWidth="0dp" app:tabGravity="fill" app:tabMode="fixed" - app:tabIndicatorColor="@color/tab_indicator_color" - app:tabSelectedTextColor="@color/tab_indicator_color" + app:tabIndicatorColor="?android:attr/colorAccent" + app:tabSelectedTextColor="?android:attr/colorAccent" app:tabTextAppearance="@style/TabTextAppearance" app:tabTextColor="?android:attr/textColorSecondary"/> @@ -73,8 +72,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" - android:textAppearance="@style/SortTitle" - android:textAllCaps="true" + android:textAppearance="@style/SectionHeader" android:maxLines="1" android:ellipsize="end" android:gravity="start|center_vertical"/> diff --git a/res/layout/drag_shadow_layout.xml b/res/layout/drag_shadow_layout.xml index f42474254..75bd0ca28 100644 --- a/res/layout/drag_shadow_layout.xml +++ b/res/layout/drag_shadow_layout.xml @@ -40,7 +40,7 @@ android:maxLines="1" android:ellipsize="end" android:textAlignment="viewStart" - android:textAppearance="@android:style/TextAppearance.Material.Subhead" + android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead" android:paddingStart="6dp" android:paddingBottom="1dp"/> diff --git a/res/layout/drawer_layout.xml b/res/layout/drawer_layout.xml index 0b2a81d72..d08c17d9f 100644 --- a/res/layout/drawer_layout.xml +++ b/res/layout/drawer_layout.xml @@ -38,19 +38,12 @@ android:layout_height="match_parent" app:layout_behavior="@string/scrolling_behavior"> - <LinearLayout + <FrameLayout + android:id="@+id/container_directory" + android:clipToPadding="false" android:layout_width="match_parent" android:layout_height="match_parent" - android:orientation="vertical"> - - <FrameLayout - android:id="@+id/container_directory" - android:clipToPadding="false" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_weight="1" /> - - </LinearLayout> + android:layout_weight="1" /> <FrameLayout android:id="@+id/container_search_fragment" @@ -58,8 +51,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" /> - <!-- Drawer edge is a dummy view used to capture hovering event - on view edge to open the drawer. (b/28345294) --> + <!-- Drawer edge is a placeholder view used to capture hovering + event on view edge to open the drawer. (b/28345294) --> <View android:id="@+id/drawer_edge" android:background="@android:color/transparent" @@ -95,7 +88,7 @@ android:background="?android:attr/colorBackground" android:elevation="0dp" app:titleTextAppearance="@style/DrawerMenuTitle" - app:titleTextColor="?android:colorPrimary"/> + app:titleTextColor="?android:colorAccent"/> <FrameLayout android:id="@+id/container_roots" diff --git a/res/layout/fragment_directory.xml b/res/layout/fragment_directory.xml index dda841205..015039a6a 100644 --- a/res/layout/fragment_directory.xml +++ b/res/layout/fragment_directory.xml @@ -49,7 +49,6 @@ android:clipToPadding="false" android:scrollbars="none" android:drawSelectorOnTop="true" - android:overScrollMode="never" app:fastScrollEnabled="false"/> </com.android.documentsui.dirlist.DocumentsSwipeRefreshLayout> diff --git a/res/layout/fragment_pick.xml b/res/layout/fragment_pick.xml index 5522c5a81..88c28bdbc 100644 --- a/res/layout/fragment_pick.xml +++ b/res/layout/fragment_pick.xml @@ -1,5 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2014 The Android Open Source Project +<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2014 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -30,7 +29,7 @@ android:layout_height="wrap_content" android:layout_marginStart="4dp" android:layout_marginEnd="4dp" - android:text="@android:string/cancel"/> + android:text="@android:string/cancel" /> <FrameLayout android:layout_width="match_parent" @@ -42,13 +41,14 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="4dp" - android:layout_marginEnd="4dp"/> + android:layout_marginEnd="4dp" /> <!-- Handles touch events when button1 is disabled. --> <FrameLayout android:id="@+id/pick_button_overlay" + android:importantForAccessibility="no" android:layout_width="match_parent" - android:layout_height="match_parent"/> + android:layout_height="match_parent" /> </FrameLayout> diff --git a/res/layout/inspector_activity.xml b/res/layout/inspector_activity.xml index df28d4968..8763351c9 100644 --- a/res/layout/inspector_activity.xml +++ b/res/layout/inspector_activity.xml @@ -68,7 +68,6 @@ android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" - android:overScrollMode="never" app:behavior_overlapTop="10dp" app:layout_behavior="@string/appbar_scrolling_view_behavior"> diff --git a/res/layout/item_dir_grid.xml b/res/layout/item_dir_grid.xml index 269dd0782..8720c37cf 100644 --- a/res/layout/item_dir_grid.xml +++ b/res/layout/item_dir_grid.xml @@ -21,19 +21,21 @@ to focus and selection states, some of which are specific to keyboard when touch mode is not enable. So, if you, heroic engineer of the future, decide to rip these out, please be sure to check out focus and keyboards. --> -<FrameLayout +<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/item_root" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_margin="2dp" - android:focusable="true"> + android:layout_margin="4dp" + android:foreground="?android:attr/selectableItemBackground" + android:clickable="true" + android:focusable="true" + app:cardElevation="0dp"> <com.google.android.material.card.MaterialCardView android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_margin="2dp" android:elevation="0dp" android:duplicateParentState="true" app:cardElevation="0dp" @@ -106,9 +108,8 @@ <View android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_margin="1dp" android:background="@drawable/item_doc_grid_border_rounded" android:contentDescription="@null" android:duplicateParentState="true"/> -</FrameLayout>
\ No newline at end of file +</com.google.android.material.card.MaterialCardView>
\ No newline at end of file diff --git a/res/layout/item_doc_grid.xml b/res/layout/item_doc_grid.xml index 0722a9d16..5e2e93842 100644 --- a/res/layout/item_doc_grid.xml +++ b/res/layout/item_doc_grid.xml @@ -20,19 +20,21 @@ to focus and selection states, some of which are specific to keyboard when touch mode is not enable. So, if you, heroic engineer of the future, decide to rip these out, please be sure to check out focus and keyboards. --> -<FrameLayout +<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/item_root" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_margin="2dp" - android:focusable="true"> + android:layout_margin="4dp" + android:foreground="?android:attr/selectableItemBackground" + android:clickable="true" + android:focusable="true" + app:cardElevation="0dp"> <com.google.android.material.card.MaterialCardView android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_margin="2dp" android:elevation="0dp" android:duplicateParentState="true" app:cardElevation="0dp" @@ -50,6 +52,7 @@ <FrameLayout android:id="@+id/thumbnail" + android:background="?attr/gridItemTint" android:layout_width="match_parent" android:layout_height="wrap_content"> @@ -173,7 +176,7 @@ android:singleLine="true" android:ellipsize="end" android:textAlignment="viewStart" - android:textAppearance="@android:style/TextAppearance.Material.Caption"/> + android:textAppearance="@style/ItemCaptionText" /> <TextView android:id="@+id/date" @@ -184,7 +187,7 @@ android:singleLine="true" android:ellipsize="end" android:textAlignment="viewStart" - android:textAppearance="@android:style/TextAppearance.Material.Caption"/> + android:textAppearance="@style/ItemCaptionText" /> </RelativeLayout> @@ -198,9 +201,8 @@ <View android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_margin="1dp" android:background="@drawable/item_doc_grid_border_rounded" android:contentDescription="@null" android:duplicateParentState="true"/> -</FrameLayout> +</com.google.android.material.card.MaterialCardView> diff --git a/res/layout/item_doc_header_message.xml b/res/layout/item_doc_header_message.xml index 25e69c8eb..4b2cf355f 100644 --- a/res/layout/item_doc_header_message.xml +++ b/res/layout/item_doc_header_message.xml @@ -34,6 +34,7 @@ <LinearLayout android:layout_height="wrap_content" android:layout_width="match_parent" + android:background="?android:attr/colorBackground" android:orientation="vertical"> <LinearLayout @@ -99,20 +100,14 @@ android:layout_width="match_parent" android:orientation="vertical"> - <View - android:layout_width="match_parent" - android:layout_height="1dp" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" - android:background="?android:strokeColor"/> - <Button android:id="@+id/action_button" android:layout_height="wrap_content" android:layout_width="wrap_content" - android:layout_marginStart="48dp" - android:layout_gravity="start" + android:layout_marginEnd="16dp" + android:layout_gravity="end" style="@style/DialogTextButton"/> + </LinearLayout> </LinearLayout> diff --git a/res/layout/item_doc_list.xml b/res/layout/item_doc_list.xml index 1189482a2..0942c4b5f 100644 --- a/res/layout/item_doc_list.xml +++ b/res/layout/item_doc_list.xml @@ -1,5 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- +<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2013 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,15 +14,16 @@ limitations under the License. --> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/item_root" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/list_item_background" + android:foreground="?android:attr/selectableItemBackground" + android:clickable="true" android:focusable="true" - android:orientation="horizontal" > - + android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" @@ -31,136 +31,132 @@ android:baselineAligned="false" android:gravity="center_vertical" android:minHeight="@dimen/list_item_height" - android:orientation="horizontal" > - - <FrameLayout - android:id="@+id/icon" - android:pointerIcon="hand" - android:layout_width="@dimen/list_item_width" - android:layout_height="@dimen/list_item_height" - android:paddingBottom="@dimen/list_item_icon_padding" - android:paddingTop="@dimen/list_item_icon_padding" - android:paddingEnd="16dp" - android:paddingStart="@dimen/list_item_padding" > - - <ImageView - android:id="@+id/icon_mime" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:contentDescription="@null" - android:scaleType="centerInside" /> - - <ImageView - android:id="@+id/icon_thumb" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:contentDescription="@null" - android:scaleType="centerCrop" /> - - <ImageView - android:id="@+id/icon_check" - android:layout_width="@dimen/check_icon_size" - android:layout_height="@dimen/check_icon_size" - android:layout_gravity="center" - android:alpha="0" - android:contentDescription="@null" - android:scaleType="fitCenter" - android:src="@drawable/ic_check_circle" /> - </FrameLayout> + android:orientation="horizontal"> + + <FrameLayout + android:id="@+id/icon" + android:pointerIcon="hand" + android:layout_width="@dimen/list_item_width" + android:layout_height="@dimen/list_item_height" + android:paddingBottom="@dimen/list_item_icon_padding" + android:paddingTop="@dimen/list_item_icon_padding" + android:paddingEnd="16dp" + android:paddingStart="@dimen/list_item_padding"> + + <com.google.android.material.card.MaterialCardView + android:layout_width="match_parent" + android:layout_height="match_parent" + app:cardBackgroundColor="@android:color/transparent" + app:cardElevation="0dp"> + + <ImageView + android:id="@+id/icon_mime" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:contentDescription="@null" + android:scaleType="centerInside" /> + + <ImageView + android:id="@+id/icon_thumb" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:contentDescription="@null" + android:scaleType="centerCrop" /> + + <ImageView + android:id="@+id/icon_check" + android:layout_width="@dimen/check_icon_size" + android:layout_height="@dimen/check_icon_size" + android:layout_gravity="center" + android:alpha="0" + android:contentDescription="@null" + android:scaleType="fitCenter" + android:src="@drawable/ic_check_circle" /> + + </com.google.android.material.card.MaterialCardView> + + </FrameLayout> + + <LinearLayout + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:orientation="vertical" + android:layout_gravity="center_vertical" + android:layout_marginEnd="@dimen/list_item_padding"> + + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="0dp" + android:layout_weight="1"> + + <ImageView + android:id="@+id/icon_briefcase" + android:layout_height="@dimen/briefcase_icon_size" + android:layout_width="@dimen/briefcase_icon_size" + android:layout_marginEnd="@dimen/briefcase_icon_margin" + android:layout_gravity="center_vertical" + android:src="@drawable/ic_briefcase" + android:contentDescription="@string/a11y_work" /> + + <TextView + android:id="@android:id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:ellipsize="end" + android:singleLine="true" + android:textAlignment="viewStart" + android:textAppearance="?android:attr/textAppearanceListItem" /> + + </LinearLayout> <LinearLayout - android:layout_width="0dp" + android:id="@+id/line2" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_weight="1" - android:orientation="vertical" - android:layout_gravity="center_vertical" - android:layout_marginEnd="@dimen/list_item_padding" > - - <LinearLayout - android:layout_width="wrap_content" - android:layout_height="0dp" - android:layout_weight="1"> - - <ImageView - android:id="@+id/icon_briefcase" - android:layout_height="@dimen/briefcase_icon_size" - android:layout_width="@dimen/briefcase_icon_size" - android:layout_marginEnd="@dimen/briefcase_icon_margin" - android:layout_gravity="center_vertical" - android:src="@drawable/ic_briefcase" - android:contentDescription="@string/a11y_work"/> - - <TextView - android:id="@android:id/title" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:ellipsize="end" - android:singleLine="true" - android:textAlignment="viewStart" - android:textAppearance="?android:attr/textAppearanceListItem"/> - </LinearLayout> - - <LinearLayout - android:id="@+id/line2" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:baselineAligned="false" - android:gravity="center_vertical" - android:orientation="horizontal" > - - <TextView - android:id="@+id/date" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_weight="0.4" - android:ellipsize="end" - android:singleLine="true" - android:textAlignment="viewStart" - android:textAppearance="@style/ItemDocListCaptionText"/> - - <TextView - android:id="@+id/size" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_marginStart="8dp" - android:layout_weight="0.3" - android:ellipsize="end" - android:singleLine="true" - android:textAlignment="viewStart" - android:textAppearance="@style/ItemDocListCaptionText"/> - - <TextView - android:id="@+id/file_type" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_marginStart="8dp" - android:layout_weight="0.3" - android:ellipsize="end" - android:singleLine="true" - android:textAlignment="viewStart" - android:textAppearance="@style/ItemDocListCaptionText"/> - </LinearLayout> + android:baselineAligned="false" + android:layout_marginTop="4dp" + android:gravity="center_vertical" + android:orientation="horizontal"> + + <TextView + android:id="@+id/metadata" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:ellipsize="end" + android:singleLine="true" + android:textAppearance="@style/ItemCaptionText" /> + </LinearLayout> - <FrameLayout - android:id="@+id/preview_icon" - android:layout_width="@dimen/list_item_width" - android:layout_height="@dimen/list_item_height" - android:padding="@dimen/list_item_icon_padding" - android:focusable="true" - android:clickable="true"> + </LinearLayout> - <ImageView - android:layout_width="@dimen/check_icon_size" - android:layout_height="@dimen/check_icon_size" - android:layout_gravity="center" - android:scaleType="fitCenter" - android:tint="?android:attr/colorControlNormal" - android:src="@drawable/ic_zoom_out"/> + <FrameLayout + android:id="@+id/preview_icon" + android:layout_width="@dimen/list_item_width" + android:layout_height="@dimen/list_item_height" + android:padding="@dimen/list_item_icon_padding" + android:focusable="true" + android:clickable="true"> - </FrameLayout> + <ImageView + android:layout_width="@dimen/check_icon_size" + android:layout_height="@dimen/check_icon_size" + android:layout_gravity="center" + android:scaleType="fitCenter" + android:tint="?android:attr/colorControlNormal" + android:src="@drawable/ic_zoom_out" /> + + </FrameLayout> </LinearLayout> -</LinearLayout> + <View + android:layout_width="match_parent" + android:layout_height="1dp" + android:layout_marginStart="72dp" + android:layout_marginEnd="8dp" + android:background="?android:strokeColor" /> + +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/navigation_breadcrumb_item.xml b/res/layout/navigation_breadcrumb_item.xml index a424a66ec..93d3feb3f 100644 --- a/res/layout/navigation_breadcrumb_item.xml +++ b/res/layout/navigation_breadcrumb_item.xml @@ -40,7 +40,6 @@ android:layout_height="match_parent" android:maxWidth="275dp" android:gravity="center_vertical" - android:duplicateParentState="true" android:maxLines="1" android:ellipsize="end" android:textAppearance="@style/BreadcrumbText" diff --git a/res/layout/search_chip_item.xml b/res/layout/search_chip_item.xml index cb6799313..3ee00c290 100644 --- a/res/layout/search_chip_item.xml +++ b/res/layout/search_chip_item.xml @@ -20,7 +20,8 @@ android:checkable="true" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/search_chip_spacing" + android:layout_marginStart="@dimen/search_chip_half_spacing" + android:layout_marginEnd="@dimen/search_chip_half_spacing" android:textAppearance="@style/SearchChipText" android:textColor="@color/search_chip_text_color" app:checkedIcon="@drawable/ic_check" diff --git a/res/layout/search_chip_row.xml b/res/layout/search_chip_row.xml index 1375177b8..ad0ac43c8 100644 --- a/res/layout/search_chip_row.xml +++ b/res/layout/search_chip_row.xml @@ -18,11 +18,17 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" - android:overScrollMode="never" android:scrollbars="none"> - <LinearLayout - android:id="@+id/search_chip_group" + + <FrameLayout android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingEnd="@dimen/search_chip_spacing"/> + android:layout_height="wrap_content" > + + <LinearLayout + android:id="@+id/search_chip_group" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/search_chip_group_margin" + android:layout_marginEnd="@dimen/search_chip_group_margin"/> + </FrameLayout> </HorizontalScrollView>
\ No newline at end of file diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml index 180573b78..b045e9040 100644 --- a/res/values-af/strings.xml +++ b/res/values-af/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Jy moet dit hernoem"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Jy moet \'n vouernaam byvoeg"</string> <string name="files_label" msgid="771781190045103748">"Lêers"</string> <string name="downloads_label" msgid="5462789470049501103">"Aflaaie"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Werk"</string> <string name="a11y_work" msgid="7504431382825242153">"Werk"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Jy kan nie lêers uit \'n ander program skuif nie."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Wys tans in roostermodus."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Wys tans in lysmodus."</string> </resources> diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml index 124d33be3..27905d5fb 100644 --- a/res/values-am/strings.xml +++ b/res/values-am/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"ይህንን እንደገና መሰየም ያስፈልግዎታል"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"የአቃፊ ስም ማከል ያስፈልግዎታል"</string> <string name="files_label" msgid="771781190045103748">"ፋይሎች"</string> <string name="downloads_label" msgid="5462789470049501103">"የወረዱ"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"ሥራ"</string> <string name="a11y_work" msgid="7504431382825242153">"ሥራ"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"ከሌላ መተግበሪያ ፋይሎችን መውሰድ አይችሉም።"</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"በፍርግርግ ሁነታ ላይ በማሳየት ላይ።"</string> + <string name="list_mode_showing" msgid="1225413902295895166">"በዝርዝር ሁነታ ላይ በማሳየት ላይ።"</string> </resources> diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index fbe4350d6..a41182579 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"يجب إعادة تسمية هذا."</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"يجب إضافة اسم للمجلد."</string> <string name="files_label" msgid="771781190045103748">"الملفات"</string> <string name="downloads_label" msgid="5462789470049501103">"عمليات التنزيل"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -366,4 +368,6 @@ <string name="work_tab" msgid="7265359366883747413">"للعمل"</string> <string name="a11y_work" msgid="7504431382825242153">"عمل"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"لا يمكنك نقل الملفات من تطبيق آخر."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"يتم العرض في وضع الشبكة."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"يتم العرض في وضع القائمة."</string> </resources> diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml index 14b404bd4..54601847a 100644 --- a/res/values-as/strings.xml +++ b/res/values-as/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"আপুনি এইটোৰ নতুন নাম দিব লাগিব"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"আপুনি এটা ফ’ল্ডাৰৰ নাম যোগ দিব লাগিব"</string> <string name="files_label" msgid="771781190045103748">"Files"</string> <string name="downloads_label" msgid="5462789470049501103">"ডাউনল\'ডসমূহ"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"কৰ্মস্থান"</string> <string name="a11y_work" msgid="7504431382825242153">"কৰ্মস্থান"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"আপুনি অন্য এটা এপৰ পৰা ফাইল স্থানান্তৰ কৰিব নোৱাৰে।"</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"গ্ৰিড ম’ডত দেখুৱাই থকা হৈছে।"</string> + <string name="list_mode_showing" msgid="1225413902295895166">"সূচীযুক্ত ম’ডত দেখুৱাই থকা হৈছে।"</string> </resources> diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml index ec090d878..c02a69259 100644 --- a/res/values-az/strings.xml +++ b/res/values-az/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Bunun adını dəyişməlisiniz"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Qovluq adı əlavə etməlisiniz"</string> <string name="files_label" msgid="771781190045103748">"Fayllar"</string> <string name="downloads_label" msgid="5462789470049501103">"Endirilənlər"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"İş"</string> <string name="a11y_work" msgid="7504431382825242153">"İş"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Başqa tətbiqdən faylları köçürə bilməzsiniz."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Tor rejimində göstərilir."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Siyahı rejimində göstərilir."</string> </resources> diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml index 5cead885f..643e401e3 100644 --- a/res/values-b+sr+Latn/strings.xml +++ b/res/values-b+sr+Latn/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Morate da preimenujete ovo"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Morate da dodate naziv foldera"</string> <string name="files_label" msgid="771781190045103748">"Datoteke"</string> <string name="downloads_label" msgid="5462789470049501103">"Preuzimanja"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -300,4 +302,6 @@ <string name="work_tab" msgid="7265359366883747413">"Posao"</string> <string name="a11y_work" msgid="7504431382825242153">"Posao"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Ne možete da premeštate datoteke iz druge aplikacije."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Prikazuje se u režimu mreže."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Prikazuje se u režimu liste."</string> </resources> diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml index 0c0eb681a..256e14ce9 100644 --- a/res/values-be/strings.xml +++ b/res/values-be/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Пераймянуйце"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Дадайце назву папкі"</string> <string name="files_label" msgid="771781190045103748">"Файлы"</string> <string name="downloads_label" msgid="5462789470049501103">"Спампоўкі"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -322,4 +324,6 @@ <string name="work_tab" msgid="7265359366883747413">"Працоўны"</string> <string name="a11y_work" msgid="7504431382825242153">"Працоўны"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Вы не можаце перамяшчаць файлы з іншай праграмы."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Паказ у рэжыме табліцы."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Паказ у рэжыме спіса."</string> </resources> diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml index 22ae7ee17..59fcc672f 100644 --- a/res/values-bg/strings.xml +++ b/res/values-bg/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Трябва да преименувате"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Трябва да добавите име на папката"</string> <string name="files_label" msgid="771781190045103748">"Файлове"</string> <string name="downloads_label" msgid="5462789470049501103">"Изтегляния"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Служебни"</string> <string name="a11y_work" msgid="7504431382825242153">"Служебно"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Не можете да местите файлове от друго приложение."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Показва се в табличен изглед."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Показва се в списъчен изглед."</string> </resources> diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml index b0b4c73ad..954a46fd2 100644 --- a/res/values-bn/strings.xml +++ b/res/values-bn/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"আপনাকে নতুন করে এর নাম দিতে হবে"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"আপনাকে ফোল্ডারের নাম যোগ করতে হবে"</string> <string name="files_label" msgid="771781190045103748">"Files"</string> <string name="downloads_label" msgid="5462789470049501103">"ডাউনলোড"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"অফিস"</string> <string name="a11y_work" msgid="7504431382825242153">"অফিসের প্রোফাইল"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"অন্য অ্যাপ থেকে ফাইল সরাতে পারবেন না।"</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"গ্রিড মোডে দেখানো হচ্ছে।"</string> + <string name="list_mode_showing" msgid="1225413902295895166">"তালিকা মোডে দেখানো হচ্ছে।"</string> </resources> diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml index e7a83e00d..a15458b99 100644 --- a/res/values-bs/strings.xml +++ b/res/values-bs/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Ovo morate preimenovati"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Morate dodati naziv foldera"</string> <string name="files_label" msgid="771781190045103748">"Fajlovi"</string> <string name="downloads_label" msgid="5462789470049501103">"Preuzimanja"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -300,4 +302,6 @@ <string name="work_tab" msgid="7265359366883747413">"Poslovno"</string> <string name="a11y_work" msgid="7504431382825242153">"Posao"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Ne možete premjestiti fajlove iz druge aplikacije."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Prikazivanje u vidu mreže."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Prikazivanje u vidu liste."</string> </resources> diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index a7510fa96..290c9085e 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Has de canviar-ne el nom"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Has d\'afegir un nom a la carpeta"</string> <string name="files_label" msgid="771781190045103748">"Fitxers"</string> <string name="downloads_label" msgid="5462789470049501103">"Baixades"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Treball"</string> <string name="a11y_work" msgid="7504431382825242153">"Treball"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"No pots moure fitxers des d\'una altra aplicació."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Es mostra en mode de quadrícula."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Es mostra en mode de llista."</string> </resources> diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index d08034868..b48603cc4 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Musíte zadat nový název"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Musíte přidat název složky"</string> <string name="files_label" msgid="771781190045103748">"Soubory"</string> <string name="downloads_label" msgid="5462789470049501103">"Stahování"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -322,4 +324,6 @@ <string name="work_tab" msgid="7265359366883747413">"Pracovní"</string> <string name="a11y_work" msgid="7504431382825242153">"Pracovní"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Není možné přesouvat soubory z jiné aplikace."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Zobrazuje se mřížka s položkami."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Zobrazuje se seznam položek."</string> </resources> diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index 67b74c232..6e33dd802 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Angiv et nyt navn"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Du skal tilføje navnet på en mappe"</string> <string name="files_label" msgid="771781190045103748">"Filer"</string> <string name="downloads_label" msgid="5462789470049501103">"Downloads"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Arbejde"</string> <string name="a11y_work" msgid="7504431382825242153">"Arbejde"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Du kan ikke flytte filer fra en anden app."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Vises i gittervisning."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Vises i listevisning."</string> </resources> diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 9be69e105..c54f373f2 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Du musst einen neuen Namen eingeben"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Du musst einen Namen für den Ordner angeben"</string> <string name="files_label" msgid="771781190045103748">"Dateien"</string> <string name="downloads_label" msgid="5462789470049501103">"Downloads"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Geschäftlich"</string> <string name="a11y_work" msgid="7504431382825242153">"Aus Arbeitsprofil"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Du kannst keine Dateien aus einer anderen App verschieben."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Wird im Rastermodus angezeigt."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Wird im Listenmodus angezeigt."</string> </resources> diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index 9b290cc63..105c41e29 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Πρέπει να μετονομάσετε αυτό το στοιχείο"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Πρέπει να προσθέσετε ένα όνομα φακέλου"</string> <string name="files_label" msgid="771781190045103748">"Αρχεία"</string> <string name="downloads_label" msgid="5462789470049501103">"Λήψεις"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Εργασίας"</string> <string name="a11y_work" msgid="7504431382825242153">"Εργασία"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Δεν είναι δυνατή η μεταφορά αρχείων από άλλη εφαρμογή."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Εμφάνιση σε λειτουργία πλέγματος."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Εμφάνιση σε λειτουργία λίστας."</string> </resources> diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml index 6806260a7..d9e94f4eb 100644 --- a/res/values-en-rAU/strings.xml +++ b/res/values-en-rAU/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"You need to rename this"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"You need to add a folder name"</string> <string name="files_label" msgid="771781190045103748">"Files"</string> <string name="downloads_label" msgid="5462789470049501103">"Downloads"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Work"</string> <string name="a11y_work" msgid="7504431382825242153">"Work"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"You can’t move files from another app."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Showing in grid mode."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Showing in list mode."</string> </resources> diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml index 6806260a7..d9e94f4eb 100644 --- a/res/values-en-rCA/strings.xml +++ b/res/values-en-rCA/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"You need to rename this"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"You need to add a folder name"</string> <string name="files_label" msgid="771781190045103748">"Files"</string> <string name="downloads_label" msgid="5462789470049501103">"Downloads"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Work"</string> <string name="a11y_work" msgid="7504431382825242153">"Work"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"You can’t move files from another app."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Showing in grid mode."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Showing in list mode."</string> </resources> diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index 6806260a7..d9e94f4eb 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"You need to rename this"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"You need to add a folder name"</string> <string name="files_label" msgid="771781190045103748">"Files"</string> <string name="downloads_label" msgid="5462789470049501103">"Downloads"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Work"</string> <string name="a11y_work" msgid="7504431382825242153">"Work"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"You can’t move files from another app."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Showing in grid mode."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Showing in list mode."</string> </resources> diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml index 6806260a7..d9e94f4eb 100644 --- a/res/values-en-rIN/strings.xml +++ b/res/values-en-rIN/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"You need to rename this"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"You need to add a folder name"</string> <string name="files_label" msgid="771781190045103748">"Files"</string> <string name="downloads_label" msgid="5462789470049501103">"Downloads"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Work"</string> <string name="a11y_work" msgid="7504431382825242153">"Work"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"You can’t move files from another app."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Showing in grid mode."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Showing in list mode."</string> </resources> diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml index 9d6414456..5090b9a4c 100644 --- a/res/values-en-rXC/strings.xml +++ b/res/values-en-rXC/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"You need to rename this"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"You need to add a folder name"</string> <string name="files_label" msgid="771781190045103748">"Files"</string> <string name="downloads_label" msgid="5462789470049501103">"Downloads"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Work"</string> <string name="a11y_work" msgid="7504431382825242153">"Work"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"You can’t move files from another app."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Showing in grid mode."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Showing in list mode."</string> </resources> diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml index f58e51aa8..ce32f4768 100644 --- a/res/values-es-rUS/strings.xml +++ b/res/values-es-rUS/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Tienes que cambiar el nombre"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Debes asignarle un nombre a la carpeta"</string> <string name="files_label" msgid="771781190045103748">"Archivos"</string> <string name="downloads_label" msgid="5462789470049501103">"Descargas"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"De trabajo"</string> <string name="a11y_work" msgid="7504431382825242153">"Trabajo"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"No puedes transferir archivos de otra app."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Se muestra en modo de cuadrícula."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Se muestra en modo de lista."</string> </resources> diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index be9ebbcda..c9f50925c 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Tienes que cambiar el nombre"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Tienes que dar un nombre a la carpeta"</string> <string name="files_label" msgid="771781190045103748">"Archivos"</string> <string name="downloads_label" msgid="5462789470049501103">"Descargas"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Trabajo"</string> <string name="a11y_work" msgid="7504431382825242153">"Trabajo"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"No puedes mover archivos de otra aplicación."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Mostrando modo de cuadrícula."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Mostrando modo de lista."</string> </resources> diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml index 98308192c..85abd4247 100644 --- a/res/values-et/strings.xml +++ b/res/values-et/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Peate nime muutma"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Peate kaustale lisama nime"</string> <string name="files_label" msgid="771781190045103748">"Failid"</string> <string name="downloads_label" msgid="5462789470049501103">"Allalaadimised"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Töö"</string> <string name="a11y_work" msgid="7504431382825242153">"Töö"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Te ei saa faile teisest rakendusest teisaldada."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Kuvatud ruudustikuvaates."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Kuvatud loendivaates."</string> </resources> diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index 2a3c838fd..cf1dda9f7 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Izena aldatu behar diozu"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Karpetari izena jarri behar diozu"</string> <string name="files_label" msgid="771781190045103748">"Fitxategiak"</string> <string name="downloads_label" msgid="5462789470049501103">"Deskargak"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -203,7 +205,7 @@ <string name="open_external_dialog_request" msgid="8173558471322861268">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> aplikazioari <xliff:g id="STORAGE"><i>^3</i></xliff:g> unitateko <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> direktoriorako sarbidea eman nahi diozu?"</string> <string name="open_external_dialog_request_primary_volume" msgid="2240992164087948176">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> aplikazioari <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> direktoriorako sarbidea eman nahi diozu?"</string> <string name="open_external_dialog_root_request" msgid="6776729293982633">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> aplikazioari zure datuak atzitzeko baimena eman nahi diozu (besteak beste, <xliff:g id="STORAGE"><i>^2</i></xliff:g> biltegian dituzun argazkiak eta bideoak)?"</string> - <string name="allow" msgid="1275746941353040309">"Eman baimena"</string> + <string name="allow" msgid="1275746941353040309">"Baimendu"</string> <string name="deny" msgid="5127201668078153379">"Ukatu"</string> <plurals name="elements_selected" formatted="false" msgid="4448165978637163692"> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> hautatuta</item> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Lanekoa"</string> <string name="a11y_work" msgid="7504431382825242153">"Lana"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Ezin dituzu mugitu beste aplikazio batzuetako fitxategiak."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Sareta moduan ikusgai."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Zerrenda moduan ikusgai."</string> </resources> diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index b68c9f3ba..9bc82b040 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"باید نام این مورد را تغییر دهید"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"باید نامی به پوشه اضافه کنید"</string> <string name="files_label" msgid="771781190045103748">"فایلها"</string> <string name="downloads_label" msgid="5462789470049501103">"بارگیریها"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"کاری"</string> <string name="a11y_work" msgid="7504431382825242153">"کاری"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"نمیتوانید فایلها را از برنامه دیگری انتقال دهید."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"نمایش در حالت جدولی."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"نمایش در حالت فهرست."</string> </resources> diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml index 17c7e9576..9903b55f7 100644 --- a/res/values-fi/strings.xml +++ b/res/values-fi/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Nimeä tämä uudelleen"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Lisää kansion nimi"</string> <string name="files_label" msgid="771781190045103748">"Tiedostot"</string> <string name="downloads_label" msgid="5462789470049501103">"Lataukset"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Työ"</string> <string name="a11y_work" msgid="7504431382825242153">"Työ"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Et voi siirtää tiedostoja toisesta sovelluksesta."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Näytetään ruudukkotilassa."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Näytetään luettelotilassa."</string> </resources> diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml index e3bedfbcd..f080d9cab 100644 --- a/res/values-fr-rCA/strings.xml +++ b/res/values-fr-rCA/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Vous devez le renommer"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Vous devez ajouter un nom de dossier"</string> <string name="files_label" msgid="771781190045103748">"Fichiers"</string> <string name="downloads_label" msgid="5462789470049501103">"Téléchargements"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Professionnel"</string> <string name="a11y_work" msgid="7504431382825242153">"Travail"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Vous ne pouvez pas déplacer de fichiers d\'une autre application."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Affichage en mode grille."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Affichage en mode liste."</string> </resources> diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index b923d4952..926d34cab 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Vous devez lui attribuer un autre nom"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Vous devez ajouter un nom de dossier"</string> <string name="files_label" msgid="771781190045103748">"Fichiers"</string> <string name="downloads_label" msgid="5462789470049501103">"Téléchargements"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Professionnel"</string> <string name="a11y_work" msgid="7504431382825242153">"Pro"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Vous ne pouvez pas déplacer de fichiers depuis une autre application."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Affichage en mode grille."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Affichage en mode liste."</string> </resources> diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index d3048c364..a852abe3a 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Debes cambiarlle o nome a este elemento"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Debes engadir un nome para o cartafol"</string> <string name="files_label" msgid="771781190045103748">"Ficheiros"</string> <string name="downloads_label" msgid="5462789470049501103">"Descargas"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Traballo"</string> <string name="a11y_work" msgid="7504431382825242153">"Traballo"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Non se poden mover ficheiros desde outra aplicación."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Mostrando modo de grade."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Mostrando modo de lista."</string> </resources> diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml index 55fb61f19..3077bf65d 100644 --- a/res/values-gu/strings.xml +++ b/res/values-gu/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"તમારે આનું નામ બદલવાની જરૂર છે"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"તમારે ફોલ્ડરનું નામ ઉમેરવાની જરૂર છે"</string> <string name="files_label" msgid="771781190045103748">"Files"</string> <string name="downloads_label" msgid="5462789470049501103">"ડાઉનલોડ"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"ઑફિસ"</string> <string name="a11y_work" msgid="7504431382825242153">"ઑફિસ"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"તમે કોઈ અન્ય ઍપમાંથી ફાઇલો ખસેડી શકતાં નથી."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"ગ્રિડ મોડમાં બતાવી રહ્યાં છીએ."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"સૂચિ મોડમાં બતાવી રહ્યાં છીએ."</string> </resources> diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml index 13fa5be01..7694f7d32 100644 --- a/res/values-hi/strings.xml +++ b/res/values-hi/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"आपको इसका नाम बदलना होगा"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"फ़ोल्डर का नाम जोड़ना ज़रूरी है"</string> <string name="files_label" msgid="771781190045103748">"Files"</string> <string name="downloads_label" msgid="5462789470049501103">"डाउनलोड"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -68,7 +70,7 @@ <string name="not_sorted" msgid="7813496644889115530">"क्रमबद्ध नहीं हैं"</string> <string name="sort_dimension_name" msgid="6325591541414177579">"नाम"</string> <string name="sort_dimension_summary" msgid="7724534446881397860">"सारांश"</string> - <string name="sort_dimension_file_type" msgid="5779709622922085381">"टाइप"</string> + <string name="sort_dimension_file_type" msgid="5779709622922085381">"प्रकार"</string> <string name="sort_dimension_size" msgid="2190547351159472884">"आकार"</string> <string name="sort_dimension_date" msgid="4231005651895254033">"बदले जाने का समय"</string> <string name="sort_dimension_name_ascending" msgid="3715725253270614742">"फ़ाइल का नाम (A से Z)"</string> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"काम से जुड़ी"</string> <string name="a11y_work" msgid="7504431382825242153">"काम से जुड़ी"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"आप किसी दूसरे ऐप्लिकेशन से फ़ाइलें नहीं ले जा सकते."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"ग्रिड मोड में दिखाया जा रहा है."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"सूची मोड में दिखाया जा रहा है."</string> </resources> diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml index 15ada351f..95476a146 100644 --- a/res/values-hr/strings.xml +++ b/res/values-hr/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Trebate promijeniti naziv"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Trebate dodati naziv mape"</string> <string name="files_label" msgid="771781190045103748">"Datoteke"</string> <string name="downloads_label" msgid="5462789470049501103">"Preuzimanja"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -300,4 +302,6 @@ <string name="work_tab" msgid="7265359366883747413">"Posao"</string> <string name="a11y_work" msgid="7504431382825242153">"Poslovni"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Ne možete premjestiti datoteke iz druge aplikacije."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Prikazivanje u načinu rešetke."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Prikazivanje u načinu popisa."</string> </resources> diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml index 12a44e87a..7f8676dae 100644 --- a/res/values-hu/strings.xml +++ b/res/values-hu/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Átnevezés szükséges."</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"A mappa nevének megadása kötelező."</string> <string name="files_label" msgid="771781190045103748">"Fájlok"</string> <string name="downloads_label" msgid="5462789470049501103">"Letöltések"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Munkahelyi"</string> <string name="a11y_work" msgid="7504431382825242153">"Munka"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Nem lehet áthelyezni fájlokat más alkalmazásból."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Megjelenítés rácsnézetben."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Megjelenítés listanézetben."</string> </resources> diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml index f67f19497..fc58aea01 100644 --- a/res/values-hy/strings.xml +++ b/res/values-hy/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Վերանվանեք սա"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Ավելացրեք պանակի անուն"</string> <string name="files_label" msgid="771781190045103748">"Ֆայլեր"</string> <string name="downloads_label" msgid="5462789470049501103">"Ներբեռնումներ"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -235,7 +237,7 @@ <string name="sign_in" msgid="6253762676723505592">"Մուտք գործել"</string> <string name="new_archive_file_name" msgid="1604650338077249838">"archive<xliff:g id="EXTENSION">%s</xliff:g>"</string> <string name="overwrite_file_confirmation_message" msgid="2496109652768222716">"Փոխարինե՞լ <xliff:g id="NAME">%1$s</xliff:g> ֆայլը։"</string> - <string name="continue_in_background" msgid="1974214559047793331">"Շարունակել հետին պլանում"</string> + <string name="continue_in_background" msgid="1974214559047793331">"Շարունակել ֆոնում"</string> <plurals name="selected_count" formatted="false" msgid="7555250236512981129"> <item quantity="one">Ընտրված է՝ <xliff:g id="COUNT_1">%1$d</xliff:g></item> <item quantity="other">Ընտրված է՝ <xliff:g id="COUNT_1">%1$d</xliff:g></item> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Աշխատանքային"</string> <string name="a11y_work" msgid="7504431382825242153">"Աշխատանքային"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Դուք չեք կարող տեղափոխել ֆայլեր այլ հավելվածից։"</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Ցուցադրվում է ցանցի տեսքով։"</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Ցուցադրվում է ցանկի տեսքով։"</string> </resources> diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index 4aba46b61..d08fc7369 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Anda perlu mengganti nama ini"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Anda perlu menambahkan nama folder"</string> <string name="files_label" msgid="771781190045103748">"File"</string> <string name="downloads_label" msgid="5462789470049501103">"Download"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Kerja"</string> <string name="a11y_work" msgid="7504431382825242153">"Kerja"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Anda tidak dapat memindahkan file ke aplikasi lain."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Menampilkan dalam mode petak."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Menampilkan dalam mode daftar."</string> </resources> diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml index c29bc29e8..f8b8ed9f0 100644 --- a/res/values-is/strings.xml +++ b/res/values-is/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Þú þarft að endurnefna þetta"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Þú þarft að bæta möppuheiti við"</string> <string name="files_label" msgid="771781190045103748">"Skrár"</string> <string name="downloads_label" msgid="5462789470049501103">"Niðurhal"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Vinna"</string> <string name="a11y_work" msgid="7504431382825242153">"Vinna"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Ekki er hægt að færa skrár úr öðru forriti."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Sýnir töfluyfirlit."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Sýnir listayfirlit."</string> </resources> diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index a4818721a..592a37acf 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Devi rinominare"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Devi aggiungere un nome per la cartella"</string> <string name="files_label" msgid="771781190045103748">"File"</string> <string name="downloads_label" msgid="5462789470049501103">"Download"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Di lavoro"</string> <string name="a11y_work" msgid="7504431382825242153">"Lavoro"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Impossibile spostare file da un\'altra app."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Visualizzazione in modalità griglia."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Visualizzazione in modalità elenco."</string> </resources> diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml index f65604ae1..29e89220b 100644 --- a/res/values-iw/strings.xml +++ b/res/values-iw/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"צריך לתת לזה שם חדש"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"צריך להוסיף שם לתיקייה"</string> <string name="files_label" msgid="771781190045103748">"קבצים"</string> <string name="downloads_label" msgid="5462789470049501103">"הורדות"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -322,4 +324,6 @@ <string name="work_tab" msgid="7265359366883747413">"עבודה"</string> <string name="a11y_work" msgid="7504431382825242153">"עבודה"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"אי אפשר להעביר קבצים מאפליקציה אחרת."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"הצגה בתצוגת טבלה."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"הצגה בתצוגת רשימה."</string> </resources> diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index 2eba79e48..7abf91f3f 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"この名前を変更してください"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"フォルダ名を追加してください"</string> <string name="files_label" msgid="771781190045103748">"ファイル"</string> <string name="downloads_label" msgid="5462789470049501103">"ダウンロード"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"仕事用"</string> <string name="a11y_work" msgid="7504431382825242153">"仕事用"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"別のアプリからファイルを移動することはできません。"</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"グリッドモードで表示しています。"</string> + <string name="list_mode_showing" msgid="1225413902295895166">"リストモードで表示しています。"</string> </resources> diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml index e10afb8fa..5b67b5575 100644 --- a/res/values-ka/strings.xml +++ b/res/values-ka/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"საჭიროა ამის გადარქმევა"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"საჭიროა საქაღალდის სახელის დამატება"</string> <string name="files_label" msgid="771781190045103748">"ფაილები"</string> <string name="downloads_label" msgid="5462789470049501103">"ჩამოტვირთვები"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"სამსახური"</string> <string name="a11y_work" msgid="7504431382825242153">"სამსახური"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"ფაილების სხვა აპიდან გადმოტანა შეუძლებელია."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"ნაჩვენებია ბადის რეჟიმში."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"ნაჩვენებია სიის რეჟიმში."</string> </resources> diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml index 1a44e35a6..6a7a250e2 100644 --- a/res/values-kk/strings.xml +++ b/res/values-kk/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Мұның атауын өзгертуіңіз қажет."</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Қалта атауын енгізуіңіз қажет."</string> <string name="files_label" msgid="771781190045103748">"Файлдар"</string> <string name="downloads_label" msgid="5462789470049501103">"Жүктеп алынғандар"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -43,7 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Тасымалдау…"</string> <string name="menu_compress" msgid="37539111904724188">"Сығу"</string> <string name="menu_extract" msgid="8171946945982532262">"Алынуда…"</string> - <string name="menu_rename" msgid="1883113442688817554">"Атын өзгерту"</string> + <string name="menu_rename" msgid="1883113442688817554">"Атауын өзгерту"</string> <string name="menu_inspect" msgid="7279855349299446224">"Ақпарат алу"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Жасырын файлдарды көрсету"</string> <string name="menu_hide_hidden_files" msgid="5654495713350153702">"Жасырын файлдарды көрсетпеу"</string> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Жұмыс"</string> <string name="a11y_work" msgid="7504431382825242153">"Жұмыс"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Файлдарды басқа қолданбадан тасымалдай алмайсыз."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Тор режимінде көрсетіледі."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Тізім режимінде көрсетіледі."</string> </resources> diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml index 00eb40322..d842441a9 100644 --- a/res/values-km/strings.xml +++ b/res/values-km/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"អ្នកត្រូវប្ដូរឈ្មោះវា"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"អ្នកត្រូវបញ្ចូលឈ្មោះថត"</string> <string name="files_label" msgid="771781190045103748">"ឯកសារ"</string> <string name="downloads_label" msgid="5462789470049501103">"ដោនឡូត"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"ការងារ"</string> <string name="a11y_work" msgid="7504431382825242153">"ការងារ"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"អ្នកមិនអាចផ្លាស់ទីឯកសារពីកម្មវិធីផ្សេងទៀតបានទេ។"</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"បង្ហាញក្នុងមុខងារក្រឡា។"</string> + <string name="list_mode_showing" msgid="1225413902295895166">"បង្ហាញក្នុងមុខងារបញ្ជី។"</string> </resources> diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index 2b60ed5c6..5fdc1fc20 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"ನೀವು ಇದನ್ನು ಮರುಹೆಸರಿಸಬೇಕಾಗುತ್ತದೆ"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"ನೀವು ಫೋಲ್ಡರ್ನ ಹೆಸರನ್ನು ಸೇರಿಸಬೇಕಾಗುತ್ತದೆ"</string> <string name="files_label" msgid="771781190045103748">"Files"</string> <string name="downloads_label" msgid="5462789470049501103">"ಡೌನ್ಲೋಡ್ಗಳು"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"ಉದ್ಯೋಗ"</string> <string name="a11y_work" msgid="7504431382825242153">"ಉದ್ಯೋಗ"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"ನೀವು ಬೇರೊಂದು ಆ್ಯಪ್ನಿಂದ ಫೈಲ್ಗಳನ್ನು ಸರಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"ಗ್ರಿಡ್ ಮೋಡ್ನಲ್ಲಿ ತೋರಿಸಲಾಗುತ್ತಿದೆ."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"ಪಟ್ಟಿ ಮೋಡ್ನಲ್ಲಿ ತೋರಿಸಲಾಗುತ್ತಿದೆ."</string> </resources> diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index 752dafda4..e0166c60e 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"이름을 변경해야 합니다."</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"폴더 이름을 추가해야 합니다."</string> <string name="files_label" msgid="771781190045103748">"파일"</string> <string name="downloads_label" msgid="5462789470049501103">"다운로드"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"직장"</string> <string name="a11y_work" msgid="7504431382825242153">"직장"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"파일을 다른 앱에서 이동할 수 없습니다."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"그리드 모드로 표시 중입니다."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"목록 모드로 표시 중입니다."</string> </resources> diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml index f03a4a50a..c5ab5118b 100644 --- a/res/values-ky/strings.xml +++ b/res/values-ky/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Мунун аталышын өзгөртүшүңүз керек"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Папканын аталышын жазышыңыз керек"</string> <string name="files_label" msgid="771781190045103748">"Файлдар"</string> <string name="downloads_label" msgid="5462789470049501103">"Жүктөлүп алынган нерселер"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Жумуш"</string> <string name="a11y_work" msgid="7504431382825242153">"Жумуш"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Башка колдонмодогу файлдарды жылдырууга болбойт."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Торчо режиминде көрсөтүлүүдө."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Тизме режиминде көрсөтүлүүдө."</string> </resources> diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml index e37ce344c..5b9ce871d 100644 --- a/res/values-lo/strings.xml +++ b/res/values-lo/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"ທ່ານຕ້ອງປ່ຽນຊື່ອັນນີ້"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"ທ່ານຕ້ອງເພີ່ມຊື່ໂຟນເດີ"</string> <string name="files_label" msgid="771781190045103748">"ໄຟລ໌"</string> <string name="downloads_label" msgid="5462789470049501103">"ດາວໂຫລດ"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"ວຽກ"</string> <string name="a11y_work" msgid="7504431382825242153">"ວຽກ"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"ບໍ່ສາມາດຍ້າຍໄຟລ໌ຈາກແອັບອື່ນໄດ້."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"ກຳລັງສະແດງໃນໂໝດຕາຕະລາງ."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"ກຳລັງສະແດງໃນໂໝດລາຍຊື່."</string> </resources> diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml index 902d1026c..17554c228 100644 --- a/res/values-lt/strings.xml +++ b/res/values-lt/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Turite tai pervardyti"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Turite pridėti aplanko pavadinimą"</string> <string name="files_label" msgid="771781190045103748">"Failai"</string> <string name="downloads_label" msgid="5462789470049501103">"Atsisiuntimai"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -322,4 +324,6 @@ <string name="work_tab" msgid="7265359366883747413">"Darbo"</string> <string name="a11y_work" msgid="7504431382825242153">"Darbo"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Negalite perkelti failų iš kitos programos."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Rodoma tinklelio režimu."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Rodoma sąrašo režimu."</string> </resources> diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml index 362038620..03fcd89db 100644 --- a/res/values-lv/strings.xml +++ b/res/values-lv/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Jums ir jāpārdēvē šis vienums."</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Jums ir jāpievieno mapes nosaukums."</string> <string name="files_label" msgid="771781190045103748">"Faili"</string> <string name="downloads_label" msgid="5462789470049501103">"Lejupielādes"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -300,4 +302,6 @@ <string name="work_tab" msgid="7265359366883747413">"Darba profils"</string> <string name="a11y_work" msgid="7504431382825242153">"Darbs"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Jūs nevarat pārvietot failus no citas lietotnes."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Tiek attēlots režģa režīms."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Tiek attēlots saraksta režīms."</string> </resources> diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml index 56936fdfb..b10dd1169 100644 --- a/res/values-mk/strings.xml +++ b/res/values-mk/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Треба да го преименувате ова"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Треба да додадете име на папка"</string> <string name="files_label" msgid="771781190045103748">"Датотеки"</string> <string name="downloads_label" msgid="5462789470049501103">"Преземања"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Работен"</string> <string name="a11y_work" msgid="7504431382825242153">"Работен профил"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Не може да преместувате датотеки од друга апликација."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Се прикажува во режим на решетка."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Се прикажува во режим на список."</string> </resources> diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml index 0dd3ca233..5f7d36a92 100644 --- a/res/values-ml/strings.xml +++ b/res/values-ml/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"നിങ്ങൾ ഇതിന്റെ പേര് മാറ്റേണ്ടതുണ്ട്"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"നിങ്ങൾ ഫോൾഡറിന്റെ പേര് ചേർക്കേണ്ടതുണ്ട്"</string> <string name="files_label" msgid="771781190045103748">"Files"</string> <string name="downloads_label" msgid="5462789470049501103">"ഡൗൺലോഡുകൾ"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"ഔദ്യോഗികം"</string> <string name="a11y_work" msgid="7504431382825242153">"ഔദ്യോഗികം"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"മറ്റ് ആപ്പിൽ നിന്ന് ഫയലുകൾ നീക്കാൻ നിങ്ങൾക്ക് കഴിയില്ല."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"ഗ്രിഡ് മോഡിൽ കാണിക്കുന്നു."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"ലിസ്റ്റ് മോഡിൽ കാണിക്കുന്നു."</string> </resources> diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml index 7ccbc9927..4526f0643 100644 --- a/res/values-mn/strings.xml +++ b/res/values-mn/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Та үүний нэрийг өөрчлөх шаардлагатай"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Та фолдерын нэр нэмэх шаардлагатай"</string> <string name="files_label" msgid="771781190045103748">"Файл"</string> <string name="downloads_label" msgid="5462789470049501103">"Татаж авсан файл"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Ажлын"</string> <string name="a11y_work" msgid="7504431382825242153">"Ажил"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Та өөр аппаас файлууд зөөх боломжгүй."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Хүснэгтийн горимд харуулж байна."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Жагсаалтын горимд харуулж байна."</string> </resources> diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml index 14a876c73..125447464 100644 --- a/res/values-mr/strings.xml +++ b/res/values-mr/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"तुम्ही याचे नाव बदलणे आवश्यक आहे"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"तुम्ही फोल्डरचे नाव जोडणे आवश्यक आहे"</string> <string name="files_label" msgid="771781190045103748">"Files"</string> <string name="downloads_label" msgid="5462789470049501103">"डाउनलोड"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -26,7 +28,7 @@ <string name="title_save" msgid="4384490653102710025">"येथे सेव्ह करा"</string> <string name="menu_create_dir" msgid="2413624798689091042">"नवीन फोल्डर"</string> <string name="menu_grid" msgid="1453636521731880680">"ग्रिड दृश्य"</string> - <string name="menu_list" msgid="6714267452146410402">"सूची दृश्य"</string> + <string name="menu_list" msgid="6714267452146410402">"सूची"</string> <string name="menu_search" msgid="1876699106790719849">"Search"</string> <string name="menu_settings" msgid="6520844520117939047">"स्टोरेज सेटिंग्ज"</string> <string name="menu_open" msgid="9092138100049759315">"उघडा"</string> @@ -43,7 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"यामध्ये हलवा…"</string> <string name="menu_compress" msgid="37539111904724188">"कॉंप्रेस करा"</string> <string name="menu_extract" msgid="8171946945982532262">"मध्ये काढा..."</string> - <string name="menu_rename" msgid="1883113442688817554">"नाव बदला"</string> + <string name="menu_rename" msgid="1883113442688817554">"पुनर्नामित करा"</string> <string name="menu_inspect" msgid="7279855349299446224">"माहिती मिळवा"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"लपवलेल्या फाइल दाखवा"</string> <string name="menu_hide_hidden_files" msgid="5654495713350153702">"लपवलेल्या फाइल दाखवू नका"</string> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"ऑफिस"</string> <string name="a11y_work" msgid="7504431382825242153">"ऑफिस"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"तुम्ही दुसऱ्या ॲपमधील फाइल हलवू शकत नाही."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"ग्रिड मोडमध्ये दाखवत आहे."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"सूची मोडमध्ये दाखवत आहे."</string> </resources> diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml index 79cf28454..555af2b60 100644 --- a/res/values-ms/strings.xml +++ b/res/values-ms/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Anda perlu menamakan semula ini"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Anda perlu menambahkan nama folder"</string> <string name="files_label" msgid="771781190045103748">"Fail"</string> <string name="downloads_label" msgid="5462789470049501103">"Muat turun"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Kerja"</string> <string name="a11y_work" msgid="7504431382825242153">"Kerja"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Anda tidak boleh mengalihkan fail daripada apl lain."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Ditunjukkan dalam mod grid."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Ditunjukkan dalam mod senarai."</string> </resources> diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml index 58d08eb18..6863c480c 100644 --- a/res/values-my/strings.xml +++ b/res/values-my/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"၎င်းကို အမည်ပြောင်းရန် လိုအပ်သည်"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"ဖိုင်တွဲအမည်ကို ထည့်သွင်းရန် လိုအပ်သည်"</string> <string name="files_label" msgid="771781190045103748">"ဖိုင်များ"</string> <string name="downloads_label" msgid="5462789470049501103">"ဒေါင်းလုဒ်များ"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"အလုပ်"</string> <string name="a11y_work" msgid="7504431382825242153">"အလုပ်"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"အခြားအက်ပ်မှဖိုင်ကို ရွှေ့၍မရပါ။"</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"ဇယားကွက်မုဒ်ဖြင့် ပြသရန်။"</string> + <string name="list_mode_showing" msgid="1225413902295895166">"စာရင်းမုဒ်ဖြင့် ပြသရန်။"</string> </resources> diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index c1580839a..9b300e338 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Du må gi nytt navn til dette"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Du må legge til et mappenavn"</string> <string name="files_label" msgid="771781190045103748">"Filer"</string> <string name="downloads_label" msgid="5462789470049501103">"Laster ned"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Jobb"</string> <string name="a11y_work" msgid="7504431382825242153">"Jobb"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Du kan ikke flytte filer fra en annen app."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Viser i rutenettmodus."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Viser i listemodus."</string> </resources> diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml index c2a539ff0..77759d7d9 100644 --- a/res/values-ne/strings.xml +++ b/res/values-ne/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"तपाईंले यसको नाम बदल्नु पर्ने हुन्छ"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"तपाईंले फोल्डरको नाम हाल्नु पर्ने हुन्छ"</string> <string name="files_label" msgid="771781190045103748">"फाइलहरू"</string> <string name="downloads_label" msgid="5462789470049501103">"डाउनलोडहरू"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -90,7 +92,7 @@ <string name="save_error" msgid="8631128801982095782">"कागजातलाई सुरक्षित गर्न सकिएन"</string> <string name="create_error" msgid="3092144450044861994">"फोल्डर सिर्जना गर्न सकिएन"</string> <string name="query_error" msgid="6625421453613879336">"यस समय सामग्री लोड गर्न सकिँदैन"</string> - <string name="quiet_mode_error_title" msgid="9126656325282792843">"कार्यलयको प्रोफाइल पज गरिएको छ"</string> + <string name="quiet_mode_error_title" msgid="9126656325282792843">"कार्यलयको प्रोफाइल अस्थायी रूपमा रोक्का गरिएको छ"</string> <string name="quiet_mode_button" msgid="6977115032320235420">"सक्रिय गरियोस्"</string> <string name="cant_select_work_files_error_title" msgid="6688716319549644354">"कार्यालयका फाइलहरू चयन गर्न मिल्दैन"</string> <string name="cant_select_work_files_error_message" msgid="683480676150690641">"तपाईंका IT एडमिनले तपाईंलाई व्यक्तिगत अनुप्रयोगमार्फत कार्यालयका फाइलहरू प्रयोग गर्ने अनुमति दिनुभएको छैन"</string> @@ -227,7 +229,7 @@ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> वस्तुहरूलाई मेट्ने हो?</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> वस्तुलाई मेट्ने हो?</item> </plurals> - <string name="images_shortcut_label" msgid="2545168016070493574">"फोटो"</string> + <string name="images_shortcut_label" msgid="2545168016070493574">"छविहरू"</string> <string name="archive_loading_failed" msgid="7243436722828766996">"ब्राउजिङको अभिलेख खोल्न सकिएन। फाइल या त बिग्रेको छ वा कुनै समर्थन नगरिने ढाँचामा छ।"</string> <string name="name_conflict" msgid="28407269328862986">"यो नाम भएको फाइल पहिले नै छ।"</string> <string name="authentication_required" msgid="8030880723643436099">"यो निर्देशिका हेर्न <xliff:g id="NAME">%1$s</xliff:g> मा साइन इन गर्नुहोस्"</string> @@ -249,12 +251,12 @@ <string name="root_info_header_app_with_summary" msgid="3223302581236069702">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> का फाइलहरू"</string> <string name="root_info_header_image_recent" msgid="7494373563753926014">"हालसालैका फोटोहरू"</string> <string name="root_info_header_image_global_search" msgid="7307009823489854697">"फोटोहरू"</string> - <string name="root_info_header_image_downloads" msgid="7072252612657612307">"डाउनलोड नामक फोल्डरमा भएका फोटो"</string> - <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g> मा रहेका फोटो"</string> - <string name="root_info_header_image_folder" msgid="5980430877636279667">"<xliff:g id="FOLDER">%1$s</xliff:g> मा भएका फोटो"</string> - <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g> का फोटो"</string> - <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> का फोटो"</string> - <string name="chip_title_images" msgid="7838299046109841015">"फोटो"</string> + <string name="root_info_header_image_downloads" msgid="7072252612657612307">"डाउनलोड नामक फोल्डरमा भएका छविहरू"</string> + <string name="root_info_header_image_storage" msgid="5086740886360075930">"<xliff:g id="DEVICE">%1$s</xliff:g> मा रहेका छविहरू"</string> + <string name="root_info_header_image_folder" msgid="5980430877636279667">"<xliff:g id="FOLDER">%1$s</xliff:g> मा भएका छविहरू"</string> + <string name="root_info_header_image_app" msgid="4858114210851525359">"<xliff:g id="LABEL">%1$s</xliff:g> का छविहरू"</string> + <string name="root_info_header_image_app_with_summary" msgid="6404842960923224778">"<xliff:g id="LABEL">%1$s</xliff:g> / <xliff:g id="SUMMARY">%2$s</xliff:g> का छविहरू"</string> + <string name="chip_title_images" msgid="7838299046109841015">"छविहरू"</string> <string name="chip_title_audio" msgid="1032801828748235436">"अडियो"</string> <string name="chip_title_videos" msgid="7011260091979776447">"भिडियोहरू"</string> <string name="chip_title_documents" msgid="7432457563000753983">"कागजातहरू"</string> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"काम"</string> <string name="a11y_work" msgid="7504431382825242153">"काम"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"तपाईं अर्को एपमा रहेका फाइलहरू सार्न सक्नुहुन्न।"</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"ग्रिड मोडमा देखाइँदै।"</string> + <string name="list_mode_showing" msgid="1225413902295895166">"सूची मोडमा देखाइँदै।"</string> </resources> diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml index 86bcbbc48..169f52f35 100644 --- a/res/values-night/colors.xml +++ b/res/values-night/colors.xml @@ -22,15 +22,15 @@ <color name="secondary">#3D8AB4F8</color> <color name="hairline">#5F6368</color> - <color name="briefcase_icon_color">#669DF6</color> <!-- Blue 400 --> - <color name="cross_profile_button_text_color">#669DF6</color> <!-- Blue 400 --> <color name="empty_state_text">@android:color/white</color> <color name="error_image_color">@android:color/white</color> <color name="edge_effect">@android:color/white</color> - <color name="tab_indicator_color">#669DF6</color> <!-- Blue 400 --> <!-- AppCompat.textColorSecondary --> <color name="doc_list_item_subtitle_enabled">#b3ffffff</color> <color name="doc_list_item_subtitle_disabled">#36ffffff</color> + + <color name="list_divider_color">#9aa0a6</color> + <color name="list_item_selected_background_color">?android:colorSecondary</color> </resources> diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 108917c17..3edc7654f 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Je moet deze naam wijzigen"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Je moet een mapnaam toevoegen"</string> <string name="files_label" msgid="771781190045103748">"Bestanden"</string> <string name="downloads_label" msgid="5462789470049501103">"Downloads"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Werk"</string> <string name="a11y_work" msgid="7504431382825242153">"Werk"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Je kunt geen bestanden verplaatsen vanuit een andere app."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Tonen in rastermodus."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Tonen in lijstmodus."</string> </resources> diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml index 58911a222..c200d354c 100644 --- a/res/values-or/strings.xml +++ b/res/values-or/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"ଆପଣଙ୍କୁ ଏହାର ନାମ ବଦଳାଇବା ଆବଶ୍ୟକ"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"ଆପଣଙ୍କୁ ଏକ ଫୋଲ୍ଡରର ନାମ ଯୋଗ କରିବା ଆବଶ୍ୟକ"</string> <string name="files_label" msgid="771781190045103748">"Files"</string> <string name="downloads_label" msgid="5462789470049501103">"ଡାଉନଲୋଡ୍"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"ୱାର୍କ"</string> <string name="a11y_work" msgid="7504431382825242153">"ୱାର୍କ"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"ଆପଣ ଅନ୍ୟ ଏକ ଆପରୁ ଫାଇଲଗୁଡ଼ିକ ମୁଭ୍ କରିପାରିବେ ନାହିଁ।"</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"ଗ୍ରିଡ୍ ମୋଡରେ ଦେଖାଉଛି।"</string> + <string name="list_mode_showing" msgid="1225413902295895166">"ତାଲିକା ମୋଡରେ ଦେଖାଉଛି।"</string> </resources> diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml index afbc0a137..130414315 100644 --- a/res/values-pa/strings.xml +++ b/res/values-pa/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"ਤੁਹਾਨੂੰ ਇਸਦਾ ਨਾਮ ਬਦਲਣ ਦੀ ਲੋੜ ਹੈ"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"ਤੁਹਾਨੂੰ ਕੋਈ ਫੋਲਡਰ ਨਾਮ ਸ਼ਾਮਲ ਕਰਨ ਦੀ ਲੋੜ ਹੈ"</string> <string name="files_label" msgid="771781190045103748">"Files"</string> <string name="downloads_label" msgid="5462789470049501103">"ਡਾਊਨਲੋਡਾਂ"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"ਕਾਰਜ-ਸਥਾਨ"</string> <string name="a11y_work" msgid="7504431382825242153">"ਕੰਮ"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"ਤੁਸੀਂ ਕਿਸੇ ਹੋਰ ਐਪ ਤੋਂ ਫ਼ਾਈਲਾਂ ਨਹੀਂ ਲਿਜਾ ਸਕਦੇ।"</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"ਗ੍ਰਿਡ ਮੋਡ ਵਿੱਚ ਦਿਖਾਈਆਂ ਜਾ ਰਹੀਆਂ ਹਨ"</string> + <string name="list_mode_showing" msgid="1225413902295895166">"ਸੂਚੀ ਮੋਡ ਵਿੱਚ ਦਿਖਾਈਆਂ ਜਾ ਰਹੀਆਂ ਹਨ।"</string> </resources> diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index e2b201f13..f4bb256e8 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Musisz zmienić nazwę"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Musisz dodać nazwę folderu"</string> <string name="files_label" msgid="771781190045103748">"Pliki"</string> <string name="downloads_label" msgid="5462789470049501103">"Pobieranie"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -322,4 +324,6 @@ <string name="work_tab" msgid="7265359366883747413">"Służbowe"</string> <string name="a11y_work" msgid="7504431382825242153">"Służbowy"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Nie można przenosić plików z innej aplikacji."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Wyświetlanie w trybie siatki."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Wyświetlanie w trybie listy."</string> </resources> diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml index 8be287b9b..d21309193 100644 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Mude o nome"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Adicione um nome para a pasta"</string> <string name="files_label" msgid="771781190045103748">"Arquivos"</string> <string name="downloads_label" msgid="5462789470049501103">"Downloads"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Trabalho"</string> <string name="a11y_work" msgid="7504431382825242153">"Trabalho"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Não é possível mover arquivos de outro app."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Exibindo modo de grade."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Exibindo modo de lista."</string> </resources> diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index 6df6d3cf3..a403d3b8a 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Tem de mudar o nome"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Tem de adicionar um nome da pasta"</string> <string name="files_label" msgid="771781190045103748">"Ficheiros"</string> <string name="downloads_label" msgid="5462789470049501103">"Transferências"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Trabalho"</string> <string name="a11y_work" msgid="7504431382825242153">"Trabalho"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Não pode mover ficheiros de outra app."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"A mostrar no modo de grelha…"</string> + <string name="list_mode_showing" msgid="1225413902295895166">"A mostrar no modo de lista…"</string> </resources> diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index 8be287b9b..d21309193 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Mude o nome"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Adicione um nome para a pasta"</string> <string name="files_label" msgid="771781190045103748">"Arquivos"</string> <string name="downloads_label" msgid="5462789470049501103">"Downloads"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Trabalho"</string> <string name="a11y_work" msgid="7504431382825242153">"Trabalho"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Não é possível mover arquivos de outro app."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Exibindo modo de grade."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Exibindo modo de lista."</string> </resources> diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index 957272bb2..0311b8dcc 100644 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Trebuie să redenumiți elementul"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Trebuie să adăugați un nume de dosar"</string> <string name="files_label" msgid="771781190045103748">"Fișiere"</string> <string name="downloads_label" msgid="5462789470049501103">"Descărcări"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -300,4 +302,6 @@ <string name="work_tab" msgid="7265359366883747413">"Serviciu"</string> <string name="a11y_work" msgid="7504431382825242153">"Serviciu"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Nu puteți muta fișiere din altă aplicație."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Se afișează în modul grilă."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Se afișează în modul listă."</string> </resources> diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 593f17981..09958d5c2 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Измените название."</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Укажите название папки."</string> <string name="files_label" msgid="771781190045103748">"Файлы"</string> <string name="downloads_label" msgid="5462789470049501103">"Скачанное"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -322,4 +324,6 @@ <string name="work_tab" msgid="7265359366883747413">"Рабочее"</string> <string name="a11y_work" msgid="7504431382825242153">"Работа"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Перемещать файлы из другого приложения нельзя."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Показано в виде таблицы."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Показано в виде списка."</string> </resources> diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml index 6fc7b69b2..6bf320f37 100644 --- a/res/values-si/strings.xml +++ b/res/values-si/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"ඔබ මෙය යළි නම් කළ යුතුය"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"ඔබ ෆෝල්ඩරයේ නමක් එක් කළ යුතුය"</string> <string name="files_label" msgid="771781190045103748">"ගොනු"</string> <string name="downloads_label" msgid="5462789470049501103">"බාගැනීම්"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"කාර්යාල"</string> <string name="a11y_work" msgid="7504431382825242153">"කාර්යාල"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"ඔබට වෙනත් යෙදුමකින් ගොනු ගෙන ඒමට නොහැකිය."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"ජාලක ප්රකාරය තුළ පෙන්වමින්."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"ලැයිස්තු ප්රකාරය තුළ පෙන්වමින්."</string> </resources> diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index baf7e0c25..a4465a90c 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Toto musíte premenovať"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Musíte pridať názov priečinka"</string> <string name="files_label" msgid="771781190045103748">"Súbory"</string> <string name="downloads_label" msgid="5462789470049501103">"Stiahnuté súbory"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -322,4 +324,6 @@ <string name="work_tab" msgid="7265359366883747413">"Práca"</string> <string name="a11y_work" msgid="7504431382825242153">"Práca"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Nemôžete presúvať súbory z inej aplikácie."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Zobrazované v režime mriežky."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Zobrazované v režime zoznamu."</string> </resources> diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml index 181250821..d4f75b898 100644 --- a/res/values-sl/strings.xml +++ b/res/values-sl/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"To morate preimenovati."</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Dodati morate ime mape."</string> <string name="files_label" msgid="771781190045103748">"Datoteke"</string> <string name="downloads_label" msgid="5462789470049501103">"Prenosi"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -322,4 +324,6 @@ <string name="work_tab" msgid="7265359366883747413">"Služba"</string> <string name="a11y_work" msgid="7504431382825242153">"Delovna"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Datotek iz druge aplikacije ni mogoče premakniti."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Prikazano v načinu mreže"</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Prikazano v načinu seznama"</string> </resources> diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml index 8d8790f96..eb6671e9a 100644 --- a/res/values-sq/strings.xml +++ b/res/values-sq/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Duhet ta riemërtosh këtë"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Duhet të shtosh një emër dosjeje"</string> <string name="files_label" msgid="771781190045103748">"Skedarët"</string> <string name="downloads_label" msgid="5462789470049501103">"Shkarkimet"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Puna"</string> <string name="a11y_work" msgid="7504431382825242153">"Puna"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Nuk mund t\'i zhvendosësh skedarët nga një aplikacion tjetër."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Po shfaq në modalitetin \"rrjetë\"."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Po shfaq në modalitetin \"listë\"."</string> </resources> diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index f691ecab2..7682be981 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Морате да преименујете ово"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Морате да додате назив фолдера"</string> <string name="files_label" msgid="771781190045103748">"Датотеке"</string> <string name="downloads_label" msgid="5462789470049501103">"Преузимања"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -300,4 +302,6 @@ <string name="work_tab" msgid="7265359366883747413">"Посао"</string> <string name="a11y_work" msgid="7504431382825242153">"Посао"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Не можете да премештате датотеке из друге апликације."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Приказује се у режиму мреже."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Приказује се у режиму листе."</string> </resources> diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index 001b9b352..dc852f6a5 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Du måste byta namn"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Du måste lägga till ett mappnamn"</string> <string name="files_label" msgid="771781190045103748">"Filer"</string> <string name="downloads_label" msgid="5462789470049501103">"Nedladdningar"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Arbete"</string> <string name="a11y_work" msgid="7504431382825242153">"Jobb"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Du kan inte flytta filer från en annan app."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Visas i rutnätsläge."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Visas i listläge."</string> </resources> diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml index 1b14b70fa..683a99dd7 100644 --- a/res/values-sw/strings.xml +++ b/res/values-sw/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Unahitaji kubadilisha jina hili"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Unahitaji kuweka jina la folda"</string> <string name="files_label" msgid="771781190045103748">"Faili"</string> <string name="downloads_label" msgid="5462789470049501103">"Vipakuliwa"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Kazini"</string> <string name="a11y_work" msgid="7504431382825242153">"Kazi"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Huwezi kuhamisha faili kutoka programu nyingine."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Kuonyesha katika hali ya gridi."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Kuonyesha katika hali ya orodha."</string> </resources> diff --git a/res/values-sw720dp/dimens.xml b/res/values-sw720dp/dimens.xml index 7ce3b5307..85c370ab9 100644 --- a/res/values-sw720dp/dimens.xml +++ b/res/values-sw720dp/dimens.xml @@ -28,6 +28,4 @@ <dimen name="search_bar_text_margin_start">55dp</dimen> <dimen name="search_bar_text_margin_end">24dp</dimen> <dimen name="search_bar_icon_padding">16dp</dimen> - - <dimen name="action_bar_space_margin">0dp</dimen> </resources> diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml index 5fe58f7a2..92b7c7ca4 100644 --- a/res/values-ta/strings.xml +++ b/res/values-ta/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"நீங்கள் இதற்குப் பெயர் மாற்றம் செய்ய வேண்டும்"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"கோப்புறைக்கான பெயர் சேர்க்கப்பட வேண்டும்"</string> <string name="files_label" msgid="771781190045103748">"Files"</string> <string name="downloads_label" msgid="5462789470049501103">"இறக்கங்கள்"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"பணி"</string> <string name="a11y_work" msgid="7504431382825242153">"பணி"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"வேறொரு ஆப்ஸிலிருந்து ஃபைல்களை நகர்த்த முடியாது."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"கட்டக் காட்சியில் காட்டுகிறது."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"பட்டியல் காட்சியில் காட்டுகிறது."</string> </resources> diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml index b8db58ef9..2f3053cc1 100644 --- a/res/values-te/strings.xml +++ b/res/values-te/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"మీరు దీని పేరు మార్చాలి"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"మీరు ఫోల్డర్ పేరును జోడించాలి"</string> <string name="files_label" msgid="771781190045103748">"Files"</string> <string name="downloads_label" msgid="5462789470049501103">"డౌన్లోడ్లు"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -90,7 +92,7 @@ <string name="save_error" msgid="8631128801982095782">"పత్రాన్ని సేవ్ చేయడంలో విఫలమైంది"</string> <string name="create_error" msgid="3092144450044861994">"ఫోల్డర్ను సృష్టించడంలో విఫలమైంది"</string> <string name="query_error" msgid="6625421453613879336">"ఈ సమయంలో కంటెంట్ను లోడ్ చేయడం సాధ్యపడదు"</string> - <string name="quiet_mode_error_title" msgid="9126656325282792843">"వర్క్ ప్రొఫైల్ పాజ్ చేయబడింది"</string> + <string name="quiet_mode_error_title" msgid="9126656325282792843">"కార్యాలయ ప్రొఫైల్ పాజ్ చేయబడింది"</string> <string name="quiet_mode_button" msgid="6977115032320235420">"ఆన్ చేయి"</string> <string name="cant_select_work_files_error_title" msgid="6688716319549644354">"కార్యాలయ ఫైళ్లను ఎంపిక చేయడం సాధ్యం కాదు"</string> <string name="cant_select_work_files_error_message" msgid="683480676150690641">"వ్యక్తిగత యాప్ నుండి ఆఫీస్ ఫైళ్లను యాక్సెస్ చేయడానికి మీ IT అడ్మిన్ అనుమతించరు"</string> @@ -115,7 +117,7 @@ <string name="toast_failed_delete" msgid="3453846588205817591">"కొన్ని పత్రాలను తొలగించడం సాధ్యపడలేదు"</string> <string name="toast_share_over_limit" msgid="5805442886537093015">"<xliff:g id="COUNT">%1$d</xliff:g> ఫైల్ల కంటే ఎక్కువ షేర్ చేయలేరు"</string> <string name="toast_action_not_allowed" msgid="1329382474450572415">"చర్యకు అనుమతి లేదు"</string> - <string name="share_via" msgid="8725082736005677161">"దీనితో షేర్ చేయండి"</string> + <string name="share_via" msgid="8725082736005677161">"దీనితో భాగస్వామ్యం చేయండి"</string> <string name="copy_notification_title" msgid="52256435625098456">"ఫైల్లు కాపీ అవుతున్నాయి"</string> <string name="compress_notification_title" msgid="6830195148113751021">"ఫైల్లను కుదిస్తోంది"</string> <string name="extract_notification_title" msgid="5067393961754430469">"ఫైల్లను సంగ్రహిస్తోంది"</string> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"కార్యాలయ డైరెక్టరీ"</string> <string name="a11y_work" msgid="7504431382825242153">"ఆఫీసు"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"మీరు వేరే ఇతర యాప్ నుండి ఫైల్స్ను తరలించలేరు."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"గ్రిడ్ మోడ్లో చూపుతోంది."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"లిస్ట్ మోడ్లో చూపుతోంది."</string> </resources> diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml index bb3676086..525c35b7c 100644 --- a/res/values-th/strings.xml +++ b/res/values-th/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"คุณต้องเปลี่ยนชื่อนี้"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"คุณต้องป้อนชื่อโฟลเดอร์"</string> <string name="files_label" msgid="771781190045103748">"ไฟล์"</string> <string name="downloads_label" msgid="5462789470049501103">"ดาวน์โหลด"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"งาน"</string> <string name="a11y_work" msgid="7504431382825242153">"งาน"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"คุณย้ายไฟล์จากแอปอื่นไม่ได้"</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"กำลังแสดงในโหมดตารางกริด"</string> + <string name="list_mode_showing" msgid="1225413902295895166">"กำลังแสดงในโหมดรายการ"</string> </resources> diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml index c2a5f8279..b394b8df9 100644 --- a/res/values-tl/strings.xml +++ b/res/values-tl/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Kailangan mong i-rename ito"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Kailangan mong magdagdag ng pangalan ng folder"</string> <string name="files_label" msgid="771781190045103748">"Mga File"</string> <string name="downloads_label" msgid="5462789470049501103">"Mga Download"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Work"</string> <string name="a11y_work" msgid="7504431382825242153">"Trabaho"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Hindi ka makakapaglipat ng mga file mula sa ibang app."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Ipinapakita sa grid mode."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Ipinapakita sa list mode."</string> </resources> diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index f59ae833d..354cb88ea 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Bunu yeniden adlandırmanız gerekiyor"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Bir klasör adı eklemeniz gerekiyor"</string> <string name="files_label" msgid="771781190045103748">"Dosyalar"</string> <string name="downloads_label" msgid="5462789470049501103">"İndirilenler"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"İş"</string> <string name="a11y_work" msgid="7504431382825242153">"İş"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Başka bir uygulamadan dosya taşıyamazsınız."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Tablo modunda gösteriliyor."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Liste modunda gösteriliyor."</string> </resources> diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index 91b358de7..0c223b276 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Змініть цю назву"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Додайте назву папки"</string> <string name="files_label" msgid="771781190045103748">"Файли"</string> <string name="downloads_label" msgid="5462789470049501103">"Завантаження"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -322,4 +324,6 @@ <string name="work_tab" msgid="7265359366883747413">"Робоче"</string> <string name="a11y_work" msgid="7504431382825242153">"Робоче"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Не можна переміщувати файли з іншого додатка."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Перегляд у режимі таблиці."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Перегляд у режимі списку."</string> </resources> diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml index fb2666ca6..037a9a4b7 100644 --- a/res/values-ur/strings.xml +++ b/res/values-ur/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"آپ کو اس کا نام تبدیل کرنے کی ضرورت ہے"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"آپ کو ایک فولڈر کا نام شامل کرنے کی ضرورت ہے"</string> <string name="files_label" msgid="771781190045103748">"فائلیں"</string> <string name="downloads_label" msgid="5462789470049501103">"ڈاؤن لوڈز"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"دفتری"</string> <string name="a11y_work" msgid="7504431382825242153">"کام"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"آپ کسی اور ایپ سے فائلیں منتقل نہیں کر سکتے ہیں۔"</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"گرڈ وضع میں دکھائی جا رہی ہیں۔"</string> + <string name="list_mode_showing" msgid="1225413902295895166">"فہرست وضع میں دکھائی جا رہی ہیں۔"</string> </resources> diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml index 768ee91af..92b6cc687 100644 --- a/res/values-uz/strings.xml +++ b/res/values-uz/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Buni qayta nomlang"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Jild nomini kiriting"</string> <string name="files_label" msgid="771781190045103748">"Fayllar"</string> <string name="downloads_label" msgid="5462789470049501103">"Yuklanmalar"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Ish"</string> <string name="a11y_work" msgid="7504431382825242153">"Ish"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Fayllarni boshqa ilovadan koʻchirish imkonsiz."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Jadval shaklida chiqarilmoqda."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Roʻyxat shaklida chiqarilmoqda."</string> </resources> diff --git a/res/values-v31/config.xml b/res/values-v31/config.xml new file mode 100644 index 000000000..a96a3e999 --- /dev/null +++ b/res/values-v31/config.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ 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. + --> + +<resources> + <!-- Starting from Android S, using DocumentsUI as a file browser with launcher icon is no + longer supported. --> + <bool name="is_launcher_enabled">false</bool> +</resources> diff --git a/res/values-v31/dimens.xml b/res/values-v31/dimens.xml new file mode 100644 index 000000000..15a781473 --- /dev/null +++ b/res/values-v31/dimens.xml @@ -0,0 +1,19 @@ +<!-- + ~ 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. + --> +<resources> + <dimen name="action_bar_elevation">0dp</dimen> + <dimen name="action_bar_margin">0dp</dimen> +</resources> diff --git a/res/values-v31/styles.xml b/res/values-v31/styles.xml new file mode 100644 index 000000000..bcdfa7287 --- /dev/null +++ b/res/values-v31/styles.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ 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. + --> + +<resources> + <style name="SectionHeader" parent="@*android:style/TextAppearance.DeviceDefault.Medium"> + <item name="android:textColor">?android:attr/textColorPrimary</item> + <item name="fontFamily">@string/config_fontFamilyMedium</item> + <item name="android:textSize">12sp</item> + </style> +</resources> diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index cdd98ddcf..3092b4d89 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Bạn cần đổi tên này"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Bạn cần thêm tên thư mục"</string> <string name="files_label" msgid="771781190045103748">"Tệp"</string> <string name="downloads_label" msgid="5462789470049501103">"Tệp đã tải xuống"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Công việc"</string> <string name="a11y_work" msgid="7504431382825242153">"Công việc"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Bạn không thể di chuyển các tệp từ một ứng dụng khác."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Đang hiển thị ở chế độ lưới."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Đang hiển thị ở chế độ danh sách."</string> </resources> diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index eb63cd1c6..793bdc77e 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"您需要进行重命名"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"您需要添加文件夹名称"</string> <string name="files_label" msgid="771781190045103748">"文件"</string> <string name="downloads_label" msgid="5462789470049501103">"下载"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"工作"</string> <string name="a11y_work" msgid="7504431382825242153">"工作"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"您无法移动其他应用中的文件。"</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"目前以网格模式显示。"</string> + <string name="list_mode_showing" msgid="1225413902295895166">"目前以列表模式显示。"</string> </resources> diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml index f4f84909b..e55940435 100644 --- a/res/values-zh-rHK/strings.xml +++ b/res/values-zh-rHK/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"您需要重新命名"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"您需要新增資料夾名稱"</string> <string name="files_label" msgid="771781190045103748">"檔案"</string> <string name="downloads_label" msgid="5462789470049501103">"下載"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"工作"</string> <string name="a11y_work" msgid="7504431382825242153">"工作"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"您無法移動其他應用程式的檔案。"</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"用格狀模式顯示緊。"</string> + <string name="list_mode_showing" msgid="1225413902295895166">"用清單模式顯示緊。"</string> </resources> diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 4b9ab889a..896426f74 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"請重新命名"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"請新增資料夾名稱"</string> <string name="files_label" msgid="771781190045103748">"檔案"</string> <string name="downloads_label" msgid="5462789470049501103">"下載"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"工作"</string> <string name="a11y_work" msgid="7504431382825242153">"工作"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"你無法將其他應用程式中的檔案移動至此。"</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"目前以格線模式顯示。"</string> + <string name="list_mode_showing" msgid="1225413902295895166">"目前以清單模式顯示。"</string> </resources> diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml index fdef101f0..8065b465c 100644 --- a/res/values-zu/strings.xml +++ b/res/values-zu/strings.xml @@ -16,6 +16,8 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="missing_rename_error" msgid="9098952207447981103">"Kudingeka ukuthi uqambe kabusha lokhu"</string> + <string name="add_folder_name_error" msgid="6014615052491406810">"Kudingeka ukuthi wengeze igama lefolda"</string> <string name="files_label" msgid="771781190045103748">"Amafayela"</string> <string name="downloads_label" msgid="5462789470049501103">"Okulandiwe"</string> <!-- no translation found for app_label (8089292432455111409) --> @@ -278,4 +280,6 @@ <string name="work_tab" msgid="7265359366883747413">"Umsebenzi"</string> <string name="a11y_work" msgid="7504431382825242153">"Umsebenzi"</string> <string name="drag_from_another_app" msgid="8310249276199969905">"Awukwazi ukuhambisa amafayela kusuka kolunye uhlelo lokusebenza."</string> + <string name="grid_mode_showing" msgid="2803166871485028508">"Ibonisa kumodi yegridi."</string> + <string name="list_mode_showing" msgid="1225413902295895166">"Ibonisa kumodi yohlu."</string> </resources> diff --git a/res/values/colors.xml b/res/values/colors.xml index e00984ada..98287627e 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -42,14 +42,15 @@ <color name="shortcut_foreground">#ff3367d6</color> <color name="shortcut_background">#fff5f5f5</color> - <color name="briefcase_icon_color">#1A73E8</color> - <color name="cross_profile_button_text_color">#1A73E8</color> <color name="empty_state_text">#202124</color> <color name="error_image_color">#757575</color> - <color name="tab_indicator_color">#1A73E8</color> <!-- Blue 600 --> <color name="edge_effect">@android:color/black</color> <color name="doc_list_item_subtitle_enabled">#5F6368</color> <!-- Gray 700 --> <color name="doc_list_item_subtitle_disabled">#613c4043</color> <!-- 38% Grey800 --> + + <color name="list_divider_color">#1f000000</color> + <color name="list_item_selected_background_color">?android:colorSecondary</color> + <color name="color_surface_header">@color/app_background_color</color> </resources> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 07ee69526..3b326e136 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -89,8 +89,9 @@ <dimen name="root_info_header_height">60dp</dimen> <dimen name="root_info_header_horizontal_padding">24dp</dimen> - <dimen name="search_chip_group_margin">8dp</dimen> + <dimen name="search_chip_group_margin">20dp</dimen> <dimen name="search_chip_spacing">8dp</dimen> + <dimen name="search_chip_half_spacing">4dp</dimen> <dimen name="search_chip_icon_padding">4dp</dimen> <dimen name="search_chip_radius">16dp</dimen> @@ -110,15 +111,16 @@ <dimen name="apps_row_exit_icon_margin_bottom">6dp</dimen> <dimen name="apps_row_item_text_margin_horizontal">8dp</dimen> + <dimen name="search_bar_elevation">3dp</dimen> <dimen name="search_bar_radius">8dp</dimen> <dimen name="search_bar_background_margin_start">0dp</dimen> <dimen name="search_bar_background_margin_end">0dp</dimen> <dimen name="search_bar_margin">8dp</dimen> <dimen name="search_bar_text_size">16dp</dimen> + + <dimen name="action_bar_elevation">3dp</dimen> + <dimen name="action_bar_margin">1dp</dimen> <dimen name="action_bar_size">48dp</dimen> - <!--This value should equal actionBarSize + (2 x search_bar_margin)--> - <dimen name="action_bar_space_height">64dp</dimen> - <dimen name="action_bar_space_margin">@dimen/action_bar_space_height</dimen> <dimen name="action_mode_text_size">18sp</dimen> <dimen name="refresh_icon_range">64dp</dimen> diff --git a/res/values/overlayable.xml b/res/values/overlayable.xml index 621de83d4..31b374757 100644 --- a/res/values/overlayable.xml +++ b/res/values/overlayable.xml @@ -40,6 +40,8 @@ <!-- START COLOR --> <item type="color" name="primary"/> + <item type="color" name="list_item_selected_background_color"/> + <item type="color" name="color_surface_header"/> <!-- END COLOR --> <!-- START DIMEN --> diff --git a/res/values/strings.xml b/res/values/strings.xml index 088e67266..85950899c 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -15,6 +15,13 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Error when rename does not have any string--> + <string name="missing_rename_error">You need to rename this</string> + + <!-- Error to create new folder when name is not added --> + <string name="add_folder_name_error">You need to add a folder name</string> + <!-- Title of the Files application [CHAR LIMIT=32] --> <string name="files_label">Files</string> @@ -540,4 +547,11 @@ <!-- Snackbar shown when users drag and drop files from another app to DocumentsUI. [CHAR_LIMIT=100] --> <string name="drag_from_another_app">You can\u2019t move files from another app.</string> + + <!-- Accessibility announcement when switching to grid mode of files and directories shown. [CHAR_LIMIT=100] --> + <string name="grid_mode_showing">Showing in grid mode.</string> + + <!-- Accessibility announcement when switching to list mode of files and directories shown. [CHAR_LIMIT=100] --> + <string name="list_mode_showing">Showing in list mode.</string> + </resources> diff --git a/res/values/styles.xml b/res/values/styles.xml index 7b90d06dc..264f2b4e6 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -21,7 +21,7 @@ <style name="ActionModeStyle" parent="Widget.AppCompat.ActionMode"> <!-- attr "height" was used by support lib should not in overlay scope --> - <item name="height">@dimen/action_bar_space_height</item> + <item name="height">@dimen/action_bar_size</item> <item name="titleTextStyle">@style/ActionModeTitle</item> <item name="android:layout_margin">@dimen/search_bar_margin</item> </style> @@ -85,6 +85,7 @@ <style name="DialogTextButton" parent="@style/Widget.MaterialComponents.Button.TextButton.Dialog"> <item name="android:textAppearance">@style/MaterialButtonTextAppearance</item> + <item name="android:textColor">?android:attr/colorAccent</item> </style> <style name="EmptyStateButton" parent="@style/Widget.MaterialComponents.Button.TextButton"> diff --git a/res/values/styles_text.xml b/res/values/styles_text.xml index 8b3273183..6c3805921 100644 --- a/res/values/styles_text.xml +++ b/res/values/styles_text.xml @@ -19,6 +19,13 @@ <item name="android:textSize">11sp</item> </style> + <style name="SectionHeader" parent="@*android:style/TextAppearance.DeviceDefault.Medium"> + <item name="android:textColor">?android:attr/textColorPrimary</item> + <item name="android:textAllCaps">true</item> + <item name="fontFamily">@string/config_fontFamilyMedium</item> + <item name="android:textSize">12sp</item> + </style> + <style name="SortList" parent="@style/TextAppearance.AppCompat.Subhead"> <item name="android:textColor">@color/sort_list_text</item> <item name="fontFamily">@string/config_fontFamilyMedium</item> @@ -53,35 +60,36 @@ <style name="CardPrimaryText" parent="@style/TextAppearance.AppCompat.Subhead"> <item name="android:textColor">?android:attr/textColorPrimary</item> <item name="android:textSize">14sp</item> + <item name="fontFamily">@string/config_fontFamily</item> </style> <style name="ActionModeTitle" parent="@style/ToolbarTitle"> <item name="android:textSize">@dimen/action_mode_text_size</item> </style> - <style name="ToolbarTitle" parent="@android:style/TextAppearance.Material.Title"> + <style name="ToolbarTitle" parent="@*android:style/TextAppearance.DeviceDefault.Title"> <item name="fontFamily">@string/config_fontFamilyMedium</item> </style> - <style name="DrawerMenuTitle" parent="@android:style/TextAppearance.Material.Title"> + <style name="DrawerMenuTitle" parent="@*android:style/TextAppearance.DeviceDefault.Title"> <item name="android:textSize">24sp</item> <item name="fontFamily">@string/config_fontFamilyMedium</item> </style> - <style name="DrawerMenuHeader" parent="@android:style/TextAppearance.Material.Subhead"> + <style name="DrawerMenuHeader" parent="@*android:style/TextAppearance.DeviceDefault.Subhead"> <item name="android:textColor">?android:attr/textColorSecondary</item> <item name="android:textAllCaps">true</item> <item name="android:textSize">11sp</item> <item name="fontFamily">@string/config_fontFamilyMedium</item> </style> - <style name="DrawerMenuPrimary" parent="android:style/TextAppearance.Material.Body2"> + <style name="DrawerMenuPrimary" parent="*android:style/TextAppearance.DeviceDefault.Body2"> <item name="android:textSize">14sp</item> <item name="android:textColor">@color/item_root_primary_text</item> <item name="fontFamily">@string/config_fontFamilyMedium</item> </style> - <style name="DrawerMenuSecondary" parent="android:style/TextAppearance.Material.Body2"> + <style name="DrawerMenuSecondary" parent="*android:style/TextAppearance.DeviceDefault.Body2"> <item name="android:textSize">12sp</item> <item name="android:textColor">@color/item_root_secondary_text</item> </style> @@ -96,7 +104,7 @@ </style> <style name="BreadcrumbText" parent="@style/TextAppearance.Widget.AppCompat.Toolbar.Subtitle"> - <item name="android:textColor">?android:attr/colorControlNormal</item> + <item name="android:textColor">@color/horizontal_breadcrumb_color</item> <item name="android:textSize">14sp</item> <item name="fontFamily">@string/config_fontFamilyMedium</item> </style> @@ -113,18 +121,24 @@ </style> <style name="EmptyStateButtonTextAppearance"> - <item name="android:textColor">@color/cross_profile_button_text_color</item> + <item name="android:textColor">?android:attr/colorAccent</item> <item name="android:textSize">14sp</item> <item name="fontFamily">@string/config_fontFamilyMedium</item> </style> - <style name="TabTextAppearance" parent="@android:style/TextAppearance.DeviceDefault.Medium"> + <style name="TabTextAppearance" parent="@*android:style/TextAppearance.DeviceDefault.Medium"> <item name="android:textSize">14sp</item> <item name="fontFamily">@string/config_fontFamilyMedium</item> </style> - <style name="ItemDocListCaptionText" parent="@android:style/TextAppearance.Material.Caption"> + <style name="ItemCaptionText" parent="@*android:style/TextAppearance.DeviceDefault.Caption"> <item name="android:textColor">@color/doc_list_item_subtitle_color</item> + <item name="fontFamily">@string/config_fontFamily</item> + </style> + + <style name="MenuItemTextAppearance" parent="*android:style/TextAppearance.DeviceDefault.Body2"> + <item name="android:textSize">14sp</item> + <item name="fontFamily">@string/config_fontFamily</item> </style> </resources>
\ No newline at end of file diff --git a/res/values/themes.xml b/res/values/themes.xml index 59ddec056..443374282 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -74,9 +74,10 @@ <item name="materialAlertDialogTheme">@style/MaterialAlertDialogTheme</item> <item name="queryBackground">@color/menu_search_background</item> <item name="snackbarButtonStyle">@style/SnackbarButtonStyle</item> + <item name="android:itemTextAppearance">@style/MenuItemTextAppearance</item> </style> - <style name="TabTheme" parent="@style/Theme.MaterialComponents.DayNight"> + <style name="TabTheme" parent="@android:style/Theme.DeviceDefault.DayNight"> <item name="colorPrimary">@color/edge_effect</item> </style> </resources> diff --git a/src/com/android/documentsui/AbstractActionHandler.java b/src/com/android/documentsui/AbstractActionHandler.java index 0c612eddd..a310acee2 100644 --- a/src/com/android/documentsui/AbstractActionHandler.java +++ b/src/com/android/documentsui/AbstractActionHandler.java @@ -76,6 +76,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.concurrent.Executor; +import java.util.concurrent.Semaphore; import java.util.function.Consumer; import javax.annotation.Nullable; @@ -94,6 +95,7 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA private static final String TAG = "AbstractActionHandler"; private static final int REFRESH_SPINNER_TIMEOUT = 500; + private final Semaphore mLoaderSemaphore = new Semaphore(1); protected final T mActivity; protected final State mState; @@ -745,7 +747,7 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA public void onRootLoaded(@Nullable RootInfo root) { if (root == null) { // There is no such root in the other profile. Maybe the provider is missing on - // the other profile. Create a dummy root and open it to show error message. + // the other profile. Create a placeholder root and open it to show error message. root = RootInfo.copyRootInfo(mOriginalRoot); root.userId = mSelectedUserId; } @@ -767,7 +769,13 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA // For RecentsLoader and GlobalSearchLoader, they do not require rootDoc so it is no-op. // For DirectoryLoader, the loader needs to handle the case when stack.peek() returns null. - mActivity.getSupportLoaderManager().restartLoader(LOADER_ID, null, mBindings); + // Only allow restartLoader when the previous loader is finished or reset. Allowing + // multiple consecutive calls to restartLoader() / onCreateLoader() will probably create + // multiple active loaders, because restartLoader() does not interrupt previous loaders' + // loading, therefore may block the UI thread and cause ANR. + if (mLoaderSemaphore.tryAcquire()) { + mActivity.getSupportLoaderManager().restartLoader(LOADER_ID, null, mBindings); + } } protected final boolean launchToDocument(Uri uri) { @@ -942,10 +950,13 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA assert(result != null); mInjector.getModel().update(result); + mLoaderSemaphore.release(); } @Override - public void onLoaderReset(Loader<DirectoryResult> loader) {} + public void onLoaderReset(Loader<DirectoryResult> loader) { + mLoaderSemaphore.release(); + } } /** * A class primarily for the support of isolating our tests diff --git a/src/com/android/documentsui/ActionModeController.java b/src/com/android/documentsui/ActionModeController.java index d8cf59000..89b8ff383 100644 --- a/src/com/android/documentsui/ActionModeController.java +++ b/src/com/android/documentsui/ActionModeController.java @@ -46,6 +46,7 @@ public class ActionModeController extends SelectionObserver<String> private final Activity mActivity; private final SelectionTracker<String> mSelectionMgr; + private final NavigationViewManager mNavigator; private final MenuManager mMenuManager; private final MessageBuilder mMessages; @@ -58,11 +59,13 @@ public class ActionModeController extends SelectionObserver<String> public ActionModeController( Activity activity, SelectionTracker<String> selectionMgr, + NavigationViewManager navigator, MenuManager menuManager, MessageBuilder messages) { mActivity = activity; mSelectionMgr = selectionMgr; + mNavigator = navigator; mMenuManager = menuManager; mMessages = messages; } @@ -132,6 +135,8 @@ public class ActionModeController extends SelectionObserver<String> // Re-enable TalkBack for the toolbars, as they are no longer covered by action mode. mScope.accessibilityImportanceSetter.setAccessibilityImportance( View.IMPORTANT_FOR_ACCESSIBILITY_AUTO, R.id.toolbar, R.id.roots_toolbar); + + mNavigator.setActionModeActivated(false); } @Override @@ -141,6 +146,7 @@ public class ActionModeController extends SelectionObserver<String> mode.setTitle(mActivity.getResources().getQuantityString(R.plurals.selected_count, size)); if (size > 0) { + mNavigator.setActionModeActivated(true); // Hide the toolbars if action mode is enabled, so TalkBack doesn't navigate to // these controls when using linear navigation. diff --git a/src/com/android/documentsui/BaseActivity.java b/src/com/android/documentsui/BaseActivity.java index 8c0d9693f..b4ab5bdf0 100644 --- a/src/com/android/documentsui/BaseActivity.java +++ b/src/com/android/documentsui/BaseActivity.java @@ -167,6 +167,11 @@ public abstract class BaseActivity mNavigator = new NavigationViewManager(this, mDrawer, mState, this, breadcrumb, profileTabsContainer, DocumentsApplication.getUserIdManager(this)); + AppBarLayout appBarLayout = findViewById(R.id.app_bar); + if (appBarLayout != null) { + appBarLayout.addOnOffsetChangedListener(mNavigator); + } + SearchManagerListener searchListener = new SearchManagerListener() { /** * Called when search results changed. Refreshes the content of the directory. It @@ -934,7 +939,7 @@ public abstract class BaseActivity getMainLooper().getQueue().addIdleHandler(new IdleHandler() { @Override public boolean queueIdle() { - // If startup benchmark is requested by a whitelisted testing package, then + // If startup benchmark is requested by an allowedlist testing package, then // close the activity once idle, and notify the testing activity. if (getIntent().getBooleanExtra(EXTRA_BENCHMARK, false) && BENCHMARK_TESTING_PACKAGE.equals(getCallingPackage())) { diff --git a/src/com/android/documentsui/BreadcrumbHolder.java b/src/com/android/documentsui/BreadcrumbHolder.java index 68c0e6a0e..4baaf9ca5 100644 --- a/src/com/android/documentsui/BreadcrumbHolder.java +++ b/src/com/android/documentsui/BreadcrumbHolder.java @@ -27,14 +27,12 @@ public final class BreadcrumbHolder extends RecyclerView.ViewHolder { protected TextView mTitle; protected ImageView mArrow; - protected int mDefaultTextColor; protected boolean mLast; public BreadcrumbHolder(View itemView) { super(itemView); mTitle = itemView.findViewById(R.id.breadcrumb_text); mArrow = itemView.findViewById(R.id.breadcrumb_arrow); - mDefaultTextColor = mTitle.getTextColors().getDefaultColor(); mLast = false; } diff --git a/src/com/android/documentsui/CreateDirectoryFragment.java b/src/com/android/documentsui/CreateDirectoryFragment.java index 9ef58839b..4b066edb6 100644 --- a/src/com/android/documentsui/CreateDirectoryFragment.java +++ b/src/com/android/documentsui/CreateDirectoryFragment.java @@ -25,7 +25,6 @@ import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; @@ -37,6 +36,7 @@ import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.inputmethod.EditorInfo; +import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; @@ -59,6 +59,9 @@ import com.google.android.material.textfield.TextInputLayout; */ public class CreateDirectoryFragment extends DialogFragment { private static final String TAG_CREATE_DIRECTORY = "create_directory"; + private @Nullable DialogInterface mDialog; + private EditText mEditText; + private TextInputLayout mInputWrapper; public static void show(FragmentManager fm) { if (fm.isStateSaved()) { @@ -78,30 +81,20 @@ public class CreateDirectoryFragment extends DialogFragment { final LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext()); final View view = dialogInflater.inflate(R.layout.dialog_file_name, null, false); - final EditText editText = (EditText) view.findViewById(android.R.id.text1); + mEditText = (EditText) view.findViewById(android.R.id.text1); - final TextInputLayout inputWrapper = view.findViewById(R.id.input_wrapper); - inputWrapper.setHint(getString(R.string.input_hint_new_folder)); + mInputWrapper = view.findViewById(R.id.input_wrapper); + mInputWrapper.setHint(getString(R.string.input_hint_new_folder)); builder.setTitle(R.string.menu_create_dir); builder.setView(view); - - builder.setPositiveButton( - android.R.string.ok, - new OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - createDirectory(editText.getText().toString()); - } - }); - + builder.setPositiveButton(android.R.string.ok, null); builder.setNegativeButton(android.R.string.cancel, null); final AlertDialog dialog = builder.create(); - + dialog.setOnShowListener(this::onShowDialog); // Workaround for the problem - virtual keyboard doesn't show on the phone. Shared.ensureKeyboardPresent(context, dialog); - - editText.setOnEditorActionListener( + mEditText.setOnEditorActionListener( new OnEditorActionListener() { @Override public boolean onEditorAction( @@ -109,24 +102,39 @@ public class CreateDirectoryFragment extends DialogFragment { if ((actionId == EditorInfo.IME_ACTION_DONE) || (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER && event.hasNoModifiers())) { - createDirectory(editText.getText().toString()); - dialog.dismiss(); + createDirectory(mEditText.getText().toString()); return true; } return false; } }); - editText.requestFocus(); + mEditText.requestFocus(); return dialog; } - private void createDirectory(String name) { - final BaseActivity activity = (BaseActivity) getActivity(); - final DocumentInfo cwd = activity.getCurrentDirectory(); + private void onShowDialog(DialogInterface dialog) { + mDialog = dialog; + Button button = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE); + button.setOnClickListener(this::onClickDialog); + } + + private void onClickDialog(View view) { + createDirectory(mEditText.getText().toString()); + } - new CreateDirectoryTask(activity, cwd, name).executeOnExecutor( - ProviderExecutor.forAuthority(cwd.authority)); + private void createDirectory(String name) { + if (name.isEmpty()) { + mInputWrapper.setError(getContext().getString( + R.string.add_folder_name_error)); + } else { + final BaseActivity activity = (BaseActivity) getActivity(); + final DocumentInfo cwd = activity.getCurrentDirectory(); + + new CreateDirectoryTask(activity, cwd, name).executeOnExecutor( + ProviderExecutor.forAuthority(cwd.authority)); + mDialog.dismiss(); + } } private class CreateDirectoryTask extends AsyncTask<Void, Void, DocumentInfo> { diff --git a/src/com/android/documentsui/DirectoryLoader.java b/src/com/android/documentsui/DirectoryLoader.java index 31963962a..816144758 100644 --- a/src/com/android/documentsui/DirectoryLoader.java +++ b/src/com/android/documentsui/DirectoryLoader.java @@ -56,8 +56,7 @@ import java.util.concurrent.Executor; public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> { private static final String TAG = "DirectoryLoader"; - - private static final String[] SEARCH_REJECT_MIMES = new String[] { Document.MIME_TYPE_DIR }; + private static final String[] SEARCH_REJECT_MIMES = new String[]{Document.MIME_TYPE_DIR}; private static final String[] PHOTO_PICKING_ACCEPT_MIMES = new String[] {Document.MIME_TYPE_DIR, MimeTypes.IMAGE_MIME}; @@ -178,17 +177,16 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> { } cursor.registerContentObserver(mObserver); - // Filter hidden files. - cursor = new FilteringCursorWrapper(cursor, mState.showHiddenFiles); - + FilteringCursorWrapper filteringCursor = new FilteringCursorWrapper(cursor); + filteringCursor.filterHiddenFiles(mState.showHiddenFiles); if (mSearchMode && !mFeatures.isFoldersInSearchResultsEnabled()) { // There is no findDocumentPath API. Enable filtering on folders in search mode. - cursor = new FilteringCursorWrapper(cursor, null, SEARCH_REJECT_MIMES); + filteringCursor.filterMimes(/* acceptMimes= */ null, SEARCH_REJECT_MIMES); } - if (mPhotoPicking) { - cursor = new FilteringCursorWrapper(cursor, PHOTO_PICKING_ACCEPT_MIMES, null); + filteringCursor.filterMimes(PHOTO_PICKING_ACCEPT_MIMES, /* rejectMimes= */ null); } + cursor = filteringCursor; // TODO: When API tweaks have landed, use ContentResolver.EXTRA_HONORED_ARGS // instead of checking directly for ContentResolver.QUERY_ARG_SORT_COLUMNS (won't work) @@ -198,7 +196,7 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> { } else { cursor = mModel.sortCursor(cursor, mFileTypeLookup); } - result.cursor = cursor; + result.setCursor(cursor); } catch (Exception e) { Log.w(TAG, "Failed to query", e); result.exception = e; @@ -307,8 +305,8 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> { // Ensure the loader is stopped onStopLoading(); - if (mResult != null && mResult.cursor != null && mObserver != null) { - mResult.cursor.unregisterContentObserver(mObserver); + if (mResult != null && mResult.getCursor() != null && mObserver != null) { + mResult.getCursor().unregisterContentObserver(mObserver); } FileUtils.closeQuietly(mResult); @@ -316,10 +314,10 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> { } private boolean checkIfCursorStale(DirectoryResult result) { - if (result == null || result.cursor == null || result.cursor.isClosed()) { + if (result == null || result.getCursor() == null || result.getCursor().isClosed()) { return true; } - Cursor cursor = result.cursor; + Cursor cursor = result.getCursor(); try { cursor.moveToPosition(-1); for (int pos = 0; pos < cursor.getCount(); ++pos) { diff --git a/src/com/android/documentsui/DirectoryResult.java b/src/com/android/documentsui/DirectoryResult.java index f820db988..15ab0076d 100644 --- a/src/com/android/documentsui/DirectoryResult.java +++ b/src/com/android/documentsui/DirectoryResult.java @@ -16,29 +16,97 @@ package com.android.documentsui; +import static com.android.documentsui.base.DocumentInfo.getCursorString; + import android.content.ContentProviderClient; import android.database.Cursor; import android.os.FileUtils; +import android.provider.DocumentsContract; +import android.util.Log; import com.android.documentsui.archives.ArchivesProvider; import com.android.documentsui.base.DocumentInfo; +import java.util.HashSet; +import java.util.Set; + public class DirectoryResult implements AutoCloseable { - public Cursor cursor; + private static final String TAG = "DirectoryResult"; + public Exception exception; public DocumentInfo doc; ContentProviderClient client; + private Cursor mCursor; + private Set<String> mFileNames; + private String[] mModelIds; + @Override public void close() { - FileUtils.closeQuietly(cursor); + FileUtils.closeQuietly(mCursor); if (client != null && doc.isInArchive()) { ArchivesProvider.releaseArchive(client, doc.derivedUri); } FileUtils.closeQuietly(client); - cursor = null; client = null; doc = null; + + setCursor(null); + } + + public Cursor getCursor() { + return mCursor; + } + + public String[] getModelIds() { + return mModelIds; + } + + public Set<String> getFileNames() { + return mFileNames; + } + + /** Update the cursor and populate cursor-related fields. */ + public void setCursor(Cursor cursor) { + mCursor = cursor; + + if (mCursor == null) { + mFileNames = null; + mModelIds = null; + } else { + loadDataFromCursor(); + } + } + + /** Populate cursor-related field. Must not be called from UI thread. */ + private void loadDataFromCursor() { + ThreadHelper.assertNotOnMainThread(); + int cursorCount = mCursor.getCount(); + String[] modelIds = new String[cursorCount]; + Set<String> fileNames = new HashSet<>(); + try { + mCursor.moveToPosition(-1); + for (int pos = 0; pos < cursorCount; ++pos) { + if (!mCursor.moveToNext()) { + Log.e(TAG, "Fail to move cursor to next pos: " + pos); + return; + } + + // Generates a Model ID for a cursor entry that refers to a document. The Model + // ID is a unique string that can be used to identify the document referred to by + // the cursor. Prefix the ids with the authority to avoid collisions. + modelIds[pos] = ModelId.build(mCursor); + fileNames.add( + getCursorString(mCursor, DocumentsContract.Document.COLUMN_DISPLAY_NAME)); + } + } catch (Exception e) { + Log.e(TAG, "Exception when moving cursor. Stale cursor?", e); + return; + } + + // Model related data is only non-null when no error iterating through cursor. + mModelIds = modelIds; + mFileNames = fileNames; } } diff --git a/src/com/android/documentsui/DocsSelectionHelper.java b/src/com/android/documentsui/DocsSelectionHelper.java index b7a720c8b..956527a2e 100644 --- a/src/com/android/documentsui/DocsSelectionHelper.java +++ b/src/com/android/documentsui/DocsSelectionHelper.java @@ -37,10 +37,10 @@ public final class DocsSelectionHelper extends SelectionTracker<String> { private final DelegateFactory mFactory; - // initialize to a dummy object incase we get some input + // initialize to a stub object incase we get some input // event drive calls before we're properly initialized. // See: b/69306667. - private SelectionTracker<String> mDelegate = new DummySelectionTracker<>(); + private SelectionTracker<String> mDelegate = new StubSelectionTracker<>(); @VisibleForTesting DocsSelectionHelper(DelegateFactory factory) { diff --git a/src/com/android/documentsui/DrawerController.java b/src/com/android/documentsui/DrawerController.java index cb536162d..56b3a879f 100644 --- a/src/com/android/documentsui/DrawerController.java +++ b/src/com/android/documentsui/DrawerController.java @@ -55,7 +55,7 @@ public abstract class DrawerController implements DrawerListener { DrawerLayout layout = (DrawerLayout) activity.findViewById(R.id.drawer_layout); if (layout == null) { - return new DummyDrawerController(); + return new StubDrawerController(); } View drawer = activity.findViewById(R.id.drawer_roots); @@ -76,8 +76,8 @@ public abstract class DrawerController implements DrawerListener { /** * Returns a controller suitable for {@code Layout}. */ - static DrawerController createDummy() { - return new DummyDrawerController(); + static DrawerController createStub() { + return new StubDrawerController(); } private static int calculateDrawerWidth(Activity activity) { @@ -235,9 +235,9 @@ public abstract class DrawerController implements DrawerListener { } /* - * Dummy controller useful with clients that don't host a real drawer. + * Stub controller useful with clients that don't host a real drawer. */ - private static final class DummyDrawerController extends DrawerController { + private static final class StubDrawerController extends DrawerController { @Override public void setOpen(boolean open) {} diff --git a/src/com/android/documentsui/HorizontalBreadcrumb.java b/src/com/android/documentsui/HorizontalBreadcrumb.java index 5cfc65e09..94f0e13f9 100644 --- a/src/com/android/documentsui/HorizontalBreadcrumb.java +++ b/src/com/android/documentsui/HorizontalBreadcrumb.java @@ -176,7 +176,6 @@ public final class HorizontalBreadcrumb extends RecyclerView implements Breadcru public void onBindViewHolder(BreadcrumbHolder holder, int position) { final int padding = (int) holder.itemView.getResources() .getDimension(R.dimen.breadcrumb_item_padding); - final int enableColor = holder.itemView.getContext().getColor(R.color.primary); final boolean isFirst = position == 0; // Note that when isFirst is true, there might not be a DocumentInfo on the stack as it // could be an error state screen accessible from the root info. @@ -184,7 +183,7 @@ public final class HorizontalBreadcrumb extends RecyclerView implements Breadcru holder.mTitle.setText( isFirst ? mEnv.getCurrentRoot().title : mState.stack.get(position).displayName); - holder.mTitle.setTextColor(isLast ? enableColor : holder.mDefaultTextColor); + holder.mTitle.setEnabled(isLast); holder.mTitle.setPadding(isFirst ? padding * 3 : padding, padding, isLast ? padding * 2 : padding, padding); holder.mArrow.setVisibility(isLast ? View.GONE : View.VISIBLE); diff --git a/src/com/android/documentsui/Model.java b/src/com/android/documentsui/Model.java index 49e3c9b26..fdcebae3c 100644 --- a/src/com/android/documentsui/Model.java +++ b/src/com/android/documentsui/Model.java @@ -16,7 +16,6 @@ package com.android.documentsui; -import static com.android.documentsui.base.DocumentInfo.getCursorString; import static com.android.documentsui.base.SharedMinimal.DEBUG; import static com.android.documentsui.base.SharedMinimal.VERBOSE; @@ -25,7 +24,6 @@ import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.DocumentsContract; -import android.provider.DocumentsContract.Document; import android.util.Log; import androidx.annotation.IntDef; @@ -125,11 +123,21 @@ public class Model { return; } - mCursor = result.cursor; + mCursor = result.getCursor(); mCursorCount = mCursor.getCount(); doc = result.doc; - updateModelData(); + if (result.getModelIds() != null && result.getFileNames() != null) { + mIds = result.getModelIds(); + mFileNames.clear(); + mFileNames.addAll(result.getFileNames()); + + // Populate the positions. + mPositions.clear(); + for (int i = 0; i < mCursorCount; ++i) { + mPositions.put(mIds[i], i); + } + } final Bundle extras = mCursor.getExtras(); if (extras != null) { @@ -146,33 +154,6 @@ public class Model { return mCursorCount; } - /** - * Scan over the incoming cursor data, generate Model IDs for each row, and sort the IDs - * according to the current sort order. - */ - private void updateModelData() { - mIds = new String[mCursorCount]; - mFileNames.clear(); - mCursor.moveToPosition(-1); - for (int pos = 0; pos < mCursorCount; ++pos) { - if (!mCursor.moveToNext()) { - Log.e(TAG, "Fail to move cursor to next pos: " + pos); - return; - } - // Generates a Model ID for a cursor entry that refers to a document. The Model ID is a - // unique string that can be used to identify the document referred to by the cursor. - // Prefix the ids with the authority to avoid collisions. - mIds[pos] = ModelId.build(mCursor); - mFileNames.add(getCursorString(mCursor, Document.COLUMN_DISPLAY_NAME)); - } - - // Populate the positions. - mPositions.clear(); - for (int i = 0; i < mCursorCount; ++i) { - mPositions.put(mIds[i], i); - } - } - public boolean hasFileWithName(String name) { return mFileNames.contains(name); } diff --git a/src/com/android/documentsui/MultiRootDocumentsLoader.java b/src/com/android/documentsui/MultiRootDocumentsLoader.java index e7d09bfd3..7668b0693 100644 --- a/src/com/android/documentsui/MultiRootDocumentsLoader.java +++ b/src/com/android/documentsui/MultiRootDocumentsLoader.java @@ -104,8 +104,6 @@ public abstract class MultiRootDocumentsLoader extends AsyncTaskLoader<Directory * @param state current state * @param executors the executors of authorities * @param fileTypeMap the map of mime types and file types. - * @param lock the selection lock - * @param contentChangedCallback callback when content changed */ public MultiRootDocumentsLoader(Context context, ProvidersAccess providers, State state, Lookup<String, Executor> executors, Lookup<String, String> fileTypeMap) { @@ -126,8 +124,13 @@ public abstract class MultiRootDocumentsLoader extends AsyncTaskLoader<Directory @Override public DirectoryResult loadInBackground() { - synchronized (mTasks) { - return loadInBackgroundLocked(); + try { + synchronized (mTasks) { + return loadInBackgroundLocked(); + } + } catch (InterruptedException e) { + Log.w(TAG, "loadInBackground is interrupted: ", e); + return null; } } @@ -135,7 +138,7 @@ public abstract class MultiRootDocumentsLoader extends AsyncTaskLoader<Directory mObserver = observer; } - private DirectoryResult loadInBackgroundLocked() { + private DirectoryResult loadInBackgroundLocked() throws InterruptedException { if (mFirstPassLatch == null) { // First time through we kick off all the recent tasks, and wait // around to see if everyone finishes quickly. @@ -146,6 +149,11 @@ public abstract class MultiRootDocumentsLoader extends AsyncTaskLoader<Directory getQueryTask(rootEntry.getKey(), rootEntry.getValue())); } + if (isLoadInBackgroundCanceled()) { + // Loader is cancelled (e.g. about to be reset), preempt loading. + throw new InterruptedException("Loading is cancelled!"); + } + mFirstPassLatch = new CountDownLatch(mTasks.size()); for (QueryTask task : mTasks.values()) { mExecutors.lookup(task.authority).execute(task); @@ -166,6 +174,11 @@ public abstract class MultiRootDocumentsLoader extends AsyncTaskLoader<Directory int totalQuerySize = 0; List<Cursor> cursors = new ArrayList<>(mTasks.size()); for (QueryTask task : mTasks.values()) { + if (isLoadInBackgroundCanceled()) { + // Loader is cancelled (e.g. about to be reset), preempt loading. + throw new InterruptedException("Loading is cancelled!"); + } + if (task.isDone()) { try { final Cursor[] taskCursors = task.get(); @@ -181,17 +194,18 @@ public abstract class MultiRootDocumentsLoader extends AsyncTaskLoader<Directory continue; } - // Filter hidden files. - cursor = new FilteringCursorWrapper(cursor, mState.showHiddenFiles); - - final FilteringCursorWrapper filtered = new FilteringCursorWrapper( - cursor, mState.acceptMimes, getRejectMimes(), rejectBefore) { + final FilteringCursorWrapper filteredCursor = + new FilteringCursorWrapper(cursor) { @Override public void close() { // Ignored, since we manage cursor lifecycle internally } }; - cursors.add(filtered); + filteredCursor.filterHiddenFiles(mState.showHiddenFiles); + filteredCursor.filterMimes(mState.acceptMimes, getRejectMimes()); + filteredCursor.filterLastModified(rejectBefore); + + cursors.add(filteredCursor); } } catch (InterruptedException e) { @@ -238,7 +252,7 @@ public abstract class MultiRootDocumentsLoader extends AsyncTaskLoader<Directory extras.putBoolean(DocumentsContract.EXTRA_LOADING, !allDone); sorted.setExtras(extras); - result.cursor = sorted; + result.setCursor(sorted); return result; } @@ -292,7 +306,7 @@ public abstract class MultiRootDocumentsLoader extends AsyncTaskLoader<Directory DirectoryResult oldResult = mResult; mResult = result; - if (isStarted()) { + if (isStarted() && !isAbandoned() && !isLoadInBackgroundCanceled()) { super.deliverResult(result); } @@ -326,9 +340,6 @@ public abstract class MultiRootDocumentsLoader extends AsyncTaskLoader<Directory protected void onReset() { super.onReset(); - // Ensure the loader is stopped - onStopLoading(); - synchronized (mTasks) { for (QueryTask task : mTasks.values()) { mExecutors.lookup(task.authority).execute(() -> FileUtils.closeQuietly(task)); @@ -459,10 +470,10 @@ public abstract class MultiRootDocumentsLoader extends AsyncTaskLoader<Directory } private boolean checkIfCursorStale(DirectoryResult result) { - if (result == null || result.cursor == null || result.cursor.isClosed()) { + if (result == null || result.getCursor() == null || result.getCursor().isClosed()) { return true; } - Cursor cursor = result.cursor; + Cursor cursor = result.getCursor(); try { cursor.moveToPosition(-1); for (int pos = 0; pos < cursor.getCount(); ++pos) { diff --git a/src/com/android/documentsui/NavigationViewManager.java b/src/com/android/documentsui/NavigationViewManager.java index 204971dce..83979ab6e 100644 --- a/src/com/android/documentsui/NavigationViewManager.java +++ b/src/com/android/documentsui/NavigationViewManager.java @@ -19,35 +19,44 @@ package com.android.documentsui; import static com.android.documentsui.base.SharedMinimal.VERBOSE; import android.content.res.Resources; +import android.content.res.TypedArray; import android.graphics.Outline; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.util.Log; import android.view.View; import android.view.ViewOutlineProvider; +import android.view.Window; +import android.view.WindowManager; +import android.widget.FrameLayout; +import androidx.annotation.ColorRes; import androidx.annotation.Nullable; import androidx.appcompat.widget.Toolbar; +import androidx.core.content.ContextCompat; import com.android.documentsui.base.RootInfo; import com.android.documentsui.base.State; import com.android.documentsui.base.UserId; import com.android.documentsui.dirlist.AnimationView; +import com.android.documentsui.util.VersionUtils; import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.CollapsingToolbarLayout; -import com.google.android.material.tabs.TabLayout; import java.util.function.IntConsumer; /** * A facade over the portions of the app and drawer toolbars. */ -public class NavigationViewManager { +public class NavigationViewManager implements AppBarLayout.OnOffsetChangedListener { private static final String TAG = "NavigationViewManager"; private final DrawerController mDrawer; private final Toolbar mToolbar; + private final BaseActivity mActivity; + private final View mHeader; private final State mState; private final NavigationViewManager.Environment mEnv; private final Breadcrumb mBreadcrumb; @@ -55,9 +64,13 @@ public class NavigationViewManager { private final View mSearchBarView; private final CollapsingToolbarLayout mCollapsingBarLayout; private final Drawable mDefaultActionBarBackground; + private final ViewOutlineProvider mDefaultOutlineProvider; private final ViewOutlineProvider mSearchBarOutlineProvider; private final boolean mShowSearchBar; + private boolean mIsActionModeActivated = false; + private @ColorRes int mDefaultStatusBarColorResId; + public NavigationViewManager( BaseActivity activity, DrawerController drawer, @@ -67,7 +80,9 @@ public class NavigationViewManager { View tabLayoutContainer, UserIdManager userIdManager) { + mActivity = activity; mToolbar = activity.findViewById(R.id.toolbar); + mHeader = activity.findViewById(R.id.directory_header); mDrawer = drawer; mState = state; mEnv = env; @@ -85,8 +100,18 @@ public class NavigationViewManager { mSearchBarView = activity.findViewById(R.id.searchbar_title); mCollapsingBarLayout = activity.findViewById(R.id.collapsing_toolbar); mDefaultActionBarBackground = mToolbar.getBackground(); + mDefaultOutlineProvider = mToolbar.getOutlineProvider(); mShowSearchBar = activity.getResources().getBoolean(R.bool.show_search_bar); + final int[] styledAttrs = {android.R.attr.statusBarColor}; + TypedArray a = mActivity.obtainStyledAttributes(styledAttrs); + mDefaultStatusBarColorResId = a.getResourceId(0, -1); + if (mDefaultStatusBarColorResId == -1) { + Log.w(TAG, "Retrieve statusBarColorResId from theme failed, assigned default"); + mDefaultStatusBarColorResId = R.color.app_background_color; + } + a.recycle(); + final Resources resources = mToolbar.getResources(); final int radius = resources.getDimensionPixelSize(R.dimen.search_bar_radius); final int marginStart = @@ -102,6 +127,36 @@ public class NavigationViewManager { }; } + @Override + public void onOffsetChanged(AppBarLayout appBarLayout, int offset) { + if (!VersionUtils.isAtLeastS()) { + return; + } + + // For S+ Only. Change toolbar color dynamically based on scroll offset. + // Usually this can be done in xml using app:contentScrim and app:statusBarScrim, however + // in our case since we also put directory_header.xml inside the CollapsingToolbarLayout, + // the scrim will also cover the directory header. Long term need to think about how to + // move directory_header out of the AppBarLayout. + + Window window = mActivity.getWindow(); + View actionBar = window.getDecorView().findViewById(R.id.action_mode_bar); + int dynamicHeaderColor = ContextCompat.getColor(mActivity, + offset == 0 ? mDefaultStatusBarColorResId : R.color.color_surface_header); + if (actionBar != null) { + // Action bar needs to be updated separately for selection mode. + actionBar.setBackgroundColor(dynamicHeaderColor); + } + + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + window.setStatusBarColor(dynamicHeaderColor); + if (shouldShowSearchBar()) { + // Do not change search bar background. + } else { + mToolbar.setBackground(new ColorDrawable(dynamicHeaderColor)); + } + } + public void setSearchBarClickListener(View.OnClickListener listener) { mSearchBarView.setOnClickListener(listener); } @@ -138,6 +193,11 @@ public class NavigationViewManager { return mProfileTabs.getSelectedUser(); } + public void setActionModeActivated(boolean actionModeActivated) { + mIsActionModeActivated = actionModeActivated; + update(); + } + public void update() { updateScrollFlag(); updateToolbar(); @@ -177,30 +237,57 @@ public class NavigationViewManager { AppBarLayout.LayoutParams lp = (AppBarLayout.LayoutParams) mCollapsingBarLayout.getLayoutParams(); - if (shouldShowSearchBar()) { - lp.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL - | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS - | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED); - } else { - lp.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL - | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED); - } + lp.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL + | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED); mCollapsingBarLayout.setLayoutParams(lp); } private void updateToolbar() { - if (shouldShowSearchBar()) { + if (mCollapsingBarLayout == null) { + // Tablet mode does not use CollapsingBarLayout + // (res/layout-sw720dp/directory_app_bar.xml or res/layout/fixed_layout.xml) + if (shouldShowSearchBar()) { + mToolbar.setBackgroundResource(R.drawable.search_bar_background); + mToolbar.setOutlineProvider(mSearchBarOutlineProvider); + } else { + mToolbar.setBackground(mDefaultActionBarBackground); + mToolbar.setOutlineProvider(null); + } + return; + } + + CollapsingToolbarLayout.LayoutParams toolbarLayoutParams = + (CollapsingToolbarLayout.LayoutParams) mToolbar.getLayoutParams(); + + int headerTopOffset = 0; + if (shouldShowSearchBar() && !mIsActionModeActivated) { mToolbar.setBackgroundResource(R.drawable.search_bar_background); mToolbar.setOutlineProvider(mSearchBarOutlineProvider); + int searchBarMargin = mToolbar.getResources().getDimensionPixelSize( + R.dimen.search_bar_margin); + toolbarLayoutParams.setMargins(searchBarMargin, searchBarMargin, searchBarMargin, + searchBarMargin); + mToolbar.setLayoutParams(toolbarLayoutParams); + mToolbar.setElevation( + mToolbar.getResources().getDimensionPixelSize(R.dimen.search_bar_elevation)); + headerTopOffset = toolbarLayoutParams.height + searchBarMargin * 2; } else { mToolbar.setBackground(mDefaultActionBarBackground); - mToolbar.setOutlineProvider(null); + mToolbar.setOutlineProvider(mDefaultOutlineProvider); + int actionBarMargin = mToolbar.getResources().getDimensionPixelSize( + R.dimen.action_bar_margin); + toolbarLayoutParams.setMargins(0, 0, 0, /* bottom= */ actionBarMargin); + mToolbar.setLayoutParams(toolbarLayoutParams); + mToolbar.setElevation( + mToolbar.getResources().getDimensionPixelSize(R.dimen.action_bar_elevation)); + headerTopOffset = toolbarLayoutParams.height + actionBarMargin; } - if (mCollapsingBarLayout != null) { - View overlayBackground = - mCollapsingBarLayout.findViewById(R.id.toolbar_background_layout); - overlayBackground.setVisibility(shouldShowSearchBar() ? View.GONE : View.VISIBLE); + if (!mIsActionModeActivated) { + FrameLayout.LayoutParams headerLayoutParams = + (FrameLayout.LayoutParams) mHeader.getLayoutParams(); + headerLayoutParams.setMargins(0, /* top= */ headerTopOffset, 0, 0); + mHeader.setLayoutParams(headerLayoutParams); } } @@ -209,7 +296,8 @@ public class NavigationViewManager { } // Hamburger if drawer is present, else sad nullness. - private @Nullable Drawable getActionBarIcon() { + private @Nullable + Drawable getActionBarIcon() { if (mDrawer.isPresent()) { return mToolbar.getContext().getDrawable(R.drawable.ic_hamburger); } else { @@ -223,16 +311,23 @@ public class NavigationViewManager { interface Breadcrumb { void setup(Environment env, State state, IntConsumer listener); + void show(boolean visibility); + void postUpdate(); } interface Environment { - @Deprecated // Use CommonAddones#getCurrentRoot + @Deprecated + // Use CommonAddones#getCurrentRoot RootInfo getCurrentRoot(); + String getDrawerTitle(); - @Deprecated // Use CommonAddones#refreshCurrentRootAndDirectory + + @Deprecated + // Use CommonAddones#refreshCurrentRootAndDirectory void refreshCurrentRootAndDirectory(int animation); + boolean isSearchExpanded(); } } diff --git a/src/com/android/documentsui/PreBootReceiver.java b/src/com/android/documentsui/PreBootReceiver.java index c47631654..f5ad9395a 100644 --- a/src/com/android/documentsui/PreBootReceiver.java +++ b/src/com/android/documentsui/PreBootReceiver.java @@ -30,6 +30,7 @@ import android.content.res.Resources; import android.util.Log; import com.android.documentsui.theme.ThemeOverlayManager; +import com.android.documentsui.util.VersionUtils; /** * A receiver listening action.PRE_BOOT_COMPLETED event for setting component enable or disable. @@ -91,11 +92,15 @@ public class PreBootReceiver extends BroadcastReceiver { int resId = overlayRes.getIdentifier(config, "bool", overlayPkg); if (resId != 0) { final ComponentName component = new ComponentName(packageName, className); - final boolean value = overlayRes.getBoolean(resId); + boolean enabled = overlayRes.getBoolean(resId); + if (VersionUtils.isAtLeastS() && CONFIG_IS_LAUNCHER_ENABLED.equals(config)) { + enabled = false; // Do not allow LauncherActivity to be enabled for S+. + } if (DEBUG) { - Log.i(TAG, "Overlay package:" + overlayPkg + ", customize " + config + ":" + value); + Log.i(TAG, + "Overlay package:" + overlayPkg + ", customize " + config + ":" + enabled); } - pm.setComponentEnabledSetting(component, value + pm.setComponentEnabledSetting(component, enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); diff --git a/src/com/android/documentsui/RootsMonitor.java b/src/com/android/documentsui/RootsMonitor.java index d4354b4cb..e87e53a64 100644 --- a/src/com/android/documentsui/RootsMonitor.java +++ b/src/com/android/documentsui/RootsMonitor.java @@ -22,7 +22,6 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.Uri; - import androidx.localbroadcastmanager.content.LocalBroadcastManager; import com.android.documentsui.AbstractActionHandler.CommonAddons; @@ -137,7 +136,7 @@ final class RootsMonitor<T extends Activity & CommonAddons> { // activity. final Uri uri = mOwner.getIntent().getData(); if (uri != null && uri.equals(mCurrentRoot.getUri())) { - mOwner.finishAndRemoveTask(); + mOwner.finish(); return; } diff --git a/src/com/android/documentsui/DummyProfileTabsAddons.java b/src/com/android/documentsui/StubProfileTabsAddons.java index 697025e23..cac175945 100644 --- a/src/com/android/documentsui/DummyProfileTabsAddons.java +++ b/src/com/android/documentsui/StubProfileTabsAddons.java @@ -17,9 +17,9 @@ package com.android.documentsui; /** - * A dummy {@ProfileTabsAddons} implementation. + * A stub {@ProfileTabsAddons} implementation. */ -public class DummyProfileTabsAddons implements ProfileTabsAddons { +public class StubProfileTabsAddons implements ProfileTabsAddons { @Override public void setEnabled(boolean enabled) { diff --git a/src/com/android/documentsui/DummySelectionTracker.java b/src/com/android/documentsui/StubSelectionTracker.java index 49b9ad918..1a392144f 100644 --- a/src/com/android/documentsui/DummySelectionTracker.java +++ b/src/com/android/documentsui/StubSelectionTracker.java @@ -26,10 +26,11 @@ import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver; import java.util.Set; /** - * A dummy SelectionTracker used by DocsSelectionHelper before a real SelectionTracker has been + * A stub SelectionTracker used by DocsSelectionHelper before a real SelectionTracker has been * initialized by DirectoryFragment. + * @param <K> Selection key type which extends {@link SelectionTracker}. */ -public class DummySelectionTracker<K> extends SelectionTracker<K> { +public class StubSelectionTracker<K> extends SelectionTracker<K> { @Override public void addObserver(SelectionObserver observer) { diff --git a/src/com/android/documentsui/ThreadHelper.java b/src/com/android/documentsui/ThreadHelper.java new file mode 100644 index 000000000..bb123b69b --- /dev/null +++ b/src/com/android/documentsui/ThreadHelper.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.documentsui; + +import android.os.Looper; + +/** Class for handler/thread utils. */ +public final class ThreadHelper { + private ThreadHelper() { + } + + static final String MUST_NOT_ON_MAIN_THREAD_MSG = + "This method should not be called on main thread."; + static final String MUST_ON_MAIN_THREAD_MSG = + "This method should only be called on main thread."; + + /** Verifies that current thread is not the UI thread. */ + public static void assertNotOnMainThread() { + if (Looper.getMainLooper().getThread() == Thread.currentThread()) { + fatalAssert(MUST_NOT_ON_MAIN_THREAD_MSG); + } + } + + /** Verifies that current thread is the UI thread. */ + public static void assertOnMainThread() { + if (Looper.getMainLooper().getThread() != Thread.currentThread()) { + fatalAssert(MUST_ON_MAIN_THREAD_MSG); + } + } + + /** + * Exceptions thrown in background threads are silently swallowed on Android. Use the + * uncaught exception handler of the UI thread to force the app to crash. + */ + public static void fatalAssert(final String message) { + crashMainThread(new AssertionError(message)); + } + + private static void crashMainThread(Throwable t) { + Thread.UncaughtExceptionHandler uiThreadExceptionHandler = + Looper.getMainLooper().getThread().getUncaughtExceptionHandler(); + uiThreadExceptionHandler.uncaughtException(Thread.currentThread(), t); + } +} diff --git a/src/com/android/documentsui/archives/ArchiveEntryInputStream.java b/src/com/android/documentsui/archives/ArchiveEntryInputStream.java index 0b1c0c2e6..2c34e5a71 100644 --- a/src/com/android/documentsui/archives/ArchiveEntryInputStream.java +++ b/src/com/android/documentsui/archives/ArchiveEntryInputStream.java @@ -20,16 +20,16 @@ import android.text.TextUtils; import androidx.annotation.NonNull; -import java.io.Closeable; -import java.io.IOException; -import java.io.InputStream; - import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.ArchiveInputStream; import org.apache.commons.compress.archivers.sevenz.SevenZFile; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipFile; +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; + /** * To simulate the input stream by using ZipFile, SevenZFile, or ArchiveInputStream. */ @@ -124,7 +124,7 @@ abstract class ArchiveEntryInputStream extends InputStream { throw new IllegalArgumentException("ArchiveEntry is empty"); } - if (archiveEntry.isDirectory() || archiveEntry.getSize() <= 0 + if (archiveEntry.isDirectory() || archiveEntry.getSize() < 0 || TextUtils.isEmpty(archiveEntry.getName())) { throw new IllegalArgumentException("ArchiveEntry is an invalid file entry"); } diff --git a/src/com/android/documentsui/base/FilteringCursorWrapper.java b/src/com/android/documentsui/base/FilteringCursorWrapper.java index 9e557b4aa..577e47c33 100644 --- a/src/com/android/documentsui/base/FilteringCursorWrapper.java +++ b/src/com/android/documentsui/base/FilteringCursorWrapper.java @@ -29,67 +29,62 @@ import android.provider.DocumentsContract.Document; import android.util.Log; /** - * Cursor wrapper that filters MIME types not matching given list. + * Cursor wrapper that filters cursor results by given conditions. */ public class FilteringCursorWrapper extends AbstractCursor { private final Cursor mCursor; - private final int[] mPosition; + private int[] mPositions; private int mCount; - public FilteringCursorWrapper(Cursor cursor, String[] acceptMimes) { - this(cursor, acceptMimes, null, Long.MIN_VALUE); - } - - public FilteringCursorWrapper(Cursor cursor, String[] acceptMimes, String[] rejectMimes) { - this(cursor, acceptMimes, rejectMimes, Long.MIN_VALUE); - } - - public FilteringCursorWrapper( - Cursor cursor, String[] acceptMimes, String[] rejectMimes, long rejectBefore) { + public FilteringCursorWrapper(Cursor cursor) { mCursor = cursor; + mCount = cursor.getCount(); + mPositions = new int[mCount]; + for (int i = 0; i < mCount; i++) { + mPositions[i] = i; + } + } - final int count = cursor.getCount(); - mPosition = new int[count]; - - cursor.moveToPosition(-1); - while (cursor.moveToNext() && mCount < count) { + /** + * Filters cursor according to mimes. If both lists are empty, all mimes will be rejected. + * + * @param acceptMimes allowed list of mimes + * @param rejectMimes blocked list of mimes + */ + public void filterMimes(String[] acceptMimes, String[] rejectMimes) { + filterByCondition((cursor) -> { final String mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); - final long lastModified = getCursorLong(cursor, Document.COLUMN_LAST_MODIFIED); if (rejectMimes != null && MimeTypes.mimeMatches(rejectMimes, mimeType)) { - continue; + return false; } - if (lastModified < rejectBefore) { - continue; - } - if (MimeTypes.mimeMatches(acceptMimes, mimeType)) { - mPosition[mCount++] = cursor.getPosition(); - } - } - - if (DEBUG && mCount != cursor.getCount()) { - Log.d(TAG, "Before filtering " + cursor.getCount() + ", after " + mCount); - } + return MimeTypes.mimeMatches(acceptMimes, mimeType); + }); } - public FilteringCursorWrapper(Cursor cursor, boolean showHiddenFiles) { - mCursor = cursor; - - final int count = cursor.getCount(); - mPosition = new int[count]; + /** Filters cursor according to last modified time, and reject earlier than given timestamp. */ + public void filterLastModified(long rejectBeforeTimestamp) { + filterByCondition((cursor) -> { + final long lastModified = getCursorLong(cursor, Document.COLUMN_LAST_MODIFIED); + return lastModified >= rejectBeforeTimestamp; + }); + } - cursor.moveToPosition(-1); - while (cursor.moveToNext() && mCount < count) { - final String name = getCursorString(cursor, Document.COLUMN_DISPLAY_NAME); - if (!showHiddenFiles && name != null && name.startsWith(".")) { - continue; - } - mPosition[mCount++] = cursor.getPosition(); + /** Filter hidden files based on preference. */ + public void filterHiddenFiles(boolean showHiddenFiles) { + if (showHiddenFiles) { + return; } - if (DEBUG && mCount != cursor.getCount()) { - Log.d(TAG, "Before filtering " + cursor.getCount() + ", after " + mCount); - } + filterByCondition((cursor) -> { + // Judge by name and documentId separately because for some providers + // e.g. DownloadProvider, documentId may not contain file name. + final String name = getCursorString(cursor, Document.COLUMN_DISPLAY_NAME); + final String documentId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID); + boolean documentIdHidden = documentId != null && documentId.contains("/."); + boolean fileNameHidden = name != null && name.startsWith("."); + return !(documentIdHidden || fileNameHidden); + }); } @Override @@ -105,7 +100,7 @@ public class FilteringCursorWrapper extends AbstractCursor { @Override public boolean onMove(int oldPosition, int newPosition) { - return mCursor.moveToPosition(mPosition[newPosition]); + return mCursor.moveToPosition(mPositions[newPosition]); } @Override @@ -167,4 +162,27 @@ public class FilteringCursorWrapper extends AbstractCursor { public void unregisterContentObserver(ContentObserver observer) { mCursor.unregisterContentObserver(observer); } + + private interface FilteringCondition { + boolean accept(Cursor cursor); + } + + private void filterByCondition(FilteringCondition condition) { + final int oldCount = this.getCount(); + int[] newPositions = new int[oldCount]; + int newCount = 0; + + this.moveToPosition(-1); + while (this.moveToNext() && newCount < oldCount) { + if (condition.accept(mCursor)) { + newPositions[newCount++] = mPositions[this.getPosition()]; + } + } + + if (DEBUG && newCount != this.getCount()) { + Log.d(TAG, "Before filtering " + oldCount + ", after " + newCount); + } + mCount = newCount; + mPositions = newPositions; + } } diff --git a/src/com/android/documentsui/base/Shared.java b/src/com/android/documentsui/base/Shared.java index f0f650b7b..5ac9de4d7 100644 --- a/src/com/android/documentsui/base/Shared.java +++ b/src/com/android/documentsui/base/Shared.java @@ -171,6 +171,10 @@ public final class Shared { * Whether the calling app should be restricted in Storage Access Framework or not. */ public static boolean shouldRestrictStorageAccessFramework(Activity activity) { + if (VersionUtils.isAtLeastS()) { + return true; + } + if (!VersionUtils.isAtLeastR()) { return false; } @@ -314,7 +318,8 @@ public final class Shared { public static void ensureKeyboardPresent(Context context, AlertDialog dialog) { if (!isHardwareKeyboardAvailable(context)) { dialog.getWindow().setSoftInputMode( - WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); + WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE + | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); } } diff --git a/src/com/android/documentsui/base/DummyLookup.java b/src/com/android/documentsui/base/StubLookup.java index 11a637580..2a2dc9bf1 100644 --- a/src/com/android/documentsui/base/DummyLookup.java +++ b/src/com/android/documentsui/base/StubLookup.java @@ -17,8 +17,10 @@ package com.android.documentsui.base; /** * Lookup that always returns null. + * @param <K> input type (the "key") which implements {@link Lookup}. + * @param <V> output type (the "value") which implements {@link Lookup}. */ -public final class DummyLookup<K, V> implements Lookup<K, V> { +public final class StubLookup<K, V> implements Lookup<K, V> { @Override public V lookup(K key) { return null; diff --git a/src/com/android/documentsui/dirlist/DirectoryFragment.java b/src/com/android/documentsui/dirlist/DirectoryFragment.java index 8fa02ca46..25efb8c50 100644 --- a/src/com/android/documentsui/dirlist/DirectoryFragment.java +++ b/src/com/android/documentsui/dirlist/DirectoryFragment.java @@ -180,6 +180,7 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On private SelectionMetadata mSelectionMetadata; private KeyInputHandler mKeyListener; private @Nullable DragHoverListener mDragHoverListener; + private View mRootView; private IconHelper mIconHelper; private SwipeRefreshLayout mRefreshLayout; private RecyclerView mRecView; @@ -348,12 +349,12 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On mHandler = new Handler(Looper.getMainLooper()); mActivity = (BaseActivity) getActivity(); - final View view = inflater.inflate(R.layout.fragment_directory, container, false); + mRootView = inflater.inflate(R.layout.fragment_directory, container, false); - mProgressBar = view.findViewById(R.id.progressbar); + mProgressBar = mRootView.findViewById(R.id.progressbar); assert mProgressBar != null; - mRecView = (RecyclerView) view.findViewById(R.id.dir_list); + mRecView = (RecyclerView) mRootView.findViewById(R.id.dir_list); mRecView.setRecyclerListener( new RecyclerListener() { @Override @@ -362,12 +363,12 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On } }); - mRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.refresh_layout); + mRefreshLayout = (SwipeRefreshLayout) mRootView.findViewById(R.id.refresh_layout); mRefreshLayout.setOnRefreshListener(this); mRecView.setItemAnimator(new DirectoryItemAnimator()); mInjector = mActivity.getInjector(); - // Initially, this selection tracker (delegator) uses a dummy implementation, so it must be + // Initially, this selection tracker (delegator) uses a stub implementation, so it must be // updated (reset) when necessary things are ready. mSelectionMgr = mInjector.selectionMgr; mModel = mInjector.getModel(); @@ -398,7 +399,7 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On setPreDrawListenerEnabled(true); - return view; + return mRootView; } @Override @@ -492,7 +493,7 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On this::getModelId, mRecView::findChildViewUnder, DocumentsApplication.getDragAndDropManager(mActivity)) - : DragStartListener.DUMMY; + : DragStartListener.STUB; { // Limiting the scope of the localTracker so nobody uses it. @@ -585,6 +586,9 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On // Add listener to update contents on sort model change mState.sortModel.addListener(mSortListener); + // After SD card is formatted, we go out of the view and come back. Similarly when users + // go out of the app to delete some files, we want to refresh the directory. + onRefresh(); } @Override @@ -684,6 +688,9 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On public void onViewModeChanged() { // Mode change is just visual change; no need to kick loader. + mRootView.announceForAccessibility(getString( + mState.derivedMode == State.MODE_GRID ? R.string.grid_mode_showing + : R.string.list_mode_showing)); onDisplayStateChanged(); } diff --git a/src/com/android/documentsui/dirlist/DocumentsAdapter.java b/src/com/android/documentsui/dirlist/DocumentsAdapter.java index 7d09d689f..41ce73c8c 100644 --- a/src/com/android/documentsui/dirlist/DocumentsAdapter.java +++ b/src/com/android/documentsui/dirlist/DocumentsAdapter.java @@ -36,8 +36,8 @@ import java.util.List; /** * DocumentsAdapter provides glue between a directory Model, and RecyclerView. We've * abstracted this a bit in order to decompose some specialized support - * for adding dummy layout objects (@see SectionBreakDocumentsAdapter). Handling of the - * dummy layout objects was error prone when interspersed with the core mode / adapter code. + * for adding stub layout objects (@see SectionBreakDocumentsAdapter). Handling of the + * stub layout objects was error prone when interspersed with the core mode / adapter code. * * @see ModelBackedDocumentsAdapter * @see DirectoryAddonsAdapter diff --git a/src/com/android/documentsui/dirlist/DocumentsSwipeRefreshLayout.java b/src/com/android/documentsui/dirlist/DocumentsSwipeRefreshLayout.java index a1963645b..4b66b857f 100644 --- a/src/com/android/documentsui/dirlist/DocumentsSwipeRefreshLayout.java +++ b/src/com/android/documentsui/dirlist/DocumentsSwipeRefreshLayout.java @@ -42,12 +42,12 @@ public class DocumentsSwipeRefreshLayout extends SwipeRefreshLayout { public DocumentsSwipeRefreshLayout(Context context, AttributeSet attrs) { super(context, attrs); - final int[] styledAttrs = {android.R.attr.colorPrimary}; + final int[] styledAttrs = {android.R.attr.colorAccent}; TypedArray a = context.obtainStyledAttributes(styledAttrs); @ColorRes int colorId = a.getResourceId(0, -1); if (colorId == -1) { - Log.w(TAG, "Retrive colorPrimary colorId from theme fail, assign R.color.primary"); + Log.w(TAG, "Retrieve colorAccent colorId from theme fail, assign R.color.primary"); colorId = R.color.primary; } a.recycle(); diff --git a/src/com/android/documentsui/dirlist/DragStartListener.java b/src/com/android/documentsui/dirlist/DragStartListener.java index 8fe087229..0adddcca8 100644 --- a/src/com/android/documentsui/dirlist/DragStartListener.java +++ b/src/com/android/documentsui/dirlist/DragStartListener.java @@ -48,7 +48,7 @@ import javax.annotation.Nullable; */ interface DragStartListener { - static final DragStartListener DUMMY = new DragStartListener() { + DragStartListener STUB = new DragStartListener() { @Override public boolean onDragEvent(MotionEvent event) { return false; diff --git a/src/com/android/documentsui/dirlist/GridDocumentHolder.java b/src/com/android/documentsui/dirlist/GridDocumentHolder.java index 9e429688a..631298f12 100644 --- a/src/com/android/documentsui/dirlist/GridDocumentHolder.java +++ b/src/com/android/documentsui/dirlist/GridDocumentHolder.java @@ -89,7 +89,6 @@ final class GridDocumentHolder extends DocumentHolder { // But it should be an error to be set to selected && be disabled. if (!itemView.isEnabled()) { assert(!selected); - return; } super.setSelected(selected, animate); diff --git a/src/com/android/documentsui/dirlist/ListDocumentHolder.java b/src/com/android/documentsui/dirlist/ListDocumentHolder.java index 1bbeec1dd..f6a900236 100644 --- a/src/com/android/documentsui/dirlist/ListDocumentHolder.java +++ b/src/com/android/documentsui/dirlist/ListDocumentHolder.java @@ -22,7 +22,9 @@ import static com.android.documentsui.base.DocumentInfo.getCursorString; import android.content.Context; import android.database.Cursor; import android.graphics.Rect; +import android.text.TextUtils; import android.text.format.Formatter; +import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; @@ -41,15 +43,20 @@ import com.android.documentsui.base.UserId; import com.android.documentsui.roots.RootCursorWrapper; import com.android.documentsui.ui.Views; +import java.util.ArrayList; import java.util.function.Function; final class ListDocumentHolder extends DocumentHolder { + private static final String TAG = "ListDocumentHolder"; private final TextView mTitle; - private final @Nullable LinearLayout mDetails; // Container of date/size/summary - private final TextView mDate; - private final TextView mSize; - private final TextView mType; + private final @Nullable TextView mDate; // Non-null for tablets/sw720dp, null for other devices. + private final @Nullable TextView mSize; // Non-null for tablets/sw720dp, null for other devices. + private final @Nullable TextView mType; // Non-null for tablets/sw720dp, null for other devices. + // Container for date + size + summary, null only for tablets/sw720dp + private final @Nullable LinearLayout mDetails; + // TextView for date + size + summary, null only for tablets/sw720dp + private final @Nullable TextView mMetadataView; private final ImageView mIconMime; private final ImageView mIconThumb; private final ImageView mIconCheck; @@ -75,6 +82,7 @@ final class ListDocumentHolder extends DocumentHolder { mSize = (TextView) itemView.findViewById(R.id.size); mDate = (TextView) itemView.findViewById(R.id.date); mType = (TextView) itemView.findViewById(R.id.file_type); + mMetadataView = (TextView) itemView.findViewById(R.id.metadata); // Warning: mDetails view doesn't exists in layout-sw720dp-land layout mDetails = (LinearLayout) itemView.findViewById(R.id.line2); mPreviewIcon = itemView.findViewById(R.id.preview_icon); @@ -97,8 +105,7 @@ final class ListDocumentHolder extends DocumentHolder { } if (!itemView.isEnabled()) { - assert(!selected); - return; + assert (!selected); } super.setSelected(selected, animate); @@ -183,12 +190,13 @@ final class ListDocumentHolder extends DocumentHolder { /** * Bind this view to the given document for display. + * * @param cursor Pointing to the item to be bound. * @param modelId The model ID of the item. */ @Override public void bind(Cursor cursor, String modelId) { - assert(cursor != null); + assert (cursor != null); mModelId = modelId; @@ -208,33 +216,50 @@ final class ListDocumentHolder extends DocumentHolder { mTitle.setText(mDoc.displayName, TextView.BufferType.SPANNABLE); mTitle.setVisibility(View.VISIBLE); - - boolean hasDetails = false; if (mDoc.isDirectory()) { // Note, we don't show any details for any directory...ever. - hasDetails = false; - } else { - if (mDoc.lastModified > 0) { - hasDetails = true; - mDate.setText(Shared.formatTime(mContext, mDoc.lastModified)); - } else { - mDate.setText(null); + if (mDetails != null) { + // Non-tablets + mDetails.setVisibility(View.GONE); } - - if (mDoc.size > -1) { - hasDetails = true; - mSize.setVisibility(View.VISIBLE); - mSize.setText(Formatter.formatFileSize(mContext, mDoc.size)); + } else { + // For tablets metadata is provided in columns mDate, mSize, mType. + // For other devices mMetadataView consolidates the metadata info. + if (mMetadataView != null) { + // Non-tablets + boolean hasDetails = false; + ArrayList<String> metadataList = new ArrayList<>(); + if (mDoc.lastModified > 0) { + hasDetails = true; + metadataList.add(Shared.formatTime(mContext, mDoc.lastModified)); + } + if (mDoc.size > -1) { + hasDetails = true; + metadataList.add(Formatter.formatFileSize(mContext, mDoc.size)); + } + metadataList.add(mFileTypeLookup.lookup(mDoc.mimeType)); + mMetadataView.setText(TextUtils.join(", ", metadataList)); + if (mDetails != null) { + mDetails.setVisibility(hasDetails ? View.VISIBLE : View.GONE); + } else { + Log.w(TAG, "mDetails is unexpectedly null for non-tablet devices!"); + } } else { - mSize.setVisibility(View.INVISIBLE); + // Tablets + if (mDoc.lastModified > 0) { + mDate.setVisibility(View.VISIBLE); + mDate.setText(Shared.formatTime(mContext, mDoc.lastModified)); + } else { + mDate.setVisibility(View.INVISIBLE); + } + if (mDoc.size > -1) { + mSize.setVisibility(View.VISIBLE); + mSize.setText(Formatter.formatFileSize(mContext, mDoc.size)); + } else { + mSize.setVisibility(View.INVISIBLE); + } + mType.setText(mFileTypeLookup.lookup(mDoc.mimeType)); } - - mType.setText(mFileTypeLookup.lookup(mDoc.mimeType)); - } - - // mDetails view doesn't exists in layout-sw720dp-land layout - if (mDetails != null) { - mDetails.setVisibility(hasDetails ? View.VISIBLE : View.GONE); } // TODO: Add document debug info diff --git a/src/com/android/documentsui/dirlist/RenameDocumentFragment.java b/src/com/android/documentsui/dirlist/RenameDocumentFragment.java index f46c4e54f..12873a218 100644 --- a/src/com/android/documentsui/dirlist/RenameDocumentFragment.java +++ b/src/com/android/documentsui/dirlist/RenameDocumentFragment.java @@ -158,16 +158,6 @@ public class RenameDocumentFragment extends DialogFragment { } /** - * Validates if string is a proper document name. - * Checks if string is not empty. More rules might be added later. - * @param docName string representing document name - * @returns true if string is a valid name. - **/ - private boolean isValidDocumentName(String docName) { - return !docName.isEmpty(); - } - - /** * Fills text field with the file name and selects the name without extension. * * @param editText text field to be filled @@ -193,17 +183,13 @@ public class RenameDocumentFragment extends DialogFragment { if (newDisplayName.equals(mDocument.displayName)) { mDialog.dismiss(); - } else if (!isValidDocumentName(newDisplayName)) { - Log.w(TAG, "Failed to rename file - invalid name:" + newDisplayName); - mRenameInputWrapper.setError(getContext().getString(R.string.rename_error)); - Metrics.logRenameFileError(); - } else if (activity.getInjector().getModel().hasFileWithName(newDisplayName)){ + } else if (newDisplayName.isEmpty()) { + mRenameInputWrapper.setError(getContext().getString(R.string.missing_rename_error)); + } else if (activity.getInjector().getModel().hasFileWithName(newDisplayName)) { mRenameInputWrapper.setError(getContext().getString(R.string.name_conflict)); selectFileName(mEditText); - Metrics.logRenameFileError(); } else { new RenameDocumentsTask(activity, newDisplayName).execute(mDocument); - if (mDialog != null) { mDialog.dismiss(); } diff --git a/src/com/android/documentsui/files/FilesActivity.java b/src/com/android/documentsui/files/FilesActivity.java index 1afb38eac..7c09811c9 100644 --- a/src/com/android/documentsui/files/FilesActivity.java +++ b/src/com/android/documentsui/files/FilesActivity.java @@ -37,7 +37,6 @@ import com.android.documentsui.ActionModeController; import com.android.documentsui.BaseActivity; import com.android.documentsui.DocsSelectionHelper; import com.android.documentsui.DocumentsApplication; -import com.android.documentsui.DummyProfileTabsAddons; import com.android.documentsui.FocusManager; import com.android.documentsui.Injector; import com.android.documentsui.MenuManager.DirectoryDetails; @@ -49,6 +48,7 @@ import com.android.documentsui.ProviderExecutor; import com.android.documentsui.R; import com.android.documentsui.SharedInputHandler; import com.android.documentsui.ShortcutsUpdater; +import com.android.documentsui.StubProfileTabsAddons; import com.android.documentsui.base.DocumentInfo; import com.android.documentsui.base.Features; import com.android.documentsui.base.RootInfo; @@ -76,7 +76,7 @@ public class FilesActivity extends BaseActivity implements AbstractActionHandler private Injector<ActionHandler<FilesActivity>> mInjector; private ActivityInputHandler mActivityInputHandler; private SharedInputHandler mSharedInputHandler; - private final ProfileTabsAddons mProfileTabsAddonsStub = new DummyProfileTabsAddons(); + private final ProfileTabsAddons mProfileTabsAddonsStub = new StubProfileTabsAddons(); public FilesActivity() { super(R.layout.files_activity, TAG); @@ -132,6 +132,7 @@ public class FilesActivity extends BaseActivity implements AbstractActionHandler mInjector.actionModeController = new ActionModeController( this, mInjector.selectionMgr, + mNavigator, mInjector.menuManager, mInjector.messages); @@ -150,7 +151,7 @@ public class FilesActivity extends BaseActivity implements AbstractActionHandler mInjector.searchManager = mSearchManager; - // No profile tabs will be shown on FilesActivity. Use a dummy to avoid unnecessary + // No profile tabs will be shown on FilesActivity. Use a stub to avoid unnecessary // operations. mInjector.profileTabsController = new ProfileTabsController( mInjector.selectionMgr, diff --git a/src/com/android/documentsui/inspector/DebugView.java b/src/com/android/documentsui/inspector/DebugView.java index ffd4b7e05..908d19242 100644 --- a/src/com/android/documentsui/inspector/DebugView.java +++ b/src/com/android/documentsui/inspector/DebugView.java @@ -27,8 +27,8 @@ import androidx.annotation.StringRes; import com.android.documentsui.R; import com.android.documentsui.base.DocumentInfo; -import com.android.documentsui.base.DummyLookup; import com.android.documentsui.base.Lookup; +import com.android.documentsui.base.StubLookup; import com.android.documentsui.inspector.InspectorController.DebugDisplay; import java.text.NumberFormat; @@ -47,7 +47,7 @@ public class DebugView extends TableView implements DebugDisplay { private final Context mContext; private final Resources mRes; - private Lookup<String, Executor> mExecutors = new DummyLookup<>(); + private Lookup<String, Executor> mExecutors = new StubLookup<>(); public DebugView(Context context) { this(context, null); diff --git a/src/com/android/documentsui/picker/PickActivity.java b/src/com/android/documentsui/picker/PickActivity.java index 5328c640e..c2fbd50a0 100644 --- a/src/com/android/documentsui/picker/PickActivity.java +++ b/src/com/android/documentsui/picker/PickActivity.java @@ -121,6 +121,7 @@ public class PickActivity extends BaseActivity implements ActionHandler.Addons { mInjector.actionModeController = new ActionModeController( this, mInjector.selectionMgr, + mNavigator, mInjector.menuManager, mInjector.messages); diff --git a/src/com/android/documentsui/picker/PickFragment.java b/src/com/android/documentsui/picker/PickFragment.java index d7bd9277e..e9610a510 100644 --- a/src/com/android/documentsui/picker/PickFragment.java +++ b/src/com/android/documentsui/picker/PickFragment.java @@ -98,7 +98,7 @@ public class PickFragment extends Fragment { final PickFragment fragment = new PickFragment(); final FragmentTransaction ft = fm.beginTransaction(); ft.replace(R.id.container_save, fragment, TAG); - ft.commitAllowingStateLoss(); + ft.commitNowAllowingStateLoss(); } public static PickFragment get(FragmentManager fm) { diff --git a/src/com/android/documentsui/queries/SearchChipViewManager.java b/src/com/android/documentsui/queries/SearchChipViewManager.java index ebda22bf3..f80a3a7fa 100644 --- a/src/com/android/documentsui/queries/SearchChipViewManager.java +++ b/src/com/android/documentsui/queries/SearchChipViewManager.java @@ -24,6 +24,7 @@ import android.provider.DocumentsContract; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.accessibility.AccessibilityEvent; import android.widget.HorizontalScrollView; import androidx.annotation.NonNull; @@ -35,6 +36,7 @@ import com.android.documentsui.MetricConsts; import com.android.documentsui.R; import com.android.documentsui.base.MimeTypes; import com.android.documentsui.base.Shared; +import com.android.documentsui.util.VersionUtils; import com.google.android.material.chip.Chip; import com.google.common.primitives.Ints; @@ -96,9 +98,11 @@ public class SearchChipViewManager { static { sMimeTypesChipItems.put(TYPE_IMAGES, new SearchChipData(TYPE_IMAGES, R.string.chip_title_images, IMAGES_MIMETYPES)); - sMimeTypesChipItems.put(TYPE_DOCUMENTS, - new SearchChipData(TYPE_DOCUMENTS, R.string.chip_title_documents, - DOCUMENTS_MIMETYPES)); + if (VersionUtils.isAtLeastR()) { + sMimeTypesChipItems.put(TYPE_DOCUMENTS, + new SearchChipData(TYPE_DOCUMENTS, R.string.chip_title_documents, + DOCUMENTS_MIMETYPES)); + } sMimeTypesChipItems.put(TYPE_AUDIO, new SearchChipData(TYPE_AUDIO, R.string.chip_title_audio, AUDIO_MIMETYPES)); sMimeTypesChipItems.put(TYPE_VIDEOS, @@ -395,7 +399,7 @@ public class SearchChipViewManager { * Reorder the chips in chip group. The checked chip has higher order. * * @param clickedChip the clicked chip, may be null. - * @param hasAnim if true, play move animation. Otherwise, not. + * @param hasAnim if true, play move animation. Otherwise, not. */ private void reorderCheckedChips(@Nullable Chip clickedChip, boolean hasAnim) { final ArrayList<Chip> chipList = new ArrayList<>(); @@ -421,9 +425,10 @@ public class SearchChipViewManager { return; } - final int chipSpacing = mChipGroup.getPaddingEnd(); + final int chipSpacing = mChipGroup.getResources().getDimensionPixelSize( + R.dimen.search_chip_spacing); final boolean isRtl = mChipGroup.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; - float lastX = isRtl ? mChipGroup.getWidth() - chipSpacing : chipSpacing; + float lastX = isRtl ? mChipGroup.getWidth() - chipSpacing / 2 : chipSpacing / 2; // remove all chips except current clicked chip to avoid losing // accessibility focus. @@ -465,6 +470,10 @@ public class SearchChipViewManager { if (parent instanceof HorizontalScrollView) { final int scrollToX = isRtl ? parent.getWidth() : 0; ((HorizontalScrollView) parent).smoothScrollTo(scrollToX, 0); + if (mChipGroup.getChildCount() > 0) { + mChipGroup.getChildAt(0) + .sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED); + } } } } diff --git a/src/com/android/documentsui/queries/SearchFragment.java b/src/com/android/documentsui/queries/SearchFragment.java index 7f2e779bb..92cd91a3f 100644 --- a/src/com/android/documentsui/queries/SearchFragment.java +++ b/src/com/android/documentsui/queries/SearchFragment.java @@ -40,7 +40,7 @@ import com.android.documentsui.R; import java.util.List; -public class SearchFragment extends Fragment{ +public class SearchFragment extends Fragment { private static final String TAG = "SearchFragment"; private static final String KEY_QUERY = "query"; @@ -97,8 +97,8 @@ public class SearchFragment extends Fragment{ } @Override - public void onActivityCreated(@Nullable Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); final BaseActivity activity = (BaseActivity) getActivity(); final Injector injector = activity.getInjector(); @@ -121,14 +121,16 @@ public class SearchFragment extends Fragment{ mListView.setAdapter(mAdapter); mListView.setOnItemClickListener(this::onHistoryItemClicked); - View toolbar = getActivity().findViewById(R.id.toolbar_background_layout); - if (toolbar != null) { - // Align top with the bottom of search bar. + View toolbar = getActivity().findViewById(R.id.toolbar); + View collapsingBarLayout = getActivity().findViewById(R.id.collapsing_toolbar); + if (toolbar != null && collapsingBarLayout != null) { + // If collapsingBarLayout is used (i.e. not in Tablet mode), + // need to align top with the bottom of search bar. FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); layoutParams.setMargins(0, getResources().getDimensionPixelSize( - R.dimen.action_bar_space_height), 0, 0); + R.dimen.action_bar_margin) + toolbar.getLayoutParams().height, 0, 0); getView().setLayoutParams(layoutParams); } @@ -150,7 +152,7 @@ public class SearchFragment extends Fragment{ final String item = mHistoryList.get(position); mSearchViewManager.setHistorySearch(); mSearchViewManager.setCurrentSearch(item); - mSearchViewManager.restoreSearch(true); + mSearchViewManager.restoreSearch(/* keepFocus= */ false); } private void dismiss() { diff --git a/src/com/android/documentsui/queries/SearchViewManager.java b/src/com/android/documentsui/queries/SearchViewManager.java index e94e900e8..b1016952f 100644 --- a/src/com/android/documentsui/queries/SearchViewManager.java +++ b/src/com/android/documentsui/queries/SearchViewManager.java @@ -333,8 +333,6 @@ public class SearchViewManager implements public boolean cancelSearch() { if (mSearchView != null && (isExpanded() || isSearching())) { cancelQueuedSearch(); - // If the query string is not empty search view won't get iconified - mSearchView.setQuery("", false); if (mFullBar) { onClose(); @@ -420,6 +418,11 @@ public class SearchViewManager implements // Refresh the directory if a search was done if (mCurrentSearch != null || mChipViewManager.hasCheckedItems()) { + // Make sure SearchFragment was dismissed. + if (mFragmentManager != null) { + SearchFragment.dismissFragment(mFragmentManager); + } + // Clear checked chips mChipViewManager.clearCheckedChips(); mCurrentSearch = null; diff --git a/src/com/android/documentsui/roots/ProvidersCache.java b/src/com/android/documentsui/roots/ProvidersCache.java index f35d05e2f..ebd54972e 100644 --- a/src/com/android/documentsui/roots/ProvidersCache.java +++ b/src/com/android/documentsui/roots/ProvidersCache.java @@ -62,6 +62,7 @@ import com.android.documentsui.base.UserId; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; +import com.google.common.util.concurrent.MoreExecutors; import java.util.ArrayList; import java.util.Collection; @@ -72,6 +73,10 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Semaphore; +import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.function.Function; @@ -90,6 +95,7 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName { // ArchivesProvider doesn't support any roots. add(ArchivesProvider.AUTHORITY); }}; + private static final int FIRST_LOAD_TIMEOUT_MS = 5000; private final Context mContext; @@ -111,6 +117,7 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName { private Multimap<UserAuthority, RootInfo> mRoots = ArrayListMultimap.create(); @GuardedBy("mLock") private HashSet<UserAuthority> mStoppedAuthorities = new HashSet<>(); + private final Semaphore mMultiProviderUpdateTaskSemaphore = new Semaphore(1); @GuardedBy("mObservedAuthoritiesDetails") private final Map<UserAuthority, PackageDetails> mObservedAuthoritiesDetails = new HashMap<>(); @@ -205,13 +212,16 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName { assert (recentRoot.availableBytes == -1); } - new UpdateTask(forceRefreshAll, null, callback).executeOnExecutor( + new MultiProviderUpdateTask(forceRefreshAll, null, callback).executeOnExecutor( AsyncTask.THREAD_POOL_EXECUTOR); } public void updatePackageAsync(UserId userId, String packageName) { - new UpdateTask(false, new UserPackage(userId, packageName), - /* callback= */ null).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + new MultiProviderUpdateTask( + /* forceRefreshAll= */ false, + new UserPackage(userId, packageName), + /* callback= */ null) + .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } public void updateAuthorityAsync(UserId userId, String authority) { @@ -235,7 +245,7 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName { } /** - * Block until the first {@link UpdateTask} pass has finished. + * Block until the first {@link MultiProviderUpdateTask} pass has finished. * * @return {@code true} if cached roots is ready to roll, otherwise * {@code false} if we timed out while waiting. @@ -243,7 +253,7 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName { private boolean waitForFirstLoad() { boolean success = false; try { - success = mFirstLoad.await(15, TimeUnit.SECONDS); + success = mFirstLoad.await(FIRST_LOAD_TIMEOUT_MS, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { } if (!success) { @@ -254,7 +264,7 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName { /** * Load roots from authorities that are in stopped state. Normal - * {@link UpdateTask} passes ignore stopped applications. + * {@link MultiProviderUpdateTask} passes ignore stopped applications. */ private void loadStoppedAuthorities() { synchronized (mLock) { @@ -266,7 +276,7 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName { } /** - * Load roots from a stopped authority. Normal {@link UpdateTask} passes + * Load roots from a stopped authority. Normal {@link MultiProviderUpdateTask} passes * ignore stopped applications. */ private void loadStoppedAuthority(UserAuthority userAuthority) { @@ -433,7 +443,7 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName { waitForFirstLoad(); loadStoppedAuthorities(); synchronized (mLock) { - return mRoots.values(); + return new HashSet<>(mRoots.values()); } } @@ -485,15 +495,17 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName { Log.i(TAG, output.toString()); } - private class UpdateTask extends AsyncTask<Void, Void, Void> { + private class MultiProviderUpdateTask extends AsyncTask<Void, Void, Void> { private final boolean mForceRefreshAll; @Nullable private final UserPackage mForceRefreshUserPackage; @Nullable private final Runnable mCallback; - private final Multimap<UserAuthority, RootInfo> mTaskRoots = ArrayListMultimap.create(); - private final HashSet<UserAuthority> mTaskStoppedAuthorities = new HashSet<>(); + @GuardedBy("mLock") + private Multimap<UserAuthority, RootInfo> mLocalRoots = ArrayListMultimap.create(); + @GuardedBy("mLock") + private HashSet<UserAuthority> mLocalStoppedAuthorities = new HashSet<>(); /** * Create task to update roots cache. @@ -504,7 +516,9 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName { * values for this specific user package should be ignored. * @param callback when non-null, it will be invoked after the task is executed. */ - UpdateTask(boolean forceRefreshAll, @Nullable UserPackage forceRefreshUserPackage, + MultiProviderUpdateTask( + boolean forceRefreshAll, + @Nullable UserPackage forceRefreshUserPackage, @Nullable Runnable callback) { mForceRefreshAll = forceRefreshAll; mForceRefreshUserPackage = forceRefreshUserPackage; @@ -513,12 +527,25 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName { @Override protected Void doInBackground(Void... params) { + if (!mMultiProviderUpdateTaskSemaphore.tryAcquire()) { + // Abort, since previous update task is still running. + return null; + } + + int previousPriority = Thread.currentThread().getPriority(); + Thread.currentThread().setPriority(Thread.MAX_PRIORITY); + final long start = SystemClock.elapsedRealtime(); for (UserId userId : mUserIdManager.getUserIds()) { final RootInfo recents = createOrGetRecentsRoot(userId); - mTaskRoots.put(new UserAuthority(recents.userId, recents.authority), recents); + synchronized (mLock) { + mLocalRoots.put(new UserAuthority(recents.userId, recents.authority), recents); + } + } + List<SingleProviderUpdateTaskInfo> taskInfos = new ArrayList<>(); + for (UserId userId : mUserIdManager.getUserIds()) { final PackageManager pm = userId.getPackageManager(mContext); // Pick up provider with action string final Intent intent = new Intent(DocumentsContract.PROVIDER_INTERFACE); @@ -526,25 +553,55 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName { for (ResolveInfo info : providers) { ProviderInfo providerInfo = info.providerInfo; if (providerInfo.authority != null) { - handleDocumentsProvider(providerInfo, userId); + taskInfos.add(new SingleProviderUpdateTaskInfo(providerInfo, userId)); } } } + if (!taskInfos.isEmpty()) { + CountDownLatch updateTaskInternalCountDown = new CountDownLatch(taskInfos.size()); + ExecutorService executor = MoreExecutors.getExitingExecutorService( + (ThreadPoolExecutor) Executors.newCachedThreadPool()); + for (SingleProviderUpdateTaskInfo taskInfo: taskInfos) { + executor.submit(() -> + startSingleProviderUpdateTask( + taskInfo.providerInfo, + taskInfo.userId, + updateTaskInternalCountDown)); + } + + // Block until all SingleProviderUpdateTask threads finish executing. + // Use a shorter timeout for first load since it could block picker UI. + long timeoutMs = mFirstLoadDone ? 15000 : FIRST_LOAD_TIMEOUT_MS; + boolean success = false; + try { + success = updateTaskInternalCountDown.await(timeoutMs, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + } + if (!success) { + Log.w(TAG, "Timeout executing update task!"); + } + } + final long delta = SystemClock.elapsedRealtime() - start; - if (VERBOSE) Log.v(TAG, - "Update found " + mTaskRoots.size() + " roots in " + delta + "ms"); synchronized (mLock) { mFirstLoadDone = true; if (mBootCompletedResult != null) { mBootCompletedResult.finish(); mBootCompletedResult = null; } - mRoots = mTaskRoots; - mStoppedAuthorities = mTaskStoppedAuthorities; + mRoots = mLocalRoots; + mStoppedAuthorities = mLocalStoppedAuthorities; + } + if (VERBOSE) { + Log.v(TAG, "Update found " + mLocalRoots.size() + " roots in " + delta + "ms"); } + mFirstLoad.countDown(); LocalBroadcastManager.getInstance(mContext).sendBroadcast(new Intent(BROADCAST_ACTION)); + mMultiProviderUpdateTaskSemaphore.release(); + + Thread.currentThread().setPriority(previousPriority); return null; } @@ -555,6 +612,17 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName { } } + private void startSingleProviderUpdateTask( + ProviderInfo providerInfo, + UserId userId, + CountDownLatch updateCountDown) { + int previousPriority = Thread.currentThread().getPriority(); + Thread.currentThread().setPriority(Thread.MAX_PRIORITY); + handleDocumentsProvider(providerInfo, userId); + updateCountDown.countDown(); + Thread.currentThread().setPriority(previousPriority); + } + private void handleDocumentsProvider(ProviderInfo info, UserId userId) { UserAuthority userAuthority = new UserAuthority(userId, info.authority); // Ignore stopped packages for now; we might query them @@ -563,16 +631,20 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName { if (VERBOSE) { Log.v(TAG, "Ignoring stopped authority " + info.authority + ", user " + userId); } - mTaskStoppedAuthorities.add(userAuthority); + synchronized (mLock) { + mLocalStoppedAuthorities.add(userAuthority); + } return; } final boolean forceRefresh = mForceRefreshAll - || Objects.equals(new UserPackage(userId, info.packageName), - mForceRefreshUserPackage); - mTaskRoots.putAll(userAuthority, loadRootsForAuthority(userAuthority, forceRefresh)); + || Objects.equals( + new UserPackage(userId, info.packageName), mForceRefreshUserPackage); + synchronized (mLock) { + mLocalRoots.putAll(userAuthority, + loadRootsForAuthority(userAuthority, forceRefresh)); + } } - } private static class UserAuthority { @@ -611,6 +683,16 @@ public class ProvidersCache implements ProvidersAccess, LookupApplicationName { } } + private static class SingleProviderUpdateTaskInfo { + private final ProviderInfo providerInfo; + private final UserId userId; + + SingleProviderUpdateTaskInfo(ProviderInfo providerInfo, UserId userId) { + this.providerInfo = providerInfo; + this.userId = userId; + } + } + private static class PackageDetails { private String applicationName; private String packageName; diff --git a/src/com/android/documentsui/services/CompressJob.java b/src/com/android/documentsui/services/CompressJob.java index 1f2ea4436..e9ba6e4c8 100644 --- a/src/com/android/documentsui/services/CompressJob.java +++ b/src/com/android/documentsui/services/CompressJob.java @@ -16,6 +16,8 @@ package com.android.documentsui.services; +import static android.content.ContentResolver.wrap; + import static com.android.documentsui.services.FileOperationService.OPERATION_MOVE; import android.app.Notification; @@ -45,6 +47,8 @@ final class CompressJob extends CopyJob { private static final String TAG = "CompressJob"; private static final String NEW_ARCHIVE_EXTENSION = ".zip"; + private Uri mArchiveUri; + /** * Moves files to a destination identified by {@code destination}. * Performs most work by delegating to CopyJob, then deleting @@ -99,17 +103,16 @@ final class CompressJob extends CopyJob { displayName = service.getString(R.string.new_archive_file_name, NEW_ARCHIVE_EXTENSION); } - Uri archiveUri; try { - archiveUri = DocumentsContract.createDocument( - resolver, mDstInfo.derivedUri, "application/zip", displayName); + mArchiveUri = DocumentsContract.createDocument( + resolver, mDstInfo.derivedUri, "application/zip", displayName); } catch (Exception e) { - archiveUri = null; + mArchiveUri = null; } try { mDstInfo = DocumentInfo.fromUri(resolver, ArchivesProvider.buildUriForArchive( - archiveUri, ParcelFileDescriptor.MODE_WRITE_ONLY), UserId.DEFAULT_USER); + mArchiveUri, ParcelFileDescriptor.MODE_WRITE_ONLY), UserId.DEFAULT_USER); ArchivesProvider.acquireArchive(getClient(mDstInfo), mDstInfo.derivedUri); } catch (FileNotFoundException e) { Log.e(TAG, "Failed to create dstInfo.", e); @@ -132,7 +135,14 @@ final class CompressJob extends CopyJob { Log.e(TAG, "Failed to release the archive."); } - // TODO: Remove the archive file in case of an error. + // Remove the archive file in case of an error. + try { + if (!isFinished() || isCanceled()) { + DocumentsContract.deleteDocument(wrap(getClient(mArchiveUri)), mArchiveUri); + } + } catch (RemoteException | FileNotFoundException e) { + Log.w(TAG, "Failed to cleanup after compress error: " + mDstInfo.toString(), e); + } super.finish(); } diff --git a/src/com/android/documentsui/services/CopyJob.java b/src/com/android/documentsui/services/CopyJob.java index f81966eb6..c972c33ef 100644 --- a/src/com/android/documentsui/services/CopyJob.java +++ b/src/com/android/documentsui/services/CopyJob.java @@ -187,7 +187,8 @@ class CopyJob extends ResolvedResourcesJob { .setContentText(service.getString( R.string.notification_touch_for_details)) .setContentIntent(PendingIntent.getActivity(appContext, 0, navigateIntent, - PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT)) + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT + | PendingIntent.FLAG_IMMUTABLE)) .setCategory(Notification.CATEGORY_ERROR) .setSmallIcon(R.drawable.ic_menu_copy) .setAutoCancel(true); diff --git a/src/com/android/documentsui/services/FileOperationService.java b/src/com/android/documentsui/services/FileOperationService.java index ca6166a7c..c7be5f4fc 100644 --- a/src/com/android/documentsui/services/FileOperationService.java +++ b/src/com/android/documentsui/services/FileOperationService.java @@ -18,7 +18,6 @@ package com.android.documentsui.services; import static com.android.documentsui.base.SharedMinimal.DEBUG; -import androidx.annotation.IntDef; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; @@ -29,9 +28,11 @@ import android.os.Handler; import android.os.IBinder; import android.os.PowerManager; import android.os.UserManager; -import androidx.annotation.VisibleForTesting; import android.util.Log; +import androidx.annotation.IntDef; +import androidx.annotation.VisibleForTesting; + import com.android.documentsui.R; import com.android.documentsui.base.Features; @@ -97,7 +98,9 @@ public class FileOperationService extends Service implements Job.Listener { static final String NOTIFICATION_CHANNEL_ID = "channel_id"; - private static final int POOL_SIZE = 2; // "pool size", not *max* "pool size". + // This is a temporary solution, we will gray out the UI when a transaction is in progress to + // not enable users to make a transaction. + private static final int POOL_SIZE = 1; // Allow only 1 executor operation @VisibleForTesting static final int NOTIFICATION_ID_PROGRESS = 1; private static final int NOTIFICATION_ID_FAILURE = 2; diff --git a/src/com/android/documentsui/services/Job.java b/src/com/android/documentsui/services/Job.java index 5659c06bd..71f0ae861 100644 --- a/src/com/android/documentsui/services/Job.java +++ b/src/com/android/documentsui/services/Job.java @@ -310,7 +310,8 @@ abstract public class Job implements Runnable { failureCount, failureCount)) .setContentText(service.getString(R.string.notification_touch_for_details)) .setContentIntent(PendingIntent.getActivity(appContext, 0, navigateIntent, - PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT)) + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT + | PendingIntent.FLAG_MUTABLE)) .setCategory(Notification.CATEGORY_ERROR) .setSmallIcon(icon) .setAutoCancel(true); @@ -327,7 +328,8 @@ abstract public class Job implements Runnable { .setContentTitle(title) .setContentIntent( PendingIntent.getActivity(appContext, 0, - buildNavigateIntent(INTENT_TAG_PROGRESS), 0)) + buildNavigateIntent(INTENT_TAG_PROGRESS), + PendingIntent.FLAG_IMMUTABLE)) .setCategory(Notification.CATEGORY_PROGRESS) .setSmallIcon(icon) .setOngoing(true); @@ -341,7 +343,8 @@ abstract public class Job implements Runnable { service, 0, cancelIntent, - PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT)); + PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT + | PendingIntent.FLAG_MUTABLE)); return progressBuilder; } diff --git a/src/com/android/documentsui/sidebar/RootItem.java b/src/com/android/documentsui/sidebar/RootItem.java index 9af396e4c..a0a3210f8 100644 --- a/src/com/android/documentsui/sidebar/RootItem.java +++ b/src/com/android/documentsui/sidebar/RootItem.java @@ -210,13 +210,13 @@ public class RootItem extends Item { } /** - * Creates a dummy root item for a user. A dummy root item is used as a place holder when + * Creates a stub root item for a user. A stub root item is used as a place holder when * there is no such root available. We can therefore show the item on the UI. */ - public static RootItem createDummyItem(RootItem item, UserId targetUser) { - RootInfo dummyRootInfo = RootInfo.copyRootInfo(item.root); - dummyRootInfo.userId = targetUser; - RootItem dummy = new RootItem(dummyRootInfo, item.mActionHandler, item.mMaybeShowBadge); - return dummy; + public static RootItem createStubItem(RootItem item, UserId targetUser) { + RootInfo stubRootInfo = RootInfo.copyRootInfo(item.root); + stubRootInfo.userId = targetUser; + RootItem stub = new RootItem(stubRootInfo, item.mActionHandler, item.mMaybeShowBadge); + return stub; } } diff --git a/src/com/android/documentsui/sidebar/RootItemListBuilder.java b/src/com/android/documentsui/sidebar/RootItemListBuilder.java index 4bdce15f3..b29bd0d87 100644 --- a/src/com/android/documentsui/sidebar/RootItemListBuilder.java +++ b/src/com/android/documentsui/sidebar/RootItemListBuilder.java @@ -37,7 +37,7 @@ import java.util.List; * selected user. * * <p>If no root of the selected user was added but that of the other user was added, - * a dummy root of that root for the selected user will be generated. + * a stub root of that root for the selected user will be generated. * * <p>The builder group the roots using {@link Item#stringId} as key. * @@ -45,9 +45,9 @@ import java.util.List; * itemC[10], itemX[0],itemY[10] where root itemX, itemY do not support cross profile. * * <p>When the selected user is user 0, {@link #getList()} returns itemA[0], itemB[0], - * dummyC[0], itemX[0], itemY[10]. + * stubC[0], itemX[0], itemY[10]. * - * <p>When the selected user is user 10, {@link #getList()} returns itemA[10], dummyB[10], + * <p>When the selected user is user 10, {@link #getList()} returns itemA[10], stubB[10], * itemC[10], itemX[0], itemY[10]. */ class RootItemListBuilder { @@ -87,7 +87,7 @@ class RootItemListBuilder { return items; } - // If the root supports cross-profile, we return the added root or create a dummy root if + // If the root supports cross-profile, we return the added root or create a stub root if // it was not added for the selected user. for (RootItem item : items) { if (item.userId.equals(mSelectedUser)) { @@ -96,6 +96,6 @@ class RootItemListBuilder { } } - return Collections.singletonList(RootItem.createDummyItem(testRootItem, mSelectedUser)); + return Collections.singletonList(RootItem.createStubItem(testRootItem, mSelectedUser)); } } diff --git a/src/com/android/documentsui/sidebar/SpacerItem.java b/src/com/android/documentsui/sidebar/SpacerItem.java index d0f49c9d1..44dd75cbb 100644 --- a/src/com/android/documentsui/sidebar/SpacerItem.java +++ b/src/com/android/documentsui/sidebar/SpacerItem.java @@ -25,7 +25,7 @@ import com.android.documentsui.R; import com.android.documentsui.base.UserId; /** - * Dummy {@link Item} for dividers between different types of {@link Item}s. + * Stub {@link Item} for dividers between different types of {@link Item}s. */ class SpacerItem extends Item { private static final String TAG = "SpacerItem"; diff --git a/src/com/android/documentsui/util/VersionUtils.java b/src/com/android/documentsui/util/VersionUtils.java index 58ae3cdca..aba6374ec 100644 --- a/src/com/android/documentsui/util/VersionUtils.java +++ b/src/com/android/documentsui/util/VersionUtils.java @@ -27,10 +27,19 @@ public class VersionUtils { } /** - * Returns whether the device is running on the Android R or newer. + * Returns whether the device is running on Android R or newer. */ public static boolean isAtLeastR() { - return Build.VERSION.CODENAME.equals("R") - || (Build.VERSION.CODENAME.equals("REL") && Build.VERSION.SDK_INT >= 30); + return isAtLeastS() // Keep reference to isAtLeastS() so it's not stripped from test apk + || Build.VERSION.CODENAME.equals("R") + || Build.VERSION.SDK_INT >= 30; + } + + /** + * Returns whether the device is running on Android S or newer. + */ + public static boolean isAtLeastS() { + return Build.VERSION.CODENAME.equals("S") + || Build.VERSION.SDK_INT >= 31; } } diff --git a/tests/common/com/android/documentsui/DemoProvider.java b/tests/common/com/android/documentsui/DemoProvider.java index 6d1a3640c..459e13bd3 100644 --- a/tests/common/com/android/documentsui/DemoProvider.java +++ b/tests/common/com/android/documentsui/DemoProvider.java @@ -95,7 +95,8 @@ public class DemoProvider extends TestRootProvider { case DIR_AUTH: Intent intent = new Intent("com.android.documentsui.test.action.AUTHENTICATE"); PendingIntent pIntent = PendingIntent.getActivity(getContext(), - AbstractActionHandler.CODE_AUTHENTICATION, intent, 0); + AbstractActionHandler.CODE_AUTHENTICATION, intent, + PendingIntent.FLAG_IMMUTABLE); throw new AuthenticationRequiredException(new UnsupportedOperationException(), pIntent); diff --git a/tests/common/com/android/documentsui/InspectorProvider.java b/tests/common/com/android/documentsui/InspectorProvider.java index 1d678d12c..722799314 100644 --- a/tests/common/com/android/documentsui/InspectorProvider.java +++ b/tests/common/com/android/documentsui/InspectorProvider.java @@ -34,10 +34,10 @@ import java.io.FileNotFoundException; * * Structure of the provider. * - * Top ------------> Middle ------> Bottom -------> Dummy21 50B - * openInProvider Dummy1 50B Dummy11 50B Dummy22 150B - * test.txt Dummy2 150B Dummy12 150B Dummy23 100B - * update.txt Dummy3 100B Dummy13 100B + * Top ------------> Middle ------> Bottom -------> Stub21 50B + * openInProvider Stub1 50B Stub11 50B Stub22 150B + * test.txt Stub2 150B Stub12 150B Stub23 100B + * update.txt Stub3 100B Stub13 100B * test.jpg * invalid.jpg */ @@ -97,24 +97,24 @@ public class InspectorProvider extends TestRootProvider { if("Top".equals(s)) { MatrixCursor c = createDocCursor(projection); addFolder(c, "Middle"); - addFileWithSize(c, "dummy1", 50); - addFileWithSize(c, "dummy2", 150); - addFileWithSize(c, "dummy3", 100); + addFileWithSize(c, "stub1", 50); + addFileWithSize(c, "stub2", 150); + addFileWithSize(c, "stub3", 100); return c; } else if("Middle".equals(s)) { MatrixCursor c = createDocCursor(projection); addFolder(c, "Bottom"); - addFileWithSize(c, "dummy11", 50); - addFileWithSize(c, "dummy12", 150); - addFileWithSize(c, "dummy13", 100); + addFileWithSize(c, "stub11", 50); + addFileWithSize(c, "stub12", 150); + addFileWithSize(c, "stub13", 100); return c; } else if("Bottom".equals(s)) { MatrixCursor c = createDocCursor(projection); - addFileWithSize(c, "dummy21", 50); - addFileWithSize(c, "dummy22", 150); - addFileWithSize(c, "dummy23", 100); + addFileWithSize(c, "stub21", 50); + addFileWithSize(c, "stub22", 150); + addFileWithSize(c, "stub23", 100); return c; } else { diff --git a/tests/common/com/android/documentsui/bots/SearchBot.java b/tests/common/com/android/documentsui/bots/SearchBot.java index da7dc5481..d14fd1375 100644 --- a/tests/common/com/android/documentsui/bots/SearchBot.java +++ b/tests/common/com/android/documentsui/bots/SearchBot.java @@ -34,6 +34,7 @@ import android.content.Context; import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiObject; import android.support.test.uiautomator.UiObjectNotFoundException; +import android.support.test.uiautomator.UiSelector; import android.view.View; import androidx.recyclerview.R; @@ -48,7 +49,7 @@ import org.hamcrest.Matcher; */ public class SearchBot extends Bots.BaseBot { - // Dumb search layout changes substantially between Ryu and Angler. + // Base search layout changes substantially between Ryu and Angler. @SuppressWarnings("unchecked") private static final Matcher<View> SEARCH_WIDGET = allOf( withId(R.id.option_menu_search), @@ -76,6 +77,13 @@ public class SearchBot extends Bots.BaseBot { clear.click(); } + // Click on the search history item with specified queryText, if exists. + public void clickSearchHistory(String queryText) throws UiObjectNotFoundException { + UiObject history = findSearchHistoryView(); + UiSelector historyItemSelector = new UiSelector().text(queryText); + mDevice.findObject(history.getSelector().childSelector(historyItemSelector)).click(); + } + public void setInputText(String query) throws UiObjectNotFoundException { onView(SEARCH_INPUT).perform(typeText(query)); } @@ -92,6 +100,18 @@ public class SearchBot extends Bots.BaseBot { } } + public void assertSearchHistoryVisible(boolean visible) { + if (visible) { + assertTrue( + "Search fragment should be shown.", + findSearchHistoryView().exists()); + } else { + assertFalse( + "Search fragment should be dismissed.", + findSearchHistoryView().exists()); + } + } + public void assertInputEquals(String query) throws UiObjectNotFoundException { UiObject textField = findSearchViewTextField(); @@ -117,6 +137,10 @@ public class SearchBot extends Bots.BaseBot { return findObject(mTargetPackage + ":id/option_menu_search"); } + private UiObject findSearchHistoryView() { + return findObject(mTargetPackage + ":id/history_list"); + } + private UiObject findSearchViewTextField() { return findObject(mTargetPackage + ":id/option_menu_search", mTargetPackage + ":id/search_src_text"); diff --git a/tests/common/com/android/documentsui/dirlist/TestFocusHandler.java b/tests/common/com/android/documentsui/dirlist/TestFocusHandler.java index 565665566..969ddcf36 100644 --- a/tests/common/com/android/documentsui/dirlist/TestFocusHandler.java +++ b/tests/common/com/android/documentsui/dirlist/TestFocusHandler.java @@ -22,7 +22,7 @@ import android.view.KeyEvent; import android.view.View; /** - * A purely dummy instance of FocusHandler. + * A purely placeholder instance of FocusHandler. */ public final class TestFocusHandler implements FocusHandler { diff --git a/tests/common/com/android/documentsui/testing/TestEnv.java b/tests/common/com/android/documentsui/testing/TestEnv.java index e5c7eb8d4..3249c8cf1 100644 --- a/tests/common/com/android/documentsui/testing/TestEnv.java +++ b/tests/common/com/android/documentsui/testing/TestEnv.java @@ -192,7 +192,7 @@ public class TestEnv { DocumentInfo rootDoc = model.getDocument( ModelId.build(model.mUserId, TestProvidersAccess.HOME.authority, "1")); - // These are test setup sanity checks, not test assertions. + // These are test setup quick checks, not test assertions. assert rootDoc != null; assert rootDoc.isDirectory(); assert FOLDER_0.equals(rootDoc); diff --git a/tests/common/com/android/documentsui/testing/TestModel.java b/tests/common/com/android/documentsui/testing/TestModel.java index 5a0ff89d3..452238189 100644 --- a/tests/common/com/android/documentsui/testing/TestModel.java +++ b/tests/common/com/android/documentsui/testing/TestModel.java @@ -64,7 +64,7 @@ public class TestModel extends Model { public void update() { DirectoryResult r = new DirectoryResult(); - r.cursor = mCursor; + r.setCursor(mCursor); super.update(r); } diff --git a/tests/common/com/android/documentsui/testing/Views.java b/tests/common/com/android/documentsui/testing/Views.java index 30f79a63a..6f5b1a2b8 100644 --- a/tests/common/com/android/documentsui/testing/Views.java +++ b/tests/common/com/android/documentsui/testing/Views.java @@ -34,7 +34,7 @@ public final class Views { } /* - * Dummy View object with (x, y) coordinates + * Mock View object with (x, y) coordinates */ public static View createTestView(float x, float y) { View view = createTestView(); diff --git a/tests/functional/com/android/documentsui/ActivityTest.java b/tests/functional/com/android/documentsui/ActivityTest.java index 65271d092..ec4e6cbea 100644 --- a/tests/functional/com/android/documentsui/ActivityTest.java +++ b/tests/functional/com/android/documentsui/ActivityTest.java @@ -32,6 +32,7 @@ import android.support.test.uiautomator.Configurator; import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiObjectNotFoundException; import android.test.ActivityInstrumentationTestCase2; +import android.view.KeyEvent; import android.view.MotionEvent; import com.android.documentsui.base.Features; @@ -125,6 +126,8 @@ public abstract class ActivityTest<T extends Activity> extends ActivityInstrumen getTestingProviderAuthority()); device.setOrientationNatural(); + device.pressKeyCode(KeyEvent.KEYCODE_WAKEUP); + device.pressKeyCode(KeyEvent.KEYCODE_MENU); setupTestingRoots(); launchActivity(); diff --git a/tests/functional/com/android/documentsui/CancelFromNotificationUiTest.java b/tests/functional/com/android/documentsui/CancelFromNotificationUiTest.java index 06970560c..953e3504b 100644 --- a/tests/functional/com/android/documentsui/CancelFromNotificationUiTest.java +++ b/tests/functional/com/android/documentsui/CancelFromNotificationUiTest.java @@ -47,7 +47,7 @@ import java.util.concurrent.TimeUnit; public class CancelFromNotificationUiTest extends ActivityTest<FilesActivity> { private static final String TAG = "CancelFromNotificationUiTest"; - private static final String TARGET_FILE = "dummy.data"; + private static final String TARGET_FILE = "stub.data"; private static final int BUFFER_SIZE = 10 * 1024 * 1024; @@ -127,20 +127,20 @@ public class CancelFromNotificationUiTest extends ActivityTest<FilesActivity> { @Override public void initTestFiles() throws RemoteException { try { - createDummyFile(); + createStubFile(); } catch (Exception e) { fail("Initialization failed. " + e.toString()); } } - private void createDummyFile() throws Exception { + private void createStubFile() throws Exception { Uri uri = mDocsHelper.createDocument(rootDir0, "*/*", TARGET_FILE); - byte[] dummyByte = new byte[BUFFER_SIZE]; - mDocsHelper.writeDocument(uri, dummyByte); + byte[] stubByte = new byte[BUFFER_SIZE]; + mDocsHelper.writeDocument(uri, stubByte); for (int i = 0; i < 49; i++) { - dummyByte = null; - dummyByte = new byte[BUFFER_SIZE]; - mDocsHelper.writeAppendDocument(uri, dummyByte, dummyByte.length); + stubByte = null; + stubByte = new byte[BUFFER_SIZE]; + mDocsHelper.writeAppendDocument(uri, stubByte, stubByte.length); } } diff --git a/tests/functional/com/android/documentsui/FileDeleteUiTest.java b/tests/functional/com/android/documentsui/FileDeleteUiTest.java index d68dbd652..5a1396229 100644 --- a/tests/functional/com/android/documentsui/FileDeleteUiTest.java +++ b/tests/functional/com/android/documentsui/FileDeleteUiTest.java @@ -49,7 +49,7 @@ import java.util.concurrent.TimeUnit; public class FileDeleteUiTest extends ActivityTest<FilesActivity> { private static final String TAG = "FileDeleteUiTest"; - private static final int DUMMY_FILE_COUNT = 1000; + private static final int STUB_FILE_COUNT = 1000; private static final int WAIT_TIME_SECONDS = 60; @@ -126,17 +126,17 @@ public class FileDeleteUiTest extends ActivityTest<FilesActivity> { @Override public void initTestFiles() throws RemoteException { try { - createDummyFiles(); + createStubFiles(); } catch (Exception e) { fail("Initialization failed"); } } - private void createDummyFiles() throws Exception { + private void createStubFiles() throws Exception { final ThreadPoolExecutor exec = new ThreadPoolExecutor( 5, 5, 1000L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(100, true)); - for (int i = 0; i < DUMMY_FILE_COUNT; i++) { + for (int i = 0; i < STUB_FILE_COUNT; i++) { final String fileName = "file" + String.format("%04d", i) + ".log"; if (exec.getQueue().size() >= 80) { Thread.sleep(50); diff --git a/tests/functional/com/android/documentsui/SearchViewUiTest.java b/tests/functional/com/android/documentsui/SearchViewUiTest.java index bc08c4984..04ea87a41 100644 --- a/tests/functional/com/android/documentsui/SearchViewUiTest.java +++ b/tests/functional/com/android/documentsui/SearchViewUiTest.java @@ -100,6 +100,23 @@ public class SearchViewUiTest extends ActivityTest<FilesActivity> { bots.search.assertInputExists(false); } + public void testSearchFragment_DismissedOnCloseAfterCancel() throws Exception { + bots.search.clickIcon(); + bots.search.setInputText("query text"); + + // Cancel search + device.pressBack(); + device.waitForIdle(); + + // Close search + device.pressBack(); + device.waitForIdle(); + + bots.search.assertIconVisible(true); + bots.search.assertInputExists(false); + bots.search.assertSearchHistoryVisible(false); + } + public void testSearchView_ClearsTextOnBack() throws Exception { bots.search.clickIcon(); bots.search.setInputText("file2"); @@ -227,5 +244,23 @@ public class SearchViewUiTest extends ActivityTest<FilesActivity> { bots.search.assertInputExists(true); bots.search.assertInputFocused(true); + bots.search.assertSearchHistoryVisible(true); + } + + public void testSearchView_focusClearedAfterSelectingSearchHistory() throws Exception { + String queryText = "history"; + bots.search.clickIcon(); + bots.search.setInputText(queryText); + bots.keyboard.pressEnter(); + device.waitForIdle(); + + bots.search.clickSearchViewClearButton(); + device.waitForIdle(); + bots.search.assertInputFocused(true); + bots.search.assertSearchHistoryVisible(true); + + bots.search.clickSearchHistory(queryText); + bots.search.assertInputFocused(false); + bots.search.assertSearchHistoryVisible(false); } } diff --git a/tests/functional/com/android/documentsui/archives/ArchiveHandleTest.java b/tests/functional/com/android/documentsui/archives/ArchiveHandleTest.java index f84da2a3b..1e0e95e1c 100644 --- a/tests/functional/com/android/documentsui/archives/ArchiveHandleTest.java +++ b/tests/functional/com/android/documentsui/archives/ArchiveHandleTest.java @@ -394,7 +394,7 @@ public class ArchiveHandleTest { try { archiveHandle.getInputStream(archiveEntry); fail("It should not be here."); - } catch (IllegalArgumentException | ArchiveException | CompressorException e) { + } catch (ClassCastException e) { /* do nothing */ } } @@ -416,13 +416,13 @@ public class ArchiveHandleTest { } @Test - public void getInputStream_zeroSizeEntry_shouldFail() throws Exception { + public void getInputStream_negativeSizeEntry_shouldFail() throws Exception { ArchiveHandle archiveHandle = prepareArchiveHandle("archives/zip/hello.zip", ".zip", "application/zip"); ArchiveEntry archiveEntry = mock(ArchiveEntry.class); when(archiveEntry.isDirectory()).thenReturn(false); - when(archiveEntry.getSize()).thenReturn(0L); + when(archiveEntry.getSize()).thenReturn(-1L); try { archiveHandle.getInputStream(archiveEntry); diff --git a/tests/functional/com/android/documentsui/dirlist/DirectoryAddonsAdapterTest.java b/tests/functional/com/android/documentsui/dirlist/DirectoryAddonsAdapterTest.java index 303c8e521..bcd1131b7 100644 --- a/tests/functional/com/android/documentsui/dirlist/DirectoryAddonsAdapterTest.java +++ b/tests/functional/com/android/documentsui/dirlist/DirectoryAddonsAdapterTest.java @@ -186,7 +186,7 @@ public class DirectoryAddonsAdapterTest extends AndroidTestCase { assertTrue(mAdapter.getItemViewType(index) == type); } - private static class DummyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { + private static class StubAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { @Override public int getItemCount() { diff --git a/tests/functional/com/android/documentsui/services/AbstractCopyJobTest.java b/tests/functional/com/android/documentsui/services/AbstractCopyJobTest.java index eaafb37e2..7b2cb828c 100644 --- a/tests/functional/com/android/documentsui/services/AbstractCopyJobTest.java +++ b/tests/functional/com/android/documentsui/services/AbstractCopyJobTest.java @@ -179,7 +179,7 @@ public abstract class AbstractCopyJobTest<T extends CopyJob> extends AbstractJob // Init FileCountProgressTracker with 10 docs required to copy. TestCopyJobProcessTracker<CopyJob.FileCountProgressTracker> tracker = new TestCopyJobProcessTracker(CopyJob.FileCountProgressTracker.class, 10, - createJob(newArrayList(mDocs.createFolder(mSrcRoot, "dummyDir"))), + createJob(newArrayList(mDocs.createFolder(mSrcRoot, "tempDir"))), (completed) -> NumberFormat.getPercentInstance().format(completed), (time) -> mContext.getString(R.string.copy_remaining, DateUtils.formatDuration((Long) time))); @@ -213,7 +213,7 @@ public abstract class AbstractCopyJobTest<T extends CopyJob> extends AbstractJob // Init ByteCountProgressTracker with 100 KBytes required to copy. TestCopyJobProcessTracker<CopyJob.ByteCountProgressTracker> tracker = new TestCopyJobProcessTracker(CopyJob.ByteCountProgressTracker.class, 100000, - createJob(newArrayList(mDocs.createFolder(mSrcRoot, "dummyDir"))), + createJob(newArrayList(mDocs.createFolder(mSrcRoot, "tempDir"))), (completed) -> NumberFormat.getPercentInstance().format(completed), (time) -> mContext.getString(R.string.copy_remaining, DateUtils.formatDuration((Long) time))); diff --git a/tests/functional/com/android/documentsui/ui/DarkThemeUiTest.java b/tests/functional/com/android/documentsui/ui/DarkThemeUiTest.java index 870e8ac05..ae57dcdb4 100644 --- a/tests/functional/com/android/documentsui/ui/DarkThemeUiTest.java +++ b/tests/functional/com/android/documentsui/ui/DarkThemeUiTest.java @@ -16,6 +16,8 @@ package com.android.documentsui.ui; +import static org.junit.Assume.assumeFalse; + import android.content.Context; import android.content.res.Configuration; @@ -24,6 +26,7 @@ import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.documentsui.tests.R; +import com.android.documentsui.util.VersionUtils; import org.junit.Before; import org.junit.Test; @@ -46,7 +49,8 @@ public class DarkThemeUiTest extends ThemeUiTestBase { } @Test - public void themeNightModeEnable_actionBarColorShouldBeDark() { + public void themeNightModeEnable_actionBarColorShouldBeDark() throws Exception { + assumeFalse(VersionUtils.isAtLeastS()); // Disable for S dynamic color assertTheme(R.styleable.ThemeColor, R.styleable.ThemeColor_android_colorBackground, mTheme.getResources().getColor(com.android.documentsui.R.color.app_background_color, mTheme)); @@ -71,22 +75,25 @@ public class DarkThemeUiTest extends ThemeUiTestBase { } @Test - public void themeNightModeEnable_windowBackgroundColorShouldBeDark() { + public void themeNightModeEnable_windowBackgroundColorShouldBeDark() throws Exception { + assumeFalse(VersionUtils.isAtLeastS()); // Disable for S dynamic color assertTheme(R.styleable.SystemWindow, R.styleable.SystemWindow_android_windowBackground, mTheme.getResources().getColor(com.android.documentsui.R.color.app_background_color, mTheme)); } @Test - public void themeNightModeEnable_statusBarColorShouldBeDark() { + public void themeNightModeEnable_statusBarColorShouldBeDark() throws Exception { + assumeFalse(VersionUtils.isAtLeastS()); // Disable for S dynamic color assertTheme(R.styleable.SystemWindow, R.styleable.SystemWindow_android_statusBarColor, mTheme.getResources().getColor(com.android.documentsui.R.color.app_background_color, mTheme)); } @Test - public void appCompatThemeNightModeEnable_colorPrimaryShouldBeThemeable() { + public void appCompatThemeNightModeEnable_colorPrimaryShouldBeThemeable() throws Exception { + assumeFalse(VersionUtils.isAtLeastS()); // Disable for S dynamic color assertTheme(R.styleable.ThemeColor, R.styleable.ThemeColor_android_colorPrimary, mTheme.getResources().getColor(com.android.documentsui.R.color.primary, mTheme)); } -} +}
\ No newline at end of file diff --git a/tests/functional/com/android/documentsui/ui/ThemeUiTest.java b/tests/functional/com/android/documentsui/ui/ThemeUiTest.java index 292ea831f..f3172e4a5 100644 --- a/tests/functional/com/android/documentsui/ui/ThemeUiTest.java +++ b/tests/functional/com/android/documentsui/ui/ThemeUiTest.java @@ -16,6 +16,8 @@ package com.android.documentsui.ui; +import static org.junit.Assume.assumeFalse; + import android.content.res.Configuration; import android.graphics.Color; @@ -23,6 +25,7 @@ import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.documentsui.tests.R; +import com.android.documentsui.util.VersionUtils; import org.junit.Before; import org.junit.Test; @@ -43,7 +46,8 @@ public class ThemeUiTest extends ThemeUiTestBase { } @Test - public void themeNightModeDisable_actionBarColorShouldBeLight() { + public void themeNightModeDisable_actionBarColorShouldBeLight() throws Exception { + assumeFalse(VersionUtils.isAtLeastS()); // Disable for S dynamic color assertTheme(R.styleable.ThemeColor, R.styleable.ThemeColor_android_colorBackground, Color.WHITE); } @@ -61,26 +65,30 @@ public class ThemeUiTest extends ThemeUiTestBase { } @Test - public void themeNightModeDisable_navigationBarColorShouldBeLight() { + public void themeNightModeDisable_navigationBarColorShouldBeLight() throws Exception { + assumeFalse(VersionUtils.isAtLeastS()); // Disable for S dynamic color assertTheme(R.styleable.SystemWindow, R.styleable.SystemWindow_android_navigationBarColor, Color.WHITE); } @Test - public void themeNightModeDisable_windowBackgroundColorShouldBeLight() { + public void themeNightModeDisable_windowBackgroundColorShouldBeLight() throws Exception { + assumeFalse(VersionUtils.isAtLeastS()); // Disable for S dynamic color assertTheme(R.styleable.SystemWindow, R.styleable.SystemWindow_android_windowBackground, Color.WHITE); } @Test - public void themeNightModeDisable_statusBarColorShouldBeLight() { + public void themeNightModeDisable_statusBarColorShouldBeLight() throws Exception { + assumeFalse(VersionUtils.isAtLeastS()); // Disable for S dynamic color assertTheme(R.styleable.SystemWindow, R.styleable.SystemWindow_android_statusBarColor, Color.WHITE); } @Test - public void appCompatThemeNightModeDisable_colorPrimaryShouldBeThemeable() { + public void appCompatThemeNightModeDisable_colorPrimaryShouldBeThemeable() throws Exception { + assumeFalse(VersionUtils.isAtLeastS()); // Disable for S dynamic color assertTheme(R.styleable.ThemeColor, R.styleable.ThemeColor_android_colorPrimary, mTheme.getResources().getColor(com.android.documentsui.R.color.primary, mTheme)); } -} +}
\ No newline at end of file diff --git a/tests/unit/com/android/documentsui/DirectoryResultTest.java b/tests/unit/com/android/documentsui/DirectoryResultTest.java index 5994bdc1c..3cda1bc1a 100644 --- a/tests/unit/com/android/documentsui/DirectoryResultTest.java +++ b/tests/unit/com/android/documentsui/DirectoryResultTest.java @@ -48,7 +48,7 @@ public class DirectoryResultTest { DocumentInfo doc = new DocumentInfo(); result.client = mClient; - result.cursor = mCursor; + result.setCursor(mCursor); result.doc = doc; result.close(); diff --git a/tests/unit/com/android/documentsui/DocsSelectionHelperTest.java b/tests/unit/com/android/documentsui/DocsSelectionHelperTest.java index e377f0a50..3d250073b 100644 --- a/tests/unit/com/android/documentsui/DocsSelectionHelperTest.java +++ b/tests/unit/com/android/documentsui/DocsSelectionHelperTest.java @@ -102,7 +102,7 @@ public class DocsSelectionHelperTest { mSelectionMgr.reset(mgr); } - private static final class TestSelectionManager extends DummySelectionTracker<String> { + private static final class TestSelectionManager extends StubSelectionTracker<String> { private boolean mCleared; private Map<String, Boolean> mSelected = new HashMap<>(); diff --git a/tests/unit/com/android/documentsui/GlobalSearchLoaderTest.java b/tests/unit/com/android/documentsui/GlobalSearchLoaderTest.java index 1c86f39df..c52dbd3de 100644 --- a/tests/unit/com/android/documentsui/GlobalSearchLoaderTest.java +++ b/tests/unit/com/android/documentsui/GlobalSearchLoaderTest.java @@ -132,7 +132,7 @@ public class GlobalSearchLoaderTest { final DirectoryResult result = mLoader.loadInBackground(); - final Cursor c = result.cursor; + final Cursor c = result.getCursor(); assertEquals(1, c.getCount()); c.moveToNext(); @@ -142,25 +142,27 @@ public class GlobalSearchLoaderTest { @Test public void testShowOrHideHiddenFiles() { - final DocumentInfo doc = mEnv.model.createFile(".test" + SEARCH_STRING); - doc.lastModified = System.currentTimeMillis(); + final DocumentInfo doc1 = mEnv.model.createFile(".test" + SEARCH_STRING); + final DocumentInfo doc2 = mEnv.model.createFile("test" + SEARCH_STRING); + doc1.documentId = ".test"; + doc2.documentId = "parent_folder/.hidden_folder/test"; mEnv.mockProviders.get(TestProvidersAccess.DOWNLOADS.authority) - .setNextChildDocumentsReturns(doc); + .setNextChildDocumentsReturns(doc1, doc2); assertEquals(false, mLoader.mState.showHiddenFiles); DirectoryResult result = mLoader.loadInBackground(); - assertEquals(0, result.cursor.getCount()); + assertEquals(0, result.getCursor().getCount()); mLoader.mState.showHiddenFiles = true; result = mLoader.loadInBackground(); - assertEquals(1, result.cursor.getCount()); + assertEquals(2, result.getCursor().getCount()); } @Test public void testSearchResult_isNotMovable() { final DirectoryResult result = mLoader.loadInBackground(); - final Cursor c = result.cursor; + final Cursor c = result.getCursor(); assertEquals(1, c.getCount()); c.moveToNext(); @@ -191,7 +193,7 @@ public class GlobalSearchLoaderTest { .setNextChildDocumentsReturns(otherUserDoc); final DirectoryResult result = mLoader.loadInBackground(); - final Cursor c = result.cursor; + final Cursor c = result.getCursor(); assertThat(c.getCount()).isEqualTo(1); c.moveToNext(); @@ -221,7 +223,7 @@ public class GlobalSearchLoaderTest { SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_ASCENDING); final DirectoryResult result = mLoader.loadInBackground(); - final Cursor c = result.cursor; + final Cursor c = result.getCursor(); assertEquals(2, c.getCount()); @@ -255,7 +257,7 @@ public class GlobalSearchLoaderTest { SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_ASCENDING); final DirectoryResult result = mLoader.loadInBackground(); - final Cursor c = result.cursor; + final Cursor c = result.getCursor(); assertEquals(3, c.getCount()); @@ -287,7 +289,7 @@ public class GlobalSearchLoaderTest { SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_ASCENDING); final DirectoryResult result = mLoader.loadInBackground(); - final Cursor c = result.cursor; + final Cursor c = result.getCursor(); assertEquals(1, c.getCount()); @@ -321,7 +323,7 @@ public class GlobalSearchLoaderTest { SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_ASCENDING); final DirectoryResult result = mLoader.loadInBackground(); - final Cursor c = result.cursor; + final Cursor c = result.getCursor(); assertEquals(3, c.getCount()); @@ -350,7 +352,7 @@ public class GlobalSearchLoaderTest { SortModel.SORT_DIMENSION_ID_TITLE, SortDimension.SORT_DIRECTION_ASCENDING); final DirectoryResult result = mLoader.loadInBackground(); - assertThat(result.cursor.getCount()).isEqualTo(0); + assertThat(result.getCursor().getCount()).isEqualTo(0); // We don't expect exception even if all roots are from other users. assertThat(result.exception).isNull(); diff --git a/tests/unit/com/android/documentsui/ModelTest.java b/tests/unit/com/android/documentsui/ModelTest.java index 7d44477c5..82577903d 100644 --- a/tests/unit/com/android/documentsui/ModelTest.java +++ b/tests/unit/com/android/documentsui/ModelTest.java @@ -93,9 +93,9 @@ public class ModelTest { cursor = c; DirectoryResult r = new DirectoryResult(); - r.cursor = cursor; + r.setCursor(cursor); - // Instantiate the model with a dummy view adapter and listener that (for now) do nothing. + // Instantiate the model with a stub view adapter and listener that (for now) do nothing. model = new Model(features); // not sure why we add a listener here at all. model.addUpdateListener(new TestEventListener<>()); @@ -132,7 +132,7 @@ public class ModelTest { // Update the model, then make sure it contains all the expected items. DirectoryResult r = new DirectoryResult(); - r.cursor = cIn; + r.setCursor(cIn); model.update(r); assertEquals(ITEM_COUNT * 2, model.getItemCount()); diff --git a/tests/unit/com/android/documentsui/RecentsLoaderTests.java b/tests/unit/com/android/documentsui/RecentsLoaderTests.java index 575baf3f1..d95e9243c 100644 --- a/tests/unit/com/android/documentsui/RecentsLoaderTests.java +++ b/tests/unit/com/android/documentsui/RecentsLoaderTests.java @@ -99,24 +99,28 @@ public class RecentsLoaderTests { final DirectoryResult result = mLoader.loadInBackground(); - final Cursor c = result.cursor; + final Cursor c = result.getCursor(); assertEquals(0, c.getCount()); } @Test public void testShowOrHideHiddenFiles() { - final DocumentInfo doc = mEnv.model.createFile(".test"); - doc.lastModified = System.currentTimeMillis(); + final DocumentInfo doc1 = mEnv.model.createFile(".test"); + final DocumentInfo doc2 = mEnv.model.createFile("test"); + doc1.documentId = ".test"; + doc2.documentId = "parent_folder/.hidden_folder/test"; + doc1.lastModified = System.currentTimeMillis(); + doc2.lastModified = System.currentTimeMillis(); mEnv.mockProviders.get(TestProvidersAccess.HOME.authority) - .setNextRecentDocumentsReturns(doc); + .setNextRecentDocumentsReturns(doc1, doc2); assertEquals(false, mLoader.mState.showHiddenFiles); DirectoryResult result = mLoader.loadInBackground(); - assertEquals(0, result.cursor.getCount()); + assertEquals(0, result.getCursor().getCount()); mLoader.mState.showHiddenFiles = true; result = mLoader.loadInBackground(); - assertEquals(1, result.cursor.getCount()); + assertEquals(2, result.getCursor().getCount()); } @Test @@ -131,7 +135,7 @@ public class RecentsLoaderTests { final DirectoryResult result = mLoader.loadInBackground(); - final Cursor c = result.cursor; + final Cursor c = result.getCursor(); assertEquals(1, c.getCount()); for (int i = 0; i < c.getCount(); ++i) { c.moveToNext(); @@ -174,7 +178,7 @@ public class RecentsLoaderTests { TestProvidersAccess.OtherUser.USER_ID); final DirectoryResult result = mLoader.loadInBackground(); - assertThat(result.cursor).isNull(); + assertThat(result.getCursor()).isNull(); assertThat(result.exception).isInstanceOf(CrossProfileNoPermissionException.class); } @@ -183,7 +187,7 @@ public class RecentsLoaderTests { when(mActivity.userManager.isQuietModeEnabled(any())).thenReturn(true); final DirectoryResult result = mLoader.loadInBackground(); - assertThat(result.cursor).isNull(); + assertThat(result.getCursor()).isNull(); assertThat(result.exception).isInstanceOf(CrossProfileQuietModeException.class); } } diff --git a/tests/unit/com/android/documentsui/files/ActionHandlerTest.java b/tests/unit/com/android/documentsui/files/ActionHandlerTest.java index d7bdbd1ec..62fea24f0 100644 --- a/tests/unit/com/android/documentsui/files/ActionHandlerTest.java +++ b/tests/unit/com/android/documentsui/files/ActionHandlerTest.java @@ -30,6 +30,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; import android.app.Activity; import android.app.DownloadManager; @@ -70,6 +71,7 @@ import com.android.documentsui.testing.TestFeatures; import com.android.documentsui.testing.TestProvidersAccess; import com.android.documentsui.testing.UserManagers; import com.android.documentsui.ui.TestDialogController; +import com.android.documentsui.util.VersionUtils; import org.junit.Before; import org.junit.Test; @@ -510,28 +512,31 @@ public class ActionHandlerTest { @Test public void testDragAndDrop_OnReadOnlyRoot() throws Exception { + assumeTrue(VersionUtils.isAtLeastS()); RootInfo root = new RootInfo(); // root by default has no SUPPORT_CREATE flag - DragEvent event = DragEvent.obtain(DragEvent.ACTION_DROP, 1, 1, null, null, null, - null, true); + DragEvent event = DragEvent.obtain(DragEvent.ACTION_DROP, 1, 1, 0, 0, null, null, null, + null, null, true); assertFalse(mHandler.dropOn(event, root)); } @Test public void testDragAndDrop_OnLibraryRoot() throws Exception { - DragEvent event = DragEvent.obtain(DragEvent.ACTION_DROP, 1, 1, null, null, null, - null, true); + assumeTrue(VersionUtils.isAtLeastS()); + DragEvent event = DragEvent.obtain(DragEvent.ACTION_DROP, 1, 1, 0, 0, null, null, null, + null, null, true); assertFalse(mHandler.dropOn(event, TestProvidersAccess.RECENTS)); } @Test public void testDragAndDrop_DropsOnWritableRoot() throws Exception { + assumeTrue(VersionUtils.isAtLeastS()); // DragEvent gets recycled in Android, so it is possible that by the time the callback is // called, event.getLocalState() and event.getClipData() returns null. This tests to ensure // our Clipper is getting the original CipData passed in. Object localState = new Object(); ClipData clipData = ClipDatas.createTestClipData(); - DragEvent event = DragEvent.obtain(DragEvent.ACTION_DROP, 1, 1, localState, null, clipData, - null, true); + DragEvent event = DragEvent.obtain(DragEvent.ACTION_DROP, 1, 1, 0, 0, localState, null, + clipData, null, null, true); mHandler.dropOn(event, TestProvidersAccess.DOWNLOADS); event.recycle(); @@ -586,7 +591,7 @@ public class ActionHandlerTest { public void testAuthentication() throws Exception { PendingIntent intent = PendingIntent.getActivity( InstrumentationRegistry.getInstrumentation().getTargetContext(), 0, new Intent(), - 0); + PendingIntent.FLAG_IMMUTABLE); mHandler.startAuthentication(intent); assertEquals(intent.getIntentSender(), mActivity.startIntentSender.getLastValue().first); diff --git a/tests/unit/com/android/documentsui/picker/MenuManagerTest.java b/tests/unit/com/android/documentsui/picker/MenuManagerTest.java index d3e2f2d9f..cf9699a3b 100644 --- a/tests/unit/com/android/documentsui/picker/MenuManagerTest.java +++ b/tests/unit/com/android/documentsui/picker/MenuManagerTest.java @@ -524,7 +524,7 @@ public final class MenuManagerTest { } DirectoryResult r = new DirectoryResult(); - r.cursor = c; + r.setCursor(c); Model model = new Model(new TestFeatures()); model.update(r); diff --git a/tests/unit/com/android/documentsui/queries/SearchChipViewManagerTest.java b/tests/unit/com/android/documentsui/queries/SearchChipViewManagerTest.java index 9dbef02a7..da83c38fa 100644 --- a/tests/unit/com/android/documentsui/queries/SearchChipViewManagerTest.java +++ b/tests/unit/com/android/documentsui/queries/SearchChipViewManagerTest.java @@ -34,6 +34,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.documentsui.R; import com.android.documentsui.base.MimeTypes; import com.android.documentsui.base.Shared; +import com.android.documentsui.util.VersionUtils; import org.junit.Before; import org.junit.Test; @@ -49,6 +50,8 @@ public final class SearchChipViewManagerTest { private static final String LARGE_FILES_CHIP_MIME_TYPE = ""; private static final String FROM_THIS_WEEK_CHIP_MIME_TYPE = ""; + private static final String[] TEST_MIME_TYPES_INCLUDING_DOCUMENT = + new String[]{"image/*", "video/*", "text/*"}; private static final String[] TEST_MIME_TYPES = new String[]{"image/*", "video/*"}; private static final String[] TEST_OTHER_TYPES = @@ -88,6 +91,18 @@ public final class SearchChipViewManagerTest { } @Test + public void testUpdateChips_documentsFilterOnlyAvailableAboveR() throws Exception { + mSearchChipViewManager.updateChips(TEST_MIME_TYPES_INCLUDING_DOCUMENT); + + int totalChipLength = TEST_MIME_TYPES_INCLUDING_DOCUMENT.length + TEST_OTHER_TYPES.length; + if (VersionUtils.isAtLeastR()) { + assertThat(mChipGroup.getChildCount()).isEqualTo(totalChipLength); + } else { + assertThat(mChipGroup.getChildCount()).isEqualTo(totalChipLength - 1); + } + } + + @Test public void testUpdateChips_withSingleMimeType_hasCorrectChipCount() throws Exception { mSearchChipViewManager.updateChips(new String[]{"image/*"}); diff --git a/tests/unit/com/android/documentsui/sidebar/RootItemListBuilderTest.java b/tests/unit/com/android/documentsui/sidebar/RootItemListBuilderTest.java index 2574ecc5a..aadb73630 100644 --- a/tests/unit/com/android/documentsui/sidebar/RootItemListBuilderTest.java +++ b/tests/unit/com/android/documentsui/sidebar/RootItemListBuilderTest.java @@ -173,10 +173,10 @@ public class RootItemListBuilderTest { List<RootItem> result = mBuilder.getList(); assertThat(result).containsExactlyElementsIn(Lists.newArrayList( - RootItem.createDummyItem( + RootItem.createStubItem( DOWNLOADS_DEFAULT_USER, TestProvidersAccess.OtherUser.USER_ID), SDCARD_DEFAULT_USER, - RootItem.createDummyItem(HOME_DEFAULT_USER, TestProvidersAccess.OtherUser.USER_ID), + RootItem.createStubItem(HOME_DEFAULT_USER, TestProvidersAccess.OtherUser.USER_ID), IMAGE_OTHER_USER, PICKLES_DEFAULT_USER)); } diff --git a/tests/unit/com/android/documentsui/sorting/SortModelTest.java b/tests/unit/com/android/documentsui/sorting/SortModelTest.java index da8903022..25c026e1f 100644 --- a/tests/unit/com/android/documentsui/sorting/SortModelTest.java +++ b/tests/unit/com/android/documentsui/sorting/SortModelTest.java @@ -70,14 +70,14 @@ public class SortModelTest { DIMENSION_3 }; - private static final DummyListener DUMMY_LISTENER = new DummyListener(); + private static final StubListener STUB_LISTENER = new StubListener(); private SortModel mModel; @Before public void setUp() { mModel = new SortModel(Arrays.asList(DIMENSIONS)); - mModel.addListener(DUMMY_LISTENER); + mModel.addListener(STUB_LISTENER); } @Test @@ -106,7 +106,7 @@ public class SortModelTest { mModel.setDimensionVisibility(DIMENSION_1.getId(), View.GONE); assertEquals(View.GONE, DIMENSION_1.getVisibility()); - assertEquals(SortModel.UPDATE_TYPE_VISIBILITY, DUMMY_LISTENER.mLastUpdateType); + assertEquals(SortModel.UPDATE_TYPE_VISIBILITY, STUB_LISTENER.mLastUpdateType); } @Test @@ -122,8 +122,8 @@ public class SortModelTest { assertSame(DIMENSION_1, sortedDimension); assertEquals(DIMENSION_1.getDefaultSortDirection(), sortedDimension.getSortDirection()); - assertSame(mModel, DUMMY_LISTENER.mLastSortModel); - assertEquals(SortModel.UPDATE_TYPE_SORTING, DUMMY_LISTENER.mLastUpdateType); + assertSame(mModel, STUB_LISTENER.mLastSortModel); + assertEquals(SortModel.UPDATE_TYPE_SORTING, STUB_LISTENER.mLastUpdateType); } @Test @@ -134,8 +134,8 @@ public class SortModelTest { assertSame(DIMENSION_1, sortedDimension); assertEquals(SortDimension.SORT_DIRECTION_DESCENDING, sortedDimension.getSortDirection()); - assertSame(mModel, DUMMY_LISTENER.mLastSortModel); - assertEquals(SortModel.UPDATE_TYPE_SORTING, DUMMY_LISTENER.mLastUpdateType); + assertSame(mModel, STUB_LISTENER.mLastSortModel); + assertEquals(SortModel.UPDATE_TYPE_SORTING, STUB_LISTENER.mLastUpdateType); } @Test @@ -147,8 +147,8 @@ public class SortModelTest { assertSame(DIMENSION_1, sortedDimension); assertEquals(SortDimension.SORT_DIRECTION_DESCENDING, sortedDimension.getSortDirection()); - assertSame(mModel, DUMMY_LISTENER.mLastSortModel); - assertEquals(SortModel.UPDATE_TYPE_SORTING, DUMMY_LISTENER.mLastUpdateType); + assertSame(mModel, STUB_LISTENER.mLastSortModel); + assertEquals(SortModel.UPDATE_TYPE_SORTING, STUB_LISTENER.mLastUpdateType); } @Test @@ -160,8 +160,8 @@ public class SortModelTest { assertSame(DIMENSION_1, sortedDimension); assertEquals(SortDimension.SORT_DIRECTION_DESCENDING, sortedDimension.getSortDirection()); - assertSame(mModel, DUMMY_LISTENER.mLastSortModel); - assertEquals(SortModel.UPDATE_TYPE_SORTING, DUMMY_LISTENER.mLastUpdateType); + assertSame(mModel, STUB_LISTENER.mLastSortModel); + assertEquals(SortModel.UPDATE_TYPE_SORTING, STUB_LISTENER.mLastUpdateType); } @Test @@ -225,7 +225,7 @@ public class SortModelTest { return mModel.getDimensionById(sortedDimensionId); } - private static class DummyListener implements UpdateListener { + private static class StubListener implements UpdateListener { private SortModel mLastSortModel; private @UpdateType int mLastUpdateType; |
