summaryrefslogtreecommitdiff
path: root/packages/DocumentsUI
diff options
context:
space:
mode:
Diffstat (limited to 'packages/DocumentsUI')
-rw-r--r--packages/DocumentsUI/AndroidManifest.xml6
-rw-r--r--packages/DocumentsUI/perf-tests/Android.mk2
-rw-r--r--packages/DocumentsUI/res/color/item_eject_icon.xml (renamed from packages/DocumentsUI/res/values-az-rAZ/config.xml)14
-rw-r--r--packages/DocumentsUI/res/drawable/breadcrumb_item_background.xml42
-rw-r--r--packages/DocumentsUI/res/drawable/ic_eject.xml24
-rw-r--r--packages/DocumentsUI/res/drawable/root_item_background.xml35
-rw-r--r--packages/DocumentsUI/res/layout/drawer_layout.xml19
-rw-r--r--packages/DocumentsUI/res/layout/fixed_layout.xml13
-rw-r--r--packages/DocumentsUI/res/layout/fragment_directory.xml107
-rw-r--r--packages/DocumentsUI/res/layout/fragment_roots.xml1
-rw-r--r--packages/DocumentsUI/res/layout/item_root.xml26
-rw-r--r--packages/DocumentsUI/res/layout/navigation_breadcrumb_item.xml53
-rw-r--r--packages/DocumentsUI/res/menu/activity.xml7
-rw-r--r--packages/DocumentsUI/res/menu/context_menu.xml27
-rw-r--r--packages/DocumentsUI/res/menu/mode_directory.xml5
-rw-r--r--packages/DocumentsUI/res/menu/root_context_menu.xml (renamed from packages/DocumentsUI/res/values-ar/config.xml)18
-rw-r--r--packages/DocumentsUI/res/values-af/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-af/strings.xml49
-rw-r--r--packages/DocumentsUI/res/values-am/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-am/strings.xml53
-rw-r--r--packages/DocumentsUI/res/values-ar/strings.xml95
-rw-r--r--packages/DocumentsUI/res/values-az-rAZ/strings.xml64
-rw-r--r--packages/DocumentsUI/res/values-b+sr+Latn/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-b+sr+Latn/strings.xml60
-rw-r--r--packages/DocumentsUI/res/values-be-rBY/strings.xml168
-rw-r--r--packages/DocumentsUI/res/values-bg/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-bg/strings.xml49
-rw-r--r--packages/DocumentsUI/res/values-bn-rBD/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-bn-rBD/strings.xml65
-rw-r--r--packages/DocumentsUI/res/values-bs-rBA/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-bs-rBA/strings.xml256
-rw-r--r--packages/DocumentsUI/res/values-ca/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-ca/strings.xml49
-rw-r--r--packages/DocumentsUI/res/values-cs/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-cs/strings.xml67
-rw-r--r--packages/DocumentsUI/res/values-da/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-da/strings.xml57
-rw-r--r--packages/DocumentsUI/res/values-de/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-de/strings.xml57
-rw-r--r--packages/DocumentsUI/res/values-el/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-el/strings.xml51
-rw-r--r--packages/DocumentsUI/res/values-en-rAU/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-en-rAU/strings.xml61
-rw-r--r--packages/DocumentsUI/res/values-en-rGB/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-en-rGB/strings.xml61
-rw-r--r--packages/DocumentsUI/res/values-en-rIN/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-en-rIN/strings.xml61
-rw-r--r--packages/DocumentsUI/res/values-es-rUS/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-es-rUS/strings.xml57
-rw-r--r--packages/DocumentsUI/res/values-es/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-es/strings.xml48
-rw-r--r--packages/DocumentsUI/res/values-et-rEE/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-et-rEE/strings.xml61
-rw-r--r--packages/DocumentsUI/res/values-eu-rES/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-eu-rES/strings.xml49
-rw-r--r--packages/DocumentsUI/res/values-fa/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-fa/strings.xml61
-rw-r--r--packages/DocumentsUI/res/values-fi/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-fi/strings.xml53
-rw-r--r--packages/DocumentsUI/res/values-fr-rCA/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-fr-rCA/strings.xml51
-rw-r--r--packages/DocumentsUI/res/values-fr/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-fr/strings.xml49
-rw-r--r--packages/DocumentsUI/res/values-gl-rES/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-gl-rES/strings.xml49
-rw-r--r--packages/DocumentsUI/res/values-gu-rIN/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-gu-rIN/strings.xml59
-rw-r--r--packages/DocumentsUI/res/values-hi/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-hi/strings.xml50
-rw-r--r--packages/DocumentsUI/res/values-hr/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-hr/strings.xml54
-rw-r--r--packages/DocumentsUI/res/values-hu/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-hu/strings.xml55
-rw-r--r--packages/DocumentsUI/res/values-hy-rAM/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-hy-rAM/strings.xml55
-rw-r--r--packages/DocumentsUI/res/values-in/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-in/strings.xml46
-rw-r--r--packages/DocumentsUI/res/values-is-rIS/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-is-rIS/strings.xml53
-rw-r--r--packages/DocumentsUI/res/values-it/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-it/strings.xml49
-rw-r--r--packages/DocumentsUI/res/values-iw/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-iw/strings.xml67
-rw-r--r--packages/DocumentsUI/res/values-ja/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-ja/strings.xml57
-rw-r--r--packages/DocumentsUI/res/values-ka-rGE/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-ka-rGE/strings.xml53
-rw-r--r--packages/DocumentsUI/res/values-kk-rKZ/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-kk-rKZ/strings.xml57
-rw-r--r--packages/DocumentsUI/res/values-km-rKH/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-km-rKH/strings.xml63
-rw-r--r--packages/DocumentsUI/res/values-kn-rIN/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-kn-rIN/strings.xml53
-rw-r--r--packages/DocumentsUI/res/values-ko/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-ko/strings.xml53
-rw-r--r--packages/DocumentsUI/res/values-ky-rKG/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-ky-rKG/strings.xml55
-rw-r--r--packages/DocumentsUI/res/values-lo-rLA/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-lo-rLA/strings.xml65
-rw-r--r--packages/DocumentsUI/res/values-lt/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-lt/strings.xml59
-rw-r--r--packages/DocumentsUI/res/values-lv/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-lv/strings.xml66
-rw-r--r--packages/DocumentsUI/res/values-mk-rMK/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-mk-rMK/strings.xml63
-rw-r--r--packages/DocumentsUI/res/values-ml-rIN/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-ml-rIN/strings.xml53
-rw-r--r--packages/DocumentsUI/res/values-mn-rMN/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-mn-rMN/strings.xml57
-rw-r--r--packages/DocumentsUI/res/values-mr-rIN/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-mr-rIN/strings.xml56
-rw-r--r--packages/DocumentsUI/res/values-ms-rMY/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-ms-rMY/strings.xml49
-rw-r--r--packages/DocumentsUI/res/values-my-rMM/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-my-rMM/strings.xml69
-rw-r--r--packages/DocumentsUI/res/values-nb/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-nb/strings.xml49
-rw-r--r--packages/DocumentsUI/res/values-ne-rNP/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-ne-rNP/strings.xml57
-rw-r--r--packages/DocumentsUI/res/values-nl/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-nl/strings.xml46
-rw-r--r--packages/DocumentsUI/res/values-pa-rIN/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-pa-rIN/strings.xml74
-rw-r--r--packages/DocumentsUI/res/values-pl/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-pl/strings.xml67
-rw-r--r--packages/DocumentsUI/res/values-pt-rBR/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-pt-rBR/strings.xml49
-rw-r--r--packages/DocumentsUI/res/values-pt-rPT/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-pt-rPT/strings.xml46
-rw-r--r--packages/DocumentsUI/res/values-pt/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-pt/strings.xml49
-rw-r--r--packages/DocumentsUI/res/values-ro/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-ro/strings.xml68
-rw-r--r--packages/DocumentsUI/res/values-ru/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-ru/strings.xml85
-rw-r--r--packages/DocumentsUI/res/values-si-rLK/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-si-rLK/strings.xml57
-rw-r--r--packages/DocumentsUI/res/values-sk/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-sk/strings.xml67
-rw-r--r--packages/DocumentsUI/res/values-sl/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-sl/strings.xml59
-rw-r--r--packages/DocumentsUI/res/values-sq-rAL/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-sq-rAL/strings.xml49
-rw-r--r--packages/DocumentsUI/res/values-sr/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-sr/strings.xml60
-rw-r--r--packages/DocumentsUI/res/values-sv/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-sv/strings.xml53
-rw-r--r--packages/DocumentsUI/res/values-sw/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-sw/strings.xml55
-rw-r--r--packages/DocumentsUI/res/values-ta-rIN/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-ta-rIN/strings.xml49
-rw-r--r--packages/DocumentsUI/res/values-te-rIN/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-te-rIN/strings.xml54
-rw-r--r--packages/DocumentsUI/res/values-th/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-th/strings.xml61
-rw-r--r--packages/DocumentsUI/res/values-tl/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-tl/strings.xml55
-rw-r--r--packages/DocumentsUI/res/values-tr/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-tr/strings.xml51
-rw-r--r--packages/DocumentsUI/res/values-uk/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-uk/strings.xml59
-rw-r--r--packages/DocumentsUI/res/values-ur-rPK/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-ur-rPK/strings.xml55
-rw-r--r--packages/DocumentsUI/res/values-uz-rUZ/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-uz-rUZ/strings.xml71
-rw-r--r--packages/DocumentsUI/res/values-vi/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-vi/strings.xml51
-rw-r--r--packages/DocumentsUI/res/values-zh-rCN/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-zh-rCN/strings.xml49
-rw-r--r--packages/DocumentsUI/res/values-zh-rHK/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-zh-rHK/strings.xml55
-rw-r--r--packages/DocumentsUI/res/values-zh-rTW/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-zh-rTW/strings.xml55
-rw-r--r--packages/DocumentsUI/res/values-zu/config.xml20
-rw-r--r--packages/DocumentsUI/res/values-zu/strings.xml46
-rw-r--r--packages/DocumentsUI/res/values/attrs.xml (renamed from packages/DocumentsUI/res/values-ldrtl/config.xml)7
-rw-r--r--packages/DocumentsUI/res/values/colors.xml1
-rw-r--r--packages/DocumentsUI/res/values/config.xml3
-rw-r--r--packages/DocumentsUI/res/values/dimens.xml4
-rw-r--r--packages/DocumentsUI/res/values/layouts.xml1
-rw-r--r--packages/DocumentsUI/res/values/strings.xml11
-rw-r--r--packages/DocumentsUI/res/values/tags.xml (renamed from packages/DocumentsUI/res/values-sw720dp-land/config.xml)5
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java138
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/CheckedTask.java80
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/DocumentClipper.java167
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java68
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/DocumentsApplication.java40
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/DocumentsMenuManager.java85
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/DragOverTextView.java52
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/DrawerController.java29
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/DropdownBreadcrumb.java158
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/EjectRootTask.java75
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/Events.java104
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/Files.java36
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java88
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/FilesMenuManager.java99
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/HorizontalBreadcrumb.java258
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/ItemDragListener.java161
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/MenuManager.java221
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/Metrics.java9
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/NavigationView.java238
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/NavigationViewManager.java137
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/OperationDialogFragment.java4
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/PairedTask.java44
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java20
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/RetainedState.java36
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/RootItemView.java55
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/RootsCache.java16
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java414
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/SearchViewManager.java6
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/Shared.java30
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/Snackbars.java24
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/State.java6
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/ThumbnailCache.java274
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/clipping/ClipStorage.java270
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/clipping/ClipStorageReader.java125
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/clipping/DocumentClipper.java339
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/clipping/UrisSupplier.java282
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/dirlist/BandController.java1264
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryDragListener.java48
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java1152
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentHolder.java102
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentsAdapter.java10
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/dirlist/DragShadowBuilder.java68
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/dirlist/FocusHandler.java51
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/dirlist/FocusManager.java20
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java88
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/dirlist/GridDocumentHolder.java4
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/dirlist/IconHelper.java148
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java3
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/dirlist/ListeningGestureDetector.java86
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java17
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java22
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java1327
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapper.java8
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/dirlist/TouchSwipeRefreshLayout.java43
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/dirlist/UserInputHandler.java423
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java25
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/model/DocumentStack.java27
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java27
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java192
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/services/DeleteJob.java72
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/services/FileOperation.java240
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java238
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/services/FileOperations.java182
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/services/Job.java116
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java64
-rw-r--r--packages/DocumentsUI/tests/Android.mk5
-rw-r--r--packages/DocumentsUI/tests/jarjar-rules.txt2
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/ActivityTest.java39
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/DocumentsMenuManagerTest.java246
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/FileManagementUiTest.java123
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityDefaultsUiTest.java75
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java180
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/FilesMenuManagerTest.java286
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/IntegratedDownloadsUiTest.java71
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/ItemDragListenerTest.java215
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/KeyboardNavigationUiTest.java64
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/RenameDocumentUiTest.java56
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/RootsUiTest.java2
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/SearchViewUiTest.java157
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/TestInputEvent.java29
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/ThumbnailCacheTest.java202
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/bots/BaseBot.java74
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/bots/Bots.java99
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/bots/BreadBot.java153
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/bots/DirectoryListBot.java20
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/bots/KeyboardBot.java22
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/bots/Matchers.java48
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/bots/RootsListBot.java32
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/bots/SearchBot.java124
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/bots/UiBot.java207
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/clipping/ClipStorageTest.java159
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/clipping/UrisSupplierTest.java150
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/BandController_GridModelTest.java (renamed from packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManager_GridModelTest.java)8
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/DocumentHolderTest.java51
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java10
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManagerTest.java277
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManager_SingleSelectTest.java66
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestData.java30
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestDocumentsAdapter.java6
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestFocusHandler.java44
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestSelectionEnvironment.java2
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/UserInputHandler_MouseTest.java110
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/UserInputHandler_RangeTest.java147
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/UserInputHandler_TouchTest.java118
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractCopyJobTest.java16
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractJobTest.java29
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/services/CopyJobTest.java19
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/services/DeleteJobTest.java16
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/services/FileOperationServiceTest.java237
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/services/MoveJobTest.java20
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/services/TestJob.java38
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/services/TestJobListener.java5
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/testing/Bitmaps.java31
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/testing/ClipDatas.java33
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/testing/DocsProviders.java31
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/testing/DragEvents.java50
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestDirectoryDetails.java66
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestDrawable.java53
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestEvent.java138
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestHandler.java70
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestMenu.java90
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestMenuItem.java96
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestPredicate.java47
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestScheduledExecutorService.java (renamed from packages/DocumentsUI/tests/src/com/android/documentsui/services/TestScheduledExecutorService.java)12
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestSearchViewManager.java59
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestSelectionDetails.java50
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestTimer.java150
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/testing/Views.java39
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/testing/dirlist/SelectionProbe.java89
-rw-r--r--packages/DocumentsUI/tests/src/com/android/documentsui/testing/dirlist/TestSelectionListener.java56
312 files changed, 15421 insertions, 6992 deletions
diff --git a/packages/DocumentsUI/AndroidManifest.xml b/packages/DocumentsUI/AndroidManifest.xml
index a3edae35cc2b..b224510fd9fc 100644
--- a/packages/DocumentsUI/AndroidManifest.xml
+++ b/packages/DocumentsUI/AndroidManifest.xml
@@ -114,9 +114,13 @@
</intent-filter>
</receiver>
+ <!-- Run FileOperationService in a separate process so that we can use FileLock class to
+ wait until jumbo clip is done writing to disk before reading it. See ClipStorage for
+ details. -->
<service
android:name=".services.FileOperationService"
- android:exported="false">
+ android:exported="false"
+ android:process=":com.android.documentsui.services">
</service>
</application>
</manifest>
diff --git a/packages/DocumentsUI/perf-tests/Android.mk b/packages/DocumentsUI/perf-tests/Android.mk
index 5ebf85f74d2a..39a08f741066 100644
--- a/packages/DocumentsUI/perf-tests/Android.mk
+++ b/packages/DocumentsUI/perf-tests/Android.mk
@@ -11,7 +11,7 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) \
../tests/src/com/android/documentsui/StubProvider.java
LOCAL_JAVA_LIBRARIES := android-support-v4 android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := mockito-target ub-uiautomator ub-janktesthelper
+LOCAL_STATIC_JAVA_LIBRARIES := mockito-target ub-uiautomator ub-janktesthelper espresso-core
LOCAL_PACKAGE_NAME := DocumentsUIPerfTests
LOCAL_INSTRUMENTATION_FOR := DocumentsUI
diff --git a/packages/DocumentsUI/res/values-az-rAZ/config.xml b/packages/DocumentsUI/res/color/item_eject_icon.xml
index 843a8aad4051..15e7e8e60990 100644
--- a/packages/DocumentsUI/res/values-az-rAZ/config.xml
+++ b/packages/DocumentsUI/res/color/item_eject_icon.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
+<?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.
@@ -12,9 +12,9 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
- -->
+-->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_enabled="false" android:alpha="@*android:dimen/disabled_alpha_material_light" android:color="@*android:color/primary_text_default_material_light" />
+ <item android:color="@*android:color/primary_text_default_material_light" />
+</selector>
diff --git a/packages/DocumentsUI/res/drawable/breadcrumb_item_background.xml b/packages/DocumentsUI/res/drawable/breadcrumb_item_background.xml
new file mode 100644
index 000000000000..c4bc77b3bb40
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable/breadcrumb_item_background.xml
@@ -0,0 +1,42 @@
+<?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.
+-->
+
+<ripple
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res/com.android.documentsui"
+ android:color="?attr/colorControlHighlight">
+ <item
+ android:id="@android:id/mask"
+ android:drawable="@android:color/white"/>
+
+ <item>
+ <selector>
+ <item
+ app:state_highlighted="true"
+ android:drawable="@color/item_breadcrumb_background_hovered"/>
+ <item
+ app:state_highlighted="false"
+ android:drawable="@android:color/transparent">
+ <corners
+ android:topLeftRadius="2dp"
+ android:topRightRadius="2dp"
+ android:bottomLeftRadius="2dp"
+ android:bottomRightRadius="2dp"
+ />
+ </item>
+ </selector>
+ </item>
+</ripple> \ No newline at end of file
diff --git a/packages/DocumentsUI/res/drawable/ic_eject.xml b/packages/DocumentsUI/res/drawable/ic_eject.xml
new file mode 100644
index 000000000000..cbcd755b8106
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable/ic_eject.xml
@@ -0,0 +1,24 @@
+<!--
+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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF737373"
+ android:pathData="M5 17h14v2H5zm7-12L5.33 15h13.34z"/>
+</vector>
diff --git a/packages/DocumentsUI/res/drawable/root_item_background.xml b/packages/DocumentsUI/res/drawable/root_item_background.xml
new file mode 100644
index 000000000000..cc56f1e56e4d
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable/root_item_background.xml
@@ -0,0 +1,35 @@
+<?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.
+-->
+
+<ripple
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res/com.android.documentsui"
+ android:color="?attr/colorControlHighlight">
+ <item
+ android:id="@android:id/mask"
+ android:drawable="@android:color/white"/>
+
+ <item>
+ <selector>
+ <item
+ app:state_highlighted="true"
+ android:drawable="@color/item_doc_background_selected"/>
+ <item
+ app:state_highlighted="false"
+ android:drawable="@android:color/transparent"/>
+ </selector>
+ </item>
+</ripple> \ No newline at end of file
diff --git a/packages/DocumentsUI/res/layout/drawer_layout.xml b/packages/DocumentsUI/res/layout/drawer_layout.xml
index b65c5a066bf6..32ba6d03c249 100644
--- a/packages/DocumentsUI/res/layout/drawer_layout.xml
+++ b/packages/DocumentsUI/res/layout/drawer_layout.xml
@@ -41,8 +41,8 @@
android:theme="?actionBarTheme"
android:popupTheme="?actionBarPopupTheme">
- <Spinner
- android:id="@+id/stack"
+ <com.android.documentsui.DropdownBreadcrumb
+ android:id="@+id/dropdown_breadcrumb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
@@ -52,7 +52,20 @@
</com.android.documentsui.DocumentsToolbar>
- <include layout="@layout/directory_cluster"/>
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <include layout="@layout/directory_cluster"/>
+
+ <!-- Drawer edge is a dummy 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"
+ android:layout_width="@dimen/drawer_edge_width"
+ android:layout_height="match_parent"/>
+ </FrameLayout>
</LinearLayout>
diff --git a/packages/DocumentsUI/res/layout/fixed_layout.xml b/packages/DocumentsUI/res/layout/fixed_layout.xml
index deb089418fe9..9882e94878f7 100644
--- a/packages/DocumentsUI/res/layout/fixed_layout.xml
+++ b/packages/DocumentsUI/res/layout/fixed_layout.xml
@@ -39,14 +39,11 @@
android:theme="?actionBarTheme"
android:popupTheme="?actionBarPopupTheme">
- <Spinner
- android:id="@+id/stack"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="4dp"
- android:popupTheme="?actionBarPopupTheme"
- android:background="@android:color/transparent"
- android:overlapAnchor="true" />
+ <com.android.documentsui.HorizontalBreadcrumb
+ android:id="@+id/horizontal_breadcrumb"
+ android:layout_marginRight="20dp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
</com.android.documentsui.DocumentsToolbar>
diff --git a/packages/DocumentsUI/res/layout/fragment_directory.xml b/packages/DocumentsUI/res/layout/fragment_directory.xml
index 8eb46ddffe48..1c086a614a5c 100644
--- a/packages/DocumentsUI/res/layout/fragment_directory.xml
+++ b/packages/DocumentsUI/res/layout/fragment_directory.xml
@@ -39,65 +39,70 @@
android:background="@color/material_grey_50"
android:visibility="gone"/>
- <!-- The empty container view -->
- <FrameLayout
- android:id="@android:id/empty"
- android:gravity="center"
+ <com.android.documentsui.dirlist.TouchSwipeRefreshLayout
+ android:id="@+id/refresh_layout"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:background="@color/directory_background"
- android:focusable="true"
- android:focusableInTouchMode="true"
- android:visibility="gone">
+ android:layout_height="match_parent">
- <LinearLayout
- android:id="@+id/content"
- android:gravity="center"
+ <FrameLayout
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
+ android:layout_height="match_parent">
+ <!-- The empty container view -->
+ <FrameLayout
+ android:id="@android:id/empty"
+ android:gravity="center"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:background="@color/directory_background"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ android:visibility="gone"
+ android:clickable="true">
- <ImageView
- android:id="@+id/artwork"
- android:src="@drawable/cabinet"
- android:adjustViewBounds="true"
- android:layout_height="250dp"
- android:layout_width="fill_parent"
- android:alpha="1"
- android:layout_centerVertical="true"
- android:layout_marginBottom="25dp"
- android:scaleType="fitCenter"
- android:contentDescription="@null" />
+ <LinearLayout
+ android:id="@+id/content"
+ android:gravity="center"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
- <TextView
- android:id="@+id/message"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/empty"
- style="@android:style/TextAppearance.Material.Subhead" />
+ <ImageView
+ android:id="@+id/artwork"
+ android:src="@drawable/cabinet"
+ android:adjustViewBounds="true"
+ android:layout_height="250dp"
+ android:layout_width="fill_parent"
+ android:alpha="1"
+ android:layout_centerVertical="true"
+ android:layout_marginBottom="25dp"
+ android:scaleType="fitCenter"
+ android:contentDescription="@null"/>
- </LinearLayout>
- </FrameLayout>
+ <TextView
+ android:id="@+id/message"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/empty"
+ style="@android:style/TextAppearance.Material.Subhead"/>
- <!-- This FrameLayout works around b/24189541 -->
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent">
+ </LinearLayout>
+ </FrameLayout>
- <android.support.v7.widget.RecyclerView
- android:id="@+id/dir_list"
- android:scrollbars="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingStart="0dp"
- android:paddingEnd="0dp"
- android:paddingTop="0dp"
- android:paddingBottom="0dp"
- android:clipToPadding="false"
- android:scrollbarStyle="outsideOverlay"
- android:drawSelectorOnTop="true" />
+ <android.support.v7.widget.RecyclerView
+ android:id="@+id/dir_list"
+ android:scrollbars="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingStart="0dp"
+ android:paddingEnd="0dp"
+ android:paddingTop="0dp"
+ android:paddingBottom="0dp"
+ android:clipToPadding="false"
+ android:scrollbarStyle="outsideOverlay"
+ android:drawSelectorOnTop="true"/>
+ </FrameLayout>
- </FrameLayout>
+ </com.android.documentsui.dirlist.TouchSwipeRefreshLayout>
</com.android.documentsui.dirlist.AnimationView>
diff --git a/packages/DocumentsUI/res/layout/fragment_roots.xml b/packages/DocumentsUI/res/layout/fragment_roots.xml
index b33b8d09b992..ae462072c6b3 100644
--- a/packages/DocumentsUI/res/layout/fragment_roots.xml
+++ b/packages/DocumentsUI/res/layout/fragment_roots.xml
@@ -19,5 +19,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="8dp"
+ android:listSelector="@android:color/transparent"
android:drawSelectorOnTop="true"
android:divider="@null" />
diff --git a/packages/DocumentsUI/res/layout/item_root.xml b/packages/DocumentsUI/res/layout/item_root.xml
index 816cb8a0d556..114fd09a86ce 100644
--- a/packages/DocumentsUI/res/layout/item_root.xml
+++ b/packages/DocumentsUI/res/layout/item_root.xml
@@ -14,7 +14,8 @@
limitations under the License.
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.documentsui.RootItemView
+ xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dp"
@@ -22,7 +23,8 @@
android:paddingEnd="@dimen/list_item_padding"
android:gravity="center_vertical"
android:orientation="horizontal"
- android:baselineAligned="false">
+ android:baselineAligned="false"
+ android:background="@drawable/root_item_background">
<FrameLayout
android:layout_width="@dimen/icon_size"
@@ -44,7 +46,8 @@
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
- android:orientation="vertical">
+ android:orientation="vertical"
+ android:layout_weight="1">
<TextView
android:id="@android:id/title"
@@ -68,4 +71,19 @@
</LinearLayout>
-</LinearLayout>
+ <FrameLayout
+ android:layout_width="@dimen/icon_size"
+ android:layout_height="@dimen/icon_size"
+ android:duplicateParentState="true">
+
+ <ImageView
+ android:id="@+id/eject_icon"
+ android:layout_width="@dimen/root_icon_size"
+ android:layout_height="match_parent"
+ android:scaleType="centerInside"
+ android:contentDescription="@string/menu_eject_root"
+ android:visibility="gone" />
+
+ </FrameLayout>
+
+</com.android.documentsui.RootItemView>
diff --git a/packages/DocumentsUI/res/layout/navigation_breadcrumb_item.xml b/packages/DocumentsUI/res/layout/navigation_breadcrumb_item.xml
new file mode 100644
index 000000000000..720f7953c7dd
--- /dev/null
+++ b/packages/DocumentsUI/res/layout/navigation_breadcrumb_item.xml
@@ -0,0 +1,53 @@
+<?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.
+-->
+
+
+<!--
+ CoordinatorLayout is necessary for various components (e.g. Snackbars, and
+ floating action buttons) to operate correctly.
+-->
+<!--
+ focusableInTouchMode is set in order to force key events to go to the activity's global key
+ callback, which is necessary for proper event routing. See BaseActivity.onKeyDown.
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/breadcrumb_item_height"
+ android:layout_alignParentTop="true"
+ android:gravity="center_vertical"
+ android:orientation="horizontal">
+
+ <com.android.documentsui.DragOverTextView
+ android:id="@+id/breadcrumb_text"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:textAppearance="@android:style/TextAppearance.Material.Widget.ActionBar.Title"
+ android:background="@drawable/breadcrumb_item_background" />
+
+ <ImageView
+ android:id="@+id/breadcrumb_arrow"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_breadcrumb_arrow"
+ android:layout_marginTop="2dp"
+ android:layout_marginRight="3dp"
+ android:layout_marginLeft="3dp" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/packages/DocumentsUI/res/menu/activity.xml b/packages/DocumentsUI/res/menu/activity.xml
index 85e7a7ae004c..ed47bbcf2e2e 100644
--- a/packages/DocumentsUI/res/menu/activity.xml
+++ b/packages/DocumentsUI/res/menu/activity.xml
@@ -58,13 +58,6 @@
android:showAsAction="never"
android:visible="false" />
<item
- android:id="@+id/menu_paste_from_clipboard"
- android:title="@string/menu_paste_from_clipboard"
- android:alphabeticShortcut="v"
- android:showAsAction="never"
- android:visible="false" />
- <!-- Copy action is defined in mode_directory.xml -->
- <item
android:id="@+id/menu_sort"
android:title="@string/menu_sort"
android:icon="@drawable/ic_menu_sortby"
diff --git a/packages/DocumentsUI/res/menu/context_menu.xml b/packages/DocumentsUI/res/menu/context_menu.xml
new file mode 100644
index 000000000000..74748590a2b9
--- /dev/null
+++ b/packages/DocumentsUI/res/menu/context_menu.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:id="@+id/menu_cut_to_clipboard"
+ android:title="@string/menu_cut_to_clipboard" />
+ <item
+ android:id="@+id/menu_copy_to_clipboard"
+ android:title="@string/menu_copy_to_clipboard" />
+ <item
+ android:id="@+id/menu_paste_from_clipboard"
+ android:title="@string/menu_paste_from_clipboard" />
+</menu>
diff --git a/packages/DocumentsUI/res/menu/mode_directory.xml b/packages/DocumentsUI/res/menu/mode_directory.xml
index 6f9bfb557f62..e2125ad215a3 100644
--- a/packages/DocumentsUI/res/menu/mode_directory.xml
+++ b/packages/DocumentsUI/res/menu/mode_directory.xml
@@ -30,11 +30,6 @@
android:title="@string/menu_delete"
android:showAsAction="always" />
<item
- android:id="@+id/menu_copy_to_clipboard"
- android:title="@string/menu_copy_to_clipboard"
- android:showAsAction="never"
- android:visible="false" />
- <item
android:id="@+id/menu_select_all"
android:title="@string/menu_select_all"
android:showAsAction="never" />
diff --git a/packages/DocumentsUI/res/values-ar/config.xml b/packages/DocumentsUI/res/menu/root_context_menu.xml
index 843a8aad4051..0cf00a422515 100644
--- a/packages/DocumentsUI/res/values-ar/config.xml
+++ b/packages/DocumentsUI/res/menu/root_context_menu.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
+<?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.
@@ -12,9 +12,13 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
- -->
+-->
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:id="@+id/menu_eject_root"
+ android:title="@string/menu_eject_root" />
+ <item
+ android:id="@+id/menu_settings"
+ android:title="@string/menu_settings" />
+</menu>
diff --git a/packages/DocumentsUI/res/values-af/config.xml b/packages/DocumentsUI/res/values-af/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-af/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-af/strings.xml b/packages/DocumentsUI/res/values-af/strings.xml
index 458c309c83f2..bc00af737bbf 100644
--- a/packages/DocumentsUI/res/values-af/strings.xml
+++ b/packages/DocumentsUI/res/values-af/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumente"</string>
- <string name="files_label" msgid="6051402950202690279">"Lêers"</string>
<string name="downloads_label" msgid="959113951084633612">"Aflaaie"</string>
<string name="title_open" msgid="4353228937663917801">"Maak oop vanuit"</string>
<string name="title_save" msgid="2433679664882857999">"Stoor na"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Lysaansig"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sorteer volgens"</string>
<string name="menu_search" msgid="3816712084502856974">"Soek"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Berginginstellings"</string>
<string name="menu_open" msgid="432922957274920903">"Maak oop"</string>
<string name="menu_save" msgid="2394743337684426338">"Stoor"</string>
<string name="menu_share" msgid="3075149983979628146">"Deel"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Kopieer na …"</string>
<string name="menu_move" msgid="1828090633118079817">"Skuif na …"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Nuwe venster"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Knip"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopieer"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Plak"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Wys interne berging"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Versteek wortels"</string>
<string name="save_error" msgid="6167009778003223664">"Kon nie dokument stoor nie"</string>
<string name="create_error" msgid="3735649141335444215">"Kon nie vouer skep nie"</string>
- <string name="query_error" msgid="1222448261663503501">"Kon nie navraag doen oor dokumente nie"</string>
+ <string name="query_error" msgid="5999895349602476581">"Kan nie op die oomblik inhoud laai nie"</string>
<string name="root_recent" msgid="4470053704320518133">"Onlangs"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> gratis"</string>
<string name="root_type_service" msgid="2178854894416775409">"Bergingdienste"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Nog programme"</string>
<string name="empty" msgid="7858882803708117596">"Geen items nie"</string>
<string name="no_results" msgid="6622510343880730446">"Geen passings in %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Kan lêer nie oopmaak nie"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Kan nie lêer oopmaak nie"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Kan sommige dokumente nie uitvee nie"</string>
<string name="share_via" msgid="8966594246261344259">"Deel via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopieer tans lêers"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Skuif tans lêers"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Vee tans lêers uit"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> oor"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Kopieer tans <xliff:g id="COUNT_1">%1$d</xliff:g> lêers.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Maak tans gereed vir kopieer …"</string>
<string name="move_preparing" msgid="2772219441375531410">"Berei tans voor vir skuif …"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Maak tans gereed om uit te vee …"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other">Kon <xliff:g id="COUNT_1">%1$d</xliff:g> lêers nie kopieer nie</item>
<item quantity="one">Kon <xliff:g id="COUNT_0">%1$d</xliff:g> lêer nie kopieer nie</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other">Kon <xliff:g id="COUNT_1">%1$d</xliff:g> lêers nie skuif nie</item>
<item quantity="one">Kon <xliff:g id="COUNT_0">%1$d</xliff:g> lêer nie skuif nie</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other">Kon <xliff:g id="COUNT_1">%1$d</xliff:g> lêers nie uitvee nie</item>
<item quantity="one">Kon <xliff:g id="COUNT_0">%1$d</xliff:g> lêer nie uitvee nie</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Tik om besonderhede te bekyk"</string>
<string name="close" msgid="3043722427445528732">"Maak toe"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Hierdie lêers is nie gekopieer nie: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Hierdie lêers is nie geskuif nie: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Hierdie lêers is nie gekopieer nie: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Hierdie lêers is nie geskuif nie: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Hierdie lêers is nie uitgevee nie: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Hierdie lêers is na \'n ander formaat omgeskakel: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">Het <xliff:g id="COUNT_1">%1$d</xliff:g> lêers na die knipbord gekopieer.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Kan nie die geselekteerde lêers in hierdie ligging plak nie."</string>
<string name="menu_rename" msgid="7678802479104285353">"Hernoem"</string>
<string name="rename_error" msgid="4203041674883412606">"Kon nie dokument hernoem nie"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Maak los"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Sommige lêers is omgeskakel"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Gee <xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang tot <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>-gids op <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Gee <xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang tot <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>-gids?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Gee <xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang tot jou data, insluitend foto\'s en video\'s, op <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Moenie weer vra nie"</string>
<string name="allow" msgid="7225948811296386551">"Laat toe"</string>
<string name="deny" msgid="2081879885755434506">"Weier"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> gekies</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> gekies</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Vee \"<xliff:g id="NAME">%1$s</xliff:g>\" uit?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Vee vouer \"<xliff:g id="NAME">%1$s</xliff:g>\" en sy inhoud uit?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">Vee <xliff:g id="COUNT_1">%1$d</xliff:g> lêers uit?</item>
+ <item quantity="one">Vee <xliff:g id="COUNT_0">%1$d</xliff:g> lêer uit?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">Vee <xliff:g id="COUNT_1">%1$d</xliff:g> vouers en hul inhoud uit?</item>
+ <item quantity="one">Vee <xliff:g id="COUNT_0">%1$d</xliff:g> vouer en sy inhoud uit?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other">Vee <xliff:g id="COUNT_1">%1$d</xliff:g> items uit?</item>
+ <item quantity="one">Vee <xliff:g id="COUNT_0">%1$d</xliff:g> item uit?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-am/config.xml b/packages/DocumentsUI/res/values-am/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-am/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-am/strings.xml b/packages/DocumentsUI/res/values-am/strings.xml
index 6e08df4907b2..c1689fbfc1d1 100644
--- a/packages/DocumentsUI/res/values-am/strings.xml
+++ b/packages/DocumentsUI/res/values-am/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ሰነዶች"</string>
- <string name="files_label" msgid="6051402950202690279">"ፋይሎች"</string>
<string name="downloads_label" msgid="959113951084633612">"የወረዱ"</string>
<string name="title_open" msgid="4353228937663917801">"ክፈት ከ"</string>
<string name="title_save" msgid="2433679664882857999">"አስቀምጥ ወደ"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"የዝርዝር እይታ"</string>
<string name="menu_sort" msgid="7677740407158414452">"ደርድር በ"</string>
<string name="menu_search" msgid="3816712084502856974">"ፈልግ"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"የማከማቻ ቅንብሮች"</string>
<string name="menu_open" msgid="432922957274920903">"ክፈት"</string>
<string name="menu_save" msgid="2394743337684426338">"አስቀምጥ"</string>
<string name="menu_share" msgid="3075149983979628146">"አጋራ"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"ቅዳ ወደ…"</string>
<string name="menu_move" msgid="1828090633118079817">"ይውሰዱ ወደ..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"አዲሰ መስኮት"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"ቁረጥ"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"ቅዳ"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"ለጥፍ"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"ውስጣዊ ማከማቻ አሳይ"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"ስሮችን ደብቅ"</string>
<string name="save_error" msgid="6167009778003223664">"ሰነድ ማስቀመጥ አልተሳካም"</string>
<string name="create_error" msgid="3735649141335444215">"አቃፊ መፍጠር አልተሳካም"</string>
- <string name="query_error" msgid="1222448261663503501">"ለሰነዶች መጠይቅ መስራት አልተሳካም"</string>
+ <string name="query_error" msgid="5999895349602476581">"አሁን ይዘትን መጫን አልተቻለም"</string>
<string name="root_recent" msgid="4470053704320518133">"የቅርብ ጊዜ"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ነፃ"</string>
<string name="root_type_service" msgid="2178854894416775409">"የማከማቻ አገልግሎቶች"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"ተጨማሪ መተግበሪያዎች"</string>
<string name="empty" msgid="7858882803708117596">"ምንም ንጥሎች የሉም"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s ውስጥ ምንም ተዛማጆች የሉም"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"ፋይል መክፈት አይቻልም"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"ፋይሉን መክፈት አይቻልም"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"አንዳንድ ሰነዶችን መሰረዝ አልተቻለም"</string>
<string name="share_via" msgid="8966594246261344259">"በሚከተለው በኩል ያጋሩ"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"ፋይሎች በመገልበጥ ላይ"</string>
<string name="move_notification_title" msgid="6193835179777284805">"ፋይሎችን በመውሰድ ላይ"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"ፋይሎችን በመሰረዝ ላይ"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> ቀርቷል"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎች በመቅዳት ላይ።</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"ቅጂ በማዘጋጀት ላይ…"</string>
<string name="move_preparing" msgid="2772219441375531410">"ለመውሰድ በማዘጋጀት ላይ…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"ለመሰረዝ በመዘጋጀት ላይ…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎችን መቅዳት አልተቻለም</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎችን መቅዳት አልተቻለም</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎችን መውሰድ አልተቻለም</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎችን መውሰድ አልተቻለም</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
- <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎችን መሰረዝ አልተቻለም።</item>
- <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎችን መሰረዝ አልተቻለም።</item>
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎችን መሰረዝ አልተቻለም</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎችን መሰረዝ አልተቻለም</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"ዝርዝሮችን ለመመልከት መታ ያድርጉ"</string>
<string name="close" msgid="3043722427445528732">"ዝጋ"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"እነዚህ ፋይሎች አልተቀዱም፦ <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"እነዚህ ፋይሎች አልተወሰዱም፦ <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"እነዚህ ፋይሎች አልተቀዱም፦ <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"እነዚህ ፋይሎች አልተወሰዱም፦ <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"እነዚህ ፋይሎች አልተሰረዙም፦ <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"እነዚህ ፋይሎች ወደ ሌላ ቅርጸት ተለውጠዋል፦ <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎች ወደ ቅንጥብ ሰሌዳ ቀድቷል።</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"የተመረጡትን ፋይሎች ወደዚህ አካባቢ መለጠፍ አይቻልም።"</string>
<string name="menu_rename" msgid="7678802479104285353">"እንደገና ሰይም"</string>
<string name="rename_error" msgid="4203041674883412606">"ሰነዱን ዳግም መሰየም አልተሳካም"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"አስወጣ"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"አንዳንድ ፋይሎች ተለውጠዋል"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> በ<xliff:g id="STORAGE"><i>^3</i></xliff:g> ላይ የ<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ማውጫ መደረሻ ይሰጠው?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"የ<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ማውጫ መዳረሻ ለ<xliff:g id="APPNAME"><b>^1</b></xliff:g> ይሰጠው?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"በ<xliff:g id="STORAGE"><i>^2</i></xliff:g> ላይ ያሉትን ፎቶዎች እና ቪዲዮዎች ጨምሮ የውሂብዎ መዳረሻ ለ<xliff:g id="APPNAME"><b>^1</b></xliff:g> ይሰጥ?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"ዳግም አትጠይቅ"</string>
<string name="allow" msgid="7225948811296386551">"ይፍቀዱ"</string>
<string name="deny" msgid="2081879885755434506">"ያስተባብሉ"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ተመርጠዋል</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ተመርጠዋል</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ንጥሎች</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ንጥሎች</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"«<xliff:g id="NAME">%1$s</xliff:g>» ይሰረዝ?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"አቃፊ «<xliff:g id="NAME">%1$s</xliff:g>» እና ይዘቶቹ ይሰረዙ?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎች ይሰረዙ?</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎች ይሰረዙ?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> አቃፊዎች እና ይዘቶቻቸው ይሰረዙ?</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> አቃፊዎች እና ይዘቶቻቸው ይሰረዙ?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ንጥሎች ይሰረዙ?</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ንጥሎች ይሰረዙ?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-ar/strings.xml b/packages/DocumentsUI/res/values-ar/strings.xml
index 4b7b4a86487c..620143b7d907 100644
--- a/packages/DocumentsUI/res/values-ar/strings.xml
+++ b/packages/DocumentsUI/res/values-ar/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"مستندات"</string>
- <string name="files_label" msgid="6051402950202690279">"الملفات"</string>
<string name="downloads_label" msgid="959113951084633612">"التنزيلات"</string>
<string name="title_open" msgid="4353228937663917801">"فتح من"</string>
<string name="title_save" msgid="2433679664882857999">"حفظ في"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"عرض القائمة"</string>
<string name="menu_sort" msgid="7677740407158414452">"ترتيب بحسب"</string>
<string name="menu_search" msgid="3816712084502856974">"بحث"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"إعدادات سعة التخزين"</string>
<string name="menu_open" msgid="432922957274920903">"فتح"</string>
<string name="menu_save" msgid="2394743337684426338">"حفظ"</string>
<string name="menu_share" msgid="3075149983979628146">"مشاركة"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"نسخ إلى…"</string>
<string name="menu_move" msgid="1828090633118079817">"نقل إلى..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"نافذة جديدة"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"قص"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"نسخ"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"لصق"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"إظهار وحدة التخزين الداخلية"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"إخفاء الجذور"</string>
<string name="save_error" msgid="6167009778003223664">"أخفق حفظ المستند"</string>
<string name="create_error" msgid="3735649141335444215">"أخفق إنشاء المجلد"</string>
- <string name="query_error" msgid="1222448261663503501">"أخفق إرسال طلب بحث عن المستندات"</string>
+ <string name="query_error" msgid="5999895349602476581">"يتعذر تحميل المحتوى في الوقت الحالي"</string>
<string name="root_recent" msgid="4470053704320518133">"الأخيرة"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> خالية"</string>
<string name="root_type_service" msgid="2178854894416775409">"خدمات التخزين"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"المزيد من التطبيقات"</string>
<string name="empty" msgid="7858882803708117596">"ليس هناك أي عناصر"</string>
<string name="no_results" msgid="6622510343880730446">"‏لا نتائج مطابقة في %1$s."</string>
- <string name="toast_no_application" msgid="1339885974067891667">"لا يمكن فتح الملف"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"يتعذر فتح الملف"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"تعذر حذف بعض المستندات"</string>
<string name="share_via" msgid="8966594246261344259">"مشاركة عبر"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"جارٍ نسخ الملفات"</string>
<string name="move_notification_title" msgid="6193835179777284805">"نقل الملفات"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"جارٍ حذف الملفات"</string>
<string name="copy_remaining" msgid="6283790937387975095">"المدة المتبقية: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="zero">جارٍ نسخ <xliff:g id="COUNT_1">%1$d</xliff:g> ملفات.</item>
@@ -97,34 +97,36 @@
<string name="copy_preparing" msgid="3896202461003039386">"جارٍ التحضير للنسخ ..."</string>
<string name="move_preparing" msgid="2772219441375531410">"جارٍ التحضير للنقل…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"جارٍ الإعداد للحذف…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <item quantity="zero">لم يتعذر نسخ أية ملفات (<xliff:g id="COUNT_1">%1$d</xliff:g>)</item>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="zero">Couldn’t copy <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
<item quantity="two">تعذر نسخ ملفين (<xliff:g id="COUNT_1">%1$d</xliff:g>)</item>
- <item quantity="few"> تعذر نسخ <xliff:g id="COUNT_1">%1$d</xliff:g> ملفات</item>
- <item quantity="many"> تعذر نسخ <xliff:g id="COUNT_1">%1$d</xliff:g> ملفًا</item>
- <item quantity="other"> تعذر نسخ <xliff:g id="COUNT_1">%1$d</xliff:g> من الملفات</item>
- <item quantity="one"> تعذر نسخ <xliff:g id="COUNT_0">%1$d</xliff:g> ملف</item>
+ <item quantity="few">تعذر نسخ <xliff:g id="COUNT_1">%1$d</xliff:g> ملفات</item>
+ <item quantity="many">تعذر نسخ <xliff:g id="COUNT_1">%1$d</xliff:g> ملفًا</item>
+ <item quantity="other">تعذر نسخ <xliff:g id="COUNT_1">%1$d</xliff:g> ملف</item>
+ <item quantity="one">تعذر نسخ ملف (<xliff:g id="COUNT_0">%1$d</xliff:g>)</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="zero">ليست هناك ملفات يتعذر نقلها (<xliff:g id="COUNT_1">%1$d</xliff:g>)</item>
- <item quantity="two">تعذر نقل ملفين (<xliff:g id="COUNT_1">%1$d</xliff:g>)</item>
- <item quantity="few">تعذر نقل <xliff:g id="COUNT_1">%1$d</xliff:g> ملفات</item>
- <item quantity="many">تعذر نقل <xliff:g id="COUNT_1">%1$d</xliff:g> ملفًا</item>
- <item quantity="other">تعذر نقل <xliff:g id="COUNT_1">%1$d</xliff:g> من الملفات</item>
- <item quantity="one">تعذر نقل ملف واحد (<xliff:g id="COUNT_0">%1$d</xliff:g>)</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="zero">Couldn’t move <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
+ <item quantity="two">تعذر نقل ملفين (<xliff:g id="COUNT_1">%1$d</xliff:g>)</item>
+ <item quantity="few">تعذر نقل <xliff:g id="COUNT_1">%1$d</xliff:g> ملفات</item>
+ <item quantity="many">تعذر نقل <xliff:g id="COUNT_1">%1$d</xliff:g> ملفًا</item>
+ <item quantity="other">تعذر نقل <xliff:g id="COUNT_1">%1$d</xliff:g> ملف</item>
+ <item quantity="one">تعذر نقل ملف (<xliff:g id="COUNT_0">%1$d</xliff:g>)</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
- <item quantity="zero">تعذر حذف <xliff:g id="COUNT_1">%1$d</xliff:g> ملف</item>
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+ <item quantity="zero">Couldn’t delete <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
<item quantity="two">تعذر حذف ملفين (<xliff:g id="COUNT_1">%1$d</xliff:g>)</item>
<item quantity="few">تعذر حذف <xliff:g id="COUNT_1">%1$d</xliff:g> ملفات</item>
<item quantity="many">تعذر حذف <xliff:g id="COUNT_1">%1$d</xliff:g> ملفًا</item>
<item quantity="other">تعذر حذف <xliff:g id="COUNT_1">%1$d</xliff:g> ملف</item>
- <item quantity="one">تعذر حذف <xliff:g id="COUNT_0">%1$d</xliff:g> ملف</item>
+ <item quantity="one">تعذر حذف ملف (<xliff:g id="COUNT_0">%1$d</xliff:g>)</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"انقر لعرض التفاصيل."</string>
<string name="close" msgid="3043722427445528732">"إغلاق"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"لم يتم نسخ هذه الملفات: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"لم يتم نقل الملفات التالية: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"لم يتم نسخ هذه الملفات: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"لم يتم نقل هذه الملفات: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"لم يتم حذف هذه الملفات: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"تم تحويل هذه الملفات إلى تنسيق آخر: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="zero">لم يتم نسخ أي ملف (<xliff:g id="COUNT_1">%1$d</xliff:g>) إلى الحافظة.</item>
@@ -137,7 +139,54 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"يتعذر لصق الملفات المحددة في هذا الموقع."</string>
<string name="menu_rename" msgid="7678802479104285353">"إعادة تسمية"</string>
<string name="rename_error" msgid="4203041674883412606">"أخفقت إعادة تسمية المستند."</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"إخراج"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"تم تحويل بعض الملفات"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"هل تريد منح التطبيق <xliff:g id="APPNAME"><b>^1</b></xliff:g> حق الوصول إلى الدليل <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> على <xliff:g id="STORAGE"><i>^3</i></xliff:g>؟"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"هل تريد تمكين <xliff:g id="APPNAME"><b>^1</b></xliff:g> من الدخول إلى دليل <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>؟"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"هل تريد منح <xliff:g id="APPNAME"><b>^1</b></xliff:g> حق الوصول إلى بياناتك، بما في ذلك الصور ومقاطع الفيديو على <xliff:g id="STORAGE"><i>^2</i></xliff:g>؟"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"عدم السؤال مرة أخرى"</string>
<string name="allow" msgid="7225948811296386551">"السماح"</string>
<string name="deny" msgid="2081879885755434506">"رفض"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="zero">تم تحديد <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="two">تم تحديد <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="few">تم تحديد <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="many">تم تحديد <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">تم تحديد <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">تم تحديد <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="zero"><xliff:g id="COUNT_1">%1$d</xliff:g> عنصر</item>
+ <item quantity="two">عنصران (<xliff:g id="COUNT_1">%1$d</xliff:g>)</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> عناصر</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> عنصرًا</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> عنصر</item>
+ <item quantity="one">عنصر واحد (<xliff:g id="COUNT_0">%1$d</xliff:g>)</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"هل تريد حذف \"<xliff:g id="NAME">%1$s</xliff:g>\"؟"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"هل تريد حذف المجلد \"<xliff:g id="NAME">%1$s</xliff:g>\" ومحتوياته؟"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="zero">هل تريد حذف <xliff:g id="COUNT_1">%1$d</xliff:g> ملف؟</item>
+ <item quantity="two">هل تريد حذف ملفين (<xliff:g id="COUNT_1">%1$d</xliff:g>)؟</item>
+ <item quantity="few">هل تريد حذف <xliff:g id="COUNT_1">%1$d</xliff:g> ملفات؟</item>
+ <item quantity="many">هل تريد حذف <xliff:g id="COUNT_1">%1$d</xliff:g> ملفًا؟</item>
+ <item quantity="other">هل تريد حذف <xliff:g id="COUNT_1">%1$d</xliff:g> ملف؟</item>
+ <item quantity="one">هل تريد حذف <xliff:g id="COUNT_0">%1$d</xliff:g> ملف؟</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="zero">هل تريد حذف <xliff:g id="COUNT_1">%1$d</xliff:g> مجلد ومحتوياته؟</item>
+ <item quantity="two">هل تريد حذف مجلدين (<xliff:g id="COUNT_1">%1$d</xliff:g>) ومحتوياتهما؟</item>
+ <item quantity="few">هل تريد حذف <xliff:g id="COUNT_1">%1$d</xliff:g> مجلدات ومحتوياتها؟</item>
+ <item quantity="many">هل تريد حذف <xliff:g id="COUNT_1">%1$d</xliff:g> مجلدًا ومحتويات هذه المجلدات؟</item>
+ <item quantity="other">هل تريد حذف <xliff:g id="COUNT_1">%1$d</xliff:g> مجلد ومحتويات هذه المجلدات؟</item>
+ <item quantity="one">هل تريد حذف <xliff:g id="COUNT_0">%1$d</xliff:g> مجلد ومحتوياته؟</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="zero">هل تريد حذف <xliff:g id="COUNT_1">%1$d</xliff:g> عنصر؟</item>
+ <item quantity="two">هل تريد حذف عنصرين (<xliff:g id="COUNT_1">%1$d</xliff:g>)؟</item>
+ <item quantity="few">هل تريد حذف <xliff:g id="COUNT_1">%1$d</xliff:g> عناصر؟</item>
+ <item quantity="many">هل تريد حذف <xliff:g id="COUNT_1">%1$d</xliff:g> عنصرًا؟</item>
+ <item quantity="other">هل تريد حذف <xliff:g id="COUNT_1">%1$d</xliff:g> عنصر؟</item>
+ <item quantity="one">هل تريد حذف <xliff:g id="COUNT_0">%1$d</xliff:g> عنصر؟</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-az-rAZ/strings.xml b/packages/DocumentsUI/res/values-az-rAZ/strings.xml
index 9162b956c93b..988697c1b204 100644
--- a/packages/DocumentsUI/res/values-az-rAZ/strings.xml
+++ b/packages/DocumentsUI/res/values-az-rAZ/strings.xml
@@ -17,24 +17,24 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Sənədlər"</string>
- <string name="files_label" msgid="6051402950202690279">"Fayllar"</string>
<string name="downloads_label" msgid="959113951084633612">"Endirmələr"</string>
<string name="title_open" msgid="4353228937663917801">"Vasitəsilə açın"</string>
<string name="title_save" msgid="2433679664882857999">"buraya saxlayın"</string>
<string name="menu_create_dir" msgid="2547620241173881754">"Yeni qovluq"</string>
<string name="menu_grid" msgid="6878021334497835259">"Torlu görünüş"</string>
<string name="menu_list" msgid="7279285939892417279">"Siyahı görünüşü"</string>
- <string name="menu_sort" msgid="7677740407158414452">"Bunlardan biri üzrə sırala"</string>
+ <string name="menu_sort" msgid="7677740407158414452">"Sıralayın"</string>
<string name="menu_search" msgid="3816712084502856974">"Axtarış"</string>
- <string name="menu_settings" msgid="8239065133341597825">"Yaddaş parametrləri"</string>
+ <string name="menu_settings" msgid="8239065133341597825">"Yaddaş ayarları"</string>
<string name="menu_open" msgid="432922957274920903">"Açın"</string>
<string name="menu_save" msgid="2394743337684426338">"Yadda saxlayın"</string>
<string name="menu_share" msgid="3075149983979628146">"Paylaşın"</string>
<string name="menu_delete" msgid="8138799623850614177">"Sil"</string>
<string name="menu_select_all" msgid="8323579667348729928">"Hamısını seçin"</string>
<string name="menu_copy" msgid="3612326052677229148">"Buraya kopyalayın:"</string>
- <string name="menu_move" msgid="1828090633118079817">"Köçürün…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Daşıyın..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"Yeni pəncərə"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Kəsin"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopyalayın"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Yerləşdirin"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Daxili yaddaşı göstərin"</string>
@@ -53,20 +53,21 @@
<string name="drawer_close" msgid="7602734368552123318">"Kökləri gizlədin"</string>
<string name="save_error" msgid="6167009778003223664">"Sənədi yadda saxlaya bilmədi"</string>
<string name="create_error" msgid="3735649141335444215">"Qovluq yaradıla bilmədi"</string>
- <string name="query_error" msgid="1222448261663503501">"Sənəd sorğusu alınmadı"</string>
+ <string name="query_error" msgid="5999895349602476581">"Məzmun hazırda yüklənmir"</string>
<string name="root_recent" msgid="4470053704320518133">"Son"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ödənişsiz"</string>
<string name="root_type_service" msgid="2178854894416775409">"Saxlama xidmətləri"</string>
<string name="root_type_shortcut" msgid="3318760609471618093">"Qısa yollar"</string>
<string name="root_type_device" msgid="7121342474653483538">"Cihazlar"</string>
- <string name="root_type_apps" msgid="8838065367985945189">"Daha çox tətbiq"</string>
- <string name="empty" msgid="7858882803708117596">"Element yoxdur"</string>
+ <string name="root_type_apps" msgid="8838065367985945189">"Digər tətbiqlər"</string>
+ <string name="empty" msgid="7858882803708117596">"Heç nə yoxdur"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s ilə heç bir uyğunluq yoxdur"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Faylı aça bilmir"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Fayl açılmır"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Bəzi sənədləri silə bilmir"</string>
<string name="share_via" msgid="8966594246261344259">"Bunun vasitəsilə paylaş:"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Fayllar kopyalanır"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Fayllar köçürülür"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Fayllar silinir"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> qalıb"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fayl kopyalanır.</item>
@@ -84,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Kopyalanmaq üçün hazırlanır ..."</string>
<string name="move_preparing" msgid="2772219441375531410">"Köçürmə üçün hazırlanır..."</string>
<string name="delete_preparing" msgid="5655813182533491992">"Silmək üçün hazırlanır..."</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fayl kopyalanmadı</item>
- <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fayl kopyalanmadı</item>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> fayl kopyalanmadı</item>
+ <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> fayl kopyalanmadı</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fayl köçürülə bilmədi</item>
- <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fayl köçürülə bilmədi</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> fayl köçürülmədi</item>
+ <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> fayl köçürülmədi</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> fayl silinmədi</item>
<item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> fayl silinmədi</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Detallara baxmaq üçün basın"</string>
<string name="close" msgid="3043722427445528732">"Bağla"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Bu fayllar kopyalanmadı: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Bu fayllar köçürülmədi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Bu fayllar kopyalanmadı: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Bu fayllar köçürülmədi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Bu fayllar silinmədi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Bu fayllar başqa formata konvertasiya edilib: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fayl buferə kopyalandı.</item>
@@ -108,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Seçilmiş faylları bu məkana yerləşdirmək olmaz."</string>
<string name="menu_rename" msgid="7678802479104285353">"Adını dəyişdirin"</string>
<string name="rename_error" msgid="4203041674883412606">"Sənəd adını dəyişmək uğursuz oldu"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Çıxarın"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Bəzi fayllar konvertasiya edilib"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> yaddaşında <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> kataloquna <xliff:g id="APPNAME"><b>^1</b></xliff:g> girişi təqdim edilsin?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> kataloquna <xliff:g id="APPNAME"><b>^1</b></xliff:g> girişi təqdim edilsin?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> yaddaşında foto və videolar daxil olmaqla datanıza <xliff:g id="APPNAME"><b>^1</b></xliff:g> girişi təmin edilsin?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Bir daha soruşmayın"</string>
<string name="allow" msgid="7225948811296386551">"İcazə verin"</string>
<string name="deny" msgid="2081879885755434506">"Rədd et"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> seçilib</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> seçilib</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> element</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> element</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" silinsin?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" qovluğu və onun məzmunu silinsin?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> fayl silinsin?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fayl silinsin?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> qovluq və onun məzmunu silinsin?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> qovluq və onun məzmunu silinsin?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> element silinsin?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> element silinsin?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-b+sr+Latn/config.xml b/packages/DocumentsUI/res/values-b+sr+Latn/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-b+sr+Latn/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml b/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml
index 3252a4385853..d38a431d664e 100644
--- a/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenti"</string>
- <string name="files_label" msgid="6051402950202690279">"Datoteke"</string>
<string name="downloads_label" msgid="959113951084633612">"Preuzimanja"</string>
<string name="title_open" msgid="4353228937663917801">"Otvori sa"</string>
<string name="title_save" msgid="2433679664882857999">"Sačuvaj u"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Prikaz liste"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sortiraj prema"</string>
<string name="menu_search" msgid="3816712084502856974">"Pretraži"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Podešavanja memorije"</string>
<string name="menu_open" msgid="432922957274920903">"Otvori"</string>
<string name="menu_save" msgid="2394743337684426338">"Sačuvaj"</string>
<string name="menu_share" msgid="3075149983979628146">"Deli"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Kopiraj na..."</string>
<string name="menu_move" msgid="1828090633118079817">"Premesti u..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"Novi prozor"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Iseci"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopiraj"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Nalepi"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Prikaži internu memoriju"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Sakrij osnovne elemente"</string>
<string name="save_error" msgid="6167009778003223664">"Čuvanje dokumenta nije uspelo"</string>
<string name="create_error" msgid="3735649141335444215">"Direktorijum nije napravljen"</string>
- <string name="query_error" msgid="1222448261663503501">"Slanje upita za dokumente nije uspelo"</string>
+ <string name="query_error" msgid="5999895349602476581">"Učitavanje sadržaja trenutno nije moguće"</string>
<string name="root_recent" msgid="4470053704320518133">"Nedavno"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"Slobodno je <xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="root_type_service" msgid="2178854894416775409">"Usluge skladištenja"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Još aplikacija"</string>
<string name="empty" msgid="7858882803708117596">"Nema stavki"</string>
<string name="no_results" msgid="6622510343880730446">"Nema podudaranja u %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Nije moguće otvoriti datoteku"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Otvaranje datoteke nije uspelo"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Nije moguće izbrisati neke dokumente"</string>
<string name="share_via" msgid="8966594246261344259">"Delite preko"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopiranje datoteka"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Datoteke se premeštaju"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Datoteke se brišu"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Još <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Kopiranje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke.</item>
@@ -88,25 +88,27 @@
<string name="copy_preparing" msgid="3896202461003039386">"Priprema se kopiranje…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Priprema se premeštanje..."</string>
<string name="delete_preparing" msgid="5655813182533491992">"Priprema se brisanje…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="one">Nismo uspeli da kopiramo <xliff:g id="COUNT_1">%1$d</xliff:g> datoteku</item>
<item quantity="few">Nismo uspeli da kopiramo <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke</item>
<item quantity="other">Nismo uspeli da kopiramo <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="one">Nije uspelo premeštanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke</item>
- <item quantity="few">Nije uspelo premeštanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke</item>
- <item quantity="other">Nije uspelo premeštanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="one">Premeštanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke nije uspelo</item>
+ <item quantity="few">Premeštanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke nije uspelo</item>
+ <item quantity="other">Premeštanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka nije uspelo</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="one">Brisanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke nije uspelo</item>
<item quantity="few">Brisanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke nije uspelo</item>
<item quantity="other">Brisanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka nije uspelo</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Dodirnite da biste prikazali detalje"</string>
<string name="close" msgid="3043722427445528732">"Zatvori"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Sledeće datoteke nisu kopirane: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Ove datoteke nisu premeštene: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Sledeće datoteke nisu kopirane: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Sledeće datoteke nisu premeštene: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Sledeće datoteke nisu izbrisane: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Ove datoteke su konvertovane u drugi format: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one">Kopirali ste <xliff:g id="COUNT_1">%1$d</xliff:g> datoteku u privremenu memoriju.</item>
@@ -116,7 +118,39 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Izabrane datoteke ne mogu da se nalepe na ovoj lokaciji."</string>
<string name="menu_rename" msgid="7678802479104285353">"Preimenuj"</string>
<string name="rename_error" msgid="4203041674883412606">"Preimenovanje dokumenta nije uspelo"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Izbaci"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Neke datoteke su konvertovane"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Želite li da aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> odobrite pristup direktorijumu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> na memorijskom prostoru <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Želite da dozvolite da <xliff:g id="APPNAME"><b>^1</b></xliff:g> pristupa direktorijumu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Želite da li da dozvolite da aplikacija <xliff:g id="APPNAME"><b>^1</b></xliff:g> pristupa podacima, uključujući slike i video snimke, na lokaciji <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Ne pitaj ponovo"</string>
<string name="allow" msgid="7225948811296386551">"Dozvoli"</string>
<string name="deny" msgid="2081879885755434506">"Odbij"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one">Izabrana je <xliff:g id="COUNT_1">%1$d</xliff:g> stavka</item>
+ <item quantity="few">Izabrane su <xliff:g id="COUNT_1">%1$d</xliff:g> stavke</item>
+ <item quantity="other">Izabrano je <xliff:g id="COUNT_1">%1$d</xliff:g> stavki</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> stavka</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> stavke</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> stavki</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Želite li da izbrišete „<xliff:g id="NAME">%1$s</xliff:g>“?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Želite li da izbrišete direktorijum „<xliff:g id="NAME">%1$s</xliff:g>“ i njegov sadržaj?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one">Želite li da izbrišete <xliff:g id="COUNT_1">%1$d</xliff:g> datoteku?</item>
+ <item quantity="few">Želite li da izbrišete <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke?</item>
+ <item quantity="other">Želite li da izbrišete <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one">Želite li da izbrišete <xliff:g id="COUNT_1">%1$d</xliff:g> direktorijum i njihov sadržaj?</item>
+ <item quantity="few">Želite li da izbrišete <xliff:g id="COUNT_1">%1$d</xliff:g> direktorijuma i njihov sadržaj?</item>
+ <item quantity="other">Želite li da izbrišete <xliff:g id="COUNT_1">%1$d</xliff:g> direktorijuma i njihov sadržaj?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one">Želite li da izbrišete <xliff:g id="COUNT_1">%1$d</xliff:g> stavku?</item>
+ <item quantity="few">Želite li da izbrišete <xliff:g id="COUNT_1">%1$d</xliff:g> stavke?</item>
+ <item quantity="other">Želite li da izbrišete <xliff:g id="COUNT_1">%1$d</xliff:g> stavki?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-be-rBY/strings.xml b/packages/DocumentsUI/res/values-be-rBY/strings.xml
new file mode 100644
index 000000000000..be6988f3d2d0
--- /dev/null
+++ b/packages/DocumentsUI/res/values-be-rBY/strings.xml
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="2783841764617238354">"Дакументы"</string>
+ <string name="downloads_label" msgid="959113951084633612">"Спампоўкі"</string>
+ <string name="title_open" msgid="4353228937663917801">"Адкрыць з"</string>
+ <string name="title_save" msgid="2433679664882857999">"Захаваць у"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Новая папка"</string>
+ <string name="menu_grid" msgid="6878021334497835259">"У выглядзе табліцы"</string>
+ <string name="menu_list" msgid="7279285939892417279">"У выглядзе спіса"</string>
+ <string name="menu_sort" msgid="7677740407158414452">"Сартаваць па:"</string>
+ <string name="menu_search" msgid="3816712084502856974">"Шукаць"</string>
+ <string name="menu_settings" msgid="8239065133341597825">"Налады сховішча"</string>
+ <string name="menu_open" msgid="432922957274920903">"Адкрыць"</string>
+ <string name="menu_save" msgid="2394743337684426338">"Захаваць"</string>
+ <string name="menu_share" msgid="3075149983979628146">"Абагуліць"</string>
+ <string name="menu_delete" msgid="8138799623850614177">"Выдаліць"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Выбраць усё"</string>
+ <string name="menu_copy" msgid="3612326052677229148">"Капіраваць у..."</string>
+ <string name="menu_move" msgid="1828090633118079817">"Перамясціць у..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Новае акно"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Выразаць"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Капіраваць"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Уставіць"</string>
+ <string name="menu_advanced_show" msgid="4693652895715631401">"Паказаць унутр. сховішча"</string>
+ <string name="menu_advanced_hide" msgid="4218809952721972589">"Схаваць унутр. сховішча"</string>
+ <string name="menu_file_size_show" msgid="3240323619260823076">"Паказаць памеры файлаў"</string>
+ <string name="menu_file_size_hide" msgid="8881975928502581042">"Схаваць памеры файлаў"</string>
+ <string name="button_select" msgid="527196987259139214">"Выбраць"</string>
+ <string name="button_copy" msgid="8706475544635021302">"Капіраваць"</string>
+ <string name="button_move" msgid="2202666023104202232">"Перамясціць"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Адхіліць"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Паўтарыце спробу"</string>
+ <string name="sort_name" msgid="9183560467917256779">"Па назве"</string>
+ <string name="sort_date" msgid="586080032956151448">"Па даце змянення"</string>
+ <string name="sort_size" msgid="3350681319735474741">"Па памеры"</string>
+ <string name="drawer_open" msgid="4545466532430226949">"Паказаць каранёвыя папкі"</string>
+ <string name="drawer_close" msgid="7602734368552123318">"Схаваць каранёвыя папкі"</string>
+ <string name="save_error" msgid="6167009778003223664">"Не атрымалася захаваць дакумент"</string>
+ <string name="create_error" msgid="3735649141335444215">"Не атрымалася стварыць папку"</string>
+ <string name="query_error" msgid="5999895349602476581">"Зараз немагчыма загрузіць змесціва"</string>
+ <string name="root_recent" msgid="4470053704320518133">"Нядаўнія"</string>
+ <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> свабодна"</string>
+ <string name="root_type_service" msgid="2178854894416775409">"Службы захоўвання"</string>
+ <string name="root_type_shortcut" msgid="3318760609471618093">"Ярлыкі"</string>
+ <string name="root_type_device" msgid="7121342474653483538">"Прылады"</string>
+ <string name="root_type_apps" msgid="8838065367985945189">"Іншыя праграмы"</string>
+ <string name="empty" msgid="7858882803708117596">"Няма элементаў"</string>
+ <string name="no_results" msgid="6622510343880730446">"Няма супадзенняў у %1$s"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Немагчыма адкрыць файл"</string>
+ <string name="toast_failed_delete" msgid="2180678019407244069">"Немагчыма выдаліць некаторыя дакументы"</string>
+ <string name="share_via" msgid="8966594246261344259">"Абагуліць праз"</string>
+ <string name="copy_notification_title" msgid="6374299806748219777">"Капіраванне файлаў"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Перамяшчэнне файлаў"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Выдаленне файлаў"</string>
+ <string name="copy_remaining" msgid="6283790937387975095">"Засталося <xliff:g id="DURATION">%s</xliff:g>"</string>
+ <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+ <item quantity="one">Капіраванне <xliff:g id="COUNT_1">%1$d</xliff:g> файла.</item>
+ <item quantity="few">Капіраванне <xliff:g id="COUNT_1">%1$d</xliff:g> файлаў.</item>
+ <item quantity="many">Капіраванне <xliff:g id="COUNT_1">%1$d</xliff:g> файлаў.</item>
+ <item quantity="other">Капіраванне <xliff:g id="COUNT_1">%1$d</xliff:g> файла.</item>
+ </plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one">Перамяшчэнне <xliff:g id="COUNT_1">%1$d</xliff:g> файла.</item>
+ <item quantity="few">Перамяшчэнне <xliff:g id="COUNT_1">%1$d</xliff:g> файлаў.</item>
+ <item quantity="many">Перамяшчэнне <xliff:g id="COUNT_1">%1$d</xliff:g> файлаў.</item>
+ <item quantity="other">Перамяшчэнне <xliff:g id="COUNT_1">%1$d</xliff:g> файла.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one">Выдаленне <xliff:g id="COUNT_1">%1$d</xliff:g> файла.</item>
+ <item quantity="few">Выдаленне <xliff:g id="COUNT_1">%1$d</xliff:g> файлаў.</item>
+ <item quantity="many">Выдаленне <xliff:g id="COUNT_1">%1$d</xliff:g> файлаў.</item>
+ <item quantity="other">Выдаленне <xliff:g id="COUNT_1">%1$d</xliff:g> файла.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Адрабіць"</string>
+ <string name="copy_preparing" msgid="3896202461003039386">"Падрыхтоўка да капіравання..."</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Падрыхтоўка да перамяшчэння..."</string>
+ <string name="delete_preparing" msgid="5655813182533491992">"Падрыхтоўка да выдалення..."</string>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="one">Не атрымалася скапіраваць <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
+ <item quantity="few">Не атрымалася скапіраваць <xliff:g id="COUNT_1">%1$d</xliff:g> файлы</item>
+ <item quantity="many">Не атрымалася скапіраваць <xliff:g id="COUNT_1">%1$d</xliff:g> файлаў</item>
+ <item quantity="other">Не атрымалася скапіраваць <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
+ </plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="one">Не атрымалася перамясціць <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
+ <item quantity="few">Не атрымалася перамясціць <xliff:g id="COUNT_1">%1$d</xliff:g> файлы</item>
+ <item quantity="many">Не атрымалася перамясціць <xliff:g id="COUNT_1">%1$d</xliff:g> файлаў</item>
+ <item quantity="other">Не атрымалася перамясціць <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
+ </plurals>
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+ <item quantity="one">Не атрымалася выдаліць <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
+ <item quantity="few">Не атрымалася выдаліць <xliff:g id="COUNT_1">%1$d</xliff:g> файлы</item>
+ <item quantity="many">Не атрымалася выдаліць <xliff:g id="COUNT_1">%1$d</xliff:g> файлаў</item>
+ <item quantity="other">Не атрымалася выдаліць <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
+ </plurals>
+ <string name="notification_touch_for_details" msgid="6268189413228855582">"Дакраніцеся, каб прагледзець больш падрабязна"</string>
+ <string name="close" msgid="3043722427445528732">"Закрыць"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Не былі скапіраваны наступныя файлы: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Не былі перамешчаны наступныя файлы: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Не былі выдалены наступныя файлы: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_converted_warning_content" msgid="5753861488218674361">"Гэтыя файлы былі сканвертаваныя ў іншы фармат: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one">У буфер абмену скапіраваны <xliff:g id="COUNT_1">%1$d</xliff:g> файл.</item>
+ <item quantity="few">У буфер абмену скапіраваны <xliff:g id="COUNT_1">%1$d</xliff:g> файлы.</item>
+ <item quantity="many">У буфер абмену скапіравана <xliff:g id="COUNT_1">%1$d</xliff:g> файлаў.</item>
+ <item quantity="other">У буфер абмену скапіравана <xliff:g id="COUNT_1">%1$d</xliff:g> файла.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Немагчыма ўставіць выбраныя файлы ў гэта месца."</string>
+ <string name="menu_rename" msgid="7678802479104285353">"Перайменаваць"</string>
+ <string name="rename_error" msgid="4203041674883412606">"Не атрымалася перайменаваць дакумент"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Выняць"</string>
+ <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Некаторыя файлы былі сканвертаваныя"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Даць праграме <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ да дырэкторыі <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> у <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Даць праграме <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ да каталога <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Даць <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ да вашых даных, у тым ліку фатаграфій і відэа, на <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Больш не пытацца"</string>
+ <string name="allow" msgid="7225948811296386551">"Дазволіць"</string>
+ <string name="deny" msgid="2081879885755434506">"Адмовіць"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one">Выбраны <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="few">Выбраны <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="many">Выбрана <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">Выбрана <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> элемент</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> элементы</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> элементаў</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> элемента</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Выдаліць \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Выдаліць папку \"<xliff:g id="NAME">%1$s</xliff:g>\" і яе змесціва?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one">Выдаліць <xliff:g id="COUNT_1">%1$d</xliff:g> файл?</item>
+ <item quantity="few">Выдаліць <xliff:g id="COUNT_1">%1$d</xliff:g> файлы?</item>
+ <item quantity="many">Выдаліць <xliff:g id="COUNT_1">%1$d</xliff:g> файлаў?</item>
+ <item quantity="other">Выдаліць <xliff:g id="COUNT_1">%1$d</xliff:g> файла?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one">Выдаліць <xliff:g id="COUNT_1">%1$d</xliff:g> папку і іх змесціва?</item>
+ <item quantity="few">Выдаліць <xliff:g id="COUNT_1">%1$d</xliff:g> папкі і іх змесціва?</item>
+ <item quantity="many">Выдаліць <xliff:g id="COUNT_1">%1$d</xliff:g> папак і іх змесціва?</item>
+ <item quantity="other">Выдаліць <xliff:g id="COUNT_1">%1$d</xliff:g> папкі і іх змесціва?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one">Выдаліць <xliff:g id="COUNT_1">%1$d</xliff:g> элемент?</item>
+ <item quantity="few">Выдаліць <xliff:g id="COUNT_1">%1$d</xliff:g> элементы?</item>
+ <item quantity="many">Выдаліць <xliff:g id="COUNT_1">%1$d</xliff:g> элементаў?</item>
+ <item quantity="other">Выдаліць <xliff:g id="COUNT_1">%1$d</xliff:g> элемента?</item>
+ </plurals>
+</resources>
diff --git a/packages/DocumentsUI/res/values-bg/config.xml b/packages/DocumentsUI/res/values-bg/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-bg/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-bg/strings.xml b/packages/DocumentsUI/res/values-bg/strings.xml
index 0d901cf4b437..c35075e3fb61 100644
--- a/packages/DocumentsUI/res/values-bg/strings.xml
+++ b/packages/DocumentsUI/res/values-bg/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Документи"</string>
- <string name="files_label" msgid="6051402950202690279">"Файлове"</string>
<string name="downloads_label" msgid="959113951084633612">"Изтегляния"</string>
<string name="title_open" msgid="4353228937663917801">"Отваряне от"</string>
<string name="title_save" msgid="2433679664882857999">"Запазване във:"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Списъчен изглед"</string>
<string name="menu_sort" msgid="7677740407158414452">"Сортиране по"</string>
<string name="menu_search" msgid="3816712084502856974">"Търсене"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Настройки на хранилището"</string>
<string name="menu_open" msgid="432922957274920903">"Отваряне"</string>
<string name="menu_save" msgid="2394743337684426338">"Запазване"</string>
<string name="menu_share" msgid="3075149983979628146">"Споделяне"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Копиране във…"</string>
<string name="menu_move" msgid="1828090633118079817">"Преместване във…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Нов прозорец"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Изрязване"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Копиране"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Поставяне"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Вътр. хранилище: Показв."</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Скриване на основните елементи"</string>
<string name="save_error" msgid="6167009778003223664">"Запазването на документа не бе успешно"</string>
<string name="create_error" msgid="3735649141335444215">"Създаването на папката не бе успешно"</string>
- <string name="query_error" msgid="1222448261663503501">"Заявката за документи не бе успешна"</string>
+ <string name="query_error" msgid="5999895349602476581">"Понастоящем съдържанието не може да се зареди"</string>
<string name="root_recent" msgid="4470053704320518133">"Скорошни"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"Свободно: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="root_type_service" msgid="2178854894416775409">"Услуги за съхранение"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Още приложения"</string>
<string name="empty" msgid="7858882803708117596">"Няма елементи"</string>
<string name="no_results" msgid="6622510343880730446">"В/ъв „%1$s“ няма съответствия"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Файлът не може да се отвори"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Файлът не може да се отвори"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Някои документи не могат да бъдат изтрити"</string>
<string name="share_via" msgid="8966594246261344259">"Споделяне чрез"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Файловете се копират"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Файловете се преместват"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Изтриване на файлове"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Оставащо време: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Копират се <xliff:g id="COUNT_1">%1$d</xliff:g> файла.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Подготвя се за копиране…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Преместването се подготвя…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Подготвя се за изтриване..."</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файла не можаха да се копират</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл не можа да се копира</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файла не можаха да бъдат преместени</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл не можа да бъде преместен</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файла не можаха да бъдат изтрити</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл не можа да бъде изтрит</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Докоснете, за да видите подробности"</string>
<string name="close" msgid="3043722427445528732">"Затваряне"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Следните файлове не бяха копирани: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Следните файлове не бяха преместени: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Следните файлове не бяха копирани: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Следните файлове не бяха преместени: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Следните файлове не бяха изтрити: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Следните файлове бяха преобразувани в друг формат: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">Копирахте <xliff:g id="COUNT_1">%1$d</xliff:g> файла в буферната памет.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Избраните файлове не могат да се поставят на това място."</string>
<string name="menu_rename" msgid="7678802479104285353">"Преименуване"</string>
<string name="rename_error" msgid="4203041674883412606">"Преименуването на документа не бе успешно"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Изваждане"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Някои файлове бяха преобразувани"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Да се предостави ли на <xliff:g id="APPNAME"><b>^1</b></xliff:g> достъп до директорията „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“ в/ъв <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Да се предостави ли на <xliff:g id="APPNAME"><b>^1</b></xliff:g> достъп до директорията „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Да се предостави ли на <xliff:g id="APPNAME"><b>^1</b></xliff:g> достъп до данните ви в хранилището (<xliff:g id="STORAGE"><i>^2</i></xliff:g>), включително снимки и видеоклипове?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Без повторно питане"</string>
<string name="allow" msgid="7225948811296386551">"Разрешаване"</string>
<string name="deny" msgid="2081879885755434506">"Отказване"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other">Избрахте <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">Избрахте <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> елемента</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> елемент</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Искате ли да изтриете „<xliff:g id="NAME">%1$s</xliff:g>“?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Искате ли да изтриете папката „<xliff:g id="NAME">%1$s</xliff:g>“ и съдържанието в нея?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">Искате ли да изтриете <xliff:g id="COUNT_1">%1$d</xliff:g> файла?</item>
+ <item quantity="one">Искате ли да изтриете <xliff:g id="COUNT_0">%1$d</xliff:g> файл?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">Искате ли да изтриете <xliff:g id="COUNT_1">%1$d</xliff:g> папки и съдържанието в тях?</item>
+ <item quantity="one">Искате ли да изтриете <xliff:g id="COUNT_0">%1$d</xliff:g> папка и съдържанието в нея?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <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>
</resources>
diff --git a/packages/DocumentsUI/res/values-bn-rBD/config.xml b/packages/DocumentsUI/res/values-bn-rBD/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-bn-rBD/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-bn-rBD/strings.xml b/packages/DocumentsUI/res/values-bn-rBD/strings.xml
index a99028218cfe..334a7ef7a4e5 100644
--- a/packages/DocumentsUI/res/values-bn-rBD/strings.xml
+++ b/packages/DocumentsUI/res/values-bn-rBD/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"দস্তাবেজগুলি"</string>
- <string name="files_label" msgid="6051402950202690279">"ফাইলগুলি"</string>
<string name="downloads_label" msgid="959113951084633612">"ডাউনলোডগুলি"</string>
<string name="title_open" msgid="4353228937663917801">"এখান থেকে খুলুন"</string>
<string name="title_save" msgid="2433679664882857999">"এতে সংরক্ষণ করুন"</string>
@@ -26,16 +25,16 @@
<string name="menu_list" msgid="7279285939892417279">"তালিকা দৃশ্য"</string>
<string name="menu_sort" msgid="7677740407158414452">"এই অনুসারে বাছুন"</string>
<string name="menu_search" msgid="3816712084502856974">"অনুসন্ধান করুন"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"সঞ্চয়স্থান সেটিংস"</string>
<string name="menu_open" msgid="432922957274920903">"খুলুন"</string>
<string name="menu_save" msgid="2394743337684426338">"সংরক্ষণ করুন"</string>
- <string name="menu_share" msgid="3075149983979628146">"ভাগ করুন"</string>
+ <string name="menu_share" msgid="3075149983979628146">"শেয়ার করুন"</string>
<string name="menu_delete" msgid="8138799623850614177">"মুছুন"</string>
<string name="menu_select_all" msgid="8323579667348729928">"সবগুলি নির্বাচন করুন"</string>
- <string name="menu_copy" msgid="3612326052677229148">"এতে অনুলিপি করুন…"</string>
+ <string name="menu_copy" msgid="3612326052677229148">"এতে কপি করুন…"</string>
<string name="menu_move" msgid="1828090633118079817">"এতে সরান..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"নতুন উইন্ডো"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"কাট করুন"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"প্রতিলিপি করুন"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"আটকান"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"অভ্যন্তরীণ সঞ্চয়স্থান দেখান"</string>
@@ -43,7 +42,7 @@
<string name="menu_file_size_show" msgid="3240323619260823076">"ফাইলের আকার দেখান"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"ফাইলের আকার লুকান"</string>
<string name="button_select" msgid="527196987259139214">"নির্বাচন করুন"</string>
- <string name="button_copy" msgid="8706475544635021302">"অনুলিপি করুন"</string>
+ <string name="button_copy" msgid="8706475544635021302">"কপি করুন"</string>
<string name="button_move" msgid="2202666023104202232">"সরান"</string>
<string name="button_dismiss" msgid="3714065566893946085">"খারিজ করুন"</string>
<string name="button_retry" msgid="4392027584153752797">"আবার চেষ্টা করুন"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"রুটগুলি লুকান"</string>
<string name="save_error" msgid="6167009778003223664">"দস্তাবেজ সংরক্ষণ করতে ব্যর্থ হয়েছে"</string>
<string name="create_error" msgid="3735649141335444215">"ফোল্ডার তৈরি করতে ব্যর্থ হয়েছে"</string>
- <string name="query_error" msgid="1222448261663503501">"উন্নত ডিভাইসগুলি প্রদর্শন করে"</string>
+ <string name="query_error" msgid="5999895349602476581">"এই মুহূর্তে সামগ্রী লোড করা যাবে না"</string>
<string name="root_recent" msgid="4470053704320518133">"সাম্প্রতিক"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> খালি আছে"</string>
<string name="root_type_service" msgid="2178854894416775409">"সঞ্চয়স্থান পরিষেবাগুলি"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"আরো অ্যাপ্লিকেশান"</string>
<string name="empty" msgid="7858882803708117596">"কোনো আইটেম নেই"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s এ কোনো মিল নেই"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"ফাইল খোলা যাবে না"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"ফাইল খোলা যাবে না"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"কিছু দস্তাবেজ মুছতে অসমর্থ"</string>
- <string name="share_via" msgid="8966594246261344259">"এর মাধ্যমে ভাগ করুন"</string>
+ <string name="share_via" msgid="8966594246261344259">"এর মাধ্যমে শেয়ার করুন"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"ফাইলগুলি অনুলিপি করা হচ্ছে"</string>
<string name="move_notification_title" msgid="6193835179777284805">"ফাইলগুলি সরানো হচ্ছে"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"ফাইলগুলি মোছা হচ্ছে"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> বাকি"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল অনুলিপি করা হচ্ছে৷</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"অনুলিপি করার জন্য প্রস্তুত করা হচ্ছে..."</string>
<string name="move_preparing" msgid="2772219441375531410">"সরানোর জন্য প্রস্তুত হচ্ছে..."</string>
<string name="delete_preparing" msgid="5655813182533491992">"মোছার জন্য প্রস্তুত করা হচ্ছে..."</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <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>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল প্রতিলিপি করা গেল না</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল প্রতিলিপি করা গেল না</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল সরানো যায়নি৷</item>
- <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল সরানো যায়নি৷</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল সরানো গেল না</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল সরানো গেল না</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল মোছা গেল না</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল মোছা গেল না</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"বিশদ বিবরণ দেখতে আলতো চাপুন"</string>
<string name="close" msgid="3043722427445528732">"বন্ধ করুন"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"এই ফাইলগুলির প্রতিলিপি করা হয় নি: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"এই ফাইলগুলি সরানো হয়নি: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"এই ফাইলগুলির প্রতিলিপি করা হয়নি: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"এই ফাইলগুলি সরানো হয়নি: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"এই ফাইলগুলি মোছা হয়নি: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"এই ফাইলগুলি অন্য ফরম্যাটে রূপান্তর করা হয়েছে: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল ক্লিপবোর্ডে প্রতিলিপি করা হয়েছে।</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"এই স্থানে নির্বাচিত ফাইলগুলি আটকানো যাবে না।"</string>
<string name="menu_rename" msgid="7678802479104285353">"পুনঃনামকরণ"</string>
<string name="rename_error" msgid="4203041674883412606">"দস্তাবেজের পুনঃনামকরণ ব্যর্থ হয়েছে৷"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"সরিয়ে দিন"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"কিছু ফাইল রূপান্তরিত হয়েছে"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> কে <xliff:g id="STORAGE"><i>^3</i></xliff:g> এ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> সংগ্রহ অ্যাক্সেস করার মঞ্জুরি দিতে চান?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> কে <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> সংগ্রহ অ্যাক্সেস করার অনুমতি দেবেন?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> এ থাকা ফটো ও ভিডিওগুলি সমেত <xliff:g id="APPNAME"><b>^1</b></xliff:g> কে আপনার ডেটা অ্যাক্সেস করার অনুমতি দেবেন?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"আর জিজ্ঞাসা করবেন না"</string>
<string name="allow" msgid="7225948811296386551">"অনুমতি দিন"</string>
<string name="deny" msgid="2081879885755434506">"আস্বীকার করুন"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি নির্বাচন করা হয়েছে</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি নির্বাচন করা হয়েছে</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি আইটেম</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি আইটেম</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" মুছবেন?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ফোল্ডার এবং এটির সামগ্রীগুলিকে মুছবেন?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল মুছবেন?</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল মুছবেন?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফোল্ডার এবং সেগুলির সামগ্রী মুছবেন?</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফোল্ডার এবং সেগুলির সামগ্রী মুছবেন?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি আইটেম মুছবেন?</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি আইটেম মুছবেন?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-bs-rBA/config.xml b/packages/DocumentsUI/res/values-bs-rBA/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-bs-rBA/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-bs-rBA/strings.xml b/packages/DocumentsUI/res/values-bs-rBA/strings.xml
index 9d75ddc0683f..7bdb458e436c 100644
--- a/packages/DocumentsUI/res/values-bs-rBA/strings.xml
+++ b/packages/DocumentsUI/res/values-bs-rBA/strings.xml
@@ -16,141 +16,141 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for app_label (2783841764617238354) -->
- <skip />
- <!-- no translation found for files_label (6051402950202690279) -->
- <skip />
- <!-- no translation found for downloads_label (959113951084633612) -->
- <skip />
- <!-- no translation found for title_open (4353228937663917801) -->
- <skip />
- <!-- no translation found for title_save (2433679664882857999) -->
- <skip />
- <!-- no translation found for menu_create_dir (2547620241173881754) -->
- <skip />
- <!-- no translation found for menu_grid (6878021334497835259) -->
- <skip />
- <!-- no translation found for menu_list (7279285939892417279) -->
- <skip />
- <!-- no translation found for menu_sort (7677740407158414452) -->
- <skip />
- <!-- no translation found for menu_search (3816712084502856974) -->
- <skip />
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
- <!-- no translation found for menu_open (432922957274920903) -->
- <skip />
- <!-- no translation found for menu_save (2394743337684426338) -->
- <skip />
- <!-- no translation found for menu_share (3075149983979628146) -->
- <skip />
- <!-- no translation found for menu_delete (8138799623850614177) -->
- <skip />
- <!-- no translation found for menu_select_all (8323579667348729928) -->
- <skip />
- <!-- no translation found for menu_copy (3612326052677229148) -->
- <skip />
- <!-- no translation found for menu_move (1828090633118079817) -->
- <skip />
- <!-- no translation found for menu_new_window (1226032889278727538) -->
- <skip />
- <!-- no translation found for menu_copy_to_clipboard (489311381979634291) -->
- <skip />
- <!-- no translation found for menu_paste_from_clipboard (2071583031180257091) -->
- <skip />
- <!-- no translation found for menu_advanced_show (4693652895715631401) -->
- <skip />
- <!-- no translation found for menu_advanced_hide (4218809952721972589) -->
- <skip />
- <!-- no translation found for menu_file_size_show (3240323619260823076) -->
- <skip />
- <!-- no translation found for menu_file_size_hide (8881975928502581042) -->
- <skip />
- <!-- no translation found for button_select (527196987259139214) -->
- <skip />
- <!-- no translation found for button_copy (8706475544635021302) -->
- <skip />
- <!-- no translation found for button_move (2202666023104202232) -->
- <skip />
- <!-- no translation found for button_dismiss (3714065566893946085) -->
- <skip />
- <!-- no translation found for button_retry (4392027584153752797) -->
- <skip />
- <!-- no translation found for sort_name (9183560467917256779) -->
- <skip />
- <!-- no translation found for sort_date (586080032956151448) -->
- <skip />
- <!-- no translation found for sort_size (3350681319735474741) -->
- <skip />
- <!-- no translation found for drawer_open (4545466532430226949) -->
- <skip />
- <!-- no translation found for drawer_close (7602734368552123318) -->
- <skip />
- <!-- no translation found for save_error (6167009778003223664) -->
- <skip />
- <!-- no translation found for create_error (3735649141335444215) -->
- <skip />
- <!-- no translation found for query_error (1222448261663503501) -->
- <skip />
- <!-- no translation found for root_recent (4470053704320518133) -->
- <skip />
- <!-- no translation found for root_available_bytes (8568452858617033281) -->
- <skip />
- <!-- no translation found for root_type_service (2178854894416775409) -->
- <skip />
- <!-- no translation found for root_type_shortcut (3318760609471618093) -->
- <skip />
- <!-- no translation found for root_type_device (7121342474653483538) -->
- <skip />
- <!-- no translation found for root_type_apps (8838065367985945189) -->
- <skip />
- <!-- no translation found for empty (7858882803708117596) -->
- <skip />
+ <string name="app_label" msgid="2783841764617238354">"Dokumenti"</string>
+ <string name="downloads_label" msgid="959113951084633612">"Preuzimanja"</string>
+ <string name="title_open" msgid="4353228937663917801">"Otvori iz"</string>
+ <string name="title_save" msgid="2433679664882857999">"Sačuvaj u"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Nova fascikla"</string>
+ <string name="menu_grid" msgid="6878021334497835259">"Prikaz u vidu mreže"</string>
+ <string name="menu_list" msgid="7279285939892417279">"Prikaz u vidu liste"</string>
+ <string name="menu_sort" msgid="7677740407158414452">"Sortiraj po"</string>
+ <string name="menu_search" msgid="3816712084502856974">"Traži"</string>
+ <string name="menu_settings" msgid="8239065133341597825">"Postavke pohrane"</string>
+ <string name="menu_open" msgid="432922957274920903">"Otvori"</string>
+ <string name="menu_save" msgid="2394743337684426338">"Sačuvaj"</string>
+ <string name="menu_share" msgid="3075149983979628146">"Podijeli"</string>
+ <string name="menu_delete" msgid="8138799623850614177">"Izbriši"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Odaberi sve"</string>
+ <string name="menu_copy" msgid="3612326052677229148">"Kopiraj na..."</string>
+ <string name="menu_move" msgid="1828090633118079817">"Premjesti u..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Novi prozor"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Izreži"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopiraj"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Zalijepi"</string>
+ <string name="menu_advanced_show" msgid="4693652895715631401">"Pokaži internu pohranu"</string>
+ <string name="menu_advanced_hide" msgid="4218809952721972589">"Sakrij internu pohranu"</string>
+ <string name="menu_file_size_show" msgid="3240323619260823076">"Pokaži veličinu fajla"</string>
+ <string name="menu_file_size_hide" msgid="8881975928502581042">"Sakrij veličinu fajla"</string>
+ <string name="button_select" msgid="527196987259139214">"Odaberi"</string>
+ <string name="button_copy" msgid="8706475544635021302">"Kopiraj"</string>
+ <string name="button_move" msgid="2202666023104202232">"Premjesti"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Odbaci"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Pokušajte ponovo"</string>
+ <string name="sort_name" msgid="9183560467917256779">"Po nazivu"</string>
+ <string name="sort_date" msgid="586080032956151448">"Po datumu izmjene"</string>
+ <string name="sort_size" msgid="3350681319735474741">"Po veličini"</string>
+ <string name="drawer_open" msgid="4545466532430226949">"Pokaži korijeni"</string>
+ <string name="drawer_close" msgid="7602734368552123318">"Sakrij korijenske foldere"</string>
+ <string name="save_error" msgid="6167009778003223664">"Pohranjivanje dokumenta nije uspjelo"</string>
+ <string name="create_error" msgid="3735649141335444215">"Kreiranje mape nije uspjelo"</string>
+ <string name="query_error" msgid="5999895349602476581">"Trenutno nije moguće učitati sadržaj"</string>
+ <string name="root_recent" msgid="4470053704320518133">"Nedavni"</string>
+ <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> slobodno"</string>
+ <string name="root_type_service" msgid="2178854894416775409">"Usluge pohranjivanja"</string>
+ <string name="root_type_shortcut" msgid="3318760609471618093">"Prečice"</string>
+ <string name="root_type_device" msgid="7121342474653483538">"Uređaji"</string>
+ <string name="root_type_apps" msgid="8838065367985945189">"Više aplikacija"</string>
+ <string name="empty" msgid="7858882803708117596">"Nema stavki"</string>
<string name="no_results" msgid="6622510343880730446">"Nema rezultata u %1$s"</string>
- <!-- no translation found for toast_no_application (1339885974067891667) -->
- <skip />
- <!-- no translation found for toast_failed_delete (2180678019407244069) -->
- <skip />
- <!-- no translation found for share_via (8966594246261344259) -->
- <skip />
- <!-- no translation found for copy_notification_title (6374299806748219777) -->
- <skip />
- <!-- no translation found for move_notification_title (6193835179777284805) -->
- <skip />
- <!-- no translation found for copy_remaining (6283790937387975095) -->
- <skip />
- <!-- no translation found for copy_begin (9071199452634086365) -->
- <!-- no translation found for move_begin (8430330882138871643) -->
- <!-- no translation found for deleting (5054338566802559411) -->
- <!-- no translation found for undo (7905788502491742328) -->
- <skip />
- <!-- no translation found for copy_preparing (3896202461003039386) -->
- <skip />
- <!-- no translation found for move_preparing (2772219441375531410) -->
- <skip />
+ <string name="toast_no_application" msgid="4632640357724698144">"Nije moguće otvoriti fajl"</string>
+ <string name="toast_failed_delete" msgid="2180678019407244069">"Nije moguće obrisati neke dokumente"</string>
+ <string name="share_via" msgid="8966594246261344259">"Podijeli preko"</string>
+ <string name="copy_notification_title" msgid="6374299806748219777">"Kopiraju se fajlovi"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Premještanje fajlova"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Brisanje fajlova"</string>
+ <string name="copy_remaining" msgid="6283790937387975095">"Još <xliff:g id="DURATION">%s</xliff:g>"</string>
+ <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+ <item quantity="one">Kopira se <xliff:g id="COUNT_1">%1$d</xliff:g> fajl.</item>
+ <item quantity="few">Kopiraju se <xliff:g id="COUNT_1">%1$d</xliff:g> fajla.</item>
+ <item quantity="other">Kopira se <xliff:g id="COUNT_1">%1$d</xliff:g> fajlova.</item>
+ </plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one">Premješta se <xliff:g id="COUNT_1">%1$d</xliff:g> fajl.</item>
+ <item quantity="few">Premještaju se <xliff:g id="COUNT_1">%1$d</xliff:g> fajla.</item>
+ <item quantity="other">Premješta se <xliff:g id="COUNT_1">%1$d</xliff:g> fajlova.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one">Briše se <xliff:g id="COUNT_1">%1$d</xliff:g> fajl.</item>
+ <item quantity="few">Brišu se <xliff:g id="COUNT_1">%1$d</xliff:g> fajla.</item>
+ <item quantity="other">Briše se <xliff:g id="COUNT_1">%1$d</xliff:g> fajlova.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Vrati"</string>
+ <string name="copy_preparing" msgid="3896202461003039386">"Priprema se kopiranje..."</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Priprema za premještanje..."</string>
<string name="delete_preparing" msgid="5655813182533491992">"Pripremanje za brisanje…"</string>
- <!-- no translation found for copy_error_notification_title (5267616889076217261) -->
- <!-- no translation found for move_error_notification_title (2779299594174898891) -->
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
- <item quantity="one">Nije bilo moguće izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> datoteku</item>
- <item quantity="few">Nije bilo moguće izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke</item>
- <item quantity="other">Nije bilo moguće izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka</item>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="one">Nije moguće kopirati <xliff:g id="COUNT_1">%1$d</xliff:g> fajl</item>
+ <item quantity="few">Nije moguće kopirati <xliff:g id="COUNT_1">%1$d</xliff:g> fajla</item>
+ <item quantity="other">Nije moguće kopirati <xliff:g id="COUNT_1">%1$d</xliff:g> fajlova</item>
+ </plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="one">Nije moguće premjestiti <xliff:g id="COUNT_1">%1$d</xliff:g> fajl</item>
+ <item quantity="few">Nije moguće premjestiti <xliff:g id="COUNT_1">%1$d</xliff:g> fajla</item>
+ <item quantity="other">Nije moguće premjestiti <xliff:g id="COUNT_1">%1$d</xliff:g> fajlova</item>
+ </plurals>
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+ <item quantity="one">Nije moguće izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> fajl</item>
+ <item quantity="few">Nije moguće izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> fajla</item>
+ <item quantity="other">Nije moguće izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> fajlova</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Dodirnite za prikaz detalja"</string>
<string name="close" msgid="3043722427445528732">"Zatvori"</string>
- <!-- no translation found for copy_failure_alert_content (3715575000297709082) -->
- <skip />
- <!-- no translation found for move_failure_alert_content (7151140279020481180) -->
- <skip />
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Nisu kopirani sljedeći fajlovi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Nisu premješteni sljedeći fajlovi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Nisu izbrisani sljedeći fajlovi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Ove datoteke su pretvorene u drugi format: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <!-- no translation found for clipboard_files_clipped (855459017537058539) -->
- <!-- no translation found for clipboard_files_cannot_paste (2878324825602325706) -->
- <skip />
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> fajl je kopiran u međuspremnik.</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> fajla su kopirana u međuspremnik.</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fajlova je kopirano u međuspremnik.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Odabrani fajlovi se ne mogu zalijepiti na ovu lokaciju."</string>
<string name="menu_rename" msgid="7678802479104285353">"Preimenuj"</string>
<string name="rename_error" msgid="4203041674883412606">"Nije uspjelo preimenovanje dokumenta"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Izbaci"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Neke od datoteka su pretvorene"</string>
- <!-- no translation found for allow (7225948811296386551) -->
- <skip />
- <!-- no translation found for deny (2081879885755434506) -->
- <skip />
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Omogućiti <xliff:g id="APPNAME"><b>^1</b></xliff:g> pristup direktoriju <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> sa <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Odobriti aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> pristup direktoriju <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Želite li odobriti aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> pristup svojim podacima, uključujući fotografije i video zapise, na <xliff:g id="STORAGE"><i>^2</i></xliff:g> ?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Ne pitaj ponovo"</string>
+ <string name="allow" msgid="7225948811296386551">"Dozvoli"</string>
+ <string name="deny" msgid="2081879885755434506">"Odbijte"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> stavka je odabrana</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> stavke su odabrane</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> stavki je odabrano</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> stavka</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> stavke</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> stavki</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Želite li izbrisati \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Želite li izbrisati folder \"<xliff:g id="NAME">%1$s</xliff:g>\" i njegov sadržaj?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one">Želite li izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> fajl?</item>
+ <item quantity="few">Želite li izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> fajla?</item>
+ <item quantity="other">Želite li izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> fajlova?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one">Želite li izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> folder i njihov sadržaj?</item>
+ <item quantity="few">Želite li izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> foldera i njihov sadržaj?</item>
+ <item quantity="other">Želite li izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> foldera i njihov sadržaj?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one">Želite li izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> stavku?</item>
+ <item quantity="few">Želite li izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> stavke?</item>
+ <item quantity="other">Želite li izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> stavki?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-ca/config.xml b/packages/DocumentsUI/res/values-ca/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-ca/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-ca/strings.xml b/packages/DocumentsUI/res/values-ca/strings.xml
index 25029e9cfc98..01a037fe4ee2 100644
--- a/packages/DocumentsUI/res/values-ca/strings.xml
+++ b/packages/DocumentsUI/res/values-ca/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documents"</string>
- <string name="files_label" msgid="6051402950202690279">"Fitxers"</string>
<string name="downloads_label" msgid="959113951084633612">"Baixades"</string>
<string name="title_open" msgid="4353228937663917801">"Obre des de"</string>
<string name="title_save" msgid="2433679664882857999">"Desa a"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Visualització de llista"</string>
<string name="menu_sort" msgid="7677740407158414452">"Ordena per"</string>
<string name="menu_search" msgid="3816712084502856974">"Cerca"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Config. d\'emmagatzematge"</string>
<string name="menu_open" msgid="432922957274920903">"Obre"</string>
<string name="menu_save" msgid="2394743337684426338">"Desa"</string>
<string name="menu_share" msgid="3075149983979628146">"Comparteix"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Copia a…"</string>
<string name="menu_move" msgid="1828090633118079817">"Mou a..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"Finestra nova"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Retalla"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copia"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Enganxa"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Mostra emmagatz. intern"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Amaga les arrels"</string>
<string name="save_error" msgid="6167009778003223664">"No s\'ha pogut desar el document."</string>
<string name="create_error" msgid="3735649141335444215">"No s\'ha pogut crear la carpeta"</string>
- <string name="query_error" msgid="1222448261663503501">"No s\'han pogut consultar els documents"</string>
+ <string name="query_error" msgid="5999895349602476581">"En aquest moment no es pot carregar el contingut"</string>
<string name="root_recent" msgid="4470053704320518133">"Recent"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> lliures"</string>
<string name="root_type_service" msgid="2178854894416775409">"Serveis d\'emmagatzematge"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Més aplicacions"</string>
<string name="empty" msgid="7858882803708117596">"Sense elements"</string>
<string name="no_results" msgid="6622510343880730446">"No hi ha cap coincidència a %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"No es pot obrir el fitxer."</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"No es pot obrir el fitxer"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"No es poden suprimir alguns documents."</string>
<string name="share_via" msgid="8966594246261344259">"Comparteix mitjançant"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"S\'estan copiant fitxers"</string>
<string name="move_notification_title" msgid="6193835179777284805">"S\'estan movent fitxers"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Suprimint els fitxers"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Temps restant: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">S\'estan copiant <xliff:g id="COUNT_1">%1$d</xliff:g> fitxers.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"S\'està preparant una còpia…"</string>
<string name="move_preparing" msgid="2772219441375531410">"S\'està preparant per moure\'ls..."</string>
<string name="delete_preparing" msgid="5655813182533491992">"S\'està preparant per suprimir…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other">No s\'han pogut copiar <xliff:g id="COUNT_1">%1$d</xliff:g> fitxers</item>
<item quantity="one">No s\'ha pogut copiar <xliff:g id="COUNT_0">%1$d</xliff:g> fitxer</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other">No s\'han pogut moure <xliff:g id="COUNT_1">%1$d</xliff:g> fitxers</item>
<item quantity="one">No s\'ha pogut moure <xliff:g id="COUNT_0">%1$d</xliff:g> fitxer</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other">No s\'han pogut suprimir <xliff:g id="COUNT_1">%1$d</xliff:g> fitxers</item>
<item quantity="one">No s\'ha pogut suprimir <xliff:g id="COUNT_0">%1$d</xliff:g> fitxer</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Toca per veure\'n els detalls"</string>
<string name="close" msgid="3043722427445528732">"Tanca"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Aquests fitxers no s\'han copiat: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Aquests fitxers no s\'han mogut: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Aquests fitxers no s\'han copiat: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Aquests fitxers no s\'han mogut: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Aquests fitxers no s\'han suprimit: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Aquests fitxers s\'han convertit a un altre format: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">S\'han copiat <xliff:g id="COUNT_1">%1$d</xliff:g> fitxers al porta-retalls.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"No s\'han pogut enganxar els fitxers seleccionats en aquesta ubicació."</string>
<string name="menu_rename" msgid="7678802479104285353">"Canvia el nom"</string>
<string name="rename_error" msgid="4203041674883412606">"No s\'ha pogut canviar el nom del document"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Expulsa"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"S\'han convertit alguns fitxers"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Vols que l\'aplicació <xliff:g id="APPNAME"><b>^1</b></xliff:g> tingui accés al directori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> de l\'emmagatzematge <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Vols que l\'aplicació <xliff:g id="APPNAME"><b>^1</b></xliff:g> tingui accés al directori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Vols que l\'aplicació <xliff:g id="APPNAME"><b>^1</b></xliff:g> tingui accés a les dades de <xliff:g id="STORAGE"><i>^2</i></xliff:g>, incloses les fotos i els vídeos?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"No m\'ho demanis més"</string>
<string name="allow" msgid="7225948811296386551">"Permet"</string>
<string name="deny" msgid="2081879885755434506">"Denega"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elements seleccionats</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> element seleccionat</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elements</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> element</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Vols suprimir el fitxer <xliff:g id="NAME">%1$s</xliff:g>?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Vols suprimir la carpeta <xliff:g id="NAME">%1$s</xliff:g> i el seu contingut?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">Vols suprimir <xliff:g id="COUNT_1">%1$d</xliff:g> fitxers?</item>
+ <item quantity="one">Vols suprimir <xliff:g id="COUNT_0">%1$d</xliff:g> fitxer?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">Vols suprimir <xliff:g id="COUNT_1">%1$d</xliff:g> carpetes i el seu contingut?</item>
+ <item quantity="one">Vols suprimir <xliff:g id="COUNT_0">%1$d</xliff:g> carpeta i el seu contingut?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other">Vols suprimir <xliff:g id="COUNT_1">%1$d</xliff:g> elements?</item>
+ <item quantity="one">Vols suprimir <xliff:g id="COUNT_0">%1$d</xliff:g> element?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-cs/config.xml b/packages/DocumentsUI/res/values-cs/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-cs/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-cs/strings.xml b/packages/DocumentsUI/res/values-cs/strings.xml
index bcb1748f235c..8a0d0bf8894f 100644
--- a/packages/DocumentsUI/res/values-cs/strings.xml
+++ b/packages/DocumentsUI/res/values-cs/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenty"</string>
- <string name="files_label" msgid="6051402950202690279">"Soubory"</string>
<string name="downloads_label" msgid="959113951084633612">"Stahování"</string>
<string name="title_open" msgid="4353228937663917801">"Otevřít"</string>
<string name="title_save" msgid="2433679664882857999">"Uložit do"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Zobrazení seznamu"</string>
<string name="menu_sort" msgid="7677740407158414452">"Řadit podle"</string>
<string name="menu_search" msgid="3816712084502856974">"Hledat"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Nastavení úložiště"</string>
<string name="menu_open" msgid="432922957274920903">"Otevřít"</string>
<string name="menu_save" msgid="2394743337684426338">"Uložit"</string>
<string name="menu_share" msgid="3075149983979628146">"Sdílet"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Kopírovat do…"</string>
<string name="menu_move" msgid="1828090633118079817">"Přesunout do…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Nové okno"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Vyjmout"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopírovat"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Vložit"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Zobrazit inter. úložiště"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Skrýt kořeny"</string>
<string name="save_error" msgid="6167009778003223664">"Uložení dokumentu se nezdařilo"</string>
<string name="create_error" msgid="3735649141335444215">"Složku se nepodařilo vytvořit"</string>
- <string name="query_error" msgid="1222448261663503501">"Seznam dokumentů se nepodařilo načíst"</string>
+ <string name="query_error" msgid="5999895349602476581">"Obsah nyní nelze načíst"</string>
<string name="root_recent" msgid="4470053704320518133">"Nedávné"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"Volné místo: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="root_type_service" msgid="2178854894416775409">"Služby úložiště"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Další aplikace"</string>
<string name="empty" msgid="7858882803708117596">"Žádné položky"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s – žádné shody"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Soubor nelze otevřít"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Soubor nelze otevřít"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Některé dokumenty nelze smazat"</string>
<string name="share_via" msgid="8966594246261344259">"Sdílet pomocí"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopírování souborů"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Přesouvání souborů"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Mazání souborů"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Zbývající čas: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="few">Kopírování <xliff:g id="COUNT_1">%1$d</xliff:g> souborů</item>
@@ -91,19 +91,20 @@
<string name="copy_preparing" msgid="3896202461003039386">"Příprava na kopírování…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Příprava na přesunutí…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Příprava na mazání…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <item quantity="few">Nepodařilo se zkopírovat <xliff:g id="COUNT_1">%1$d</xliff:g> soubory</item>
- <item quantity="many">Nepodařilo se zkopírovat <xliff:g id="COUNT_1">%1$d</xliff:g> souboru</item>
- <item quantity="other">Nepodařilo se zkopírovat <xliff:g id="COUNT_1">%1$d</xliff:g> souborů</item>
- <item quantity="one">Nepodařilo se zkopírovat <xliff:g id="COUNT_0">%1$d</xliff:g> soubor</item>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> soubory se zkopírovat nepodařilo</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> souboru se zkopírovat nepodařilo</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> souborů se zkopírovat nepodařilo</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> soubor se zkopírovat nepodařilo</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> soubory nelze přesunout</item>
<item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> souboru nelze přesunout</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> souborů nelze přesunout</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> soubor nelze přesunout</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> soubory se smazat nepodařilo</item>
<item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> souboru se smazat nepodařilo</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> souborů se smazat nepodařilo</item>
@@ -111,8 +112,9 @@
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Klepnutím zobrazíte podrobnosti"</string>
<string name="close" msgid="3043722427445528732">"Zavřít"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Tyto soubory nebyly zkopírovány: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Následující soubory nebyly přesunuty: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Následující soubory nebyly zkopírovány: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Následující soubory nebyly přesunuty: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Následující soubory nebyly smazány: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Soubory byly převedeny do jiného formátu: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> soubory byly zkopírovány do schránky.</item>
@@ -123,7 +125,44 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Vybrané soubory nelze vložit do tohoto umístění."</string>
<string name="menu_rename" msgid="7678802479104285353">"Přejmenovat"</string>
<string name="rename_error" msgid="4203041674883412606">"Dokument se nepodařilo přejmenovat."</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Odpojit"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Některé soubory byly převedeny"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Chcete aplikaci <xliff:g id="APPNAME"><b>^1</b></xliff:g> udělit přístup k adresáři <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> v úložišti <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Chcete aplikaci <xliff:g id="APPNAME"><b>^1</b></xliff:g> udělit přístup k adresáři <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Chcete aplikaci <xliff:g id="APPNAME"><b>^1</b></xliff:g> udělit přístup ke svým datům v úložišti <xliff:g id="STORAGE"><i>^2</i></xliff:g>, včetně fotek a videí?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Příště se neptat"</string>
<string name="allow" msgid="7225948811296386551">"Povolit"</string>
<string name="deny" msgid="2081879885755434506">"Odepřít"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="few">Vybrány <xliff:g id="COUNT_1">%1$d</xliff:g> položky</item>
+ <item quantity="many">Vybráno <xliff:g id="COUNT_1">%1$d</xliff:g> položky</item>
+ <item quantity="other">Vybráno <xliff:g id="COUNT_1">%1$d</xliff:g> položek</item>
+ <item quantity="one">Vybrána <xliff:g id="COUNT_0">%1$d</xliff:g> položka</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> položky</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> položky</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> položek</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> položka</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Smazat soubor <xliff:g id="NAME">%1$s</xliff:g>?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Smazat složku <xliff:g id="NAME">%1$s</xliff:g> a její obsah?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="few">Smazat <xliff:g id="COUNT_1">%1$d</xliff:g> soubory?</item>
+ <item quantity="many">Smazat <xliff:g id="COUNT_1">%1$d</xliff:g> souboru?</item>
+ <item quantity="other">Smazat <xliff:g id="COUNT_1">%1$d</xliff:g> souborů?</item>
+ <item quantity="one">Smazat <xliff:g id="COUNT_0">%1$d</xliff:g> soubor?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="few">Smazat <xliff:g id="COUNT_1">%1$d</xliff:g> složky a jejich obsah?</item>
+ <item quantity="many">Smazat <xliff:g id="COUNT_1">%1$d</xliff:g> složky a jejich obsah?</item>
+ <item quantity="other">Smazat <xliff:g id="COUNT_1">%1$d</xliff:g> složek a jejich obsah?</item>
+ <item quantity="one">Smazat <xliff:g id="COUNT_0">%1$d</xliff:g> složku a její obsah?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="few">Smazat <xliff:g id="COUNT_1">%1$d</xliff:g> položky?</item>
+ <item quantity="many">Smazat <xliff:g id="COUNT_1">%1$d</xliff:g> položky?</item>
+ <item quantity="other">Smazat <xliff:g id="COUNT_1">%1$d</xliff:g> položek?</item>
+ <item quantity="one">Smazat <xliff:g id="COUNT_0">%1$d</xliff:g> položku?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-da/config.xml b/packages/DocumentsUI/res/values-da/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-da/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-da/strings.xml b/packages/DocumentsUI/res/values-da/strings.xml
index 03f488126551..98117cbfb3cb 100644
--- a/packages/DocumentsUI/res/values-da/strings.xml
+++ b/packages/DocumentsUI/res/values-da/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenter"</string>
- <string name="files_label" msgid="6051402950202690279">"Filer"</string>
<string name="downloads_label" msgid="959113951084633612">"Downloads"</string>
<string name="title_open" msgid="4353228937663917801">"Åbn fra"</string>
<string name="title_save" msgid="2433679664882857999">"Gem i"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Listevisning"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sortér efter"</string>
<string name="menu_search" msgid="3816712084502856974">"Søg"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Indstillinger for lager"</string>
<string name="menu_open" msgid="432922957274920903">"Åbn"</string>
<string name="menu_save" msgid="2394743337684426338">"Gem"</string>
<string name="menu_share" msgid="3075149983979628146">"Del"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Kopiér til…"</string>
<string name="menu_move" msgid="1828090633118079817">"Flyt til…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Nyt vindue"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Klip"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopiér"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Indsæt"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Vis intern lagerplads"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Skjul rødder"</string>
<string name="save_error" msgid="6167009778003223664">"Dokumentet kunne ikke gemmes"</string>
<string name="create_error" msgid="3735649141335444215">"Mappen kunne ikke oprettes"</string>
- <string name="query_error" msgid="1222448261663503501">"Dokumenterne kunne ikke forespørges."</string>
+ <string name="query_error" msgid="5999895349602476581">"Der kan ikke indlæses indhold i øjeblikket"</string>
<string name="root_recent" msgid="4470053704320518133">"Seneste"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ledig plads"</string>
<string name="root_type_service" msgid="2178854894416775409">"Lagringstjenester"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Flere apps"</string>
<string name="empty" msgid="7858882803708117596">"Ingen elementer"</string>
<string name="no_results" msgid="6622510343880730446">"Ingen kampe i %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Filen kan ikke åbnes"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Filen kan ikke åbnes"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Nogle dokumenter kan ikke slettes"</string>
<string name="share_via" msgid="8966594246261344259">"Del via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopierer filer"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Flytter filer"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Filerne slettes"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> tilbage"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Kopierer <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Forbereder kopiering…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Forbereder flytning…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Forbereder til sletning…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> filer blev ikke kopieret</item>
- <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer blev ikke kopieret</item>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> af <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> fil kunne ikke kopieres</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer kunne ikke kopieres</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> filer blev ikke flyttet</item>
- <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer blev ikke flyttet</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> fil kunne ikke flyttes</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer kunne ikke flyttes</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> fil kunne ikke slettes</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer kunne ikke slettes</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Tryk for at se oplysninger"</string>
<string name="close" msgid="3043722427445528732">"Luk"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Disse filer blev ikke kopieret: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Følgende filer blev ikke flyttet: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Disse filer blev ikke kopieret: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Disse filer blev ikke flyttet: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Disse filer blev ikke slettet: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Disse filer er konverteret til et andet format: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> filer blev kopieret til udklipsholder.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"De valgte filer kan ikke indsættes på denne placering."</string>
<string name="menu_rename" msgid="7678802479104285353">"Omdøb"</string>
<string name="rename_error" msgid="4203041674883412606">"Dokumentet kunne ikke omdøbes"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Skub ud"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Nogle filer er konverteret"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Vil du give <xliff:g id="APPNAME"><b>^1</b></xliff:g> adgang til mappen <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> på <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Vil du give <xliff:g id="APPNAME"><b>^1</b></xliff:g> adgang til indekset <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Vil du give <xliff:g id="APPNAME"><b>^1</b></xliff:g> adgang til dine data, herunder billeder og videoer på <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Spørg ikke igen"</string>
<string name="allow" msgid="7225948811296386551">"Tillad"</string>
<string name="deny" msgid="2081879885755434506">"Afvis"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one">Der er valgt <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">Der er valgt <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> element</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementer</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Vil du slette \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Vil du slette mappen \"<xliff:g id="NAME">%1$s</xliff:g>\" og dens indhold?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one">Vil du slette <xliff:g id="COUNT_1">%1$d</xliff:g> fil?</item>
+ <item quantity="other">Vil du slette <xliff:g id="COUNT_1">%1$d</xliff:g> filer?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one">Vil du slette <xliff:g id="COUNT_1">%1$d</xliff:g> mappe og dens indhold?</item>
+ <item quantity="other">Vil du slette <xliff:g id="COUNT_1">%1$d</xliff:g> mapper og deres indhold?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one">Vil du slette <xliff:g id="COUNT_1">%1$d</xliff:g> element?</item>
+ <item quantity="other">Vil du slette <xliff:g id="COUNT_1">%1$d</xliff:g> elementer?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-de/config.xml b/packages/DocumentsUI/res/values-de/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-de/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-de/strings.xml b/packages/DocumentsUI/res/values-de/strings.xml
index 0abdd57cc94f..9a7cd85db42a 100644
--- a/packages/DocumentsUI/res/values-de/strings.xml
+++ b/packages/DocumentsUI/res/values-de/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumente"</string>
- <string name="files_label" msgid="6051402950202690279">"Dateien"</string>
<string name="downloads_label" msgid="959113951084633612">"Downloads"</string>
<string name="title_open" msgid="4353228937663917801">"Öffnen von"</string>
<string name="title_save" msgid="2433679664882857999">"Speichern unter"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Listenansicht"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sortieren nach"</string>
<string name="menu_search" msgid="3816712084502856974">"Suchen"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Speichereinstellungen"</string>
<string name="menu_open" msgid="432922957274920903">"Öffnen"</string>
<string name="menu_save" msgid="2394743337684426338">"Speichern"</string>
<string name="menu_share" msgid="3075149983979628146">"Teilen"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Kopieren nach..."</string>
<string name="menu_move" msgid="1828090633118079817">"Verschieben nach…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Neues Fenster"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Ausschneiden"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopieren"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Einfügen"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Int. Speicher anzeigen"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Root-Verzeichnis ausblenden"</string>
<string name="save_error" msgid="6167009778003223664">"Dokument konnte nicht gespeichert werden."</string>
<string name="create_error" msgid="3735649141335444215">"Ordner konnte nicht erstellt werden."</string>
- <string name="query_error" msgid="1222448261663503501">"Fehler bei der Anforderung von Dokumenten"</string>
+ <string name="query_error" msgid="5999895349602476581">"Inhalte können momentan nicht geladen werden"</string>
<string name="root_recent" msgid="4470053704320518133">"Letzte"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> verfügbar"</string>
<string name="root_type_service" msgid="2178854894416775409">"Speicherdienste"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Weitere Apps"</string>
<string name="empty" msgid="7858882803708117596">"Keine Dokumente"</string>
<string name="no_results" msgid="6622510343880730446">"Keine Übereinstimmungen in %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Datei kann nicht geöffnet werden."</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Datei kann nicht geöffnet werden"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Einige Dokumente konnten nicht gelöscht werden."</string>
<string name="share_via" msgid="8966594246261344259">"Teilen über"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Dateien werden kopiert"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Dateien werden verschoben"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Dateien werden gelöscht"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Noch <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Dateien werden kopiert.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Kopieren wird vorbereitet…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Verschieben wird vorbereitet…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Löschvorgang wird vorbereitet…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Dateien konnten nicht kopiert werden.</item>
- <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> Datei konnte nicht kopiert werden.</item>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Dateien konnten nicht kopiert werden</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> Datei konnte nicht kopiert werden</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Dateien konnten nicht verschoben werden.</item>
- <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> Datei konnte nicht verschoben werden.</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Dateien konnten nicht verschoben werden</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> Datei konnte nicht verschoben werden</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Dateien konnten nicht gelöscht werden</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> Datei konnte nicht gelöscht werden</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Zum Ansehen der Details tippen"</string>
<string name="close" msgid="3043722427445528732">"Schließen"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Diese Dateien wurden nicht kopiert: <xliff:g id="LIST">%1$s</xliff:g>."</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Diese Dateien wurden nicht verschoben: <xliff:g id="LIST">%1$s</xliff:g>."</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Diese Dateien wurden nicht kopiert: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Diese Dateien wurden nicht verschoben: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Diese Dateien wurden nicht gelöscht: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Folgende Dateien wurden in ein anderes Format konvertiert: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Dateien wurden in die Zwischenablage kopiert.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Die ausgewählten Dateien können an diesem Ort nicht eingefügt werden."</string>
<string name="menu_rename" msgid="7678802479104285353">"Umbenennen"</string>
<string name="rename_error" msgid="4203041674883412606">"Dokument konnte nicht umbenannt werden"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Auswerfen"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Einige Dateien wurden konvertiert"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> Zugriff auf das Verzeichnis <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> auf <xliff:g id="STORAGE"><i>^3</i></xliff:g> geben?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Möchtest du <xliff:g id="APPNAME"><b>^1</b></xliff:g> Zugriff auf das Verzeichnis <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> geben?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Möchtest du <xliff:g id="APPNAME"><b>^1</b></xliff:g> Zugriff auf deine Daten auf <xliff:g id="STORAGE"><i>^2</i></xliff:g> geben, einschließlich Fotos und Videos?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Nicht mehr fragen"</string>
<string name="allow" msgid="7225948811296386551">"Zulassen"</string>
<string name="deny" msgid="2081879885755434506">"Ablehnen"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ausgewählt</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ausgewählt</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Einträge</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> Eintrag</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" löschen?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Ordner \"<xliff:g id="NAME">%1$s</xliff:g>\" und dessen Inhalte löschen?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">Möchtest du <xliff:g id="COUNT_1">%1$d</xliff:g> Dateien löschen?</item>
+ <item quantity="one">Möchtest du <xliff:g id="COUNT_0">%1$d</xliff:g> Datei löschen?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">Möchtest du <xliff:g id="COUNT_1">%1$d</xliff:g> Ordner und deren Inhalte löschen?</item>
+ <item quantity="one">Möchtest du <xliff:g id="COUNT_0">%1$d</xliff:g> Ordner und dessen Inhalte löschen?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other">Möchtest du <xliff:g id="COUNT_1">%1$d</xliff:g> Elemente löschen?</item>
+ <item quantity="one">Möchtest du <xliff:g id="COUNT_0">%1$d</xliff:g> Element löschen?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-el/config.xml b/packages/DocumentsUI/res/values-el/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-el/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-el/strings.xml b/packages/DocumentsUI/res/values-el/strings.xml
index 819cb5b0f2eb..39f0f4738bb8 100644
--- a/packages/DocumentsUI/res/values-el/strings.xml
+++ b/packages/DocumentsUI/res/values-el/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Έγγραφα"</string>
- <string name="files_label" msgid="6051402950202690279">"Αρχεία"</string>
<string name="downloads_label" msgid="959113951084633612">"Λήψεις"</string>
<string name="title_open" msgid="4353228937663917801">"Άνοιγμα από"</string>
<string name="title_save" msgid="2433679664882857999">"Αποθήκευση σε"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Προβολή λίστας"</string>
<string name="menu_sort" msgid="7677740407158414452">"Ταξινόμηση κατά"</string>
<string name="menu_search" msgid="3816712084502856974">"Αναζήτηση"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Ρυθμίσεις αποθ/κού χώρου"</string>
<string name="menu_open" msgid="432922957274920903">"Άνοιγμα"</string>
<string name="menu_save" msgid="2394743337684426338">"Αποθήκευση"</string>
<string name="menu_share" msgid="3075149983979628146">"Κοινή χρήση"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Αντιγραφή σε…"</string>
<string name="menu_move" msgid="1828090633118079817">"Μετακίνηση σε..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"Νέο παράθυρο"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Αποκοπή"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Αντιγραφή"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Επικόλληση"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Εμφ.εσωτ.χώρου αποθήκ."</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Απόκρυψη ρίζας"</string>
<string name="save_error" msgid="6167009778003223664">"Αποτυχία αποθήκευσης του εγγράφου"</string>
<string name="create_error" msgid="3735649141335444215">"Αποτυχία δημιουργίας φακέλου"</string>
- <string name="query_error" msgid="1222448261663503501">"Αποτυχία υποβολής ερωτήματος για έγγραφα"</string>
+ <string name="query_error" msgid="5999895349602476581">"Δεν είναι δυνατή η φόρτωση περιεχομένου τώρα"</string>
<string name="root_recent" msgid="4470053704320518133">"Πρόσφατα"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ελεύθερα"</string>
<string name="root_type_service" msgid="2178854894416775409">"Υπηρεσίες αποθήκευσης"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Περισσότερες εφαρμογές"</string>
<string name="empty" msgid="7858882803708117596">"Δεν υπάρχουν στοιχεία"</string>
<string name="no_results" msgid="6622510343880730446">"Χωρίς αντιστοιχίσεις στο %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Δεν είναι δυνατό το άνοιγμα του αρχείου"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Δεν είναι δυνατό το άνοιγμα του αρχείου"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Δεν είναι δυνατή η διαγραφή ορισμένων εγγράφων"</string>
- <string name="share_via" msgid="8966594246261344259">"Κοινή χρήση μέσω"</string>
+ <string name="share_via" msgid="8966594246261344259">"Κοινοποίηση μέσω"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Αντιγραφή αρχείων"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Μετακίνηση αρχείων"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Διαγραφή αρχείων"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Απομένουν <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Αντιγραφή <xliff:g id="COUNT_1">%1$d</xliff:g> αρχείων.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Προετοιμασία για αντιγραφή…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Προετοιμασία για μετακίνηση…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Προετοιμασία για διαγραφή…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other">Δεν ήταν δυνατή η αντιγραφή <xliff:g id="COUNT_1">%1$d</xliff:g> αρχείων</item>
<item quantity="one">Δεν ήταν δυνατή η αντιγραφή <xliff:g id="COUNT_0">%1$d</xliff:g> αρχείου</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other">Δεν ήταν δυνατή η μετακίνηση <xliff:g id="COUNT_1">%1$d</xliff:g> αρχείων</item>
<item quantity="one">Δεν ήταν δυνατή η μετακίνηση <xliff:g id="COUNT_0">%1$d</xliff:g> αρχείου</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other">Δεν ήταν δυνατή η διαγραφή <xliff:g id="COUNT_1">%1$d</xliff:g> αρχείων</item>
<item quantity="one">Δεν ήταν δυνατή η διαγραφή <xliff:g id="COUNT_0">%1$d</xliff:g> αρχείου</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Πατήστε για προβολή λεπτομερειών"</string>
<string name="close" msgid="3043722427445528732">"Κλείσιμο"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Αυτά τα αρχεία δεν αντιγράφηκαν: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Αυτά τα αρχεία δεν μετακινήθηκαν: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Αυτά τα αρχεία δεν αντιγράφηκαν: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Αυτά τα αρχεία δεν μετακινήθηκαν: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Αυτά τα αρχεία δεν διαγράφηκαν: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Αυτά τα αρχεία μετατράπηκαν σε άλλη μορφή: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> αρχεία αντιγράφηκαν στο πρόχειρο.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Δεν είναι δυνατή η επικόλληση των επιλεγμένων αρχείων σε αυτήν την τοποθεσία."</string>
<string name="menu_rename" msgid="7678802479104285353">"Μετονομασία"</string>
<string name="rename_error" msgid="4203041674883412606">"Αποτυχία μετονομασίας εγγράφου"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Εξαγωγή"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Ορισμένα αρχεία μετατράπηκαν"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Να εκχωρηθεί στην εφαρμογή <xliff:g id="APPNAME"><b>^1</b></xliff:g> πρόσβαση στον κατάλογο <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> στον αποθηκευτικό χώρο <xliff:g id="STORAGE"><i>^3</i></xliff:g>;"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Εκχώρηση πρόσβασης στην εφαρμογή <xliff:g id="APPNAME"><b>^1</b></xliff:g> στον κατάλογο <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>;"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Θέλετε να εκχωρήσετε πρόσβαση στα δεδομένα σας στην εφαρμογή <xliff:g id="APPNAME"><b>^1</b></xliff:g>, συμπεριλαμβανομένων των φωτογραφιών και των βίντεό σας, στον αποθηκευτικό χώρο <xliff:g id="STORAGE"><i>^2</i></xliff:g>;"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Να μην ερωτηθώ ξανά"</string>
<string name="allow" msgid="7225948811296386551">"Να επιτρέπεται"</string>
<string name="deny" msgid="2081879885755434506">"Άρνηση"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> επιλεγμένα</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> επιλεγμένο</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> στοιχεία</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> στοιχείο</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Να διαγραφεί το αρχείο \"<xliff:g id="NAME">%1$s</xliff:g>\";"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Να διαγραφεί ο φάκελος \"<xliff:g id="NAME">%1$s</xliff:g>\" και τα περιεχόμενά του;"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">Να διαγραφούν <xliff:g id="COUNT_1">%1$d</xliff:g> αρχεία;</item>
+ <item quantity="one">Να διαγραφεί <xliff:g id="COUNT_0">%1$d</xliff:g> αρχείο;</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">Να διαγραφούν <xliff:g id="COUNT_1">%1$d</xliff:g> φάκελοι και τα περιεχόμενά τους;</item>
+ <item quantity="one">Να διαγραφεί <xliff:g id="COUNT_0">%1$d</xliff:g> φάκελος και τα περιεχόμενά του;</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <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>
</resources>
diff --git a/packages/DocumentsUI/res/values-en-rAU/config.xml b/packages/DocumentsUI/res/values-en-rAU/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-en-rAU/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-en-rAU/strings.xml b/packages/DocumentsUI/res/values-en-rAU/strings.xml
index f4cd4791d13b..a871ac0b687c 100644
--- a/packages/DocumentsUI/res/values-en-rAU/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rAU/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documents"</string>
- <string name="files_label" msgid="6051402950202690279">"Files"</string>
<string name="downloads_label" msgid="959113951084633612">"Downloads"</string>
<string name="title_open" msgid="4353228937663917801">"Open from"</string>
<string name="title_save" msgid="2433679664882857999">"Save to"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"List view"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sort by"</string>
<string name="menu_search" msgid="3816712084502856974">"Search"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Storage settings"</string>
<string name="menu_open" msgid="432922957274920903">"Open"</string>
<string name="menu_save" msgid="2394743337684426338">"Save"</string>
<string name="menu_share" msgid="3075149983979628146">"Share"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Copy to…"</string>
<string name="menu_move" msgid="1828090633118079817">"Move to…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"New window"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Cut"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copy"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Paste"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Show internal storage"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Hide roots"</string>
<string name="save_error" msgid="6167009778003223664">"Failed to save document"</string>
<string name="create_error" msgid="3735649141335444215">"Failed to create folder"</string>
- <string name="query_error" msgid="1222448261663503501">"Failed to query documents"</string>
+ <string name="query_error" msgid="5999895349602476581">"Can’t load content at the moment"</string>
<string name="root_recent" msgid="4470053704320518133">"Recent"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> free"</string>
<string name="root_type_service" msgid="2178854894416775409">"Storage services"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"More apps"</string>
<string name="empty" msgid="7858882803708117596">"No items"</string>
<string name="no_results" msgid="6622510343880730446">"No matches in %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Cannot open file"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Can’t open file"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Unable to delete some documents"</string>
<string name="share_via" msgid="8966594246261344259">"Share via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Copying files"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Moving files"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Deleting files"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> left"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Copying <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Preparing for copy…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Preparing for move…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Preparing to delete…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <item quantity="other">Couldn\'t copy <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
- <item quantity="one">Couldn\'t copy <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="other">Couldn’t copy <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
+ <item quantity="one">Couldn’t copy <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="other">Couldn\'t move <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
- <item quantity="one">Couldn\'t move <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="other">Couldn’t move <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
+ <item quantity="one">Couldn’t move <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
- <item quantity="other">Couldn\'t delete <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
- <item quantity="one">Couldn\'t delete <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+ <item quantity="other">Couldn’t delete <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
+ <item quantity="one">Couldn’t delete <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Tap to view details"</string>
<string name="close" msgid="3043722427445528732">"Close"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"These files weren\'t copied: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"These files weren\'t moved: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"These files weren’t copied: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"These files weren’t moved: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"These files weren’t deleted: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"These files were converted to another format: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">Copied <xliff:g id="COUNT_1">%1$d</xliff:g> files to clipboard.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Cannot paste the selected files in this location."</string>
<string name="menu_rename" msgid="7678802479104285353">"rename"</string>
<string name="rename_error" msgid="4203041674883412606">"Failed to rename document"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Eject"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Some files were converted"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory on <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to your data, including photos and videos, on <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Don\'t ask again"</string>
<string name="allow" msgid="7225948811296386551">"Allow"</string>
<string name="deny" msgid="2081879885755434506">"Deny"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Delete \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Delete folder \"<xliff:g id="NAME">%1$s</xliff:g>\" and its contents?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">Delete <xliff:g id="COUNT_1">%1$d</xliff:g> files?</item>
+ <item quantity="one">Delete <xliff:g id="COUNT_0">%1$d</xliff:g> file?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">Delete <xliff:g id="COUNT_1">%1$d</xliff:g> folders and their contents?</item>
+ <item quantity="one">Delete <xliff:g id="COUNT_0">%1$d</xliff:g> folder and its contents?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other">Delete <xliff:g id="COUNT_1">%1$d</xliff:g> items?</item>
+ <item quantity="one">Delete <xliff:g id="COUNT_0">%1$d</xliff:g> item?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-en-rGB/config.xml b/packages/DocumentsUI/res/values-en-rGB/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-en-rGB/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-en-rGB/strings.xml b/packages/DocumentsUI/res/values-en-rGB/strings.xml
index f4cd4791d13b..a871ac0b687c 100644
--- a/packages/DocumentsUI/res/values-en-rGB/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rGB/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documents"</string>
- <string name="files_label" msgid="6051402950202690279">"Files"</string>
<string name="downloads_label" msgid="959113951084633612">"Downloads"</string>
<string name="title_open" msgid="4353228937663917801">"Open from"</string>
<string name="title_save" msgid="2433679664882857999">"Save to"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"List view"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sort by"</string>
<string name="menu_search" msgid="3816712084502856974">"Search"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Storage settings"</string>
<string name="menu_open" msgid="432922957274920903">"Open"</string>
<string name="menu_save" msgid="2394743337684426338">"Save"</string>
<string name="menu_share" msgid="3075149983979628146">"Share"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Copy to…"</string>
<string name="menu_move" msgid="1828090633118079817">"Move to…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"New window"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Cut"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copy"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Paste"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Show internal storage"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Hide roots"</string>
<string name="save_error" msgid="6167009778003223664">"Failed to save document"</string>
<string name="create_error" msgid="3735649141335444215">"Failed to create folder"</string>
- <string name="query_error" msgid="1222448261663503501">"Failed to query documents"</string>
+ <string name="query_error" msgid="5999895349602476581">"Can’t load content at the moment"</string>
<string name="root_recent" msgid="4470053704320518133">"Recent"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> free"</string>
<string name="root_type_service" msgid="2178854894416775409">"Storage services"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"More apps"</string>
<string name="empty" msgid="7858882803708117596">"No items"</string>
<string name="no_results" msgid="6622510343880730446">"No matches in %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Cannot open file"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Can’t open file"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Unable to delete some documents"</string>
<string name="share_via" msgid="8966594246261344259">"Share via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Copying files"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Moving files"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Deleting files"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> left"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Copying <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Preparing for copy…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Preparing for move…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Preparing to delete…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <item quantity="other">Couldn\'t copy <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
- <item quantity="one">Couldn\'t copy <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="other">Couldn’t copy <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
+ <item quantity="one">Couldn’t copy <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="other">Couldn\'t move <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
- <item quantity="one">Couldn\'t move <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="other">Couldn’t move <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
+ <item quantity="one">Couldn’t move <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
- <item quantity="other">Couldn\'t delete <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
- <item quantity="one">Couldn\'t delete <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+ <item quantity="other">Couldn’t delete <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
+ <item quantity="one">Couldn’t delete <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Tap to view details"</string>
<string name="close" msgid="3043722427445528732">"Close"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"These files weren\'t copied: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"These files weren\'t moved: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"These files weren’t copied: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"These files weren’t moved: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"These files weren’t deleted: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"These files were converted to another format: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">Copied <xliff:g id="COUNT_1">%1$d</xliff:g> files to clipboard.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Cannot paste the selected files in this location."</string>
<string name="menu_rename" msgid="7678802479104285353">"rename"</string>
<string name="rename_error" msgid="4203041674883412606">"Failed to rename document"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Eject"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Some files were converted"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory on <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to your data, including photos and videos, on <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Don\'t ask again"</string>
<string name="allow" msgid="7225948811296386551">"Allow"</string>
<string name="deny" msgid="2081879885755434506">"Deny"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Delete \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Delete folder \"<xliff:g id="NAME">%1$s</xliff:g>\" and its contents?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">Delete <xliff:g id="COUNT_1">%1$d</xliff:g> files?</item>
+ <item quantity="one">Delete <xliff:g id="COUNT_0">%1$d</xliff:g> file?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">Delete <xliff:g id="COUNT_1">%1$d</xliff:g> folders and their contents?</item>
+ <item quantity="one">Delete <xliff:g id="COUNT_0">%1$d</xliff:g> folder and its contents?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other">Delete <xliff:g id="COUNT_1">%1$d</xliff:g> items?</item>
+ <item quantity="one">Delete <xliff:g id="COUNT_0">%1$d</xliff:g> item?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-en-rIN/config.xml b/packages/DocumentsUI/res/values-en-rIN/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-en-rIN/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-en-rIN/strings.xml b/packages/DocumentsUI/res/values-en-rIN/strings.xml
index f4cd4791d13b..a871ac0b687c 100644
--- a/packages/DocumentsUI/res/values-en-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-en-rIN/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documents"</string>
- <string name="files_label" msgid="6051402950202690279">"Files"</string>
<string name="downloads_label" msgid="959113951084633612">"Downloads"</string>
<string name="title_open" msgid="4353228937663917801">"Open from"</string>
<string name="title_save" msgid="2433679664882857999">"Save to"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"List view"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sort by"</string>
<string name="menu_search" msgid="3816712084502856974">"Search"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Storage settings"</string>
<string name="menu_open" msgid="432922957274920903">"Open"</string>
<string name="menu_save" msgid="2394743337684426338">"Save"</string>
<string name="menu_share" msgid="3075149983979628146">"Share"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Copy to…"</string>
<string name="menu_move" msgid="1828090633118079817">"Move to…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"New window"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Cut"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copy"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Paste"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Show internal storage"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Hide roots"</string>
<string name="save_error" msgid="6167009778003223664">"Failed to save document"</string>
<string name="create_error" msgid="3735649141335444215">"Failed to create folder"</string>
- <string name="query_error" msgid="1222448261663503501">"Failed to query documents"</string>
+ <string name="query_error" msgid="5999895349602476581">"Can’t load content at the moment"</string>
<string name="root_recent" msgid="4470053704320518133">"Recent"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> free"</string>
<string name="root_type_service" msgid="2178854894416775409">"Storage services"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"More apps"</string>
<string name="empty" msgid="7858882803708117596">"No items"</string>
<string name="no_results" msgid="6622510343880730446">"No matches in %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Cannot open file"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Can’t open file"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Unable to delete some documents"</string>
<string name="share_via" msgid="8966594246261344259">"Share via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Copying files"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Moving files"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Deleting files"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> left"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Copying <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Preparing for copy…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Preparing for move…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Preparing to delete…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <item quantity="other">Couldn\'t copy <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
- <item quantity="one">Couldn\'t copy <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="other">Couldn’t copy <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
+ <item quantity="one">Couldn’t copy <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="other">Couldn\'t move <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
- <item quantity="one">Couldn\'t move <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="other">Couldn’t move <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
+ <item quantity="one">Couldn’t move <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
- <item quantity="other">Couldn\'t delete <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
- <item quantity="one">Couldn\'t delete <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+ <item quantity="other">Couldn’t delete <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
+ <item quantity="one">Couldn’t delete <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Tap to view details"</string>
<string name="close" msgid="3043722427445528732">"Close"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"These files weren\'t copied: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"These files weren\'t moved: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"These files weren’t copied: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"These files weren’t moved: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"These files weren’t deleted: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"These files were converted to another format: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">Copied <xliff:g id="COUNT_1">%1$d</xliff:g> files to clipboard.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Cannot paste the selected files in this location."</string>
<string name="menu_rename" msgid="7678802479104285353">"rename"</string>
<string name="rename_error" msgid="4203041674883412606">"Failed to rename document"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Eject"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Some files were converted"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory on <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to your data, including photos and videos, on <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Don\'t ask again"</string>
<string name="allow" msgid="7225948811296386551">"Allow"</string>
<string name="deny" msgid="2081879885755434506">"Deny"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Delete \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Delete folder \"<xliff:g id="NAME">%1$s</xliff:g>\" and its contents?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">Delete <xliff:g id="COUNT_1">%1$d</xliff:g> files?</item>
+ <item quantity="one">Delete <xliff:g id="COUNT_0">%1$d</xliff:g> file?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">Delete <xliff:g id="COUNT_1">%1$d</xliff:g> folders and their contents?</item>
+ <item quantity="one">Delete <xliff:g id="COUNT_0">%1$d</xliff:g> folder and its contents?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other">Delete <xliff:g id="COUNT_1">%1$d</xliff:g> items?</item>
+ <item quantity="one">Delete <xliff:g id="COUNT_0">%1$d</xliff:g> item?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-es-rUS/config.xml b/packages/DocumentsUI/res/values-es-rUS/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-es-rUS/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-es-rUS/strings.xml b/packages/DocumentsUI/res/values-es-rUS/strings.xml
index 92eb69784ff9..fb4d13ce0e14 100644
--- a/packages/DocumentsUI/res/values-es-rUS/strings.xml
+++ b/packages/DocumentsUI/res/values-es-rUS/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documentos"</string>
- <string name="files_label" msgid="6051402950202690279">"Archivos"</string>
<string name="downloads_label" msgid="959113951084633612">"Descargas"</string>
<string name="title_open" msgid="4353228937663917801">"Abrir desde"</string>
<string name="title_save" msgid="2433679664882857999">"Guardar en"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Vista de lista"</string>
<string name="menu_sort" msgid="7677740407158414452">"Ordenar por"</string>
<string name="menu_search" msgid="3816712084502856974">"Buscar"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Configuración"</string>
<string name="menu_open" msgid="432922957274920903">"Abrir"</string>
<string name="menu_save" msgid="2394743337684426338">"Guardar"</string>
<string name="menu_share" msgid="3075149983979628146">"Compartir"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Copiar a…"</string>
<string name="menu_move" msgid="1828090633118079817">"Mover a…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Ventana nueva"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Cortar"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copiar"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Pegar"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Mostrar almacen. interno"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Ocultar raíces"</string>
<string name="save_error" msgid="6167009778003223664">"Error al guardar el documento"</string>
<string name="create_error" msgid="3735649141335444215">"Error al crear la carpeta"</string>
- <string name="query_error" msgid="1222448261663503501">"Error al consultar documentos"</string>
+ <string name="query_error" msgid="5999895349602476581">"No se puede cargar el contenido en este momento"</string>
<string name="root_recent" msgid="4470053704320518133">"Recientes"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> de espacio libre"</string>
<string name="root_type_service" msgid="2178854894416775409">"Almacenamiento"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Más aplicaciones"</string>
<string name="empty" msgid="7858882803708117596">"Sin elementos"</string>
<string name="no_results" msgid="6622510343880730446">"No hay coincidencias en %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"No se puede abrir el archivo."</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"No se puede abrir el archivo"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"No es posible eliminar algunos documentos."</string>
<string name="share_via" msgid="8966594246261344259">"Compartir mediante"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Copiando archivos"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Moviendo archivos"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Borrando los archivos"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Faltan <xliff:g id="DURATION">%s</xliff:g>."</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Copiando <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Preparación para mover archivos…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Preparando para borrar…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <item quantity="other">No se pudieron copiar <xliff:g id="COUNT_1">%1$d</xliff:g> archivos.</item>
- <item quantity="one">No se pudo copiar <xliff:g id="COUNT_0">%1$d</xliff:g> archivo.</item>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="other">No se pudieron copiar <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
+ <item quantity="one">No se pudo copiar <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="other">No se pudieron mover <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
- <item quantity="one">No se pudo mover <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="other">No se pudieron trasladar <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
+ <item quantity="one">No se pudo trasladar <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other">No se pudieron borrar <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
<item quantity="one">No se pudo borrar <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Presiona para ver los detalles"</string>
<string name="close" msgid="3043722427445528732">"Cerrar"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"No se copiaron estos archivos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"No se movieron los siguientes archivos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Los siguientes archivos no se pudieron copiar: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Los siguientes archivos no se trasladaron: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Los siguientes archivos no se pudieron borrar: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Estos archivos se convirtieron a otro formato: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">Se copiaron <xliff:g id="COUNT_1">%1$d</xliff:g> archivos al portapapeles.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"No se pueden pegar los archivos seleccionados en esta ubicación."</string>
<string name="menu_rename" msgid="7678802479104285353">"Cambiar nombre"</string>
<string name="rename_error" msgid="4203041674883412606">"No se pudo cambiar el nombre del documento"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Expulsar"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Se convirtieron algunos archivos"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"¿Otorgar acceso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> al directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> en <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"¿Quieres otorgar acceso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> al directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"¿Quieres otorgar acceso a la app de <xliff:g id="APPNAME"><b>^1</b></xliff:g> a tus datos, incluidas tus fotos y videos en <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"No volver a preguntar"</string>
<string name="allow" msgid="7225948811296386551">"Permitir"</string>
<string name="deny" msgid="2081879885755434506">"Denegar"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementos seleccionados</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elemento seleccionado</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementos</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elemento</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"¿Deseas borrar \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"¿Deseas borrar la carpeta \"<xliff:g id="NAME">%1$s</xliff:g>\" y su contenido?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">¿Deseas borrar <xliff:g id="COUNT_1">%1$d</xliff:g> archivos?</item>
+ <item quantity="one">¿Deseas borrar <xliff:g id="COUNT_0">%1$d</xliff:g> archivo?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">¿Deseas borrar <xliff:g id="COUNT_1">%1$d</xliff:g> carpetas y su contenido?</item>
+ <item quantity="one">¿Deseas borrar <xliff:g id="COUNT_0">%1$d</xliff:g> carpeta y su contenido?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other">¿Deseas borrar <xliff:g id="COUNT_1">%1$d</xliff:g> elementos?</item>
+ <item quantity="one">¿Deseas borrar <xliff:g id="COUNT_0">%1$d</xliff:g> elemento?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-es/config.xml b/packages/DocumentsUI/res/values-es/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-es/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-es/strings.xml b/packages/DocumentsUI/res/values-es/strings.xml
index 5368145dd8d2..41ace13bc86d 100644
--- a/packages/DocumentsUI/res/values-es/strings.xml
+++ b/packages/DocumentsUI/res/values-es/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documentos"</string>
- <string name="files_label" msgid="6051402950202690279">"Archivos"</string>
<string name="downloads_label" msgid="959113951084633612">"Descargas"</string>
<string name="title_open" msgid="4353228937663917801">"Abrir desde"</string>
<string name="title_save" msgid="2433679664882857999">"Guardar en"</string>
@@ -35,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Copiar en…"</string>
<string name="menu_move" msgid="1828090633118079817">"Mover a…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Nueva ventana"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Cortar"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copiar"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Pegar"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Mostrar almac. interno"</string>
@@ -44,7 +44,7 @@
<string name="button_select" msgid="527196987259139214">"Seleccionar"</string>
<string name="button_copy" msgid="8706475544635021302">"Copiar"</string>
<string name="button_move" msgid="2202666023104202232">"Mover"</string>
- <string name="button_dismiss" msgid="3714065566893946085">"Ignorar"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Descartar"</string>
<string name="button_retry" msgid="4392027584153752797">"Reintentar"</string>
<string name="sort_name" msgid="9183560467917256779">"Por nombre"</string>
<string name="sort_date" msgid="586080032956151448">"Por fecha de modificación"</string>
@@ -53,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Ocultar raíces"</string>
<string name="save_error" msgid="6167009778003223664">"Error al guardar documento"</string>
<string name="create_error" msgid="3735649141335444215">"Error al crear la carpeta"</string>
- <string name="query_error" msgid="1222448261663503501">"Error al consultar lista de documentos"</string>
+ <string name="query_error" msgid="5999895349602476581">"No se puede cargar contenido en este momento"</string>
<string name="root_recent" msgid="4470053704320518133">"Reciente"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> de espacio libre"</string>
<string name="root_type_service" msgid="2178854894416775409">"Servicios almacenamiento"</string>
@@ -62,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Más aplicaciones"</string>
<string name="empty" msgid="7858882803708117596">"No hay elementos"</string>
<string name="no_results" msgid="6622510343880730446">"Sin coincidencias en %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Error al abrir el archivo"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"No se puede abrir el archivo"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"No es posible eliminar algunos documentos"</string>
<string name="share_via" msgid="8966594246261344259">"Compartir a través de"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Copiando archivos"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Moviendo archivos"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Eliminando archivos"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Tiempo restante: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Copiando <xliff:g id="COUNT_1">%1$d</xliff:g> archivos.</item>
@@ -84,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar..."</string>
<string name="move_preparing" msgid="2772219441375531410">"Preparando para mover…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Preparando para eliminar…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> de <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other">No se han podido copiar <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
<item quantity="one">No se ha podido copiar <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other">No se han podido mover <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
<item quantity="one">No se ha podido mover <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other">No se han podido eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
<item quantity="one">No se ha podido eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Toca para ver detalles"</string>
<string name="close" msgid="3043722427445528732">"Cerrar"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Archivos que no se han copiado: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Archivos que no se han movido: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Archivos que no se han copiado: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Archivos que no se han movido: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Archivos que no se han eliminado: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Estos archivos se han convertido a otro formato: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">Se han copiado <xliff:g id="COUNT_1">%1$d</xliff:g> archivos al portapapeles.</item>
@@ -108,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Los archivos seleccionados no se pueden pegar en esta ubicación."</string>
<string name="menu_rename" msgid="7678802479104285353">"Cambiar nombre"</string>
<string name="rename_error" msgid="4203041674883412606">"Error al cambiar el nombre del documento"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Expulsar"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Se han convertido algunos archivos"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"¿Permitir que <xliff:g id="APPNAME"><b>^1</b></xliff:g> acceda al directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> (<xliff:g id="STORAGE"><i>^3</i></xliff:g>)?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"¿Permitir que <xliff:g id="APPNAME"><b>^1</b></xliff:g> acceda al directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"¿Permitir que <xliff:g id="APPNAME"><b>^1</b></xliff:g> acceda a tus datos, incluidos los vídeos y las fotos, de <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"No volver a preguntar"</string>
<string name="allow" msgid="7225948811296386551">"Permitir"</string>
<string name="deny" msgid="2081879885755434506">"Denegar"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> seleccionados</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> seleccionado</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementos</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elemento</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"¿Eliminar <xliff:g id="NAME">%1$s</xliff:g>?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"¿Eliminar la carpeta <xliff:g id="NAME">%1$s</xliff:g> y su contenido?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">¿Eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> archivos?</item>
+ <item quantity="one">¿Eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> archivo?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">¿Eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> carpetas y su contenido?</item>
+ <item quantity="one">¿Eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> carpeta y su contenido?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other">¿Eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> elementos?</item>
+ <item quantity="one">¿Eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> elemento?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-et-rEE/config.xml b/packages/DocumentsUI/res/values-et-rEE/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-et-rEE/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-et-rEE/strings.xml b/packages/DocumentsUI/res/values-et-rEE/strings.xml
index 982a9495a24d..31a6726f5412 100644
--- a/packages/DocumentsUI/res/values-et-rEE/strings.xml
+++ b/packages/DocumentsUI/res/values-et-rEE/strings.xml
@@ -17,25 +17,24 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumendid"</string>
- <string name="files_label" msgid="6051402950202690279">"Failid"</string>
<string name="downloads_label" msgid="959113951084633612">"Allalaadimised"</string>
- <string name="title_open" msgid="4353228937663917801">"Ava:"</string>
+ <string name="title_open" msgid="4353228937663917801">"Ava asukohast:"</string>
<string name="title_save" msgid="2433679664882857999">"Salvesta:"</string>
<string name="menu_create_dir" msgid="2547620241173881754">"Uus kaust"</string>
<string name="menu_grid" msgid="6878021334497835259">"Ruudustikkuva"</string>
<string name="menu_list" msgid="7279285939892417279">"Loendikuva"</string>
- <string name="menu_sort" msgid="7677740407158414452">"Sortimisalus:"</string>
+ <string name="menu_sort" msgid="7677740407158414452">"Sortimisalus"</string>
<string name="menu_search" msgid="3816712084502856974">"Otsing"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Salvestusruumi seaded"</string>
<string name="menu_open" msgid="432922957274920903">"Ava"</string>
<string name="menu_save" msgid="2394743337684426338">"Salvesta"</string>
<string name="menu_share" msgid="3075149983979628146">"Jaga"</string>
<string name="menu_delete" msgid="8138799623850614177">"Kustuta"</string>
<string name="menu_select_all" msgid="8323579667348729928">"Vali kõik"</string>
- <string name="menu_copy" msgid="3612326052677229148">"Kopeeri asukohta ..."</string>
- <string name="menu_move" msgid="1828090633118079817">"Teisaldamine kohta ..."</string>
+ <string name="menu_copy" msgid="3612326052677229148">"Kopeeri asukohta..."</string>
+ <string name="menu_move" msgid="1828090633118079817">"Teisalda asukohta..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"Uus aken"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Lõika"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopeeri"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Kleebi"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Kuva sis. salvestusruum"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Peida juured"</string>
<string name="save_error" msgid="6167009778003223664">"Dokumendi salvestamine ebaõnnestus"</string>
<string name="create_error" msgid="3735649141335444215">"Kausta loomine ebaõnnestus"</string>
- <string name="query_error" msgid="1222448261663503501">"Dokumentide päring ebaõnnestus"</string>
+ <string name="query_error" msgid="5999895349602476581">"Sisu ei saa praegu laadida"</string>
<string name="root_recent" msgid="4470053704320518133">"Hiljutised"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> on vaba"</string>
<string name="root_type_service" msgid="2178854894416775409">"Mäluruumi teenused"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Rohkem rakendusi"</string>
<string name="empty" msgid="7858882803708117596">"Üksusi ei ole"</string>
<string name="no_results" msgid="6622510343880730446">"Otsing %1$s ei andnud vasteid"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Faili ei saa avada"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Faili ei saa avada"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Mõnda dokumenti ei õnnestu kustutada"</string>
<string name="share_via" msgid="8966594246261344259">"Jagage teenusega"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Failide kopeerimine"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Failide teisaldamine"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Failide kustutamine"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Jäänud on <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> faili kopeerimine.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Kopeerimise ettevalmistamine …"</string>
<string name="move_preparing" msgid="2772219441375531410">"Teisaldamise ettevalmistamine …"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Kustutamise ettevalmistamine …"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> faili ei saanud kopeerida</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> faili ei saanud kopeerida</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> faili ei saanud teisaldada</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> faili ei saanud teisaldada</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
- <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> faili ei õnnestunud kustutada</item>
- <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> faili ei õnnestunud kustutada</item>
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> faili ei saanud kustutada</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> faili ei saanud kustutada</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Puudutage üksikasjade vaatamiseks"</string>
<string name="close" msgid="3043722427445528732">"Sule"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Neid faile ei kopeeritud: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Neid faile ei teisaldatud: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Neid faile ei kopeeritud: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Neid faile ei teisaldatud: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Neid faile ei kustutatud: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Need failid teisendati teise vormingusse: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> faili kopeeriti lõikelauale.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Valitud faile ei saa sellesse asukohta kleepida."</string>
<string name="menu_rename" msgid="7678802479104285353">"Nimeta ümber"</string>
<string name="rename_error" msgid="4203041674883412606">"Dokumendi ümbernimetamine ebaõnnestus"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Eemalda"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Mõned failid teisendati"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Kas anda rakendusele <xliff:g id="APPNAME"><b>^1</b></xliff:g> juurdepääs kataloogile <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> salvestusruumis <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Kas anda rakendusele <xliff:g id="APPNAME"><b>^1</b></xliff:g> juurdepääs kataloogile <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Kas anda rakendusele <xliff:g id="APPNAME"><b>^1</b></xliff:g> juurdepääs teie andmetele (sh fotod ja videod) salvestusruumis <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Ära enam küsi"</string>
<string name="allow" msgid="7225948811296386551">"Luba"</string>
<string name="deny" msgid="2081879885755434506">"Keela"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> on valitud</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> on valitud</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> üksust</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> üksus</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Kas kustutada fail „<xliff:g id="NAME">%1$s</xliff:g>”?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Kas kustutada kaust „<xliff:g id="NAME">%1$s</xliff:g>” ja selle sisu?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">Kas kustutada <xliff:g id="COUNT_1">%1$d</xliff:g> faili?</item>
+ <item quantity="one">Kas kustutada <xliff:g id="COUNT_0">%1$d</xliff:g> fail?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">Kas kustutada <xliff:g id="COUNT_1">%1$d</xliff:g> kausta ja nende sisu?</item>
+ <item quantity="one">Kas kustutada <xliff:g id="COUNT_0">%1$d</xliff:g> kaust ja selle sisu?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other">Kas kustutada <xliff:g id="COUNT_1">%1$d</xliff:g> üksust?</item>
+ <item quantity="one">Kas kustutada <xliff:g id="COUNT_0">%1$d</xliff:g> üksus?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-eu-rES/config.xml b/packages/DocumentsUI/res/values-eu-rES/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-eu-rES/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-eu-rES/strings.xml b/packages/DocumentsUI/res/values-eu-rES/strings.xml
index 8c13368c961e..8810f99b0437 100644
--- a/packages/DocumentsUI/res/values-eu-rES/strings.xml
+++ b/packages/DocumentsUI/res/values-eu-rES/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumentuak"</string>
- <string name="files_label" msgid="6051402950202690279">"Fitxategiak"</string>
<string name="downloads_label" msgid="959113951084633612">"Deskargak"</string>
<string name="title_open" msgid="4353228937663917801">"Ireki hemendik"</string>
<string name="title_save" msgid="2433679664882857999">"Gorde hemen"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Zerrenda-ikuspegia"</string>
<string name="menu_sort" msgid="7677740407158414452">"Ordenatzeko irizpidea"</string>
<string name="menu_search" msgid="3816712084502856974">"Bilatu"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Memoriaren ezarpenak"</string>
<string name="menu_open" msgid="432922957274920903">"Ireki"</string>
<string name="menu_save" msgid="2394743337684426338">"Gorde"</string>
<string name="menu_share" msgid="3075149983979628146">"Partekatu"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Kopiatu hemen…"</string>
<string name="menu_move" msgid="1828090633118079817">"Eraman hona…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Leiho berria"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Ebaki"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopiatu"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Itsatsi"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Erakutsi barneko memoria"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Ezkutatu erroko karpetak"</string>
<string name="save_error" msgid="6167009778003223664">"Ezin izan da dokumentua gorde"</string>
<string name="create_error" msgid="3735649141335444215">"Ezin izan da karpeta sortu"</string>
- <string name="query_error" msgid="1222448261663503501">"Ezin izan dira dokumentuak kontsultatu"</string>
+ <string name="query_error" msgid="5999895349602476581">"Une honetan ezin da kargatu edukia"</string>
<string name="root_recent" msgid="4470053704320518133">"Azkenak"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> doan"</string>
<string name="root_type_service" msgid="2178854894416775409">"Biltegiratze-zerbitzuak"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Aplikazio gehiago"</string>
<string name="empty" msgid="7858882803708117596">"Ez dago elementurik"</string>
<string name="no_results" msgid="6622510343880730446">"Ez da aurkitu ezer %1$s atalean"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Ezin da fitxategia ireki"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Ezin da ireki fitxategia"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Ezin izan dira dokumentu batzuk ezabatu"</string>
<string name="share_via" msgid="8966594246261344259">"Partekatu honen bidez:"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Fitxategiak kopiatzen"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Fitxategiak mugitzea"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Fitxategiak ezabatzea"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Falta den denbora: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fitxategi kopiatzen.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Kopiatzeko prestatzen…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Mugitzeko prestatzen…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Ezabatzeko prestatzen…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other">Ezin izan dira kopiatu <xliff:g id="COUNT_1">%1$d</xliff:g> fitxategi</item>
<item quantity="one">Ezin izan da kopiatu <xliff:g id="COUNT_0">%1$d</xliff:g> fitxategi</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other">Ezin izan dira mugitu <xliff:g id="COUNT_1">%1$d</xliff:g> fitxategi</item>
<item quantity="one">Ezin izan da mugitu <xliff:g id="COUNT_0">%1$d</xliff:g> fitxategi</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other">Ezin izan dira ezabatu <xliff:g id="COUNT_1">%1$d</xliff:g> fitxategi</item>
<item quantity="one">Ezin izan da ezabatu <xliff:g id="COUNT_0">%1$d</xliff:g> fitxategi</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Sakatu xehetasunak ikusteko"</string>
<string name="close" msgid="3043722427445528732">"Itxi"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Ez dira kopiatu fitxategi hauek: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Ez dira mugitu fitxategi hauek: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Ez dira kopiatu fitxategi hauek: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Ez dira mugitu fitxategi hauek: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Ez dira ezabatu fitxategi hauek: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Fitxategi hauek beste formatu bateko fitxategi bihurtu dira: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fitxategi kopiatu dira arbelean.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Ezin dira itsatsi hautatutako fitxategiak kokapen honetan."</string>
<string name="menu_rename" msgid="7678802479104285353">"Aldatu izena"</string>
<string name="rename_error" msgid="4203041674883412606">"Ezin izan zaio aldatu izena dokumentuari"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Atera"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Artxibo batzuk bihurtu dira"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> aplikazioari <xliff:g id="STORAGE"><i>^3</i></xliff:g> unitateko <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> direktorioa atzitzeko baimena eman nahi diozu?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<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="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> aplikazioari zure datuak atzitzea baimendu nahi diozu, besteak beste, <xliff:g id="STORAGE"><i>^2</i></xliff:g> biltegian dituzun argazkiak eta bideoak?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Ez galdetu berriro"</string>
<string name="allow" msgid="7225948811296386551">"Onartu"</string>
<string name="deny" msgid="2081879885755434506">"Ukatu"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> hautatuta</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> hautatuta</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementu</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elementu</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ezabatu nahi duzu?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" karpeta eta bertako edukia ezabatu nahi duzu?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fitxategi ezabatu nahi dituzu?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fitxategi ezabatu nahi duzu?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> karpeta eta beren eduki guztia ezabatu nahi duzu?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> karpeta eta bere eduki guztia ezabatu nahi duzu?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementu ezabatu nahi dituzu?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elementu ezabatu nahi duzu?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-fa/config.xml b/packages/DocumentsUI/res/values-fa/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-fa/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-fa/strings.xml b/packages/DocumentsUI/res/values-fa/strings.xml
index b7d09f8e0b36..39074e0a0c07 100644
--- a/packages/DocumentsUI/res/values-fa/strings.xml
+++ b/packages/DocumentsUI/res/values-fa/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"اسناد"</string>
- <string name="files_label" msgid="6051402950202690279">"فایل‌ها"</string>
<string name="downloads_label" msgid="959113951084633612">"بارگیری‌ها"</string>
<string name="title_open" msgid="4353228937663917801">"باز کردن از"</string>
<string name="title_save" msgid="2433679664882857999">"ذخیره در"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"نمای فهرستی"</string>
<string name="menu_sort" msgid="7677740407158414452">"مرتب‌سازی براساس"</string>
<string name="menu_search" msgid="3816712084502856974">"جستجو"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"تنظیمات ذخیره‌سازی"</string>
<string name="menu_open" msgid="432922957274920903">"باز کردن"</string>
<string name="menu_save" msgid="2394743337684426338">"ذخیره"</string>
<string name="menu_share" msgid="3075149983979628146">"اشتراک‌گذاری"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"کپی در..."</string>
<string name="menu_move" msgid="1828090633118079817">"انتقال به…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"پنجره جدید"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"برش"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"کپی"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"جای‌گذاری"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"نمایش فضای ذخیره‌سازی داخلی"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"پنهان کردن ریشه‌ها"</string>
<string name="save_error" msgid="6167009778003223664">"ذخیره سند انجام نشد"</string>
<string name="create_error" msgid="3735649141335444215">"ایجاد پوشه انجام نشد"</string>
- <string name="query_error" msgid="1222448261663503501">"جستجوی اسناد ناموفق بود"</string>
+ <string name="query_error" msgid="5999895349602476581">"محتوا درحال حاضر بارگیری نمی‌شود"</string>
<string name="root_recent" msgid="4470053704320518133">"اخیر"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> آزاد"</string>
<string name="root_type_service" msgid="2178854894416775409">"خدمات ذخیره‌سازی"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"برنامه‌های بیشتر"</string>
<string name="empty" msgid="7858882803708117596">"موردی موجود نیست"</string>
<string name="no_results" msgid="6622510343880730446">"‏مورد منطبقی در %1$s وجود ندارد"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"فایل باز نمی‌شود"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"فایل باز نمی‌شود"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"برخی از اسناد حذف نمی‌شوند"</string>
<string name="share_via" msgid="8966594246261344259">"اشتراک‌گذاری از طریق"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"در حال کپی کردن فایل‌ها"</string>
<string name="move_notification_title" msgid="6193835179777284805">"درحال انتقال فایل‌ها"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"در حال حذف فایل‌ها"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> باقی‌مانده"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">در حال کپی کردن <xliff:g id="COUNT_1">%1$d</xliff:g> فایل.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"در حال آماده‌سازی برای کپی..."</string>
<string name="move_preparing" msgid="2772219441375531410">"درحال آماده‌سازی برای انتقال…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"درحال آماده‌سازی برای حذف…‏"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <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>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> فایل کپی نشد</item>
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> فایل کپی نشد</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> فایل منتقل نشد</item>
- <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فایل منتقل نشد</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> فایل منتقل نشد</item>
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> فایل منتقل نشد</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
- <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> فایل حذف نشد</item>
- <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فایل حذف نشد</item>
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+ <item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> فایل حذف نشد</item>
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> فایل حذف نشد</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"برای مشاهده جزئیات ضربه بزنید"</string>
<string name="close" msgid="3043722427445528732">"بستن"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"این فایل‌ها کپی نشدند: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"این فایل‌ها منتقل نشدند: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"این فایل‌ها کپی نشدند: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"این فایل‌ها منتقل نشدند: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"این فایل‌ها حذف نشدند: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"این فایل‌ها به قالب دیگری تبدیل شدند: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> فایل در بریده‌دان کپی شد.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"نمی‌توان فایل‌های انتخابی را در این مکان جای‌گذاری کرد."</string>
<string name="menu_rename" msgid="7678802479104285353">"تغییر نام"</string>
<string name="rename_error" msgid="4203041674883412606">"نام سند تغییر نکرد"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"بیرون راندن"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"بعضی از فایل‌ها تبدیل شدند"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"به <xliff:g id="APPNAME"><b>^1</b></xliff:g> اجازه داده شود به فهرست راهنمای <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> در <xliff:g id="STORAGE"><i>^3</i></xliff:g> دسترسی داشته باشد؟"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"به <xliff:g id="APPNAME"><b>^1</b></xliff:g> اجازه دسترسی به دایرکتوری <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> داده شود؟"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"به <xliff:g id="APPNAME"><b>^1</b></xliff:g> اجازه می‌دهید به داده‌هایتان دسترسی پیدا کند، از جمله عکس‌ها و ویدیوهایتان در <xliff:g id="STORAGE"><i>^2</i></xliff:g>؟"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"دوباره سؤال نشود"</string>
<string name="allow" msgid="7225948811296386551">"ارزیابی‌شده"</string>
<string name="deny" msgid="2081879885755434506">"اجازه ندارد"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one">‏<xliff:g id="COUNT_1">%1$d</xliff:g> مورد انتخاب شد</item>
+ <item quantity="other">‏<xliff:g id="COUNT_1">%1$d</xliff:g> مورد انتخاب شد</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> مورد</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> مورد</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"«<xliff:g id="NAME">%1$s</xliff:g>» حذف شود؟"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"پوشه «<xliff:g id="NAME">%1$s</xliff:g>» و محتوای آن حذف شود؟"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> فایل حذف شود؟</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فایل حذف شود؟</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> پوشه و محتوای آن‌ها حذف شود؟</item>
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> پوشه و محتوای آن‌ها حذف شود؟</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> مورد حذف شود؟</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> مورد حذف شود؟</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-fi/config.xml b/packages/DocumentsUI/res/values-fi/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-fi/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-fi/strings.xml b/packages/DocumentsUI/res/values-fi/strings.xml
index c9517f9e31da..cc8702600dba 100644
--- a/packages/DocumentsUI/res/values-fi/strings.xml
+++ b/packages/DocumentsUI/res/values-fi/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Asiakirjat"</string>
- <string name="files_label" msgid="6051402950202690279">"Tiedostot"</string>
<string name="downloads_label" msgid="959113951084633612">"Lataukset"</string>
<string name="title_open" msgid="4353228937663917801">"Avaa sijainnista"</string>
<string name="title_save" msgid="2433679664882857999">"Tallenna kohteeseen"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Luettelonäkymä"</string>
<string name="menu_sort" msgid="7677740407158414452">"Lajitteluperuste"</string>
<string name="menu_search" msgid="3816712084502856974">"Haku"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Tallennusasetukset"</string>
<string name="menu_open" msgid="432922957274920903">"Avaa"</string>
<string name="menu_save" msgid="2394743337684426338">"Tallenna"</string>
<string name="menu_share" msgid="3075149983979628146">"Jaa"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Kopioi kohteeseen…"</string>
<string name="menu_move" msgid="1828090633118079817">"Siirrä kohteeseen…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Uusi ikkuna"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Leikkaa"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopioi"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Liitä"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Näytä sis. tallennustila"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Piilota juuret"</string>
<string name="save_error" msgid="6167009778003223664">"Asiakirjan tallennus epäonnistui"</string>
<string name="create_error" msgid="3735649141335444215">"Kansion luominen epäonnistui"</string>
- <string name="query_error" msgid="1222448261663503501">"Dokumenttikysely epäonnistui"</string>
+ <string name="query_error" msgid="5999895349602476581">"Sisältöä ei juuri nyt voi ladata."</string>
<string name="root_recent" msgid="4470053704320518133">"Viimeisimmät"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> vapaana"</string>
<string name="root_type_service" msgid="2178854894416775409">"Tallennuspalvelut"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Lisää sovelluksia"</string>
<string name="empty" msgid="7858882803708117596">"Ei kohteita"</string>
<string name="no_results" msgid="6622510343880730446">"Ei osumia kohteessa %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Tiedostoa ei voi avata"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Tiedoston avaaminen epäonnistui."</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Joitakin asiakirjoja ei voi poistaa"</string>
<string name="share_via" msgid="8966594246261344259">"Jaa sovelluksessa"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopioidaan tiedostoja"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Siirretään tiedostoja"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Poistetaan tiedostoja"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> jäljellä"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Kopioidaan <xliff:g id="COUNT_1">%1$d</xliff:g> tiedostoa.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Valmistellaan kopiointia…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Valmistellaan siirtämistä…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Valmistellaan poistamista…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> tiedoston kopioiminen epäonnistui.</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> tiedoston kopioiminen epäonnistui.</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> tiedoston siirtäminen epäonnistui.</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> tiedoston siirtäminen epäonnistui.</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
- <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> tiedoston poistaminen epäonnistui</item>
- <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> tiedoston poistaminen epäonnistui</item>
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> tiedoston poistaminen epäonnistui.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> tiedoston poistaminen epäonnistui.</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Tarkastele tietoja napauttamalla"</string>
<string name="close" msgid="3043722427445528732">"Sulje"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Seuraavia tiedostoja ei kopioitu: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Näitä tiedostoja ei siirretty: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Näitä tiedostoja ei kopioitu: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Näitä tiedostoja ei siirretty: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Näitä tiedostoja ei poistettu: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Seuraavat tiedostot muunnettiin toiseen muotoon: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> tiedostoa kopioitiin leikepöydälle.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Valittuja tiedostoja ei voi liittää tähän sijaintiin."</string>
<string name="menu_rename" msgid="7678802479104285353">"Nimeä uudelleen"</string>
<string name="rename_error" msgid="4203041674883412606">"Dokumentin nimen muuttaminen epäonnistui."</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Poista"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Joitakin tiedostoja muunnettiin."</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Myönnetäänkö sovellukselle <xliff:g id="APPNAME"><b>^1</b></xliff:g> sijainnissa <xliff:g id="STORAGE"><i>^3</i></xliff:g> olevan hakemiston <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> käyttöoikeus?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Saako <xliff:g id="APPNAME"><b>^1</b></xliff:g> käyttää hakemistoa <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Myönnetäänkö sovellukselle <xliff:g id="APPNAME"><b>^1</b></xliff:g> sijainnissa <xliff:g id="STORAGE"><i>^2</i></xliff:g> olevien tietojesi, mukaan lukien valokuviesi ja videoidesi, käyttöoikeus?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Älä kysy uudestaan"</string>
<string name="allow" msgid="7225948811296386551">"Salli"</string>
<string name="deny" msgid="2081879885755434506">"Kiellä"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> valittu</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> valittu</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> kohdetta</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> kohde</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Poistetaanko <xliff:g id="NAME">%1$s</xliff:g>?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Poistetaanko kansio <xliff:g id="NAME">%1$s</xliff:g> ja sen sisältö?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">Poistetaanko <xliff:g id="COUNT_1">%1$d</xliff:g> tiedostoa?</item>
+ <item quantity="one">Poistetaanko <xliff:g id="COUNT_0">%1$d</xliff:g> tiedosto?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">Poistetaanko <xliff:g id="COUNT_1">%1$d</xliff:g> kansiota ja niiden sisältö?</item>
+ <item quantity="one">Poistetaanko <xliff:g id="COUNT_0">%1$d</xliff:g> kansio ja sen sisältö?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other">Poistetaanko <xliff:g id="COUNT_1">%1$d</xliff:g> kohdetta?</item>
+ <item quantity="one">Poistetaanko <xliff:g id="COUNT_0">%1$d</xliff:g> kohde?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-fr-rCA/config.xml b/packages/DocumentsUI/res/values-fr-rCA/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-fr-rCA/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-fr-rCA/strings.xml b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
index ace072bb6a91..acac67a276fd 100644
--- a/packages/DocumentsUI/res/values-fr-rCA/strings.xml
+++ b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documents"</string>
- <string name="files_label" msgid="6051402950202690279">"Fichiers"</string>
<string name="downloads_label" msgid="959113951084633612">"Téléchargements"</string>
<string name="title_open" msgid="4353228937663917801">"Ouvrir à partir de"</string>
<string name="title_save" msgid="2433679664882857999">"Enregistrer dans"</string>
@@ -26,16 +25,16 @@
<string name="menu_list" msgid="7279285939892417279">"Liste"</string>
<string name="menu_sort" msgid="7677740407158414452">"Trier par"</string>
<string name="menu_search" msgid="3816712084502856974">"Rechercher"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Paramètres de stockage"</string>
<string name="menu_open" msgid="432922957274920903">"Ouvrir"</string>
<string name="menu_save" msgid="2394743337684426338">"Enregistrer"</string>
<string name="menu_share" msgid="3075149983979628146">"Partager"</string>
<string name="menu_delete" msgid="8138799623850614177">"Supprimer"</string>
<string name="menu_select_all" msgid="8323579667348729928">"Tout sélectionner"</string>
- <string name="menu_copy" msgid="3612326052677229148">"Copier vers..."</string>
+ <string name="menu_copy" msgid="3612326052677229148">"Copier dans..."</string>
<string name="menu_move" msgid="1828090633118079817">"Déplacer dans…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Nouvelle fenêtre"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Couper"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copier"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Coller"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Aff. mém. stock. interne"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Masquer les racines"</string>
<string name="save_error" msgid="6167009778003223664">"Échec de l\'enregistrement du document"</string>
<string name="create_error" msgid="3735649141335444215">"Échec de la création du dossier"</string>
- <string name="query_error" msgid="1222448261663503501">"Échec de la demande de document"</string>
+ <string name="query_error" msgid="5999895349602476581">"Impossible de charger le contenu pour le moment"</string>
<string name="root_recent" msgid="4470053704320518133">"Récents"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> disponible"</string>
<string name="root_type_service" msgid="2178854894416775409">"Services de stockage"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Plus d\'applications"</string>
<string name="empty" msgid="7858882803708117596">"Aucun élément"</string>
<string name="no_results" msgid="6622510343880730446">"Aucune correspondance dans %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Impossible d\'ouvrir le fichier"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Impossible d\'ouvrir le fichier"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Impossible de supprimer certains documents"</string>
<string name="share_via" msgid="8966594246261344259">"Partager par"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Copie de fichiers..."</string>
<string name="move_notification_title" msgid="6193835179777284805">"Déplacement des fichiers"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Suppression des fichiers"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Durée restante : <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Copier de <xliff:g id="COUNT_1">%1$d</xliff:g> fichier en cours.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Préparation de la copie en cours"</string>
<string name="move_preparing" msgid="2772219441375531410">"Préparation du déplacement..."</string>
<string name="delete_preparing" msgid="5655813182533491992">"Préparation de la suppression..."</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> sur <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="one">Impossible de copier <xliff:g id="COUNT_1">%1$d</xliff:g> fichier</item>
<item quantity="other">Impossible de copier <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="one">Impossible de déplacer <xliff:g id="COUNT_1">%1$d</xliff:g> fichier</item>
<item quantity="other">Impossible de déplacer <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="one">Impossible de supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> dossier</item>
<item quantity="other">Impossible de supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> dossiers</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Touchez pour afficher les détails"</string>
<string name="close" msgid="3043722427445528732">"Fermer"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Ces fichiers ne ont pas été copiés : <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Ces fichiers n\'ont pas été déplacés : <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Ces fichiers ne ont pas été copiés : <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Ces fichiers n\'ont pas été déplacés : <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Ces fichiers n\'ont pas été supprimés : <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Ces fichiers ont été convertis dans un autre format : <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> fichier a été copié dans le presse-papiers.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Impossible de coller les fichiers sélectionnés à cet endroit."</string>
<string name="menu_rename" msgid="7678802479104285353">"Renommer"</string>
<string name="rename_error" msgid="4203041674883412606">"Impossible de renommer le document"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Éjecter"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Certains fichiers ont été convertis"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Accorder à <xliff:g id="APPNAME"><b>^1</b></xliff:g> l\'accès au répertoire <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> sur <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Accorder à <xliff:g id="APPNAME"><b>^1</b></xliff:g> l\'accès au répertoire <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Voulez-vous accorder l\'accès à vos données à <xliff:g id="APPNAME"><b>^1</b></xliff:g>, y compris vos photos et vos vidéos, sur <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Ne plus me demander"</string>
<string name="allow" msgid="7225948811296386551">"Autoriser"</string>
<string name="deny" msgid="2081879885755434506">"Refuser"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> sélectionné</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> sélectionnés</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> article</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> articles</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Supprimer « <xliff:g id="NAME">%1$s</xliff:g> »?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Supprimer le dossier «  <xliff:g id="NAME">%1$s</xliff:g> » et son contenu?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one">Supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> fichier?</item>
+ <item quantity="other">Supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one">Supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> dossier et son contenu?</item>
+ <item quantity="other">Supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> dossiers et leur contenu?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one">Supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> élément?</item>
+ <item quantity="other">Supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> éléments?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-fr/config.xml b/packages/DocumentsUI/res/values-fr/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-fr/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-fr/strings.xml b/packages/DocumentsUI/res/values-fr/strings.xml
index b1e482722633..9a11333b8ce2 100644
--- a/packages/DocumentsUI/res/values-fr/strings.xml
+++ b/packages/DocumentsUI/res/values-fr/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Docs"</string>
- <string name="files_label" msgid="6051402950202690279">"Fichiers"</string>
<string name="downloads_label" msgid="959113951084633612">"Téléchargements"</string>
<string name="title_open" msgid="4353228937663917801">"Ouvrir à partir de"</string>
<string name="title_save" msgid="2433679664882857999">"Enregistrer sous"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Liste"</string>
<string name="menu_sort" msgid="7677740407158414452">"Trier par"</string>
<string name="menu_search" msgid="3816712084502856974">"Rechercher"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Paramètres de stockage"</string>
<string name="menu_open" msgid="432922957274920903">"Ouvrir"</string>
<string name="menu_save" msgid="2394743337684426338">"Enregistrer"</string>
<string name="menu_share" msgid="3075149983979628146">"Partager"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Copier vers…"</string>
<string name="menu_move" msgid="1828090633118079817">"Placer dans…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Nouvelle fenêtre"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Couper"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copier"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Coller"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Aff. mém. stock. interne"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Masquer les répertoires racines"</string>
<string name="save_error" msgid="6167009778003223664">"Échec de l\'enregistrement du document."</string>
<string name="create_error" msgid="3735649141335444215">"Échec de la création du dossier."</string>
- <string name="query_error" msgid="1222448261663503501">"Échec de la demande de documents."</string>
+ <string name="query_error" msgid="5999895349602476581">"Impossible de charger le contenu pour le moment"</string>
<string name="root_recent" msgid="4470053704320518133">"Récents"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"Espace disponible : <xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="root_type_service" msgid="2178854894416775409">"Services de stockage"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Autres applications"</string>
<string name="empty" msgid="7858882803708117596">"Aucun élément"</string>
<string name="no_results" msgid="6622510343880730446">"Aucune correspondance dans %1$s."</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Impossible d\'ouvrir le fichier."</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Impossible d\'ouvrir le fichier"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Impossible de supprimer certains documents."</string>
<string name="share_via" msgid="8966594246261344259">"Partager via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Copie de fichiers en cours"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Déplacement de fichiers"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Suppression des fichiers…"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Temps restant : <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Copie de <xliff:g id="COUNT_1">%1$d</xliff:g> fichier en cours…</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Préparation de la copie en cours…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Préparation au déplacement…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Préparation à la suppression…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="one">Impossible de copier <xliff:g id="COUNT_1">%1$d</xliff:g> fichier</item>
<item quantity="other">Impossible de copier <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="one">Impossible de déplacer <xliff:g id="COUNT_1">%1$d</xliff:g> fichier</item>
<item quantity="other">Impossible de déplacer <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="one">Impossible de supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> fichier</item>
<item quantity="other">Impossible de supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Appuyez pour afficher plus d\'informations."</string>
<string name="close" msgid="3043722427445528732">"Fermer"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Les fichiers suivants n\'ont pas été copiés : <xliff:g id="LIST">%1$s</xliff:g>."</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Les fichiers suivants n\'ont pas été déplacés : <xliff:g id="LIST">%1$s</xliff:g>."</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Les fichiers suivants n\'ont pas été copiés : <xliff:g id="LIST">%1$s</xliff:g>."</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Les fichiers suivants n\'ont pas été déplacés : <xliff:g id="LIST">%1$s</xliff:g>."</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Les fichiers suivants n\'ont pas été supprimés : <xliff:g id="LIST">%1$s</xliff:g>."</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Ces fichiers ont été convertis dans un autre format : <xliff:g id="LIST">%1$s</xliff:g>."</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> fichier a bien été copié dans le Presse-papiers.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Impossible de coller les fichiers sélectionnés à cet endroit."</string>
<string name="menu_rename" msgid="7678802479104285353">"Renommer"</string>
<string name="rename_error" msgid="4203041674883412606">"Échec du changement de nom du document."</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Éjecter"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Certains fichiers ont été convertis"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Autoriser <xliff:g id="APPNAME"><b>^1</b></xliff:g> à accéder à l\'annuaire \"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>\" sur <xliff:g id="STORAGE"><i>^3</i></xliff:g> ?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Autoriser <xliff:g id="APPNAME"><b>^1</b></xliff:g> à accéder à l\'annuaire \"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>\" ?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Autoriser <xliff:g id="APPNAME"><b>^1</b></xliff:g> à accéder à vos données, y compris les photos et les vidéos, sur <xliff:g id="STORAGE"><i>^2</i></xliff:g> ?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Ne plus demander"</string>
<string name="allow" msgid="7225948811296386551">"Autoriser"</string>
<string name="deny" msgid="2081879885755434506">"Refuser"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> élément sélectionné</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> éléments sélectionnés</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> élément</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> éléments</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Supprimer \"<xliff:g id="NAME">%1$s</xliff:g>\" ?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Supprimer le dossier \"<xliff:g id="NAME">%1$s</xliff:g>\" et son contenu ?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one">Supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> fichier ?</item>
+ <item quantity="other">Supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers ?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one">Supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> dossier et son contenu ?</item>
+ <item quantity="other">Supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> dossiers et leur contenu ?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one">Supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> élément ?</item>
+ <item quantity="other">Supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> éléments ?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-gl-rES/config.xml b/packages/DocumentsUI/res/values-gl-rES/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-gl-rES/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-gl-rES/strings.xml b/packages/DocumentsUI/res/values-gl-rES/strings.xml
index 9275557e03f5..645de56f7fc4 100644
--- a/packages/DocumentsUI/res/values-gl-rES/strings.xml
+++ b/packages/DocumentsUI/res/values-gl-rES/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documentos"</string>
- <string name="files_label" msgid="6051402950202690279">"Ficheiros"</string>
<string name="downloads_label" msgid="959113951084633612">"Descargas"</string>
<string name="title_open" msgid="4353228937663917801">"Abrir desde"</string>
<string name="title_save" msgid="2433679664882857999">"Gardar en"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Vista de lista"</string>
<string name="menu_sort" msgid="7677740407158414452">"Ordenar por"</string>
<string name="menu_search" msgid="3816712084502856974">"Buscar"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Configur. almacenamento"</string>
<string name="menu_open" msgid="432922957274920903">"Abrir"</string>
<string name="menu_save" msgid="2394743337684426338">"Gardar"</string>
<string name="menu_share" msgid="3075149983979628146">"Compartir"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Copiar en…"</string>
<string name="menu_move" msgid="1828090633118079817">"Mover a…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Nova ventá"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Cortar"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copiar"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Pegar"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Mostrar almacen. interno"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Ocultar raíces"</string>
<string name="save_error" msgid="6167009778003223664">"Non se puido gardar o documento"</string>
<string name="create_error" msgid="3735649141335444215">"Non se puido crear o cartafol"</string>
- <string name="query_error" msgid="1222448261663503501">"Non se puideron consultar os documentos"</string>
+ <string name="query_error" msgid="5999895349602476581">"Non se pode cargar o contido neste momento"</string>
<string name="root_recent" msgid="4470053704320518133">"Recentes"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> libres"</string>
<string name="root_type_service" msgid="2178854894416775409">"Servizos de almacenamento"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Máis aplicacións"</string>
<string name="empty" msgid="7858882803708117596">"Ningún elemento"</string>
<string name="no_results" msgid="6622510343880730446">"Non hai coincidencias en %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Non se pode abrir o ficheiro"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Non se pode abrir o ficheiro"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Non se poden eliminar algúns documentos"</string>
<string name="share_via" msgid="8966594246261344259">"Compartir a través de"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Copiando ficheiros"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Mover ficheiros"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Eliminando ficheiros"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Tempo restante: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Copiando <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Preparándose para mover..."</string>
<string name="delete_preparing" msgid="5655813182533491992">"Preparando para eliminar…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other">Non se puideron copiar <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros</item>
<item quantity="one">Non se puido copiar <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other">Non se puideron mover <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros</item>
<item quantity="one">Non se puido mover <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other">Non se puideron eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros</item>
<item quantity="one">Non se puido eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Toca para ver detalles"</string>
<string name="close" msgid="3043722427445528732">"Pechar"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Non se copiaron estes ficheiros: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Non se moveron estes ficheiros: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Non se copiaron estes ficheiros: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Non se moveron estes ficheiros: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Non se eliminaron estes ficheiros: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Estes ficheiros convertéronse a outro formato: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">Copiáronse <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros no portapapeis.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Non se poden pegar os ficheiros seleccionados nesta localización."</string>
<string name="menu_rename" msgid="7678802479104285353">"Cambiar nome"</string>
<string name="rename_error" msgid="4203041674883412606">"Non se puido cambiar o nome do documento"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Expulsar"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Convertéronse algúns ficheiros"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Queres outorgar acceso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> ao directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> no almacenamento de <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Queres darlle acceso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> ao directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Queres darlle acceso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> aos teus datos almacenados en <xliff:g id="STORAGE"><i>^2</i></xliff:g>, incluídos vídeos e fotos?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Non preguntar de novo"</string>
<string name="allow" msgid="7225948811296386551">"Permitir"</string>
<string name="deny" msgid="2081879885755434506">"Rexeitar"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other">Seleccionáronse <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">Seleccionouse <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementos</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elemento</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Queres eliminar \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Queres eliminar o cartafol \"<xliff:g id="NAME">%1$s</xliff:g>\" e o seu contido?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">Queres eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros?</item>
+ <item quantity="one">Queres eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">Queres eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> cartafoles e os seus contidos?</item>
+ <item quantity="one">Queres eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> cartafol e os seus contidos?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other">Queres eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> elementos?</item>
+ <item quantity="one">Queres eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> elemento?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-gu-rIN/config.xml b/packages/DocumentsUI/res/values-gu-rIN/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-gu-rIN/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-gu-rIN/strings.xml b/packages/DocumentsUI/res/values-gu-rIN/strings.xml
index 5dceac2d724d..7fa1b24cc6d8 100644
--- a/packages/DocumentsUI/res/values-gu-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-gu-rIN/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"દસ્તાવેજો"</string>
- <string name="files_label" msgid="6051402950202690279">"ફાઇલો"</string>
<string name="downloads_label" msgid="959113951084633612">"ડાઉનલોડ્સ"</string>
<string name="title_open" msgid="4353228937663917801">"અહીંથી ખોલો"</string>
<string name="title_save" msgid="2433679664882857999">"આમાં સાચવો"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"સૂચિ દૃશ્ય"</string>
<string name="menu_sort" msgid="7677740407158414452">"આ પ્રમાણે સૉર્ટ કરો"</string>
<string name="menu_search" msgid="3816712084502856974">"શોધો"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"સ્ટોરેજ સેટિંગ્સ"</string>
<string name="menu_open" msgid="432922957274920903">"ખોલો"</string>
<string name="menu_save" msgid="2394743337684426338">"સાચવો"</string>
<string name="menu_share" msgid="3075149983979628146">"શેર કરો"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"આના પર કૉપિ કરો…"</string>
<string name="menu_move" msgid="1828090633118079817">"આમાં ખસેડો…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"નવી વિંડો"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"કાપો"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"કૉપિ કરો"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"પેસ્ટ કરો"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"આંતરિક સ્ટોરેજ બતાવો"</string>
@@ -54,20 +53,21 @@
<string name="drawer_close" msgid="7602734368552123318">"રૂટ્સ છુપાવો"</string>
<string name="save_error" msgid="6167009778003223664">"દસ્તાવેજ સાચવવામાં નિષ્ફળ થયાં."</string>
<string name="create_error" msgid="3735649141335444215">"ફોલ્ડર બનાવવામાં નિષ્ફળ થયા"</string>
- <string name="query_error" msgid="1222448261663503501">"દસ્તાવેજોને ક્વેરી કરવામાં નિષ્ફળ થયાં"</string>
+ <string name="query_error" msgid="5999895349602476581">"આ પળે સામગ્રી લોડ કરી શકતાં નથી"</string>
<string name="root_recent" msgid="4470053704320518133">"તાજેતરના"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ખાલી"</string>
<string name="root_type_service" msgid="2178854894416775409">"સંગ્રહ સેવાઓ"</string>
<string name="root_type_shortcut" msgid="3318760609471618093">"શોર્ટકટ્સ"</string>
<string name="root_type_device" msgid="7121342474653483538">"ઉપકરણો"</string>
- <string name="root_type_apps" msgid="8838065367985945189">"વધુ એપ્લિકેશનો"</string>
+ <string name="root_type_apps" msgid="8838065367985945189">"વધુ ઍપ્લિકેશનો"</string>
<string name="empty" msgid="7858882803708117596">"કોઈ આઇટમ્સ નથી"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s માં કોઇ મેળ નથી"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"ફાઇલ ખોલી શકાતી નથી"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"ફાઇલ ખોલી શકતાં નથી"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"કેટલાક દસ્તાવેજો કાઢી નાખવામાં અસમર્થ"</string>
<string name="share_via" msgid="8966594246261344259">"આના દ્વારા શેર કરો"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"ફાઇલો કૉપિ કરી રહ્યાં છે"</string>
<string name="move_notification_title" msgid="6193835179777284805">"ફાઇલો ખસેડી રહ્યાં છે"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"ફાઇલને નીકાળી રહ્યાં છે"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> બાકી"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલો કૉપિ કરી રહ્યાં છે.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"કૉપિ માટે તૈયારી કરી રહ્યું છે…"</string>
<string name="move_preparing" msgid="2772219441375531410">"ખસેડવા માટે તૈયાર કરી રહ્યું છે…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"કાઢી નાખવાની તૈયારી કરી રહ્યાં છે…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <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>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલ કૉપિ કરી શક્યાં નથી</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલ કૉપિ કરી શક્યાં નથી</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલો ખસેડી શકાઈ નથી</item>
- <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલો ખસેડી શકાઈ નથી</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલ ખસેડી શક્યાં નથી</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલ ખસેડી શક્યાં નથી</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલ કાઢી નાખી શક્યાં નથી</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલ કાઢી નાખી શક્યાં નથી</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"વિગતો જોવા માટે ટૅપ કરો"</string>
<string name="close" msgid="3043722427445528732">"બંધ કરો"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"આ ફાઇલો કૉપિ કરી નહોતી: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"આ ફાઇલો ખસેડી નહોતી: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"આ ફાઇલો કૉપિ કરી નહોતી: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"આ ફાઇલો ખસેડી નહોતી: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"આ ફાઇલો કાઢી નાખી નહોતી: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"આ ફાઇલો બીજા ફોર્મેટમાં રૂપાંતરિત કરી હતી: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one">ક્લિપબોર્ડ પર <xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલો કૉપિ કરી.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"આ સ્થાનમાં પસંદ કરેલ ફાઇલો પેસ્ટ કરી શકાતી નથી."</string>
<string name="menu_rename" msgid="7678802479104285353">"નામ બદલો"</string>
<string name="rename_error" msgid="4203041674883412606">"દસ્તાવેજનું નામ બદલવામાં નિષ્ફળ થયાં"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"બહાર કાઢો"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"કેટલીક ફાઇલો રૂપાંતરિત કરી હતી"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ને <xliff:g id="STORAGE"><i>^3</i></xliff:g> પર <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> નિર્દેશિકાની ઍક્સેસ આપીએ?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ને <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> નિર્દેશિકાની ઍક્સેસ આપીએ?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ને <xliff:g id="STORAGE"><i>^2</i></xliff:g> પર ફોટા અને વિડિઓઝ સહિત તમારા ડેટાની અ‍ૅક્સેસ આપીએ?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"ફરીથી પૂછશો નહીં"</string>
<string name="allow" msgid="7225948811296386551">"મંજૂરી આપો"</string>
<string name="deny" msgid="2081879885755434506">"નકારો"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> પસંદ કરી</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> પસંદ કરી</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> આઇટમ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> આઇટમ</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ને કાઢી નાખીએ?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ફોલ્ડર અને તેની સામગ્રીઓને કાઢી નાખીએ?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલ કાઢી નાખીએ?</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલ કાઢી નાખીએ?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ફોલ્ડર અને તેમની સામગ્રીઓ કાઢી નાખીએ?</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ફોલ્ડર અને તેમની સામગ્રીઓ કાઢી નાખીએ?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> આઇટમ કાઢી નાખીએ?</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> આઇટમ કાઢી નાખીએ?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-hi/config.xml b/packages/DocumentsUI/res/values-hi/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-hi/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-hi/strings.xml b/packages/DocumentsUI/res/values-hi/strings.xml
index a6eeb9ff183b..da69875ef02a 100644
--- a/packages/DocumentsUI/res/values-hi/strings.xml
+++ b/packages/DocumentsUI/res/values-hi/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"दस्तावेज़"</string>
- <string name="files_label" msgid="6051402950202690279">"फ़ाइलें"</string>
<string name="downloads_label" msgid="959113951084633612">"डाउनलोड"</string>
<string name="title_open" msgid="4353228937663917801">"यहां से खोलें"</string>
<string name="title_save" msgid="2433679664882857999">"यहां सहेजें"</string>
@@ -35,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"इनकी कॉपी बनाएं..."</string>
<string name="menu_move" msgid="1828090633118079817">"इसमें ले जाएं…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"नई विंडो"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"काटें"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"कॉपी करें"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"चिपकाएं"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"आंतरिक मेमोरी दिखाएं"</string>
@@ -53,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"रूट छिपाएं"</string>
<string name="save_error" msgid="6167009778003223664">"दस्तावेज़ सहेजने में विफल रहा"</string>
<string name="create_error" msgid="3735649141335444215">"फ़ोल्डर बनाने में विफल"</string>
- <string name="query_error" msgid="1222448261663503501">"दस्तावेजों के लिए क्वेरी करने में विफल रहा"</string>
+ <string name="query_error" msgid="5999895349602476581">"इस समय सामग्री लोड नहीं की जा सकती"</string>
<string name="root_recent" msgid="4470053704320518133">"हाल ही के"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> खाली"</string>
<string name="root_type_service" msgid="2178854894416775409">"मेमोरी सेवाएं"</string>
@@ -62,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"अधिक ऐप्स"</string>
<string name="empty" msgid="7858882803708117596">"कोई आइटम नहीं"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s में कोई मिलान नहीं मिला"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"फ़ाइल नहीं खोली जा सकती"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"फ़ाइल नहीं खोली जा सकती"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"कुछ दस्तावेज़ों को हटाने में अक्षम"</string>
<string name="share_via" msgid="8966594246261344259">"इसके द्वारा साझा करें"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"फ़ाइलें कॉपी हो रही हैं"</string>
<string name="move_notification_title" msgid="6193835179777284805">"फाइलें ले जाई जा रही हैं"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"फ़ाइलें हटाई जा रही हैं"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> शेष"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें कॉपी की जा रही हैं.</item>
@@ -84,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"कॉपी करने की तैयारी हो रही है…"</string>
<string name="move_preparing" msgid="2772219441375531410">"ले जाने की तैयारी हो रही है…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"हटाने के लिए तैयार हो रहा है…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <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>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलों को कॉपी नहीं किया जा सका</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलों को कॉपी नहीं किया जा सका</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें नहीं ले जाई जा सकीं</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें नहीं ले जाई जा सकीं</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें हटाई नहीं जा सकीं</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें हटाई नहीं जा सकीं</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"विवरणों को देखने के लिए टैप करें"</string>
<string name="close" msgid="3043722427445528732">"बंद करें"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"इन फ़ाइलों की कॉपी नहीं बनाई गई: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"ये फ़ाइलें नहीं ले जाई गईं: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"इन फ़ाइलों की कॉपी नहीं बनाई गई: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"ये फ़ाइलें नहीं ले जाई गईं: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"इन फ़ाइलों को हटाया नहीं गया: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"ये फ़ाइलें किसी अन्‍य प्रारूप में रूपांतरित हो गई थीं: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one">क्‍लिपबोर्ड पर <xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलों की कॉपी बनाई गई.</item>
@@ -108,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"चयनित फ़ाइलों को इस स्‍थान में नहीं चिपकाया जा सकता."</string>
<string name="menu_rename" msgid="7678802479104285353">"नाम बदलें"</string>
<string name="rename_error" msgid="4203041674883412606">"दस्‍तावेज़ का नाम बदलना विफल रहा"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"निकालें"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"कुछ फ़ाइलें रूपांतरित हो गई थीं"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> को <xliff:g id="STORAGE"><i>^3</i></xliff:g> पर <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिका का एक्सेस दें?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> को <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिका का एक्सेस प्रदान करें?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> को <xliff:g id="STORAGE"><i>^2</i></xliff:g> पर मौजूद फ़ोटो और वीडियो सहित, अपने डेटा का एक्सेस प्रदान करें?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"फिर से ना पूछें"</string>
<string name="allow" msgid="7225948811296386551">"अनुमति दें"</string>
<string name="deny" msgid="2081879885755434506">"अस्वीकारें"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> चयनित</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> चयनित</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> आइटम</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> आइटम</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" को हटाएं?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" फ़ोल्डर और उसकी सामग्रियां हटाएं?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें हटाएं?</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें हटाएं?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ोल्डर और उनकी सामग्री हटाएं?</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ोल्डर और उनकी सामग्री हटाएं?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> आइटम हटाएं?</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> आइटम हटाएं?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-hr/config.xml b/packages/DocumentsUI/res/values-hr/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-hr/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-hr/strings.xml b/packages/DocumentsUI/res/values-hr/strings.xml
index 888cf32e3176..030fedb1dcd2 100644
--- a/packages/DocumentsUI/res/values-hr/strings.xml
+++ b/packages/DocumentsUI/res/values-hr/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenti"</string>
- <string name="files_label" msgid="6051402950202690279">"Datoteke"</string>
<string name="downloads_label" msgid="959113951084633612">"Preuzimanja"</string>
<string name="title_open" msgid="4353228937663917801">"Otvori iz"</string>
<string name="title_save" msgid="2433679664882857999">"Spremi u"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Prikaz popisa"</string>
<string name="menu_sort" msgid="7677740407158414452">"Poredano po"</string>
<string name="menu_search" msgid="3816712084502856974">"Pretraživanje"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Postavke pohrane"</string>
<string name="menu_open" msgid="432922957274920903">"Otvaranje"</string>
<string name="menu_save" msgid="2394743337684426338">"Spremi"</string>
<string name="menu_share" msgid="3075149983979628146">"Dijeli"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Kopiraj u…"</string>
<string name="menu_move" msgid="1828090633118079817">"Premjesti u…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Novi prozor"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Izreži"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopiraj"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Zalijepi"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Pokaži internu pohranu"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Sakrij korijene"</string>
<string name="save_error" msgid="6167009778003223664">"Nije uspjelo spremanje dokumenta"</string>
<string name="create_error" msgid="3735649141335444215">"Izrada mape nije uspjela"</string>
- <string name="query_error" msgid="1222448261663503501">"Traženje dokumenata nije uspjelo"</string>
+ <string name="query_error" msgid="5999895349602476581">"Sadržaj se trenutačno ne može učitati"</string>
<string name="root_recent" msgid="4470053704320518133">"Nedavno"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> besplatno"</string>
<string name="root_type_service" msgid="2178854894416775409">"Usluge pohrane"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Više aplikacija"</string>
<string name="empty" msgid="7858882803708117596">"Nema stavki"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s ne sadrži podudaranja"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Datoteku nije moguće otvoriti"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Datoteka se ne može otvoriti"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Nije moguće izbrisati neke dokumente"</string>
<string name="share_via" msgid="8966594246261344259">"Dijeli putem"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopiranje datoteka"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Premještanje datoteka"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Brisanje datoteka"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Još <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Kopiranje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke.</item>
@@ -88,25 +88,27 @@
<string name="copy_preparing" msgid="3896202461003039386">"Priprema za kopiranje…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Priprema za premještanje…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Priprema za brisanje…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteka nije kopirana</item>
<item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteke nisu kopirane</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteka nije kopirano</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteka nije premještena</item>
<item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteke nisu premještene</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteka nije premješteno</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteka nije izbrisana</item>
<item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteke nisu izbrisane</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteka nije izbrisano</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Dodirnite da biste vidjeli pojedinosti"</string>
<string name="close" msgid="3043722427445528732">"Zatvori"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Ove datoteke nisu kopirane: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Ove datoteke nisu premještene: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Ove datoteke nisu kopirane: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Ove datoteke nisu premještene: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Ove datoteke nisu izbrisane: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Ove su datoteke konvertirane u neki drugi format: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteka kopirana je u međuspremnik.</item>
@@ -116,7 +118,39 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Nije moguće zalijepiti odabrane datoteke na ovu lokaciju."</string>
<string name="menu_rename" msgid="7678802479104285353">"Promijeni naziv"</string>
<string name="rename_error" msgid="4203041674883412606">"Naziv dokumenta nije promijenjen"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Izbaci"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Neke su datoteke konvertirane"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Želite li aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> odobriti pristup direktoriju <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> na pohrani <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Želite li aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> odobriti da pristupa direktoriju <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Želite li aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> dopustiti pristup podacima, uključujući fotografije i videozapise na vanjskoj pohrani (<xliff:g id="STORAGE"><i>^2</i></xliff:g>)?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Više me ne pitaj"</string>
<string name="allow" msgid="7225948811296386551">"Dopusti"</string>
<string name="deny" msgid="2081879885755434506">"Odbij"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one">Odabrano: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="few">Odabrano: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">Odabrano: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> stavka</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> stavke</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> stavki</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Želite li izbrisati datoteku \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Želite li izbrisati mapu \"<xliff:g id="NAME">%1$s</xliff:g>\" i njezin sadržaj?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one">Želite li izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> datoteku?</item>
+ <item quantity="few">Želite li izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke?</item>
+ <item quantity="other">Želite li izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one">Želite li izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> mapu i njihov sadržaj?</item>
+ <item quantity="few">Želite li izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> mape i njihov sadržaj?</item>
+ <item quantity="other">Želite li izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> mapa i njihov sadržaj?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one">Želite li izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> stavku?</item>
+ <item quantity="few">Želite li izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> stavke?</item>
+ <item quantity="other">Želite li izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> stavki?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-hu/config.xml b/packages/DocumentsUI/res/values-hu/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-hu/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-hu/strings.xml b/packages/DocumentsUI/res/values-hu/strings.xml
index 910eb0c1d09e..2224592c34bb 100644
--- a/packages/DocumentsUI/res/values-hu/strings.xml
+++ b/packages/DocumentsUI/res/values-hu/strings.xml
@@ -17,17 +17,15 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumentumok"</string>
- <string name="files_label" msgid="6051402950202690279">"Fájlok"</string>
<string name="downloads_label" msgid="959113951084633612">"Letöltések"</string>
<string name="title_open" msgid="4353228937663917801">"Megnyitás innen"</string>
<string name="title_save" msgid="2433679664882857999">"Mentés ide"</string>
<string name="menu_create_dir" msgid="2547620241173881754">"Új mappa"</string>
<string name="menu_grid" msgid="6878021334497835259">"Rács"</string>
<string name="menu_list" msgid="7279285939892417279">"Lista"</string>
- <string name="menu_sort" msgid="7677740407158414452">"Rendezés"</string>
+ <string name="menu_sort" msgid="7677740407158414452">"Rendezés alapja"</string>
<string name="menu_search" msgid="3816712084502856974">"Keresés"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Tárolóhely beállításai"</string>
<string name="menu_open" msgid="432922957274920903">"Megnyitás"</string>
<string name="menu_save" msgid="2394743337684426338">"Mentés"</string>
<string name="menu_share" msgid="3075149983979628146">"Megosztás"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Másolás ide…"</string>
<string name="menu_move" msgid="1828090633118079817">"Áthelyezés…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Új ablak"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Kivágás"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Másolás"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Beillesztés"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Belső tárhely"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Gyökérszint elrejtése"</string>
<string name="save_error" msgid="6167009778003223664">"Nem sikerült menteni a dokumentumot"</string>
<string name="create_error" msgid="3735649141335444215">"Nem sikerült létrehozni a mappát"</string>
- <string name="query_error" msgid="1222448261663503501">"A dokumentumok lekérése nem sikerült"</string>
+ <string name="query_error" msgid="5999895349602476581">"Jelenleg nem lehet tartalmat betölteni"</string>
<string name="root_recent" msgid="4470053704320518133">"Legutóbbiak"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> szabad"</string>
<string name="root_type_service" msgid="2178854894416775409">"Tárhelyszolgáltatások"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"További alkalmazások"</string>
<string name="empty" msgid="7858882803708117596">"Nincsenek elemek"</string>
<string name="no_results" msgid="6622510343880730446">"Nincs találat itt: %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"A fájlt nem lehet megnyitni"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"A fájlt nem lehet megnyitni"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Néhány dokumentumot nem lehet törölni"</string>
<string name="share_via" msgid="8966594246261344259">"Megosztás itt:"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Fájlok másolása"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Fájlok áthelyezése"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Fájlok törlése"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> van hátra"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fájl másolása.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Felkészülés a másolásra…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Áthelyezés előkészítése…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Törlés előkészítése…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fájlt nem sikerült átmásolni</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fájlt nem sikerült átmásolni</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="other">Nem sikerült áthelyezni <xliff:g id="COUNT_1">%1$d</xliff:g> fájlt</item>
- <item quantity="one">Nem sikerült áthelyezni <xliff:g id="COUNT_0">%1$d</xliff:g> fájlt</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fájlt nem sikerült áthelyezni</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fájlt nem sikerült áthelyezni</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fájlt nem sikerült törölni</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fájlt nem sikerült törölni</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Koppintson rá a részletek megtekintéséhez"</string>
<string name="close" msgid="3043722427445528732">"Bezárás"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"A következő fájlokat nem sikerült átmásolni: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"A következő fájlok nem lettek áthelyezve: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"A következő fájlokat nem sikerült átmásolni: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"A következő fájlokat nem sikerült áthelyezni: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"A következő fájlokat nem sikerült törölni: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"A következő fájlokat a rendszer más formátumba konvertálta: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> fájl vágólapra másolva.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"A kijelölt fájlokat nem lehet beilleszteni erre a helyre."</string>
<string name="menu_rename" msgid="7678802479104285353">"Átnevezés"</string>
<string name="rename_error" msgid="4203041674883412606">"Nem sikerült átnevezni a dokumentumot"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Kiadás"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Egyes fájlokat konvertált a rendszer"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Hozzáférést biztosít a(z) <xliff:g id="APPNAME"><b>^1</b></xliff:g> számára a(z) <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> könyvtárhoz itt: <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Hozzáférést biztosít a(z) <xliff:g id="APPNAME"><b>^1</b></xliff:g> alkalmazásnak a(z) <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> könyvtárhoz?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Hozzáférést biztosít a(z) <xliff:g id="APPNAME"><b>^1</b></xliff:g> számára az Ön adataihoz, beleértve a következő tárhelyen található képekhez és videókhoz: <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Ne jelenjen meg többé"</string>
<string name="allow" msgid="7225948811296386551">"Engedélyezés"</string>
<string name="deny" msgid="2081879885755434506">"Elutasítás"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> kiválasztva</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> kiválasztva</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elem</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elem</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Törli a következőt: „<xliff:g id="NAME">%1$s</xliff:g>”?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Törli „<xliff:g id="NAME">%1$s</xliff:g>” mappát a tartalmával együtt?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">Töröl <xliff:g id="COUNT_1">%1$d</xliff:g> fájlt?</item>
+ <item quantity="one">Töröl <xliff:g id="COUNT_0">%1$d</xliff:g> fájlt?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">Töröl <xliff:g id="COUNT_1">%1$d</xliff:g> mappát a tartalmukkal együtt?</item>
+ <item quantity="one">Töröl <xliff:g id="COUNT_0">%1$d</xliff:g> mappát a tartalmával együtt?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other">Töröl <xliff:g id="COUNT_1">%1$d</xliff:g> elemet?</item>
+ <item quantity="one">Töröl <xliff:g id="COUNT_0">%1$d</xliff:g> elemet?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-hy-rAM/config.xml b/packages/DocumentsUI/res/values-hy-rAM/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-hy-rAM/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-hy-rAM/strings.xml b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
index 1471a6af8740..5d63784057a7 100644
--- a/packages/DocumentsUI/res/values-hy-rAM/strings.xml
+++ b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Փաստաթղթեր"</string>
- <string name="files_label" msgid="6051402950202690279">"Ֆայլեր"</string>
<string name="downloads_label" msgid="959113951084633612">"Ներբեռնումներ"</string>
<string name="title_open" msgid="4353228937663917801">"Բացել այստեղից"</string>
<string name="title_save" msgid="2433679664882857999">"Պահել այստեղ"</string>
@@ -26,16 +25,16 @@
<string name="menu_list" msgid="7279285939892417279">"Ցուցակի տեսք"</string>
<string name="menu_sort" msgid="7677740407158414452">"Դասավորել ըստ"</string>
<string name="menu_search" msgid="3816712084502856974">"Որոնել"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Հիշասարքի կարգավորումներ"</string>
<string name="menu_open" msgid="432922957274920903">"Բացել"</string>
<string name="menu_save" msgid="2394743337684426338">"Պահել"</string>
<string name="menu_share" msgid="3075149983979628146">"Կիսվել"</string>
<string name="menu_delete" msgid="8138799623850614177">"Ջնջել"</string>
<string name="menu_select_all" msgid="8323579667348729928">"Ընտրել բոլորը"</string>
<string name="menu_copy" msgid="3612326052677229148">"Պատճենել…"</string>
- <string name="menu_move" msgid="1828090633118079817">"Տեղափոխում դեպի…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Տեղափոխել…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Նոր պատուհան"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Կտրել"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Պատճենել"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Տեղադրել"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Ցույց տալ ներքին պահոցը"</string>
@@ -54,20 +53,21 @@
<string name="drawer_close" msgid="7602734368552123318">"Թաքցնել արմատները"</string>
<string name="save_error" msgid="6167009778003223664">"Չհաջողվեց պահել փաստաթուղթը"</string>
<string name="create_error" msgid="3735649141335444215">"Չհաջողվեց ստեղծել պանակը"</string>
- <string name="query_error" msgid="1222448261663503501">"Փաստաթղթերին հարցում կատարելիս սխալ տեղի ունեցավ"</string>
+ <string name="query_error" msgid="5999895349602476581">"Այս պահին հնարավոր չէ բեռնել բովանդակությունը"</string>
<string name="root_recent" msgid="4470053704320518133">"Վերջին"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ազատ է"</string>
<string name="root_type_service" msgid="2178854894416775409">"Պահուստի ծառայություններ"</string>
<string name="root_type_shortcut" msgid="3318760609471618093">"Դյուրանցումներ"</string>
<string name="root_type_device" msgid="7121342474653483538">"Սարքեր"</string>
<string name="root_type_apps" msgid="8838065367985945189">"Հավելյալ ծրագրեր"</string>
- <string name="empty" msgid="7858882803708117596">"Տարրեր չկան"</string>
+ <string name="empty" msgid="7858882803708117596">"Ոչինչ չկա"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s-ում համընկնումներ չկան"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Հնարավոր չէ բացել ֆայլը"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Հնարավոր չէ բացել ֆայլը"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Անհնար է ջնջել որոշ փաստաթղթեր"</string>
- <string name="share_via" msgid="8966594246261344259">"Տարածել"</string>
+ <string name="share_via" msgid="8966594246261344259">"Կիսվել"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Ֆայլերի պատճենում"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Ֆայլերի տեղափոխում"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Ֆայլերը ջնջվում են"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Մնացել է <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլի պատճենում:</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Պատճենման նախապատրաստում…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Տեղափոխման նախապատրաստում…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Պատրաստվում է ջնջել…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="one">Չհաջողվեց պատճենել <xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ</item>
<item quantity="other">Չհաջողվեց պատճենել <xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="one">Չհաջողվեց տեղափոխել <xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ</item>
<item quantity="other">Չհաջողվեց տեղափոխել <xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="one">Չհաջողվեց ջնջել <xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ</item>
<item quantity="other">Չհաջողվեց ջնջել <xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Հպեք՝ մանրամասները դիտելու համար"</string>
<string name="close" msgid="3043722427445528732">"Փակել"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Հետևյալ ֆայլերը չեն պատճենվել՝ <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Հետևյալ ֆայլերը չեն տեղափոխվել՝ <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Հետևյալ ֆայլերը չեն պատճենվել՝ <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Հետևյալ ֆայլերը չեն տեղափոխվել՝ <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Հետևյալ ֆայլերը չեն ջնջվել՝ <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Այս ֆայլերը փոխարկվել են մեկ այլ ձևաչափի՝ <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ պատճենվեց սեղմատախտակին:</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Հնարավոր չէ տեղադրել ընտրված ֆայլերը այս տեղադրությունում:"</string>
<string name="menu_rename" msgid="7678802479104285353">"Վերանվանել"</string>
<string name="rename_error" msgid="4203041674883412606">"Չհաջողվեց վերանվանել փաստաթուղթը"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Անջատել"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Որոշ ֆայլեր փոխարկվել են"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> հավելվածին տրամադրե՞լ <xliff:g id="STORAGE"><i>^3</i></xliff:g>-ի <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> գրացուցակն օգտագործելու թույլտվություն:"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> հավելվածին տրամադրե՞լ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> գրացուցակն օգտագործելու թույլտվություն:"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> հավելվածին տրամադրե՞լ <xliff:g id="STORAGE"><i>^2</i></xliff:g>-ում պահվող ձեր տվյալները, այդ թվում նաև լուսանկարները և տեսանյութերը, օգտագործելու թույլտվություն:"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Այլևս չհարցնել"</string>
<string name="allow" msgid="7225948811296386551">"Թույլատրել"</string>
<string name="deny" msgid="2081879885755434506">"Մերժել"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one">Ընտրված է՝ <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">Ընտրված է՝ <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> տարր</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> տարր</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Ջնջե՞լ «<xliff:g id="NAME">%1$s</xliff:g>» ֆայլը:"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Ջնջե՞լ «<xliff:g id="NAME">%1$s</xliff:g>» պանակը՝ բովանդակության հետ մեկտեղ:"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one">Ջնջե՞լ <xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ:</item>
+ <item quantity="other">Ջնջե՞լ <xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ:</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one">Ջնջե՞լ <xliff:g id="COUNT_1">%1$d</xliff:g> պանակ՝ բովանդակության հետ մեկտեղ:</item>
+ <item quantity="other">Ջնջե՞լ <xliff:g id="COUNT_1">%1$d</xliff:g> պանակ՝ բովանդակության հետ մեկտեղ:</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one">Ջնջե՞լ <xliff:g id="COUNT_1">%1$d</xliff:g> տարր:</item>
+ <item quantity="other">Ջնջե՞լ <xliff:g id="COUNT_1">%1$d</xliff:g> տարր:</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-in/config.xml b/packages/DocumentsUI/res/values-in/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-in/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-in/strings.xml b/packages/DocumentsUI/res/values-in/strings.xml
index 29f118eca4ab..2e8b0ea4045a 100644
--- a/packages/DocumentsUI/res/values-in/strings.xml
+++ b/packages/DocumentsUI/res/values-in/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumen"</string>
- <string name="files_label" msgid="6051402950202690279">"File"</string>
<string name="downloads_label" msgid="959113951084633612">"Unduhan"</string>
<string name="title_open" msgid="4353228937663917801">"Buka dari"</string>
<string name="title_save" msgid="2433679664882857999">"Simpan ke"</string>
@@ -35,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Salin ke…"</string>
<string name="menu_move" msgid="1828090633118079817">"Pindahkan ke..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"Jendela baru"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Potong"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Salin"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Tempel"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Tampilkan simpanan internal"</string>
@@ -53,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Sembunyikan akar"</string>
<string name="save_error" msgid="6167009778003223664">"Gagal menyimpan dokumen"</string>
<string name="create_error" msgid="3735649141335444215">"Gagal membuat folder"</string>
- <string name="query_error" msgid="1222448261663503501">"Gagal mengirim kueri untuk dokumen"</string>
+ <string name="query_error" msgid="5999895349602476581">"Saat ini tidak dapat memuat konten"</string>
<string name="root_recent" msgid="4470053704320518133">"Terkini"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> kosong"</string>
<string name="root_type_service" msgid="2178854894416775409">"Layanan penyimpanan"</string>
@@ -62,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Aplikasi lain"</string>
<string name="empty" msgid="7858882803708117596">"Tidak ada item"</string>
<string name="no_results" msgid="6622510343880730446">"Tidak ada kecocokan dalam %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Tidak dapat membuka file"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Tidak dapat membuka file"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Tidak dapat menghapus beberapa dokumen"</string>
<string name="share_via" msgid="8966594246261344259">"Bagikan melalui"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Menyalin file"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Memindahkan file"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Menghapus file"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> lagi"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Menyalin <xliff:g id="COUNT_1">%1$d</xliff:g> file.</item>
@@ -84,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Menyiapkan salinan..."</string>
<string name="move_preparing" msgid="2772219441375531410">"Menyiapkan pemindahan…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Bersiap menghapus…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other">Tidak dapat menyalin <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
<item quantity="one">Tidak dapat menyalin <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other">Tidak dapat memindahkan <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
<item quantity="one">Tidak dapat memindahkan <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other">Tidak dapat menghapus <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
<item quantity="one">Tidak dapat menghapus <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Ketuk untuk melihat detail"</string>
<string name="close" msgid="3043722427445528732">"Tutup"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Semua file ini tidak disalin: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Semua file ini tidak dipindahkan: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Semua file ini tidak disalin: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Semua file ini tidak dipindahkan: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Semua file ini tidak dihapus: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"File ini dikonversi ke format lain: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> file disalin ke papan klip.</item>
@@ -108,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Tidak dapat menempel file yang dipilih di lokasi ini."</string>
<string name="menu_rename" msgid="7678802479104285353">"Ganti nama"</string>
<string name="rename_error" msgid="4203041674883412606">"Gagal mengganti nama dokumen"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Keluarkan"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Beberapa file dikonversi"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses ke direktori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> di <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses ke direktori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses ke data Anda, termasuk foto dan video, di <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Jangan tanya lagi"</string>
<string name="allow" msgid="7225948811296386551">"Izinkan"</string>
<string name="deny" msgid="2081879885755434506">"Tolak"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dipilih</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dipilih</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> item</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Hapus \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Hapus folder \"<xliff:g id="NAME">%1$s</xliff:g>\" dan kontennya?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">Hapus <xliff:g id="COUNT_1">%1$d</xliff:g> file?</item>
+ <item quantity="one">Hapus <xliff:g id="COUNT_0">%1$d</xliff:g> file?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">Hapus <xliff:g id="COUNT_1">%1$d</xliff:g> folder dan kontennya?</item>
+ <item quantity="one">Hapus <xliff:g id="COUNT_0">%1$d</xliff:g> folder dan kontennya?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other">Hapus <xliff:g id="COUNT_1">%1$d</xliff:g> item?</item>
+ <item quantity="one">Hapus <xliff:g id="COUNT_0">%1$d</xliff:g> item?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-is-rIS/config.xml b/packages/DocumentsUI/res/values-is-rIS/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-is-rIS/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-is-rIS/strings.xml b/packages/DocumentsUI/res/values-is-rIS/strings.xml
index c95189debb07..0cb838783727 100644
--- a/packages/DocumentsUI/res/values-is-rIS/strings.xml
+++ b/packages/DocumentsUI/res/values-is-rIS/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Skjöl"</string>
- <string name="files_label" msgid="6051402950202690279">"Skrár"</string>
<string name="downloads_label" msgid="959113951084633612">"Niðurhal"</string>
<string name="title_open" msgid="4353228937663917801">"Opna frá"</string>
<string name="title_save" msgid="2433679664882857999">"Vista í"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Listayfirlit"</string>
<string name="menu_sort" msgid="7677740407158414452">"Raða eftir"</string>
<string name="menu_search" msgid="3816712084502856974">"Leita"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Geymslustillingar"</string>
<string name="menu_open" msgid="432922957274920903">"Opna"</string>
<string name="menu_save" msgid="2394743337684426338">"Vista"</string>
<string name="menu_share" msgid="3075149983979628146">"Deila"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Afrita í ..."</string>
<string name="menu_move" msgid="1828090633118079817">"Færa í…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Nýr gluggi"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Klippa"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Afrita"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Líma"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Sýna innbyggða geymslu"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Fela rótarsöfn"</string>
<string name="save_error" msgid="6167009778003223664">"Mistókst að vista skjalið"</string>
<string name="create_error" msgid="3735649141335444215">"Mistókst að búa til möppu"</string>
- <string name="query_error" msgid="1222448261663503501">"Mistókst að senda skjalafyrirspurn"</string>
+ <string name="query_error" msgid="5999895349602476581">"Ekki hægt að hlaða efni í augnablikinu"</string>
<string name="root_recent" msgid="4470053704320518133">"Nýlegt"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> laus"</string>
<string name="root_type_service" msgid="2178854894416775409">"Geymsluþjónusta"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Fleiri forrit"</string>
<string name="empty" msgid="7858882803708117596">"Engin atriði"</string>
<string name="no_results" msgid="6622510343880730446">"Engar samsvarandi niðurstöður í %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Ekki er hægt að opna skrána"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Ekki hægt að opna skrá"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Ekki er hægt að eyða einhverjum skjölum"</string>
<string name="share_via" msgid="8966594246261344259">"Deila í gegnum"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Afritar skrár"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Skrár færðar"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Eyðir skrám"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> eftir"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Afritar <xliff:g id="COUNT_1">%1$d</xliff:g> skrá.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Undirbúningur fyrir afritun…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Flutningur undirbúinn…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Býr sig undir að eyða…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <item quantity="one">Ekki var hægt að afrita <xliff:g id="COUNT_1">%1$d</xliff:g> skrá</item>
- <item quantity="other">Ekki var hægt að afrita <xliff:g id="COUNT_1">%1$d</xliff:g> skrár</item>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="one">Ekki tókst að afrita <xliff:g id="COUNT_1">%1$d</xliff:g> skrá</item>
+ <item quantity="other">Ekki tókst að afrita <xliff:g id="COUNT_1">%1$d</xliff:g> skrár</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="one">Ekki tókst að færa <xliff:g id="COUNT_1">%1$d</xliff:g> skrá</item>
<item quantity="other">Ekki tókst að færa <xliff:g id="COUNT_1">%1$d</xliff:g> skrár</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="one">Ekki tókst að eyða <xliff:g id="COUNT_1">%1$d</xliff:g> skrá</item>
<item quantity="other">Ekki tókst að eyða <xliff:g id="COUNT_1">%1$d</xliff:g> skrám</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Ýttu til að skoða frekari upplýsingar"</string>
<string name="close" msgid="3043722427445528732">"Loka"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Þessar skrár voru ekki afritaðar: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Þessar skrár voru ekki færðar: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Þessar skrár voru ekki afritaðar: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Þessar skrár voru ekki færðar: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Þessum skrám var ekki eytt: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Þessum skrám var umbreytt yfir á annað snið: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> skrá afrituð á klippiborð.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Ekki er hægt að vista valdar skrár á þessum stað."</string>
<string name="menu_rename" msgid="7678802479104285353">"Endurnefna"</string>
<string name="rename_error" msgid="4203041674883412606">"Ekki tókst að endurnefna skjalið"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Fjarlægja"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Sumum skrám var umbreytt"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Veita <xliff:g id="APPNAME"><b>^1</b></xliff:g> aðgang að skráasafninu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> á <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Viltu veita <xliff:g id="APPNAME"><b>^1</b></xliff:g> aðgang að skráasafninu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Veita <xliff:g id="APPNAME"><b>^1</b></xliff:g> aðgang að gögnunum þínum, þar á meðal myndum og myndskeiðum, á <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Ekki spyrja aftur"</string>
<string name="allow" msgid="7225948811296386551">"Leyfa"</string>
<string name="deny" msgid="2081879885755434506">"Hafna"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> valið</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> valin</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> atriði</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> atriði</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Eyða „<xliff:g id="NAME">%1$s</xliff:g>“?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Eyða möppunni „<xliff:g id="NAME">%1$s</xliff:g>“ og öllu innihaldi hennar?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one">Eyða <xliff:g id="COUNT_1">%1$d</xliff:g> skrá?</item>
+ <item quantity="other">Eyða <xliff:g id="COUNT_1">%1$d</xliff:g> skrám?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one">Eyða <xliff:g id="COUNT_1">%1$d</xliff:g> möppu og innihaldi þeirra?</item>
+ <item quantity="other">Eyða <xliff:g id="COUNT_1">%1$d</xliff:g> möppum og innihaldi þeirra?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one">Eyða <xliff:g id="COUNT_1">%1$d</xliff:g> atriði?</item>
+ <item quantity="other">Eyða <xliff:g id="COUNT_1">%1$d</xliff:g> atriðum?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-it/config.xml b/packages/DocumentsUI/res/values-it/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-it/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-it/strings.xml b/packages/DocumentsUI/res/values-it/strings.xml
index 276c9371e31c..eb06d5f71b7c 100644
--- a/packages/DocumentsUI/res/values-it/strings.xml
+++ b/packages/DocumentsUI/res/values-it/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documenti"</string>
- <string name="files_label" msgid="6051402950202690279">"File"</string>
<string name="downloads_label" msgid="959113951084633612">"Download"</string>
<string name="title_open" msgid="4353228937663917801">"Apri da"</string>
<string name="title_save" msgid="2433679664882857999">"Salva in"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Visualizzazione elenco"</string>
<string name="menu_sort" msgid="7677740407158414452">"Ordina per"</string>
<string name="menu_search" msgid="3816712084502856974">"Cerca"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Impostazioni memoria"</string>
<string name="menu_open" msgid="432922957274920903">"Apri"</string>
<string name="menu_save" msgid="2394743337684426338">"Salva"</string>
<string name="menu_share" msgid="3075149983979628146">"Condividi"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Copia in…"</string>
<string name="menu_move" msgid="1828090633118079817">"Sposta in..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"Nuova finestra"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Taglia"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copia"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Incolla"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Mostra memoria interna"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Nascondi nodi principali"</string>
<string name="save_error" msgid="6167009778003223664">"Impossibile salvare il documento"</string>
<string name="create_error" msgid="3735649141335444215">"Impossibile creare la cartella"</string>
- <string name="query_error" msgid="1222448261663503501">"Impossibile chiedere documenti"</string>
+ <string name="query_error" msgid="5999895349602476581">"Impossibile caricare i contenuti al momento"</string>
<string name="root_recent" msgid="4470053704320518133">"Recenti"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> liberi"</string>
<string name="root_type_service" msgid="2178854894416775409">"Servizi di archiviazione"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Altre app"</string>
<string name="empty" msgid="7858882803708117596">"Nessun elemento"</string>
<string name="no_results" msgid="6622510343880730446">"Nessuna corrispondenza in %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Impossibile aprire il file"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Impossibile aprire il file"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Impossibile eliminare alcuni documenti"</string>
<string name="share_via" msgid="8966594246261344259">"Condividi via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Copia di file in corso"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Spostamento di file"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Eliminazione dei file"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> rimanenti"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Copia di <xliff:g id="COUNT_1">%1$d</xliff:g> file in corso.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Preparazione alla copia…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Preparazione dello spostamento…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Preparazione eliminazione…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other">Impossibile copiare <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
<item quantity="one">Impossibile copiare <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other">Impossibile spostare <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
<item quantity="one">Impossibile spostare <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other">Impossibile eliminare <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
<item quantity="one">Impossibile eliminare <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Tocca per vedere i dettagli"</string>
<string name="close" msgid="3043722427445528732">"Chiudi"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"I seguenti file non sono stati copiati: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"I seguenti file non sono stati spostati: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"I seguenti file non sono stati copiati: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"I seguenti file non sono stati spostati: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"I seguenti file non sono stati eliminati: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"I file sono stati convertiti in un altro formato: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> file copiati negli appunti.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Impossibile incollare i file selezionati in questa posizione."</string>
<string name="menu_rename" msgid="7678802479104285353">"Rinomina"</string>
<string name="rename_error" msgid="4203041674883412606">"Ridenominazione documento non riuscita"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Espelli"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Alcuni file sono stati convertiti"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Concedere all\'app <xliff:g id="APPNAME"><b>^1</b></xliff:g> l\'accesso alla directory <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> su <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Concedere all\'app <xliff:g id="APPNAME"><b>^1</b></xliff:g> l\'accesso alla directory <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Concedere all\'app <xliff:g id="APPNAME"><b>^1</b></xliff:g> l\'accesso ai tuoi dati, inclusi video e foto, sull\'unità <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Non chiedermelo più"</string>
<string name="allow" msgid="7225948811296386551">"Consenti"</string>
<string name="deny" msgid="2081879885755434506">"Nega"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> file selezionati</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> file selezionato</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementi</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elemento</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Eliminare \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Eliminare la cartella \"<xliff:g id="NAME">%1$s</xliff:g>\" e i relativi contenuti?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">Eliminare <xliff:g id="COUNT_1">%1$d</xliff:g> file?</item>
+ <item quantity="one">Eliminare <xliff:g id="COUNT_0">%1$d</xliff:g> file?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">Eliminare <xliff:g id="COUNT_1">%1$d</xliff:g> cartelle e i relativi contenuti?</item>
+ <item quantity="one">Eliminare <xliff:g id="COUNT_0">%1$d</xliff:g> cartella e i relativi contenuti?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other">Eliminare <xliff:g id="COUNT_1">%1$d</xliff:g> elementi?</item>
+ <item quantity="one">Eliminare <xliff:g id="COUNT_0">%1$d</xliff:g> elemento?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-iw/config.xml b/packages/DocumentsUI/res/values-iw/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-iw/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-iw/strings.xml b/packages/DocumentsUI/res/values-iw/strings.xml
index 4fc561791c8b..2d81be7425ba 100644
--- a/packages/DocumentsUI/res/values-iw/strings.xml
+++ b/packages/DocumentsUI/res/values-iw/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"מסמכים"</string>
- <string name="files_label" msgid="6051402950202690279">"קבצים"</string>
<string name="downloads_label" msgid="959113951084633612">"הורדות"</string>
<string name="title_open" msgid="4353228937663917801">"פתח מ-"</string>
<string name="title_save" msgid="2433679664882857999">"שמור ב-"</string>
@@ -26,16 +25,16 @@
<string name="menu_list" msgid="7279285939892417279">"תצוגת רשימה"</string>
<string name="menu_sort" msgid="7677740407158414452">"מיין לפי"</string>
<string name="menu_search" msgid="3816712084502856974">"חפש"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"הגדרות אחסון"</string>
<string name="menu_open" msgid="432922957274920903">"פתח"</string>
<string name="menu_save" msgid="2394743337684426338">"שמור"</string>
<string name="menu_share" msgid="3075149983979628146">"שתף"</string>
<string name="menu_delete" msgid="8138799623850614177">"מחק"</string>
<string name="menu_select_all" msgid="8323579667348729928">"בחר הכל"</string>
<string name="menu_copy" msgid="3612326052677229148">"העתק אל…"</string>
- <string name="menu_move" msgid="1828090633118079817">"העברה אל…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"העבר אל…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"חלון חדש"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"גזור"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"העתק"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"הדבק"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"הצג אחסון פנימי"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"הסתר שורשים"</string>
<string name="save_error" msgid="6167009778003223664">"שמירת המסמך נכשלה"</string>
<string name="create_error" msgid="3735649141335444215">"יצירת התיקיה נכשלה"</string>
- <string name="query_error" msgid="1222448261663503501">"שאילתת המסמכים נכשלה"</string>
+ <string name="query_error" msgid="5999895349602476581">"לא ניתן כרגע לטעון תוכן"</string>
<string name="root_recent" msgid="4470053704320518133">"מהזמן האחרון"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> של שטח פנוי"</string>
<string name="root_type_service" msgid="2178854894416775409">"שירותי אחסון"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"עוד אפליקציות"</string>
<string name="empty" msgid="7858882803708117596">"אין פריטים"</string>
<string name="no_results" msgid="6622510343880730446">"‏אין התאמות ב-%1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"לא ניתן לפתוח את הקובץ"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"לא ניתן לפתוח את הקובץ"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"לא ניתן למחוק חלק מהמסמכים"</string>
<string name="share_via" msgid="8966594246261344259">"שתף באמצעות"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"מעתיק קבצים"</string>
<string name="move_notification_title" msgid="6193835179777284805">"מעביר קבצים"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"מחיקת קבצים מתבצעת"</string>
<string name="copy_remaining" msgid="6283790937387975095">"זמן נותר: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="two">מעתיק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים.</item>
@@ -91,28 +91,30 @@
<string name="copy_preparing" msgid="3896202461003039386">"מתכונן להעתקה..."</string>
<string name="move_preparing" msgid="2772219441375531410">"מתכונן להעברה…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"מתכונן למחיקה…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="two">לא ניתן היה להעתיק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
<item quantity="many">לא ניתן היה להעתיק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
<item quantity="other">לא ניתן היה להעתיק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
- <item quantity="one">לא ניתן היה להעתיק קובץ <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ <item quantity="one">לא ניתן היה להעתיק <xliff:g id="COUNT_0">%1$d</xliff:g> קובץ</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="two">לא ניתן היה להעביר <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
<item quantity="many">לא ניתן היה להעביר <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
<item quantity="other">לא ניתן היה להעביר <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
- <item quantity="one">לא ניתן היה להעביר קובץ <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ <item quantity="one">לא ניתן היה להעביר <xliff:g id="COUNT_0">%1$d</xliff:g> קובץ</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="two">לא ניתן היה למחוק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
<item quantity="many">לא ניתן היה למחוק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
<item quantity="other">לא ניתן היה למחוק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
- <item quantity="one">לא ניתן היה למחוק קובץ <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ <item quantity="one">לא ניתן היה למחוק <xliff:g id="COUNT_0">%1$d</xliff:g> קובץ</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"הקש כדי להציג פרטים"</string>
<string name="close" msgid="3043722427445528732">"סגור"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"הקבצים הבאים לא הועתקו: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"הקבצים הבאים לא הועברו: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"הקבצים הבאים לא הועתקו: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"הקבצים הבאים לא הועברו: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"הקבצים הבאים לא נמחקו: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"הקבצים האלה הומרו לפורמט אחר: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="two"><xliff:g id="COUNT_1">%1$d</xliff:g> קבצים הועתקו אל הלוח.</item>
@@ -123,7 +125,44 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"לא ניתן להדביק את הקבצים הנבחרים במיקום הזה."</string>
<string name="menu_rename" msgid="7678802479104285353">"שנה שם"</string>
<string name="rename_error" msgid="4203041674883412606">"ניסיון שינוי שם המסמך נכשל"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"הוצא"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"קבצים מסוימים הומרו"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"האם להעניק לאפליקציה <xliff:g id="APPNAME"><b>^1</b></xliff:g> גישה לספריה <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> באחסון <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"האם להעניק לאפליקציה <xliff:g id="APPNAME"><b>^1</b></xliff:g> גישה אל ספריית <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"האם להעניק לאפליקציה <xliff:g id="APPNAME"><b>^1</b></xliff:g> גישה לנתונים שלך, כולל תמונות וסרטונים, השמורים ב<xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"אל תשאל שוב"</string>
<string name="allow" msgid="7225948811296386551">"אפשר"</string>
<string name="deny" msgid="2081879885755434506">"דחה"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="two"><xliff:g id="COUNT_1">%1$d</xliff:g> נבחרו</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> נבחרו</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> נבחרו</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> נבחר</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="two"><xliff:g id="COUNT_1">%1$d</xliff:g> פריטים</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> פריטים</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> פריטים</item>
+ <item quantity="one">פריט <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"האם למחוק את \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"האם למחוק את התיקייה \"<xliff:g id="NAME">%1$s</xliff:g>\" ואת התוכן שלה?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="two">האם למחוק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים?</item>
+ <item quantity="many">האם למחוק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים?</item>
+ <item quantity="other">האם למחוק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים?</item>
+ <item quantity="one">האם למחוק <xliff:g id="COUNT_0">%1$d</xliff:g> קובץ?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="two">האם למחוק <xliff:g id="COUNT_1">%1$d</xliff:g> תיקיות ואת התוכן שלהן?</item>
+ <item quantity="many">האם למחוק <xliff:g id="COUNT_1">%1$d</xliff:g> תיקיות ואת התוכן שלהן?</item>
+ <item quantity="other">האם למחוק <xliff:g id="COUNT_1">%1$d</xliff:g> תיקיות ואת התוכן שלהן?</item>
+ <item quantity="one">האם למחוק <xliff:g id="COUNT_0">%1$d</xliff:g> תיקייה ואת התוכן שלה?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="two">האם למחוק <xliff:g id="COUNT_1">%1$d</xliff:g> פריטים?</item>
+ <item quantity="many">האם למחוק <xliff:g id="COUNT_1">%1$d</xliff:g> פריטים?</item>
+ <item quantity="other">האם למחוק <xliff:g id="COUNT_1">%1$d</xliff:g> פריטים?</item>
+ <item quantity="one">האם למחוק <xliff:g id="COUNT_0">%1$d</xliff:g> פריט?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-ja/config.xml b/packages/DocumentsUI/res/values-ja/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-ja/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-ja/strings.xml b/packages/DocumentsUI/res/values-ja/strings.xml
index 36a35f9ecdaa..200202f260cb 100644
--- a/packages/DocumentsUI/res/values-ja/strings.xml
+++ b/packages/DocumentsUI/res/values-ja/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ドキュメント"</string>
- <string name="files_label" msgid="6051402950202690279">"ファイル"</string>
<string name="downloads_label" msgid="959113951084633612">"ダウンロード"</string>
<string name="title_open" msgid="4353228937663917801">"次から開く:"</string>
<string name="title_save" msgid="2433679664882857999">"次に保存:"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"リスト表示"</string>
<string name="menu_sort" msgid="7677740407158414452">"並べ替え"</string>
<string name="menu_search" msgid="3816712084502856974">"検索"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"ストレージの設定"</string>
<string name="menu_open" msgid="432922957274920903">"開く"</string>
<string name="menu_save" msgid="2394743337684426338">"保存"</string>
<string name="menu_share" msgid="3075149983979628146">"共有"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"コピー…"</string>
<string name="menu_move" msgid="1828090633118079817">"移動..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"新しいウィンドウ"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"切り取り"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"コピー"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"貼り付け"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"内部ストレージを表示"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"ルートを非表示にする"</string>
<string name="save_error" msgid="6167009778003223664">"ドキュメントを保存できませんでした"</string>
<string name="create_error" msgid="3735649141335444215">"フォルダを作成できませんでした"</string>
- <string name="query_error" msgid="1222448261663503501">"ドキュメントのクエリに失敗しました"</string>
+ <string name="query_error" msgid="5999895349602476581">"現在、コンテンツを読み込むことができません"</string>
<string name="root_recent" msgid="4470053704320518133">"最近"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"空き容量: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="root_type_service" msgid="2178854894416775409">"ストレージサービス"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"その他のアプリ"</string>
<string name="empty" msgid="7858882803708117596">"アイテムがありません"</string>
<string name="no_results" msgid="6622510343880730446">"該当するものは %1$s にありません"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"ファイルを開けません"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"ファイルを開けません"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"一部のドキュメントを削除できません"</string>
<string name="share_via" msgid="8966594246261344259">"共有ツール"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"ファイルのコピー中"</string>
<string name="move_notification_title" msgid="6193835179777284805">"ファイルを移動中"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"ファイルを削除しています"</string>
<string name="copy_remaining" msgid="6283790937387975095">"残り<xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>個のファイルをコピーしています。</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"コピーの準備をしています…"</string>
<string name="move_preparing" msgid="2772219441375531410">"移動の準備をしています…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"削除の準備をしています…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <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>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> 個のファイルをコピーできませんでした</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> 個のファイルをコピーできませんでした</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <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 name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> 個のファイルを移動できませんでした</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> 個のファイルを移動できませんでした</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> 個のファイルを削除できませんでした</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> 個のファイルを削除できませんでした</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"タップすると詳細が表示されます"</string>
<string name="close" msgid="3043722427445528732">"閉じる"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"ファイル(<xliff:g id="LIST">%1$s</xliff:g>)をコピーできませんでした"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"ファイル(<xliff:g id="LIST">%1$s</xliff:g>)を移動できませんでした"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"次のファイルをコピーできませんでした: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"次のファイルを移動できませんでした: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"次のファイルを削除できませんでした: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"次のファイルが別の形式に変換されました: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>件のファイルをクリップボードにコピーしました。</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"選択したファイルをこの場所に貼り付けることはできません。"</string>
<string name="menu_rename" msgid="7678802479104285353">"名前を変更"</string>
<string name="rename_error" msgid="4203041674883412606">"ドキュメントの名前を変更できませんでした"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"取り外し"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"一部のファイルが変換されました"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"「<xliff:g id="STORAGE"><i>^3</i></xliff:g>」の「<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>」ディレクトリに「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」へのアクセスを許可しますか?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」アプリに「<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>」ディレクトリへのアクセスを許可しますか?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g>の写真や動画などのデータへのアクセスを「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」に許可しますか?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"今後表示しない"</string>
<string name="allow" msgid="7225948811296386551">"許可"</string>
<string name="deny" msgid="2081879885755434506">"拒否"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> 個を選択中</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> 個を選択中</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> 個のアイテム</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> 個のアイテム</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"「<xliff:g id="NAME">%1$s</xliff:g>」を削除しますか?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"フォルダ「<xliff:g id="NAME">%1$s</xliff:g>」とそのコンテンツを削除しますか?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> 個のファイルを削除しますか?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> 個のファイルを削除しますか?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> 個のフォルダとそのコンテンツを削除しますか?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> 個のフォルダとそのコンテンツを削除しますか?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <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>
</resources>
diff --git a/packages/DocumentsUI/res/values-ka-rGE/config.xml b/packages/DocumentsUI/res/values-ka-rGE/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-ka-rGE/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-ka-rGE/strings.xml b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
index eea482834266..57e565df142b 100644
--- a/packages/DocumentsUI/res/values-ka-rGE/strings.xml
+++ b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"დოკუმენტები"</string>
- <string name="files_label" msgid="6051402950202690279">"ფაილები"</string>
<string name="downloads_label" msgid="959113951084633612">"ჩამოტვირთვები"</string>
<string name="title_open" msgid="4353228937663917801">"გახსნა აქედან:"</string>
<string name="title_save" msgid="2433679664882857999">"შენახვა აქ:"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"სიის ხედი"</string>
<string name="menu_sort" msgid="7677740407158414452">"სორტირება:"</string>
<string name="menu_search" msgid="3816712084502856974">"ძიება"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"საცავის პარამეტრები"</string>
<string name="menu_open" msgid="432922957274920903">"გახსნა"</string>
<string name="menu_save" msgid="2394743337684426338">"შენახვა"</string>
<string name="menu_share" msgid="3075149983979628146">"გაზიარება"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"კოპირება…"</string>
<string name="menu_move" msgid="1828090633118079817">"გადაადგილება..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"ახალი ფანჯარა"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"ამოჭრა"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"კოპირება"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"ჩასმა"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"შიდა საცავის ჩვენება"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"ფესვების დამალვა"</string>
<string name="save_error" msgid="6167009778003223664">"დოკუმენტის შენახვა ვერ მოხერხდა"</string>
<string name="create_error" msgid="3735649141335444215">"საქაღალდის შექმნა ვერ მოხერხდა"</string>
- <string name="query_error" msgid="1222448261663503501">"დოკუმენტებზე მოთხოვნა ვერ გაიგზავნა"</string>
+ <string name="query_error" msgid="5999895349602476581">"კონტენტის ჩატვირთვა ამჟამად ვერ ხერხდება"</string>
<string name="root_recent" msgid="4470053704320518133">"ბოლო"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> თავისუფალია"</string>
<string name="root_type_service" msgid="2178854894416775409">"მეხსიერების სერვისები"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"მეტი აპები"</string>
<string name="empty" msgid="7858882803708117596">"ერთეულები არ არის"</string>
<string name="no_results" msgid="6622510343880730446">"„%1$s“-ში დამთხვევა ვერ მოიძებნა"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"ფაილის გახსნა ვერ ხერხდება"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"ფაილის გახსნა ვერ ხერხდება"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"ზოგიერთი დოკუმენტის წაშლა ვერ ხერხდება"</string>
<string name="share_via" msgid="8966594246261344259">"გაზიარება:"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"მიმდ. ფაილების კოპირება"</string>
<string name="move_notification_title" msgid="6193835179777284805">"ფაილების გადაადგილება"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"ფაილების წაშლა…"</string>
<string name="copy_remaining" msgid="6283790937387975095">"დარჩა <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">მიმდინარეობს <xliff:g id="COUNT_1">%1$d</xliff:g> ფაილის კოპირება.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"მომზადება კოპირებისთვის…"</string>
<string name="move_preparing" msgid="2772219441375531410">"გადაადგილება მზადდება..."</string>
<string name="delete_preparing" msgid="5655813182533491992">"მზადდება წასაშლელად…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <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>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>-დან"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ფაილი ვერ დაკოპირდა</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ფაილი ვერ დაკოპირდა</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ფაილი ვერ გადაადგილდა</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ფაილი ვერ გადაადგილდა</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ფაილი ვერ წაიშალა</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ფაილი ვერ წაიშალა</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"შეეხეთ დეტალების სანახავად"</string>
<string name="close" msgid="3043722427445528732">"დახურვა"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"ეს ფაილები არ იყო გადაწერილი: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"ეს ფაილები ვერ გადაადგილდა: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"შემდეგი ფაილები არ დაკოპირდა: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"შემდეგი ფაილები არ გადაადგილდა: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"შემდეგი ფაილები არ წაიშალა: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"შემდეგი ფაილები გარდაქმნილია სხვა ფორმატში: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">მოხდა <xliff:g id="COUNT_1">%1$d</xliff:g> ფაილის გაცვლის ბუფერში კოპირება.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"ამ მდებარეობაში შერჩეული ფაილების ჩასმა შეუძლებელია."</string>
<string name="menu_rename" msgid="7678802479104285353">"გადარქმევა"</string>
<string name="rename_error" msgid="4203041674883412606">"დოკუმენტის გადარქმევა ვერ მოხერხდა"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"ამოღება"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ზოგიერთი ფაილი გარდაქმნილია"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"გსურთ, <xliff:g id="APPNAME"><b>^1</b></xliff:g> სარგებლობდეს <xliff:g id="STORAGE"><i>^3</i></xliff:g>-ის დირექტორიაზე „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“ წვდომის უფლებით?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"გსურთ, <xliff:g id="APPNAME"><b>^1</b></xliff:g> სარგებლობდეს დირექტორიაზე „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“ წვდომის უფლებით?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"გსურთ, <xliff:g id="APPNAME"><b>^1</b></xliff:g> სარგებლობდეს <xliff:g id="STORAGE"><i>^2</i></xliff:g>-ზე არსებულ მონაცემებზე, მათ შორის, ფოტოებსა და ვიდეოებზე, წვდომის უფლებით?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"აღარ მკითხოთ"</string>
<string name="allow" msgid="7225948811296386551">"უფლების მიცემა"</string>
<string name="deny" msgid="2081879885755434506">"აკრძალვა"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other">არჩეულია <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">არჩეულია <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ერთეული</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ერთეული</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"გსურთ, წაშალოთ „<xliff:g id="NAME">%1$s</xliff:g>“?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"გსურთ, წაშალოთ საქაღალდე „<xliff:g id="NAME">%1$s</xliff:g>“ და მისი შიგთავსი?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">გსურთ <xliff:g id="COUNT_1">%1$d</xliff:g> ფაილის წაშლა?</item>
+ <item quantity="one">გსურთ <xliff:g id="COUNT_0">%1$d</xliff:g> ფაილის წაშლა?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">გსურთ <xliff:g id="COUNT_1">%1$d</xliff:g> საქაღალდისა და მათი შიგთავსის წაშლა?</item>
+ <item quantity="one">გსურთ <xliff:g id="COUNT_0">%1$d</xliff:g> საქაღალდისა და მისი შიგთავსის წაშლა?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <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>
</resources>
diff --git a/packages/DocumentsUI/res/values-kk-rKZ/config.xml b/packages/DocumentsUI/res/values-kk-rKZ/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-kk-rKZ/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-kk-rKZ/strings.xml b/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
index 715db08863fa..d2b89eac96fe 100644
--- a/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
+++ b/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Құжаттар"</string>
- <string name="files_label" msgid="6051402950202690279">"Файлдар"</string>
<string name="downloads_label" msgid="959113951084633612">"Жүктеулер"</string>
<string name="title_open" msgid="4353228937663917801">"Мынадан ашу:"</string>
<string name="title_save" msgid="2433679664882857999">"Сақталатын орны"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Тізім көрінісі"</string>
<string name="menu_sort" msgid="7677740407158414452">"Белгіге қарай сұрыптау"</string>
<string name="menu_search" msgid="3816712084502856974">"Іздеу"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Жад параметрлері"</string>
<string name="menu_open" msgid="432922957274920903">"Ашу"</string>
<string name="menu_save" msgid="2394743337684426338">"Сақтау"</string>
<string name="menu_share" msgid="3075149983979628146">"Бөлісу"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Көшіру орны…"</string>
<string name="menu_move" msgid="1828090633118079817">"Орнын ауыстыру…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Жаңа терезе"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Қиып алу"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Көшіру"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Қою"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Ішкі жадты көрсету"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Тамырын жасыру"</string>
<string name="save_error" msgid="6167009778003223664">"Құжатты сақтау орындалмады"</string>
<string name="create_error" msgid="3735649141335444215">"Қалта жасақтау іске аспады"</string>
- <string name="query_error" msgid="1222448261663503501">"Құжаттарды өтіну орындалмады"</string>
+ <string name="query_error" msgid="5999895349602476581">"Қазір мазмұнды жүктеу мүмкін емес"</string>
<string name="root_recent" msgid="4470053704320518133">"Жуықта қолданылған"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> бос"</string>
<string name="root_type_service" msgid="2178854894416775409">"Жад қызметтері"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Басқа қолданбалар"</string>
<string name="empty" msgid="7858882803708117596">"Бос"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s ішінде сәйкестіктер жоқ"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Файлды аша алмады"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Файлды ашу мүмкін емес"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Кейбір құжаттарды жою мүмкін болмады"</string>
<string name="share_via" msgid="8966594246261344259">"Бөлісу"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Файлдарды көшіру"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Файлдар тасымалдануда"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Файлдар жойылуда"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> қалды"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файлды көшіру.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Көшіруге дайындау…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Тасымалдауға дайындалуда..."</string>
<string name="delete_preparing" msgid="5655813182533491992">"Жоюға дайындалуда…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <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>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файлды көшіру мүмкін болмады</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файлды көшіру мүмкін болмады</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <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 name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файлды жылжыту мүмкін болмады</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файлды жылжыту мүмкін болмады</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файлды жою мүмкін болмады</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файлды жою мүмкін болмады</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Мәліметтерді көру үшін түртіңіз"</string>
<string name="close" msgid="3043722427445528732">"Жабу"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Мына файлдар көшірілген жоқ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Мына файлдар тасымалданған жоқ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Мына файлдар көшірілген жоқ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Мына файлдар жылжытылған жоқ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Келесі файлдар жойылмады: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Мына файлдар басқа пішімге түрлендірілді: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">Аралық сақтағышқа <xliff:g id="COUNT_1">%1$d</xliff:g> файл көшірілді.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Таңдалған файлдарды бұл орынға қою мүмкін емес."</string>
<string name="menu_rename" msgid="7678802479104285353">"Атын өзгерту"</string>
<string name="rename_error" msgid="4203041674883412606">"Құжат қайта аталмады"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Шығару"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Кейбір файлдар түрлендірілді"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> қолданбасына <xliff:g id="STORAGE"><i>^3</i></xliff:g> қоймасындағы <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> каталогына өтуге рұқсат беру керек пе?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> қолданбасына <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> каталогына кіруге рұқсат беру керек пе?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> <xliff:g id="STORAGE"><i>^2</i></xliff:g> қоймасындағы деректерге, соның ішінде фотосуреттерге және бейнелерге кіру мүмкіндігін беру керек пе?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Қайта сұралмасын"</string>
<string name="allow" msgid="7225948811296386551">"Рұқсат беру"</string>
<string name="deny" msgid="2081879885755434506">"Бас тарту"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> таңдалды</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> таңдалды</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> элемент</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> элемент</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" жою керек пе?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" қалтасын және оның мазмұнын жою керек пе?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файлды жою керек пе?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файлды жою керек пе?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> қалтаны ішіндегісімен бірге жою керек пе?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> қалтаны ішіндегісімен бірге жою керек пе?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <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>
</resources>
diff --git a/packages/DocumentsUI/res/values-km-rKH/config.xml b/packages/DocumentsUI/res/values-km-rKH/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-km-rKH/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-km-rKH/strings.xml b/packages/DocumentsUI/res/values-km-rKH/strings.xml
index efa7e889484f..f618c1afbe2d 100644
--- a/packages/DocumentsUI/res/values-km-rKH/strings.xml
+++ b/packages/DocumentsUI/res/values-km-rKH/strings.xml
@@ -17,8 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ឯកសារ"</string>
- <string name="files_label" msgid="6051402950202690279">"ឯកសារ"</string>
- <string name="downloads_label" msgid="959113951084633612">"ដោនឡូត"</string>
+ <string name="downloads_label" msgid="959113951084633612">"ទាញយក"</string>
<string name="title_open" msgid="4353228937663917801">"បើក​ពី"</string>
<string name="title_save" msgid="2433679664882857999">"រក្សា​ទុក​ទៅ"</string>
<string name="menu_create_dir" msgid="2547620241173881754">"ថត​ថ្មី"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"ទិដ្ឋភាព​បញ្ជី"</string>
<string name="menu_sort" msgid="7677740407158414452">"តម្រៀប​តាម"</string>
<string name="menu_search" msgid="3816712084502856974">"ស្វែងរក"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"កំណត់ការផ្ទុក"</string>
<string name="menu_open" msgid="432922957274920903">"បើក"</string>
<string name="menu_save" msgid="2394743337684426338">"រក្សាទុក"</string>
<string name="menu_share" msgid="3075149983979628146">"ចែករំលែក​"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"ថតចម្លងទៅ…"</string>
<string name="menu_move" msgid="1828090633118079817">"ផ្លាស់ទីទៅ៖"</string>
<string name="menu_new_window" msgid="1226032889278727538">"បង្អួចថ្មី"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"កាត់"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"ចម្លង"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"បិទភ្ជាប់"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"បង្ហាញឧបករណ៍ផ្ទុកខាងក្នុង"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"លាក់ roots"</string>
<string name="save_error" msgid="6167009778003223664">"បាន​បរាជ័យ​ក្នុង​ការ​រក្សា​ទុក​ឯកសារ"</string>
<string name="create_error" msgid="3735649141335444215">"បាន​បរាជ័យ​ក្នុង​ការ​បង្កើត​ថត"</string>
- <string name="query_error" msgid="1222448261663503501">"បាន​បរាជ័យ​ក្នុង​ការ​​ច្រោះ​ឯកសារ"</string>
+ <string name="query_error" msgid="5999895349602476581">"មិនអាចដំណើរការមាតិកាបានទេនៅពេលនេះ"</string>
<string name="root_recent" msgid="4470053704320518133">"ថ្មីៗ"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"ទំនេរ <xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="root_type_service" msgid="2178854894416775409">"សេវាកម្ម​ផ្ដល់​ឧបករណ៍​ផ្ទុក"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"កម្ម​វិធី​​ច្រើន​ទៀត"</string>
<string name="empty" msgid="7858882803708117596">"គ្មានធាតុ​"</string>
<string name="no_results" msgid="6622510343880730446">"មិនមានការប្រកួតនៅក្នុង %1$s ទេ"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"មិន​អាច​បើក​ឯកសារ"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"មិនអាចបើកឯកសារបានទេ"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"មិន​អាច​លុប​ឯកសារ​មួយ​ចំនួន"</string>
<string name="share_via" msgid="8966594246261344259">"ចែករំលែក​តាម"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"កំពុងថតចម្លងឯកសារ"</string>
<string name="move_notification_title" msgid="6193835179777284805">"ផ្លាស់ទីឯកសារ"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"កំពុងលុបឯកសារ"</string>
<string name="copy_remaining" msgid="6283790937387975095">"នៅសល់ <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">កំពុងថតចម្លងឯកសារចំនួន <xliff:g id="COUNT_1">%1$d</xliff:g> ។</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"កំពុងរៀបចំចម្លង…"</string>
<string name="move_preparing" msgid="2772219441375531410">"កំពុងរៀបចំផ្លាស់ទី…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"កំពុងរៀបចំលុប…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <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>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="other">មិនអាចថតចម្លងឯកសារ <xliff:g id="COUNT_1">%1$d</xliff:g> ច្បាប់</item>
+ <item quantity="one">មិនអាចថតចម្លងឯកសារ <xliff:g id="COUNT_0">%1$d</xliff:g> ច្បាប់</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <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 name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="other">មិនអាចផ្លាស់ទីឯកសារ <xliff:g id="COUNT_1">%1$d</xliff:g> ច្បាប់</item>
+ <item quantity="one">មិនអាចផ្លាស់ទីឯកសារ <xliff:g id="COUNT_0">%1$d</xliff:g> ច្បាប់</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
- <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 name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+ <item quantity="other">មិនអាចលុបឯកសារ <xliff:g id="COUNT_1">%1$d</xliff:g> ច្បាប់</item>
+ <item quantity="one">មិនអាចលុបឯកសារ <xliff:g id="COUNT_0">%1$d</xliff:g> ច្បាប់</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"ប៉ះដើម្បីមើលព័ត៌មានលម្អិត"</string>
<string name="close" msgid="3043722427445528732">"បិទ"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"ឯកសារទាំងនេះមិនបានចម្លងទេ៖ <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"ឯកសារទាំងនេះមិនអាចផ្លាស់ទីបានទេ៖ <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"ឯកសារទាំងនេះមិនត្រូវបានថតចម្លងទេ៖ <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"ឯកសារទាំងនេះមិនត្រូវបានផ្លាស់ទីទេ៖ <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"ឯកសារទាំងនេះមិនត្រូវបានលុបទេ៖ <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"ឯកសារទាំងនេះត្រូវបានបម្លែងទៅជាទម្រង់ផ្សេង៖ <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">បានចម្លងឯកសារ <xliff:g id="COUNT_1">%1$d</xliff:g> ទៅតម្បៀតខ្ទាស់។</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"មិនអាចបិទភ្ជាប់ឯកសារដែលបានជ្រើសនៅក្នុងទីតាំងនេះបានទេ។"</string>
<string name="menu_rename" msgid="7678802479104285353">"ប្ដូរឈ្មោះ"</string>
<string name="rename_error" msgid="4203041674883412606">"បានបរាជ័យក្នុងការប្តូរឈ្មោះឯកសារ"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"ដកចេញ"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ឯកសារមួយចំនួនត្រូវបានបម្លែង"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"ផ្តល់សិទ្ធិឲ្យ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ចូលដំណើរការថត <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> នៅលើ <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"ផ្តល់សិទ្ធិឲ្យ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ចូលដំណើរការថត <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ឬ?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"ផ្តល់សិទ្ធិអនុញ្ញាតដល់ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ដើម្បីចូលដំណើរការទិន្នន័យរបស់អ្នក រាប់បញ្ចូលទាំងរូបថត និងវីដេអូ នៅលើ <xliff:g id="STORAGE"><i>^2</i></xliff:g> ឬទេ?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"កុំសួរទៀត"</string>
<string name="allow" msgid="7225948811296386551">"អនុញ្ញាត​"</string>
<string name="deny" msgid="2081879885755434506">"បដិសេធ"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other">បានជ្រើស <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">បានជ្រើស <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ធាតុ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ធាតុ</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"លុប \"<xliff:g id="NAME">%1$s</xliff:g>\" ឬ?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"លុបថតឯកសារ \"<xliff:g id="NAME">%1$s</xliff:g>\" និងមាតិការបស់វាឬ?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">លុបឯកសារ <xliff:g id="COUNT_1">%1$d</xliff:g> ច្បាប់ឬ?</item>
+ <item quantity="one">លុបឯកសារ <xliff:g id="COUNT_0">%1$d</xliff:g> ច្បាប់ឬ?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">លុបថតឯកសារ <xliff:g id="COUNT_1">%1$d</xliff:g> និងមាតិការបស់វាឬ?</item>
+ <item quantity="one">លុបថតឯកសារ <xliff:g id="COUNT_0">%1$d</xliff:g> និងមាតិការបស់វាឬ?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <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>
</resources>
diff --git a/packages/DocumentsUI/res/values-kn-rIN/config.xml b/packages/DocumentsUI/res/values-kn-rIN/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-kn-rIN/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-kn-rIN/strings.xml b/packages/DocumentsUI/res/values-kn-rIN/strings.xml
index dc644a84efc0..0679776a14d3 100644
--- a/packages/DocumentsUI/res/values-kn-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-kn-rIN/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ಡಾಕ್ಯುಮೆಂಟ್‌ಗಳು"</string>
- <string name="files_label" msgid="6051402950202690279">"ಫೈಲ್‌ಗಳು"</string>
<string name="downloads_label" msgid="959113951084633612">"ಡೌನ್‌ಲೋಡ್‌ಗಳು"</string>
<string name="title_open" msgid="4353228937663917801">"ಇದರ ಮೂಲಕ ತೆರೆಯಿರಿ"</string>
<string name="title_save" msgid="2433679664882857999">"ಇವುಗಳಲ್ಲಿ ಉಳಿಸಿ"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"ಪಟ್ಟಿ ವೀಕ್ಷಣೆ"</string>
<string name="menu_sort" msgid="7677740407158414452">"ಈ ಪ್ರಕಾರ ವಿಂಗಡಿಸು"</string>
<string name="menu_search" msgid="3816712084502856974">"ಹುಡುಕು"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"ಸಂಗ್ರಹಣೆ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
<string name="menu_open" msgid="432922957274920903">"ತೆರೆ"</string>
<string name="menu_save" msgid="2394743337684426338">"ಉಳಿಸು"</string>
<string name="menu_share" msgid="3075149983979628146">"ಹಂಚು"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"ಇದಕ್ಕೆ ನಕಲಿಸಿ…"</string>
<string name="menu_move" msgid="1828090633118079817">"ಇದಕ್ಕೆ ಸರಿಸು…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"ಹೊಸ ವಿಂಡೋ"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"ಕತ್ತರಿಸು"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"ನಕಲಿಸು"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"ಅಂಟಿಸು"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"ಆಂತರಿಕ ಸಂಗ್ರಹಣೆಯನ್ನು ತೋರಿಸು"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"ರೂಟ್‌ಗಳನ್ನು ಮರೆಮಾಡು"</string>
<string name="save_error" msgid="6167009778003223664">"ಡಾಕ್ಯುಮೆಂಟ್ ಉಳಿಸಲು ವಿಫಲವಾಗಿದೆ"</string>
<string name="create_error" msgid="3735649141335444215">"ಫೋಲ್ಡರ್ ರಚಿಸಲು ವಿಫಲವಾಗಿದೆ"</string>
- <string name="query_error" msgid="1222448261663503501">"ಡಾಕ್ಯುಮೆಂಟ್‌ಗಳನ್ನು ಪ್ರಶ್ನಿಸಲು ವಿಫಲವಾಗಿದೆ"</string>
+ <string name="query_error" msgid="5999895349602476581">"ಈ ಕ್ಷಣದಲ್ಲಿ ವಿಷಯವನ್ನು ಲೋಡ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
<string name="root_recent" msgid="4470053704320518133">"ಇತ್ತೀಚಿನದು"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ಮುಕ್ತವಾಗಿದೆ"</string>
<string name="root_type_service" msgid="2178854894416775409">"ಸಂಗ್ರಹಣೆ ಸೇವೆಗಳು"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"ಇನ್ನಷ್ಟು ಅಪ್ಲಿಕೇಶನ್‌ಗಳು"</string>
<string name="empty" msgid="7858882803708117596">"ಯಾವುದೇ ಐಟಂಗಳಿಲ್ಲ"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s ರಲ್ಲಿ ಯಾವುದೇ ಹೊಂದಾಣಿಕೆಗಳಿಲ್ಲ"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"ಫೈಲ್ ತೆರೆಯಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"ಫೈಲ್ ತೆರೆಯಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"ಕೆಲವು ಡಾಕ್ಯುಮೆಂಟ್‌ಗಳನ್ನು ಅಳಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string>
<string name="share_via" msgid="8966594246261344259">"ಈ ಮೂಲಕ ಹಂಚಿಕೊಳ್ಳಿ"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"ಫೈಲ್‌ಗಳನ್ನು ನಕಲಿಸಲಾಗುತ್ತಿದೆ"</string>
<string name="move_notification_title" msgid="6193835179777284805">"ಫೈಲ್‌ಗಳನ್ನು ಸರಿಸಲಾಗುತ್ತಿದೆ"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"ಫೈಲ್ ಅಳಿಸಲಾಗುತ್ತಿದೆ"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> ಉಳಿದಿದೆ"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ನಕಲಿಸಲಾಗುತ್ತಿದೆ.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"ನಕಲಿಸಲು ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ..."</string>
<string name="move_preparing" msgid="2772219441375531410">"ಸರಿಸಲು ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"ಅಳಿಸಲು ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <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>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ನಕಲಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ನಕಲಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ಸರಿಸಲಾಗಲಿಲ್ಲ</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ಸರಿಸಲಾಗಲಿಲ್ಲ</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ಅಳಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ಅಳಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"ವಿವರಗಳನ್ನು ವೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="close" msgid="3043722427445528732">"ಮುಚ್ಚು"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"ಈ ಫೈಲ್‌ಗಳನ್ನು ನಕಲು ಮಾಡಿಲ್ಲ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"ಈ ಫೈಲ್‌ಗಳನ್ನು ಸರಿಸಲಾಗಿಲ್ಲ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"ಈ ಫೈಲ್‌ಗಳನ್ನು ನಕಲಿಸಲಾಗಿಲ್ಲ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"ಈ ಫೈಲ್‌ಗಳನ್ನು ಸರಿಸಲಾಗಿಲ್ಲ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"ಈ ಫೈಲ್‌ಗಳನ್ನು ಅಳಿಸಲಾಗಿಲ್ಲ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"ಈ ಫೈಲ್‌ಗಳನ್ನು ಮತ್ತೊಂದು ಫಾರ್ಮೆಟ್‌ಗೆ ಪರಿವರ್ತಿಸಲಾಗಿತ್ತು: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one">ಕ್ಲಿಪ್‌ಬೋರ್ಡ್‌ಗೆ <xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ನಕಲಿಸಲಾಗಿದೆ.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"ಈ ಸ್ಥಳದಲ್ಲಿ ಆಯ್ಕೆಮಾಡಿದ ಫೈಲ್‌ಗಳನ್ನು ಅಂಟಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
<string name="menu_rename" msgid="7678802479104285353">"ಮರುಹೆಸರಿಸು"</string>
<string name="rename_error" msgid="4203041674883412606">"ಡಾಕ್ಯುಮೆಂಟ್ ಮರುಹೆಸರಿಸಲು ವಿಫಲವಾಗಿದೆ"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"ಎಜೆಕ್ಟ್‌‌"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ಕೆಲವು ಫೈಲ್‌ಗಳನ್ನು ಪರಿವರ್ತಿಸಲಾಗಿದೆ"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> ರಲ್ಲಿ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ಡೈರೆಕ್ಟರಿಗೆ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ಪ್ರವೇಶ ನೀಡುವುದೇ?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g><xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ಡೈರೆಕ್ಟರಿ ಪ್ರವೇಶಿಸಲು ಅನುಮತಿಸುವುದೇ?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> ಸಂಗ್ರಹಣೆಯಲ್ಲಿನ ಪೋಟೋಗಳು ಮತ್ತು ವೀಡಿಯೊಗಳು ಸೇರಿದಂತೆ ನಿಮ್ಮ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಲು <xliff:g id="APPNAME"><b>^1</b></xliff:g> ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುವುದೇ?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"ಮತ್ತೆ ಕೇಳಬೇಡಿ"</string>
<string name="allow" msgid="7225948811296386551">"ಅನುಮತಿಸು"</string>
<string name="deny" msgid="2081879885755434506">"ನಿರಾಕರಿಸು"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ಐಟಂಗಳು</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ಐಟಂಗಳು</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ಅಳಿಸುವುದೇ?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ಫೋಲ್ಡರ್‌ ಮತ್ತು ಅದರ ವಿಷಯಗಳನ್ನು ಅಳಿಸುವುದೇ?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ಅಳಿಸುವುದೇ?</item>
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ಅಳಿಸುವುದೇ?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> ಫೋಲ್ಡರ್‌ಗಳು ಮತ್ತು ಅವುಗಳ ವಿಷಯಗಳನ್ನು ಅಳಿಸುವುದೇ?</item>
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> ಫೋಲ್ಡರ್‌ಗಳು ಮತ್ತು ಅವುಗಳ ವಿಷಯಗಳನ್ನು ಅಳಿಸುವುದೇ?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> ಐಟಂಗಳನ್ನು ಅಳಿಸುವುದೇ?</item>
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> ಐಟಂಗಳನ್ನು ಅಳಿಸುವುದೇ?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-ko/config.xml b/packages/DocumentsUI/res/values-ko/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-ko/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-ko/strings.xml b/packages/DocumentsUI/res/values-ko/strings.xml
index f807eefa6e92..ffb1363b3510 100644
--- a/packages/DocumentsUI/res/values-ko/strings.xml
+++ b/packages/DocumentsUI/res/values-ko/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"문서"</string>
- <string name="files_label" msgid="6051402950202690279">"파일"</string>
<string name="downloads_label" msgid="959113951084633612">"다운로드"</string>
<string name="title_open" msgid="4353228937663917801">"열기:"</string>
<string name="title_save" msgid="2433679664882857999">"저장 위치:"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"목록 보기"</string>
<string name="menu_sort" msgid="7677740407158414452">"정렬 기준"</string>
<string name="menu_search" msgid="3816712084502856974">"검색"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"저장소 설정"</string>
<string name="menu_open" msgid="432922957274920903">"열기"</string>
<string name="menu_save" msgid="2394743337684426338">"저장"</string>
<string name="menu_share" msgid="3075149983979628146">"공유"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"복사…"</string>
<string name="menu_move" msgid="1828090633118079817">"이동…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"새 창"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"잘라내기"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"복사"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"붙여넣기"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"내부 저장소 표시"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"루트 숨기기"</string>
<string name="save_error" msgid="6167009778003223664">"문서 저장 실패"</string>
<string name="create_error" msgid="3735649141335444215">"폴더를 만들지 못함"</string>
- <string name="query_error" msgid="1222448261663503501">"문서를 검색하지 못했습니다."</string>
+ <string name="query_error" msgid="5999895349602476581">"현재 콘텐츠를 로드할 수 없습니다."</string>
<string name="root_recent" msgid="4470053704320518133">"최근"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> 남음"</string>
<string name="root_type_service" msgid="2178854894416775409">"저장용량 서비스"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"앱 더보기"</string>
<string name="empty" msgid="7858882803708117596">"항목 없음"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s에 일치하는 항목이 없습니다."</string>
- <string name="toast_no_application" msgid="1339885974067891667">"파일을 열 수 없음"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"파일을 열 수 없습니다."</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"일부 문서를 삭제할 수 없음"</string>
<string name="share_via" msgid="8966594246261344259">"공유 방법"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"파일 복사 중"</string>
<string name="move_notification_title" msgid="6193835179777284805">"파일 이동"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"파일 삭제"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> 남음"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">파일 <xliff:g id="COUNT_1">%1$d</xliff:g>개를 복사합니다.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"사본 준비 중…"</string>
<string name="move_preparing" msgid="2772219441375531410">"이동 준비 중…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"삭제 준비 중..."</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other">파일 <xliff:g id="COUNT_1">%1$d</xliff:g>개를 복사할 수 없습니다.</item>
<item quantity="one">파일 <xliff:g id="COUNT_0">%1$d</xliff:g>개를 복사할 수 없습니다.</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <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 name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="other">파일 <xliff:g id="COUNT_1">%1$d</xliff:g>개를 이동할 수 없습니다.</item>
+ <item quantity="one">파일 <xliff:g id="COUNT_0">%1$d</xliff:g>개를 이동할 수 없습니다.</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other">파일 <xliff:g id="COUNT_1">%1$d</xliff:g>개를 삭제할 수 없습니다.</item>
<item quantity="one">파일 <xliff:g id="COUNT_0">%1$d</xliff:g>개를 삭제할 수 없습니다.</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"세부정보를 보려면 탭하세요."</string>
<string name="close" msgid="3043722427445528732">"닫기"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"다음 파일이 복사되지 않았습니다. <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"다음 파일이 이동되지 않았습니다. <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"다음 파일이 복사되지 않았습니다. <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"다음 파일이 이동되지 않았습니다. <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"다음 파일이 삭제되지 않았습니다. <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"파일이 다음과 같이 다른 형식으로 변환되었습니다. <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">파일 <xliff:g id="COUNT_1">%1$d</xliff:g>개를 클립보드에 복사함</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"선택한 파일을 이 위치에 붙여넣을 수 없습니다."</string>
<string name="menu_rename" msgid="7678802479104285353">"이름 바꾸기"</string>
<string name="rename_error" msgid="4203041674883412606">"문서 이름을 변경하지 못했습니다."</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"꺼내기"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"일부 파일이 변환되었습니다."</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>이(가) <xliff:g id="STORAGE"><i>^3</i></xliff:g>에서 <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> 디렉토리에 액세스하도록 허용하시겠습니까?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>이(가) <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> 디렉토리에 액세스하도록 허용하시겠습니까?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>에서 사진, 동영상 등 <xliff:g id="STORAGE"><i>^2</i></xliff:g>의 내 데이터에 액세스하도록 허용하시겠습니까?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"다시 묻지 않음"</string>
<string name="allow" msgid="7225948811296386551">"허용"</string>
<string name="deny" msgid="2081879885755434506">"거부"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>개 선택됨</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>개 선택됨</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other">항목 <xliff:g id="COUNT_1">%1$d</xliff:g>개</item>
+ <item quantity="one">항목 <xliff:g id="COUNT_0">%1$d</xliff:g>개</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"<xliff:g id="NAME">%1$s</xliff:g>을(를) 삭제하시겠습니까?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\'<xliff:g id="NAME">%1$s</xliff:g>\' 폴더와 폴더에 포함된 콘텐츠를 삭제하시겠습니까?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">파일 <xliff:g id="COUNT_1">%1$d</xliff:g>개를 삭제하시겠습니까?</item>
+ <item quantity="one">파일 <xliff:g id="COUNT_0">%1$d</xliff:g>개를 삭제하시겠습니까?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">폴더 <xliff:g id="COUNT_1">%1$d</xliff:g>개와 폴더에 포함된 콘텐츠를 삭제하시겠습니까?</item>
+ <item quantity="one">폴더 <xliff:g id="COUNT_0">%1$d</xliff:g>개와 폴더에 포함된 콘텐츠를 삭제하시겠습니까?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <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>
</resources>
diff --git a/packages/DocumentsUI/res/values-ky-rKG/config.xml b/packages/DocumentsUI/res/values-ky-rKG/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-ky-rKG/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-ky-rKG/strings.xml b/packages/DocumentsUI/res/values-ky-rKG/strings.xml
index bc1ea7ccfe27..9d5d47504558 100644
--- a/packages/DocumentsUI/res/values-ky-rKG/strings.xml
+++ b/packages/DocumentsUI/res/values-ky-rKG/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Документтер"</string>
- <string name="files_label" msgid="6051402950202690279">"Файлдар"</string>
<string name="downloads_label" msgid="959113951084633612">"Жүктөлүп алынгандар"</string>
<string name="title_open" msgid="4353228937663917801">"Кийинкиден ачуу:"</string>
<string name="title_save" msgid="2433679664882857999">"Кийинкиге сактоо:"</string>
@@ -26,16 +25,16 @@
<string name="menu_list" msgid="7279285939892417279">"Тизмек көрүнүшү"</string>
<string name="menu_sort" msgid="7677740407158414452">"Ылгоо"</string>
<string name="menu_search" msgid="3816712084502856974">"Издөө"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Сактагычтын жөндөөлөрү"</string>
<string name="menu_open" msgid="432922957274920903">"Ачуу"</string>
<string name="menu_save" msgid="2394743337684426338">"Сактоо"</string>
<string name="menu_share" msgid="3075149983979628146">"Бөлүшүү"</string>
- <string name="menu_delete" msgid="8138799623850614177">"Өчүрүү"</string>
+ <string name="menu_delete" msgid="8138799623850614177">"Жок кылуу"</string>
<string name="menu_select_all" msgid="8323579667348729928">"Бардыгын тандоо"</string>
<string name="menu_copy" msgid="3612326052677229148">"Төмөнкүгө көчүрүү…"</string>
<string name="menu_move" msgid="1828090633118079817">"Төмөнкүгө жылдыруу..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"Жаңы терезе"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Кесүү"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Көчүрүү"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Чаптоо"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Ички сактагычты көрсөтүү"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Папкаларды жашыруу"</string>
<string name="save_error" msgid="6167009778003223664">"Документтерди сактоо кыйрады"</string>
<string name="create_error" msgid="3735649141335444215">"Папка түзүү кыйрады"</string>
- <string name="query_error" msgid="1222448261663503501">"Документтерди алуу кыйрады"</string>
+ <string name="query_error" msgid="5999895349602476581">"Учурда мазмун жүктөлбөй жатат"</string>
<string name="root_recent" msgid="4470053704320518133">"Акыркы"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> бош"</string>
<string name="root_type_service" msgid="2178854894416775409">"Сактагыч кызматтар"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Көбүрөөк колдонмолор"</string>
<string name="empty" msgid="7858882803708117596">"Эч нерсе жок"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s ичинде дал келүүлөр жок"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Файл ачылбады"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Файл ачылбай жатат"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Кээ бир документтерди өчүрүү кыйрады"</string>
<string name="share_via" msgid="8966594246261344259">"Кийинки аркылуу бөлүшүү:"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Файлдар көчүрүлүүдө"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Файлдар жылдырылууда…"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Файлдар жок кылынууда"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> калды"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл көчүрүлүүдө.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Көчүрүүгө даярдалууда…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Жылдырууга даярдалууда…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Жок кылууга даярдалууда…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл көчүрүлбөй койду</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл көчүрүлбөй койду</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <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 name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл жылдырылбай койду</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл жылдырылбай койду</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл жок кылынбай койду</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл жок кылынбай койду</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Чоо-жайын көрүү үчүн таптаңыз"</string>
<string name="close" msgid="3043722427445528732">"Жабуу"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Төмөнкү файлдар көчүрүлгөн жок: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Төмөнкү файлдар жылдырылган жок: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Төмөнкү файлдар көчүрүлгөн жок: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Төмөнкү файлдар жылдырылган жок: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Төмөнкү файлдар өчүрүлгөн жок: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Бул файлдар башка форматка айландырылды: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл буферге көчүрүлдү.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Тандалган файлдарды бул жерге чаптоого мүмкүн эмес."</string>
<string name="menu_rename" msgid="7678802479104285353">"Аталышын өзгөртүү"</string>
<string name="rename_error" msgid="4203041674883412606">"Документтин аталышы өзгөртүлбөй калды"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Чыгаруу"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Айрым файлдардын форматы өзгөртүлдү"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> колдонмосуна <xliff:g id="STORAGE"><i>^3</i></xliff:g> түзмөгүндөгү <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> папканы пайдалануу мүмкүнчүлүгү берилсинби?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> колдонмосуна <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> каталогун пайдалануу мүмкүнчүлүгү берилсинби?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> колдонмосуна <xliff:g id="STORAGE"><i>^2</i></xliff:g> түзмөгүндөгү дайындарыңыз, сүрөттөрүңүз жана видеолоруңузду пайдалануу мүмкүнчүлүгү берилсинби?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Экинчи суралбасын"</string>
<string name="allow" msgid="7225948811296386551">"Уруксат берүү"</string>
<string name="deny" msgid="2081879885755434506">"Жок"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> тандалды</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> тандалды</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> нерсе</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> нерсе</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" жок кылынсынбы?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" куржуну мазмуну менен жок кылынсынбы?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл жок кылынсынбы?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл жок кылынсынбы?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> куржун мазмуну менен жок кылынсынбы?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> куржун мазмуну менен жок кылынсынбы?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <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>
</resources>
diff --git a/packages/DocumentsUI/res/values-lo-rLA/config.xml b/packages/DocumentsUI/res/values-lo-rLA/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-lo-rLA/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-lo-rLA/strings.xml b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
index aa1c3dff0b78..0f66f55e3946 100644
--- a/packages/DocumentsUI/res/values-lo-rLA/strings.xml
+++ b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ເອ​ກະ​ສານ"</string>
- <string name="files_label" msgid="6051402950202690279">"​ໄຟລ໌"</string>
<string name="downloads_label" msgid="959113951084633612">"ການດາວໂຫລດ"</string>
<string name="title_open" msgid="4353228937663917801">"ເປີດ​ຈາກ"</string>
<string name="title_save" msgid="2433679664882857999">"ບັນທຶກໄປທີ່"</string>
@@ -26,16 +25,16 @@
<string name="menu_list" msgid="7279285939892417279">"ມຸມມອງແບບລາຍຊື່"</string>
<string name="menu_sort" msgid="7677740407158414452">"ຮຽງລຳດັບຕາມ"</string>
<string name="menu_search" msgid="3816712084502856974">"ຊອກຫາ"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"ການຕັ້ງຄ່າບ່ອນເກັບຂໍ້ມູນ"</string>
<string name="menu_open" msgid="432922957274920903">"ເປີດ"</string>
<string name="menu_save" msgid="2394743337684426338">"ບັນທຶກ"</string>
<string name="menu_share" msgid="3075149983979628146">"ແບ່ງປັນ"</string>
<string name="menu_delete" msgid="8138799623850614177">"ລຶບ"</string>
<string name="menu_select_all" msgid="8323579667348729928">"ເລືອກທັງຫມົດ"</string>
- <string name="menu_copy" msgid="3612326052677229148">"ອັດ​ສຳ​ເນົາ​ໃສ່…"</string>
+ <string name="menu_copy" msgid="3612326052677229148">"ສຳເນົາໄປໃສ່..."</string>
<string name="menu_move" msgid="1828090633118079817">"ຍ້າຍໄປໃສ່..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"ໜ້າຈໍໃໝ່"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"​ຕັດ"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"ສຳເນົາ"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"​ວາງໃສ່"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"ສະແດງ​ໂຕເກັບ​ຂໍ້ມູນພາຍໃນ"</string>
@@ -54,8 +53,8 @@
<string name="drawer_close" msgid="7602734368552123318">"ເຊື່ອງ roots"</string>
<string name="save_error" msgid="6167009778003223664">"ການບັນທຶກເອກະສານລົ້ມເຫລວ"</string>
<string name="create_error" msgid="3735649141335444215">"ການ​ສ້າງ​ໂຟນ​ເດີລົ້ມເຫຼວ"</string>
- <string name="query_error" msgid="1222448261663503501">"ການຊອກຫາເອກະສານລົ້ມເຫຼວ"</string>
- <string name="root_recent" msgid="4470053704320518133">"ຫາກໍໃຊ້"</string>
+ <string name="query_error" msgid="5999895349602476581">"ບໍ່ສາມາດໂຫຼດເນື້ອຫາໄດ້ໃນຂະນະນີ້"</string>
+ <string name="root_recent" msgid="4470053704320518133">"ຫຼ້າສຸດ"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"ຟຣີ <xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="root_type_service" msgid="2178854894416775409">"ບໍລິການບ່ອນຈັດເກັບຂໍ້ມູນ"</string>
<string name="root_type_shortcut" msgid="3318760609471618093">"ທາງລັດ"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"ແອັບຯອື່ນໆ"</string>
<string name="empty" msgid="7858882803708117596">"ບໍ່ມີລາຍການ"</string>
<string name="no_results" msgid="6622510343880730446">"ບໍ່ພົບສິ່ງກົງກັນໃນ %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"ບໍ່ສາມດາເປີດໄຟລ໌ໄດ້"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"ບໍ່ສາມາດເປີດໄຟລ໌ໄດ້"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"ບໍ່ສາມາດລຶບບາງເອກະສານໄດ້"</string>
<string name="share_via" msgid="8966594246261344259">"ແບ່ງປັນຜ່ານ"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"ກຳ​ລັງ​ອັດ​ສຳ​ເນົາ​ໄຟ​ລ໌"</string>
<string name="move_notification_title" msgid="6193835179777284805">"ກຳ​ລັງ​ຍ້າຍ​ໄຟ​ລ໌"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"ກຳລັງລຶບໄຟລ໌"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> ຍັງ​ເຫຼືອ​ຢູ່"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">ກຳ​ລັງ​ອັດ​ສຳ​ເນົາ <xliff:g id="COUNT_1">%1$d</xliff:g> ໄຟ​ລ໌.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"ກຳ​ລັງ​ກຽມ​ອັດ​ສຳ​ເນົາ…"</string>
<string name="move_preparing" msgid="2772219441375531410">"ກຳ​ລັງ​ກະ​ກຽມ​ຍ້າຍ…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"ກຳລັງກະກຽມລຶບ…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <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>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="other">ບໍ່ສາມາດສຳເນົາ <xliff:g id="COUNT_1">%1$d</xliff:g> ໄຟລ໌ໄດ້</item>
+ <item quantity="one">ບໍ່ສາມາດສຳເນົາ <xliff:g id="COUNT_0">%1$d</xliff:g> ໄຟລ໌ໄດ້</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <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 name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="other">ບໍ່ສາມາດຍ້າຍ <xliff:g id="COUNT_1">%1$d</xliff:g> ໄຟລ໌ໄດ້</item>
+ <item quantity="one">ບໍ່ສາມາດຍ້າຍ <xliff:g id="COUNT_0">%1$d</xliff:g> ໄຟລ໌ໄດ້</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
- <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 name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+ <item quantity="other">ບໍ່ສາມາດລຶບ <xliff:g id="COUNT_1">%1$d</xliff:g> ໄຟລ໌ໄດ້</item>
+ <item quantity="one">ບໍ່ສາມາດລຶບ <xliff:g id="COUNT_0">%1$d</xliff:g> ໄຟລ໌ໄດ້</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"ແຕະເພື່ອເບິ່ງລາຍລະອຽດ"</string>
<string name="close" msgid="3043722427445528732">"ປິດ"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"ໄຟ​ລ໌​ເຫຼົ່າ​ນີ້​ບໍ່​ຖື​ກ​ອັດ​ສຳ​ເນົາ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"ໄຟ​ລ໌​ເຫຼົ່າ​ນີ້​ບໍ່​ຖືກ​ຍ້າຍ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"ໄຟລ໌ເຫຼົ່ານີ້ບໍ່ໄດ້ຖືກສຳເນົາ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"ໄຟລ໌ເຫຼົ່ານີ້ບໍ່ໄດ້ຖືກຍ້າຍ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"ໄຟລ໌ເຫຼົ່ານີ້ບໍ່ໄດ້ຖືກລຶບເທື່ອ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"ໄຟລ໌ເຫຼົ່ານີ້ໄດ້ຖືກປ່ຽນເປັນຮູບແບບອື່ນແລ້ວ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">ອັດ​ສຳ​ເນົາ <xliff:g id="COUNT_1">%1$d</xliff:g> ໄຟ​ລ໌​ໃສ່​ຄ​ລິບບອດ​ແລ້ວ.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"ບໍ່​ສາ​ມາດ​ແປະ​ໄຟ​ລ໌​ເລືອກ​ໄວ້​ຢູ່​ໃນ​ທີ່​ຕັ້ງ​ນີ້​ໄດ້."</string>
<string name="menu_rename" msgid="7678802479104285353">"ປ່ຽນຊື່"</string>
<string name="rename_error" msgid="4203041674883412606">"ປ່ຽນຊື່ເອກະສານບໍ່ສຳເລັດ"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"ຖອດອອກ"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ປ່ຽນແປງບາງໄຟລ໌ແລ້ວ"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"ອະນຸຍາດສິດເຂົ້າເຖິງໃຫ້ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ເພື່ອເຂົ້າໄດເຣກທໍຣີ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ຢູ່ <xliff:g id="STORAGE"><i>^3</i></xliff:g> ບໍ?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"ອະນຸມັດ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ໃຫ້ເຂົ້າຫາໄດເຣັກທໍຣີ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ບໍ?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"ອະນຸມັດໃຫ້ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ເຂົ້າເຖິງຂໍ້ມູນຂອງທ່ານ ເຊິ່ງຮວມເຖິງຮູບພາບ ແລະ ວິດີໂອໃນ <xliff:g id="STORAGE"><i>^2</i></xliff:g> ໄດ້ບໍ?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"ບໍ່ຕ້ອງຖາມຄືນ"</string>
<string name="allow" msgid="7225948811296386551">"ອະນຸຍາດ"</string>
<string name="deny" msgid="2081879885755434506">"ປະ​ຕິ​ເສດ"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other">ເລືອກ <xliff:g id="COUNT_1">%1$d</xliff:g> ແລ້ວ</item>
+ <item quantity="one">ເລືອກ <xliff:g id="COUNT_0">%1$d</xliff:g> ແລ້ວ</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ລາຍການ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ລາຍການ</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"ລຶບ \"<xliff:g id="NAME">%1$s</xliff:g>\" ອອກບໍ?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"ລຶບໂຟນເດີ \"<xliff:g id="NAME">%1$s</xliff:g>\" ແລະ ເນື້ອຫາທັງໝົດຂອງມັນອອກບໍ?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">ລຶບ <xliff:g id="COUNT_1">%1$d</xliff:g> ໄຟລ໌ອອກບໍ?</item>
+ <item quantity="one">ລຶບ <xliff:g id="COUNT_0">%1$d</xliff:g> ໄຟລ໌ອອກບໍ?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">ລຶບ <xliff:g id="COUNT_1">%1$d</xliff:g> ໂຟນເດີ ແລະ ເນື້ອຫາຂອງມັນອອກບໍ?</item>
+ <item quantity="one">ລຶບ <xliff:g id="COUNT_0">%1$d</xliff:g> ໂຟນເດີ ແລະ ເນື້ອຫາຂອງມັນອອກບໍ?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <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>
</resources>
diff --git a/packages/DocumentsUI/res/values-lt/config.xml b/packages/DocumentsUI/res/values-lt/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-lt/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-lt/strings.xml b/packages/DocumentsUI/res/values-lt/strings.xml
index 48339b9bbc32..02ee8f6af25c 100644
--- a/packages/DocumentsUI/res/values-lt/strings.xml
+++ b/packages/DocumentsUI/res/values-lt/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumentai"</string>
- <string name="files_label" msgid="6051402950202690279">"Failai"</string>
<string name="downloads_label" msgid="959113951084633612">"Atsisiuntimai"</string>
<string name="title_open" msgid="4353228937663917801">"Atidaryti iš"</string>
<string name="title_save" msgid="2433679664882857999">"Išsaugoti į"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Sąrašo rodinys"</string>
<string name="menu_sort" msgid="7677740407158414452">"Rūšiuoti pagal"</string>
<string name="menu_search" msgid="3816712084502856974">"Ieškoti"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Saugyklos nustatymai"</string>
<string name="menu_open" msgid="432922957274920903">"Atidaryti"</string>
<string name="menu_save" msgid="2394743337684426338">"Išsaugoti"</string>
<string name="menu_share" msgid="3075149983979628146">"Bendrinti"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Kopijuoti į..."</string>
<string name="menu_move" msgid="1828090633118079817">"Perkelti į…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Naujas langas"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Iškirpti"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopijuoti"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Įklijuoti"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Rodyti vidinę atmintį"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Slėpti šaknis"</string>
<string name="save_error" msgid="6167009778003223664">"Nepavyko išsaugoti dokumento"</string>
<string name="create_error" msgid="3735649141335444215">"Nepavyko sukurti aplanko"</string>
- <string name="query_error" msgid="1222448261663503501">"Nepavyko pateikti dokumentų užklausų"</string>
+ <string name="query_error" msgid="5999895349602476581">"Šiuo metu nepavyksta įkelti turinio"</string>
<string name="root_recent" msgid="4470053704320518133">"Naujausi"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"Laisvos vietos: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="root_type_service" msgid="2178854894416775409">"Saugyklos paslaugos"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Daugiau programų"</string>
<string name="empty" msgid="7858882803708117596">"Nėra elementų"</string>
<string name="no_results" msgid="6622510343880730446">"Nėra jokių atitikčių pagal %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Nepavyksta atidaryti failo"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Nepavyksta atidaryti failo"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Nepavyko ištrinti kai kurių dokumentų"</string>
<string name="share_via" msgid="8966594246261344259">"Bendrinti naudojant"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopijuojami failai"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Perkeliami failai"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Failų ištrynimas"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Liko: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Kopijuojamas <xliff:g id="COUNT_1">%1$d</xliff:g> failas.</item>
@@ -91,19 +91,20 @@
<string name="copy_preparing" msgid="3896202461003039386">"Ruošiamasi kopijuoti…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Ruošiamasi perkelti…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Ruošiama ištrinti…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="one">Nepavyko nukopijuoti <xliff:g id="COUNT_1">%1$d</xliff:g> failo</item>
<item quantity="few">Nepavyko nukopijuoti <xliff:g id="COUNT_1">%1$d</xliff:g> failų</item>
<item quantity="many">Nepavyko nukopijuoti <xliff:g id="COUNT_1">%1$d</xliff:g> failo</item>
<item quantity="other">Nepavyko nukopijuoti <xliff:g id="COUNT_1">%1$d</xliff:g> failų</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="one">Nepavyko perkelti <xliff:g id="COUNT_1">%1$d</xliff:g> failo</item>
<item quantity="few">Nepavyko perkelti <xliff:g id="COUNT_1">%1$d</xliff:g> failų</item>
<item quantity="many">Nepavyko perkelti <xliff:g id="COUNT_1">%1$d</xliff:g> failo</item>
<item quantity="other">Nepavyko perkelti <xliff:g id="COUNT_1">%1$d</xliff:g> failų</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="one">Nepavyko ištrinti <xliff:g id="COUNT_1">%1$d</xliff:g> failo</item>
<item quantity="few">Nepavyko ištrinti <xliff:g id="COUNT_1">%1$d</xliff:g> failų</item>
<item quantity="many">Nepavyko ištrinti <xliff:g id="COUNT_1">%1$d</xliff:g> failo</item>
@@ -111,8 +112,9 @@
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Palieskite, kad peržiūrėtumėte informaciją"</string>
<string name="close" msgid="3043722427445528732">"Uždaryti"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Šie failai nenukopijuoti: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Šie failai nebuvo perkelti: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Šie failai nebuvo nukopijuoti: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Šie failai nebuvo perkelti: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Šie failai nebuvo ištrinti: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Šie failai konvertuoti į kitą formatą: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one">Nukopijuotas <xliff:g id="COUNT_1">%1$d</xliff:g> failas į iškarpinę.</item>
@@ -123,7 +125,44 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Nepavyko įklijuoti pasirinktų failų šioje vietoje."</string>
<string name="menu_rename" msgid="7678802479104285353">"Pervardyti"</string>
<string name="rename_error" msgid="4203041674883412606">"Nepavyko pervardyti dokumento"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Pašalinti"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Kai kurie failai buvo konvertuoti"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Suteikti „<xliff:g id="APPNAME"><b>^1</b></xliff:g>“ prieigą prie katalogo „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“ <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Suteikti „<xliff:g id="APPNAME"><b>^1</b></xliff:g>“ prieigą prie katalogo „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Suteikti programai „<xliff:g id="APPNAME"><b>^1</b></xliff:g>“ prieigą prie duomenų, įskaitant nuotraukas ir vaizdo įrašus, <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Daugiau neklausti"</string>
<string name="allow" msgid="7225948811296386551">"Leisti"</string>
<string name="deny" msgid="2081879885755434506">"Atmesti"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one">Pasirinktas <xliff:g id="COUNT_1">%1$d</xliff:g> elementas</item>
+ <item quantity="few">Pasirinkti <xliff:g id="COUNT_1">%1$d</xliff:g> elementai</item>
+ <item quantity="many">Pasirinkta <xliff:g id="COUNT_1">%1$d</xliff:g> elemento</item>
+ <item quantity="other">Pasirinkta <xliff:g id="COUNT_1">%1$d</xliff:g> elementų</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> elementas</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> elementai</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> elemento</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementų</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Ištrinti „<xliff:g id="NAME">%1$s</xliff:g>“?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Ištrinti aplanką „<xliff:g id="NAME">%1$s</xliff:g>“ ir jo turinį?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one">Ištrinti <xliff:g id="COUNT_1">%1$d</xliff:g> failą?</item>
+ <item quantity="few">Ištrinti <xliff:g id="COUNT_1">%1$d</xliff:g> failus?</item>
+ <item quantity="many">Ištrinti <xliff:g id="COUNT_1">%1$d</xliff:g> failo?</item>
+ <item quantity="other">Ištrinti <xliff:g id="COUNT_1">%1$d</xliff:g> failų?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one">Ištrinti <xliff:g id="COUNT_1">%1$d</xliff:g> aplanką ir jų turinį?</item>
+ <item quantity="few">Ištrinti <xliff:g id="COUNT_1">%1$d</xliff:g> aplankus ir jų turinį?</item>
+ <item quantity="many">Ištrinti <xliff:g id="COUNT_1">%1$d</xliff:g> aplanko ir jų turinį?</item>
+ <item quantity="other">Ištrinti <xliff:g id="COUNT_1">%1$d</xliff:g> aplankų ir jų turinį?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one">Ištrinti <xliff:g id="COUNT_1">%1$d</xliff:g> elementą?</item>
+ <item quantity="few">Ištrinti <xliff:g id="COUNT_1">%1$d</xliff:g> elementus?</item>
+ <item quantity="many">Ištrinti <xliff:g id="COUNT_1">%1$d</xliff:g> elemento?</item>
+ <item quantity="other">Ištrinti <xliff:g id="COUNT_1">%1$d</xliff:g> elementų?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-lv/config.xml b/packages/DocumentsUI/res/values-lv/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-lv/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-lv/strings.xml b/packages/DocumentsUI/res/values-lv/strings.xml
index 524febae6505..b4ae3fc37300 100644
--- a/packages/DocumentsUI/res/values-lv/strings.xml
+++ b/packages/DocumentsUI/res/values-lv/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenti"</string>
- <string name="files_label" msgid="6051402950202690279">"Faili"</string>
<string name="downloads_label" msgid="959113951084633612">"Lejupielādes"</string>
<string name="title_open" msgid="4353228937663917801">"Atvēršana no:"</string>
<string name="title_save" msgid="2433679664882857999">"Saglabāšana:"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Saraksts"</string>
<string name="menu_sort" msgid="7677740407158414452">"Kārtot pēc"</string>
<string name="menu_search" msgid="3816712084502856974">"Meklēt"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Atmiņas iestatījumi"</string>
<string name="menu_open" msgid="432922957274920903">"Atvērt"</string>
<string name="menu_save" msgid="2394743337684426338">"Saglabāt"</string>
<string name="menu_share" msgid="3075149983979628146">"Kopīgot"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Kopēt…"</string>
<string name="menu_move" msgid="1828090633118079817">"Pārvietot uz…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Jauns logs"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Izgriezt"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopēt"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Ielīmēt"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Rādīt iekšējo atmiņu"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Slēpt saknes"</string>
<string name="save_error" msgid="6167009778003223664">"Neizdevās saglabāt dokumentu."</string>
<string name="create_error" msgid="3735649141335444215">"Neizdevās izveidot mapi."</string>
- <string name="query_error" msgid="1222448261663503501">"Neizdevās atrast vaicājumā norādītos dokumentus."</string>
+ <string name="query_error" msgid="5999895349602476581">"Pašlaik nevar ielādēt saturu."</string>
<string name="root_recent" msgid="4470053704320518133">"Pēdējie"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"Brīva vieta: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="root_type_service" msgid="2178854894416775409">"Glabāšanas pakalpojumi"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Vairāk lietotņu"</string>
<string name="empty" msgid="7858882803708117596">"Nav vienumu"</string>
<string name="no_results" msgid="6622510343880730446">"Failā %1$s nav atbilstību"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Nevar atvērt failu."</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Nevar atvērt failu."</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Nevar dzēst dažus dokumentus."</string>
<string name="share_via" msgid="8966594246261344259">"Kopīgot, izmantojot"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Notiek failu kopēšana"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Failu pārvietošana"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Notiek failu dzēšana"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Atlikušais laiks: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="zero">Notiek <xliff:g id="COUNT_1">%1$d</xliff:g> failu kopēšana.</item>
@@ -88,25 +88,27 @@
<string name="copy_preparing" msgid="3896202461003039386">"Gatavošanās kopēšanai…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Sagatavošana pārvietošanai…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Notiek gatavošanās dzēšanai…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> no <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="zero">Nevarēja nokopēt <xliff:g id="COUNT_1">%1$d</xliff:g> failus</item>
<item quantity="one">Nevarēja nokopēt <xliff:g id="COUNT_1">%1$d</xliff:g> failu</item>
<item quantity="other">Nevarēja nokopēt <xliff:g id="COUNT_1">%1$d</xliff:g> failus</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="zero">Nevarēja pārvietot <xliff:g id="COUNT_1">%1$d</xliff:g> failus.</item>
- <item quantity="one">Nevarēja pārvietot <xliff:g id="COUNT_1">%1$d</xliff:g> failu.</item>
- <item quantity="other">Nevarēja pārvietot <xliff:g id="COUNT_1">%1$d</xliff:g> failus.</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="zero">Nevarēja pārvietot <xliff:g id="COUNT_1">%1$d</xliff:g> failus</item>
+ <item quantity="one">Nevarēja pārvietot <xliff:g id="COUNT_1">%1$d</xliff:g> failu</item>
+ <item quantity="other">Nevarēja pārvietot <xliff:g id="COUNT_1">%1$d</xliff:g> failus</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
- <item quantity="zero">Nevarēja izdzēst <xliff:g id="COUNT_1">%1$d</xliff:g> failus.</item>
- <item quantity="one">Nevarēja izdzēst <xliff:g id="COUNT_1">%1$d</xliff:g> failu.</item>
- <item quantity="other">Nevarēja izdzēst <xliff:g id="COUNT_1">%1$d</xliff:g> failus.</item>
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+ <item quantity="zero">Nevarēja izdzēst <xliff:g id="COUNT_1">%1$d</xliff:g> failus</item>
+ <item quantity="one">Nevarēja izdzēst <xliff:g id="COUNT_1">%1$d</xliff:g> failu</item>
+ <item quantity="other">Nevarēja izdzēst <xliff:g id="COUNT_1">%1$d</xliff:g> failus</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Pieskarieties, lai skatītu informāciju"</string>
<string name="close" msgid="3043722427445528732">"Aizvērt"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Netika nokopēti šādi faili: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Šie faili netika pārvietoti: <xliff:g id="LIST">%1$s</xliff:g>."</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Netika nokopēti šādi faili: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Netika pārvietoti šādi faili: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Netika izdzēsti šādi faili: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Šie faili tika pārveidoti citā formātā: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="zero"><xliff:g id="COUNT_1">%1$d</xliff:g> faili tika kopēti starpliktuvē.</item>
@@ -116,7 +118,39 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Atlasītos failus šeit nevar ielīmēt."</string>
<string name="menu_rename" msgid="7678802479104285353">"Pārdēvēt"</string>
<string name="rename_error" msgid="4203041674883412606">"Neizdevās pārdēvēt dokumentu"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Noņemt"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Daži faili tika pārveidoti."</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Vai atļaut lietotnei <xliff:g id="APPNAME"><b>^1</b></xliff:g> piekļūt direktorijam <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> šajā krātuvē: <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Vai piešķirt lietotnei <xliff:g id="APPNAME"><b>^1</b></xliff:g> piekļuvi direktorijam <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Vai atļaut lietotnei <xliff:g id="APPNAME"><b>^1</b></xliff:g> piekļūt jūsu datiem, tostarp fotoattēliem un videoklipiem, šajā krātuvē: <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Turpmāk vairs nejautāt"</string>
<string name="allow" msgid="7225948811296386551">"Atļaut"</string>
<string name="deny" msgid="2081879885755434506">"Noraidīt"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="zero"><xliff:g id="COUNT_1">%1$d</xliff:g> atlasīti</item>
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> atlasīts</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> atlasīti</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="zero"><xliff:g id="COUNT_1">%1$d</xliff:g> vienumu</item>
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> vienums</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> vienumi</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Vai izdzēst failu “<xliff:g id="NAME">%1$s</xliff:g>”?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Vai izdzēst mapi “<xliff:g id="NAME">%1$s</xliff:g>” un tās saturu?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="zero">Vai izdzēst <xliff:g id="COUNT_1">%1$d</xliff:g> failus?</item>
+ <item quantity="one">Vai izdzēst <xliff:g id="COUNT_1">%1$d</xliff:g> failu?</item>
+ <item quantity="other">Vai izdzēst <xliff:g id="COUNT_1">%1$d</xliff:g> failus?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="zero">Vai izdzēst <xliff:g id="COUNT_1">%1$d</xliff:g> mapes un to saturu?</item>
+ <item quantity="one">Vai izdzēst <xliff:g id="COUNT_1">%1$d</xliff:g> mapi un to saturu?</item>
+ <item quantity="other">Vai izdzēst <xliff:g id="COUNT_1">%1$d</xliff:g> mapes un to saturu?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="zero">Vai izdzēst <xliff:g id="COUNT_1">%1$d</xliff:g> vienumus?</item>
+ <item quantity="one">Vai izdzēst <xliff:g id="COUNT_1">%1$d</xliff:g> vienumu?</item>
+ <item quantity="other">Vai izdzēst <xliff:g id="COUNT_1">%1$d</xliff:g> vienumus?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-mk-rMK/config.xml b/packages/DocumentsUI/res/values-mk-rMK/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-mk-rMK/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-mk-rMK/strings.xml b/packages/DocumentsUI/res/values-mk-rMK/strings.xml
index 15017e120244..9df2aade9b21 100644
--- a/packages/DocumentsUI/res/values-mk-rMK/strings.xml
+++ b/packages/DocumentsUI/res/values-mk-rMK/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Документи"</string>
- <string name="files_label" msgid="6051402950202690279">"Датотеки"</string>
<string name="downloads_label" msgid="959113951084633612">"Преземања"</string>
<string name="title_open" msgid="4353228937663917801">"Отвори од"</string>
<string name="title_save" msgid="2433679664882857999">"Зачувај во"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Приказ на список"</string>
<string name="menu_sort" msgid="7677740407158414452">"Подреди по"</string>
<string name="menu_search" msgid="3816712084502856974">"Пребарај"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Поставки на меморија"</string>
<string name="menu_open" msgid="432922957274920903">"Отвори"</string>
<string name="menu_save" msgid="2394743337684426338">"Зачувај"</string>
<string name="menu_share" msgid="3075149983979628146">"Сподели"</string>
@@ -36,12 +34,13 @@
<string name="menu_copy" msgid="3612326052677229148">"Копирај во…"</string>
<string name="menu_move" msgid="1828090633118079817">"Премести во..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"Нов прозорец"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Исечи"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Копирај"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Залепи"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Прикажи внатрешна мемор."</string>
<string name="menu_advanced_hide" msgid="4218809952721972589">"Скриј внатрешна меморија"</string>
- <string name="menu_file_size_show" msgid="3240323619260823076">"Прикажи целосна големина"</string>
- <string name="menu_file_size_hide" msgid="8881975928502581042">"Сокриј целосна големина"</string>
+ <string name="menu_file_size_show" msgid="3240323619260823076">"Прикажи ја големината"</string>
+ <string name="menu_file_size_hide" msgid="8881975928502581042">"Сокриј ја големината"</string>
<string name="button_select" msgid="527196987259139214">"Избери"</string>
<string name="button_copy" msgid="8706475544635021302">"Копирај"</string>
<string name="button_move" msgid="2202666023104202232">"Премести"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Сокриј корени"</string>
<string name="save_error" msgid="6167009778003223664">"Документот не успеа да се зачува"</string>
<string name="create_error" msgid="3735649141335444215">"Не успеа да се создаде папка"</string>
- <string name="query_error" msgid="1222448261663503501">"Барањето за документи не успеа"</string>
+ <string name="query_error" msgid="5999895349602476581">"Во моментов не може да се вчита содржина."</string>
<string name="root_recent" msgid="4470053704320518133">"Последни"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> слободен простор"</string>
<string name="root_type_service" msgid="2178854894416775409">"Услуги на складирање"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Повеќе апликации"</string>
<string name="empty" msgid="7858882803708117596">"Нема ставки"</string>
<string name="no_results" msgid="6622510343880730446">"Нема совпаѓања во %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Датотеката не се отвора"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Датотеката не може да се отвори"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Некои документи не може да се избришат"</string>
<string name="share_via" msgid="8966594246261344259">"Сподели преку"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Се копираат датотеки"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Датотеките се преместуваат"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Се бришат датотеките"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Уште <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Се копира <xliff:g id="COUNT_1">%1$d</xliff:g> датотека.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Се подготвува за копирање…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Се подготвува за преместување…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Се подготвува за бришење…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="one">Не може да копира <xliff:g id="COUNT_1">%1$d</xliff:g> датотека</item>
- <item quantity="other">Не може да копираат <xliff:g id="COUNT_1">%1$d</xliff:g> датотеки</item>
+ <item quantity="other">Не може да копира <xliff:g id="COUNT_1">%1$d</xliff:g> датотеки</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="one">Не можеше да се премести <xliff:g id="COUNT_1">%1$d</xliff:g> датотека</item>
- <item quantity="other">Не можеше да се преместат <xliff:g id="COUNT_1">%1$d</xliff:g> датотеки</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="one">Не може да премести <xliff:g id="COUNT_1">%1$d</xliff:g> датотека</item>
+ <item quantity="other">Не може да премести <xliff:g id="COUNT_1">%1$d</xliff:g> датотеки</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
- <item quantity="one">Не можеше да се избрише <xliff:g id="COUNT_1">%1$d</xliff:g> датотека</item>
- <item quantity="other">Не можеше да се избришат <xliff:g id="COUNT_1">%1$d</xliff:g> датотеки</item>
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+ <item quantity="one">Не може да избрише <xliff:g id="COUNT_1">%1$d</xliff:g> датотека</item>
+ <item quantity="other">Не може да избрише <xliff:g id="COUNT_1">%1$d</xliff:g> датотеки</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Допрете за да ги погледнете деталите"</string>
<string name="close" msgid="3043722427445528732">"Затвори"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Датотекиве не се ископирани: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Овие датотеки не се преместија: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Датотекиве не се ископирани: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Датотекиве не се преместени: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Датотекиве не се избришани: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Овие датотеки беа конвертирани во друг формат: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one">Копирана е <xliff:g id="COUNT_1">%1$d</xliff:g> датотека на таблата со исечоци.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Не може да ги залепи избраните датотеки на локацијава."</string>
<string name="menu_rename" msgid="7678802479104285353">"Преименувај"</string>
<string name="rename_error" msgid="4203041674883412606">"Не успеа да се преименува документот"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Извади"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Некои датотеки беа конвертирани"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Овозможете пристап на <xliff:g id="APPNAME"><b>^1</b></xliff:g> до директориумот <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> на <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Овозможете пристап на <xliff:g id="APPNAME"><b>^1</b></xliff:g> до директориумот <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Да се овозможи пристап на <xliff:g id="APPNAME"><b>^1</b></xliff:g> до вашите податоци, вклучувајќи фотографии и видеа, на <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Не прашувај повторно"</string>
<string name="allow" msgid="7225948811296386551">"Дозволи"</string>
<string name="deny" msgid="2081879885755434506">"Одбиј"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> е избрана</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> се избрани</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ставка</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ставки</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Да се избрише „<xliff:g id="NAME">%1$s</xliff:g>“?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Да се избрише папката „<xliff:g id="NAME">%1$s</xliff:g>“ и нејзините содржини?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one">Да се избрише <xliff:g id="COUNT_1">%1$d</xliff:g> датотека?</item>
+ <item quantity="other">Да се избришат <xliff:g id="COUNT_1">%1$d</xliff:g> датотеки?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one">Да се избрише <xliff:g id="COUNT_1">%1$d</xliff:g> папка и нивните содржини?</item>
+ <item quantity="other">Да се избришат <xliff:g id="COUNT_1">%1$d</xliff:g> папки и нивните содржини?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one">Да се избрише <xliff:g id="COUNT_1">%1$d</xliff:g> ставка?</item>
+ <item quantity="other">Да се избришат <xliff:g id="COUNT_1">%1$d</xliff:g> ставки?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-ml-rIN/config.xml b/packages/DocumentsUI/res/values-ml-rIN/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-ml-rIN/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-ml-rIN/strings.xml b/packages/DocumentsUI/res/values-ml-rIN/strings.xml
index 9a79b723dd32..8c3b885b7fcc 100644
--- a/packages/DocumentsUI/res/values-ml-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-ml-rIN/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"പ്രമാണങ്ങൾ"</string>
- <string name="files_label" msgid="6051402950202690279">"ഫയലുകൾ"</string>
<string name="downloads_label" msgid="959113951084633612">"ഡൗണ്‍ലോഡുകൾ"</string>
<string name="title_open" msgid="4353228937663917801">"ഇതിൽ നിന്നും തുറക്കുക"</string>
<string name="title_save" msgid="2433679664882857999">"ഇതില്‍‌ സംരക്ഷിക്കുക"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"ലിസ്റ്റ് കാഴ്‌ച"</string>
<string name="menu_sort" msgid="7677740407158414452">"ഇപ്രകാരം അടുക്കുക"</string>
<string name="menu_search" msgid="3816712084502856974">"തിരയൽ"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"സ്റ്റോറേജ് ക്രമീകരണം"</string>
<string name="menu_open" msgid="432922957274920903">"തുറക്കുക"</string>
<string name="menu_save" msgid="2394743337684426338">"സംരക്ഷിക്കുക"</string>
<string name="menu_share" msgid="3075149983979628146">"പങ്കിടുക"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"ഇതിൽ പകർത്തുക…"</string>
<string name="menu_move" msgid="1828090633118079817">"ഇതിലേക്ക് നീക്കുക..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"പുതിയ വിന്‍‍ഡോ"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"മുറിക്കുക"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"പകര്‍ത്തുക"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"ഒട്ടിക്കുക"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"ആന്തരിക സ്റ്റോറേജ് കാണിക്കുക"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"റൂട്ടുകൾ മറയ്‌ക്കുക"</string>
<string name="save_error" msgid="6167009778003223664">"പ്രമാണം സംരക്ഷിക്കുന്നതിൽ പരാജയപ്പെട്ടു"</string>
<string name="create_error" msgid="3735649141335444215">"ഫോൾഡർ സൃഷ്‌ടിക്കുന്നതിൽ പരാജയപ്പെട്ടു"</string>
- <string name="query_error" msgid="1222448261663503501">"പ്രമാണങ്ങൾ അന്വേഷിക്കുന്നതിൽ പരാജയപ്പെട്ടു"</string>
+ <string name="query_error" msgid="5999895349602476581">"ഇപ്പോൾ ഉള്ളടക്കം ലോഡുചെയ്യാൻ കഴിയില്ല"</string>
<string name="root_recent" msgid="4470053704320518133">"അടുത്തിടെയുള്ളവ"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ലഭ്യമാണ്"</string>
<string name="root_type_service" msgid="2178854894416775409">"സംഭരണ സേവനങ്ങൾ"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"കൂടുതൽ അപ്ലിക്കേഷനുകൾ"</string>
<string name="empty" msgid="7858882803708117596">"ഇനങ്ങളൊന്നുമില്ല"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s എന്നതിൽ പൊരുത്തങ്ങളില്ല"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"ഫയൽ തുറക്കാനായില്ല"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"ഫയൽ തുറക്കാൻ കഴിയില്ല"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"ചില പ്രമാണങ്ങൾ ഇല്ലാതാക്കാനായില്ല"</string>
<string name="share_via" msgid="8966594246261344259">"ഇതുവഴി പങ്കിടുക"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"ഫയലുകൾ പകർത്തുന്നു"</string>
<string name="move_notification_title" msgid="6193835179777284805">"ഫയലുകൾ നീക്കുന്നു"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"ഫയലുകൾ ഇല്ലാതാക്കുന്നു"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> ശേഷിക്കുന്നു"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ഫയലുകൾ പകർത്തുന്നു.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"പകർപ്പിനായി തയ്യാറെടുക്കുന്നു…"</string>
<string name="move_preparing" msgid="2772219441375531410">"നീക്കാനൊരുങ്ങുന്നു…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"ഇല്ലാതാക്കാൻ തയ്യാറെടുക്കുന്നു..."</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ഫയലുകൾ പകർത്താനായില്ല</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ഫയൽ പകർത്താനായില്ല</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ഫയലുകൾ നീക്കാനായില്ല</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ഫയൽ നീക്കാനായില്ല</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
- <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 name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ഫയലുകൾ ഇല്ലാതാക്കാനായില്ല</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ഫയൽ ഇല്ലാതാക്കാനായില്ല</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"വിശദാംശങ്ങൾ കാണുന്നതിന് ടാപ്പുചെയ്യുക"</string>
<string name="close" msgid="3043722427445528732">"അടയ്‌ക്കുക"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"ഈ ഫയലുകൾ പകർത്താനായില്ല: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"ഈ ഫയലുകളെ നീക്കിയില്ല: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"ഈ ഫയലുകൾ പകർത്തിയില്ല: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"ഈ ഫയലുകൾ നീക്കിയില്ല: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"ഈ ഫയലുകൾ ഇല്ലാതാക്കിയില്ല: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"ഈ ഫയലുകൾ മറ്റൊരു ഫോർമാറ്റിലേക്ക് പരിവർത്തനം ചെയ്യപ്പെട്ടു: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ഫയലുകൾ ക്ലിപ്പ്‌ബോർഡിലേക്ക് പകർത്തി.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"തിരഞ്ഞെടുത്ത ഫയലുകൾ ഈ ലൊക്കേഷനിൽ ഒട്ടിക്കാനാകുന്നില്ല."</string>
<string name="menu_rename" msgid="7678802479104285353">"പേരുമാറ്റുക"</string>
<string name="rename_error" msgid="4203041674883412606">"ഡോക്യുമെന്റിന്റെ പേരുമാറ്റുന്നത് പരാജയപ്പെട്ടു"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"ഒഴിവാക്കുക"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ചില ഫയലുകൾ പരിവർത്തനം ചെയ്യപ്പെട്ടു"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> സ്റ്റോറേജിലെ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> എന്ന ഡയറക്റ്ററിയിലേക്ക് <xliff:g id="APPNAME"><b>^1</b></xliff:g> ആപ്പിന് ആക്സസ് അനുവദിക്കണോ?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> എന്ന ഡയറക്ടറിയിലേക്ക് <xliff:g id="APPNAME"><b>^1</b></xliff:g> ആപ്പിന് ആക്സസ് അനുവദിക്കണോ?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> സ്റ്റോറേജിലെ ഫോട്ടോകളും വീഡിയോകളും ഉൾപ്പെടെ, നിങ്ങളുടെ ഡാറ്റയിലേക്ക് <xliff:g id="APPNAME"><b>^1</b></xliff:g> ആപ്പിന് ആക്സസ്സ് അനുവദിക്കണോ?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"വീണ്ടും ആവശ്യപ്പെടരുത്"</string>
<string name="allow" msgid="7225948811296386551">"അനുവദിക്കുക"</string>
<string name="deny" msgid="2081879885755434506">"നിരസിക്കുക"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> തിരഞ്ഞെടുത്തു</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> തിരഞ്ഞെടുത്തു</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ഇനങ്ങൾ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ഇനം</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ഇല്ലാതാക്കണോ?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" എന്ന ഫോൾഡറും അതിലെ ഉള്ളടങ്ങളും ഇല്ലാതാക്കണോ?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ഫയലുകൾ ഇല്ലാതാക്കണോ?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ഫയൽ ഇല്ലാതാക്കണോ?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ഫോൾഡറുകളും അവയിലെ ഉള്ളടക്കങ്ങളും ഇല്ലാതാക്കണോ?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ഫോൾഡറും അതിലെ ഉള്ളടക്കങ്ങളും ഇല്ലാതാക്കണോ?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <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>
</resources>
diff --git a/packages/DocumentsUI/res/values-mn-rMN/config.xml b/packages/DocumentsUI/res/values-mn-rMN/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-mn-rMN/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-mn-rMN/strings.xml b/packages/DocumentsUI/res/values-mn-rMN/strings.xml
index 67b88ef4b328..234e1a984dce 100644
--- a/packages/DocumentsUI/res/values-mn-rMN/strings.xml
+++ b/packages/DocumentsUI/res/values-mn-rMN/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Документүүд"</string>
- <string name="files_label" msgid="6051402950202690279">"Файл"</string>
<string name="downloads_label" msgid="959113951084633612">"Таталт"</string>
<string name="title_open" msgid="4353228937663917801">"Нээх"</string>
<string name="title_save" msgid="2433679664882857999">"Хадгалах"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Жагсааж харах"</string>
<string name="menu_sort" msgid="7677740407158414452">"Эрэмбэлэх"</string>
<string name="menu_search" msgid="3816712084502856974">"Хайх"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Хадгалах сангийн тохиргоо"</string>
<string name="menu_open" msgid="432922957274920903">"Нээх"</string>
<string name="menu_save" msgid="2394743337684426338">"Хадгалах"</string>
<string name="menu_share" msgid="3075149983979628146">"Хуваалцах"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"...руу хуулах"</string>
<string name="menu_move" msgid="1828090633118079817">"Байршуулах газар"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Шинэ цонх"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Таслах"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Хуулах"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Буулгах"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Дотоод санг харуулах"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Язгуурыг нууцлах"</string>
<string name="save_error" msgid="6167009778003223664">"Документыг хадгалж чадсангүй"</string>
<string name="create_error" msgid="3735649141335444215">"Фолдер үүсгэж чадсангүй"</string>
- <string name="query_error" msgid="1222448261663503501">"Документын хүсэлт гаргаж чадсангүй"</string>
+ <string name="query_error" msgid="5999895349602476581">"Одоогоор агуулгыг ачааллах боломжгүй байна"</string>
<string name="root_recent" msgid="4470053704320518133">"Саяхны"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> чөлөөтэй"</string>
<string name="root_type_service" msgid="2178854894416775409">"Сангийн үйлчилгээ"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Өөр апп-ууд"</string>
<string name="empty" msgid="7858882803708117596">"Хоосон"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s-д тохирох зүйл байхгүй байна"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Файлыг нээх боломжгүй"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Файлыг нээх боломжгүй байна"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Зарим документуудыг устгах боломжгүй"</string>
<string name="share_via" msgid="8966594246261344259">"Дараахаар дамжуулан хуваалцах"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Файлуудыг хуулж байна"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Файлыг зөөвөрлөж байна"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Эдгээр файлыг устгаж байна"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> үлдсэн"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> файлуудыг хуулж байна.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Хуулбарлахад бэлтгэж байна..."</string>
<string name="move_preparing" msgid="2772219441375531410">"Зөөвөрлөхөд бэлтгэж байна..."</string>
<string name="delete_preparing" msgid="5655813182533491992">"Устгах гэж байна..."</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <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>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> файлыг хуулж чадсангүй</item>
+ <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> файлыг хуулж чадахгүй байна</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <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 name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> файлыг зөөх боломжгүй байна</item>
+ <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> файлыг зөөх боломжгүй байна</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> файлыг устгаж чадсангүй</item>
<item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> файлыг устгаж чадсангүй</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Дэлгэрэнгүй мэдээллийг үзэхийн тулд дарна уу"</string>
<string name="close" msgid="3043722427445528732">"Хаах"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Дараах файлуудыг хуулаагүй: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Эдгээр файлыг зөөвөрлөөгүй байна: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Эдгээр файлыг хуулж чадсангүй: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Эдгээр файлыг зөөж чадсангүй: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Эдгээр файл устсангүй: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Эдгээр файлыг өөр хэлбэршилтэд хөрвүүлсэн байна: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> материалыг түр санах ой руу хуулсан.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Энэ байршилд сонгосон файлыг байршуулах боломжгүй байна."</string>
<string name="menu_rename" msgid="7678802479104285353">"Нэр өөрчлөх"</string>
<string name="rename_error" msgid="4203041674883412606">"Баримт бичгийн нэрийн өөрчилж чадсангүй"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Салгах"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Зарим файлыг хөрвүүлсэн"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g>-д байгаа <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> лавлагаанд хандахыг <xliff:g id="APPNAME"><b>^1</b></xliff:g>-д зөвшөөрөх үү?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> лавлагаанд хандах эрхийг <xliff:g id="APPNAME"><b>^1</b></xliff:g>-д олгох уу?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g>-д байгаа зураг, видео гэх мэт таны өгөгдөлд <xliff:g id="APPNAME"><b>^1</b></xliff:g> хандахыг зөвшөөрөх үү?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Дахин бүү асуу"</string>
<string name="allow" msgid="7225948811296386551">"Зөвшөөрөх"</string>
<string name="deny" msgid="2081879885755434506">"Татгалзах"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> сонгосон</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> сонгосон</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> зүйл</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> зүйл</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\"-г устгах уу?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" фолдер болон үүний агуулгыг устгах уу?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> файлыг устгах уу?</item>
+ <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> файлыг устгах уу?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> фолдер болон агуулгуудыг нь устгах уу?</item>
+ <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> фолдер болон агуулгыг нь устгах уу?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <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>
</resources>
diff --git a/packages/DocumentsUI/res/values-mr-rIN/config.xml b/packages/DocumentsUI/res/values-mr-rIN/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-mr-rIN/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-mr-rIN/strings.xml b/packages/DocumentsUI/res/values-mr-rIN/strings.xml
index 53ca8581dd9f..e204c469b1ff 100644
--- a/packages/DocumentsUI/res/values-mr-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-mr-rIN/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"दस्तऐवज"</string>
- <string name="files_label" msgid="6051402950202690279">"फायली"</string>
<string name="downloads_label" msgid="959113951084633612">"डाउनलोड"</string>
<string name="title_open" msgid="4353228937663917801">"वरून उघडा"</string>
<string name="title_save" msgid="2433679664882857999">"येथे जतन करा"</string>
@@ -35,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"यावर कॉपी करा…"</string>
<string name="menu_move" msgid="1828090633118079817">"यावर हलवा…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"नवीन विंडो"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"कट करा"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"कॉपी करा"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"पेस्ट करा"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"अंतर्गत संचयन दर्शवा"</string>
@@ -53,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"रूट लपवा"</string>
<string name="save_error" msgid="6167009778003223664">"दस्तऐवज जतन करणे अयशस्वी झाले"</string>
<string name="create_error" msgid="3735649141335444215">"फोल्डर तयार करण्यात अयशस्वी"</string>
- <string name="query_error" msgid="1222448261663503501">"दस्‍तऐवजांना क्‍वेरी करण्‍यात अयशस्‍वी"</string>
+ <string name="query_error" msgid="5999895349602476581">"याक्षणी सामग्री लोड करू शकत नाही"</string>
<string name="root_recent" msgid="4470053704320518133">"अलीकडील"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> विनामूल्‍य"</string>
<string name="root_type_service" msgid="2178854894416775409">"संचयन सेवा"</string>
@@ -62,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"अधिक अ‍ॅप्‍स"</string>
<string name="empty" msgid="7858882803708117596">"कोणतेही आयटम नाहीत"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s मध्‍ये कोणत्याही जुळण्‍या नाहीत"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"फाईल उघडू शकत नाही"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"फाईल उघडू शकत नाही"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"काही दस्‍तऐवज हटविण्‍यात अक्षम"</string>
<string name="share_via" msgid="8966594246261344259">"द्वारे सामायिक करा"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"फायली कॉपी करीत आहे"</string>
<string name="move_notification_title" msgid="6193835179777284805">"फायली हलविणे"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"फायली हटवित आहे"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> शिल्लक"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फाईल कॉपी करीत आहे.</item>
@@ -84,23 +85,25 @@
<string name="copy_preparing" msgid="3896202461003039386">"कॉपी करण्‍यासाठी तयार करीत आहे…"</string>
<string name="move_preparing" msgid="2772219441375531410">"हलविण्‍यास तयार होत आहे…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"हटविण्‍यासाठी तयार करीत आहे..."</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <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>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> फाईल कॉपी करणे शक्य झाले नाही</item>
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> फायली कॉपी करणे शक्य झाले नाही</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फाईल हलविणे शक्य झाले नाही</item>
- <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फायली हलविणे शक्य झाले नाही</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> फाईल हलविणे शक्य झाले नाही</item>
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> फायली हलविणे शक्य झाले नाही</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> फाईल हटविणे शक्य झाले नाही</item>
<item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> फायली हटविणे शक्य झाले नाही</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"तपशील पाहण्यासाठी टॅप करा"</string>
<string name="close" msgid="3043722427445528732">"बंद करा"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"या फायली कॉपी झाल्या नाहीत: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"या फायली हलविल्या नव्हत्या: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="copy_converted_warning_content" msgid="5753861488218674361">"या फायली दुसर्‍या स्वरूपनात रूपांतरित केल्या होत्या: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"या फायलींची कॉपी झाली नाही: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"या फायली हलविल्या नाहीत: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"या फायली हटविल्या नाहीत: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_converted_warning_content" msgid="5753861488218674361">"या फायली दुसऱ्या स्वरूपनात रूपांतरित केल्या होत्या: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<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>
@@ -108,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"या स्थानामध्‍ये निवडलेल्‍या फायली पेस्ट करू शकत नाही."</string>
<string name="menu_rename" msgid="7678802479104285353">"पुनर्नामित करा"</string>
<string name="rename_error" msgid="4203041674883412606">"दस्तऐवज पुनर्नामित करण्‍यात अयशस्वी झाले"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"बाहेर काढा"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"काही फायली रूपांतरित केल्या होत्या"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> वर <xliff:g id="APPNAME"><b>^1</b></xliff:g> ला <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिकेवर प्रवेशाची मंजूरी द्यायची?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ला <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिकमध्ये प्रवेश मंजूर करायचा?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ला <xliff:g id="STORAGE"><i>^2</i></xliff:g> वर फोटो आणि व्हिडिओंसह, आपल्या डेटामध्ये प्रवेश करण्याची मंजूरी द्यायची?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"पुन्हा विचारू नका"</string>
<string name="allow" msgid="7225948811296386551">"अनुमती द्या"</string>
<string name="deny" msgid="2081879885755434506">"नकार द्या"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> निवडला</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> निवडले</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> आयटम</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> आयटम</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" हटवायची?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" फोल्डर आणि त्यामधील सामग्री हटवायची?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फाईल हटवायची?</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फायली हटवायच्या?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फोल्डर आणि त्यामधील सामग्री हटवायची?</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फोल्डर आणि त्यामधील सामग्री हटवायची?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> आयटम हटवायचा?</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> आयटम हटवायचे?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-ms-rMY/config.xml b/packages/DocumentsUI/res/values-ms-rMY/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-ms-rMY/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-ms-rMY/strings.xml b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
index 24fe49cf1ef0..a16fa4cff551 100644
--- a/packages/DocumentsUI/res/values-ms-rMY/strings.xml
+++ b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumen"</string>
- <string name="files_label" msgid="6051402950202690279">"Fail"</string>
<string name="downloads_label" msgid="959113951084633612">"Muat turun"</string>
<string name="title_open" msgid="4353228937663917801">"Buka dari"</string>
<string name="title_save" msgid="2433679664882857999">"Simpan ke"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Paparan senarai"</string>
<string name="menu_sort" msgid="7677740407158414452">"Isih mengikut"</string>
<string name="menu_search" msgid="3816712084502856974">"Cari"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Tetapan storan"</string>
<string name="menu_open" msgid="432922957274920903">"Buka"</string>
<string name="menu_save" msgid="2394743337684426338">"Simpan"</string>
<string name="menu_share" msgid="3075149983979628146">"Kongsi"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Salin ke..."</string>
<string name="menu_move" msgid="1828090633118079817">"Alihkan ke…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Tetingkap baharu"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Potong"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Salin"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Tampal"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Papar storan dalaman"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Sembunyikan akar"</string>
<string name="save_error" msgid="6167009778003223664">"Gagal menyimpan dokumen"</string>
<string name="create_error" msgid="3735649141335444215">"Gagal membuat folder"</string>
- <string name="query_error" msgid="1222448261663503501">"Gagal menanyakan dokumen"</string>
+ <string name="query_error" msgid="5999895349602476581">"Tidak dapat memuatkan kandungan pada masa ini"</string>
<string name="root_recent" msgid="4470053704320518133">"Terbaharu"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> kosong"</string>
<string name="root_type_service" msgid="2178854894416775409">"Perkhidmatan storan"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Lebih banyak apl"</string>
<string name="empty" msgid="7858882803708117596">"Tiada item"</string>
<string name="no_results" msgid="6622510343880730446">"Tiada padanan dalam %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Tidak dapat membuka fail"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Tidak dapat membuka fail"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Tidak dapat memadam beberapa dokumen"</string>
<string name="share_via" msgid="8966594246261344259">"Kongsi melalui"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Menyalin fail"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Mengalihkan fail"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Memadamkan fail"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> lagi"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Menyalin <xliff:g id="COUNT_1">%1$d</xliff:g> fail.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Bersedia untuk salin..."</string>
<string name="move_preparing" msgid="2772219441375531410">"Bersedia untuk mengalih…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Bersedia untuk memadam…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other">Tidak dapat menyalin <xliff:g id="COUNT_1">%1$d</xliff:g> fail</item>
<item quantity="one">Tidak dapat menyalin <xliff:g id="COUNT_0">%1$d</xliff:g> fail</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other">Tidak dapat mengalihkan <xliff:g id="COUNT_1">%1$d</xliff:g> fail</item>
<item quantity="one">Tidak dapat mengalihkan <xliff:g id="COUNT_0">%1$d</xliff:g> fail</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other">Tidak dapat memadamkan <xliff:g id="COUNT_1">%1$d</xliff:g> fail</item>
<item quantity="one">Tidak dapat memadamkan <xliff:g id="COUNT_0">%1$d</xliff:g> fail</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Ketik untuk melihat butiran"</string>
<string name="close" msgid="3043722427445528732">"Tutup"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Fail ini tidak disalin: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Fail ini tidak dialihkan: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Fail ini tidak disalin: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Fail ini tidak dialihkan: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Fail ini tidak dipadamkan: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Fail ini telah ditukarkan kepada format lain: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fail disalin ke papan keratan.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Tidak boleh menampalkan fail yang dipilih dalam lokasi ini."</string>
<string name="menu_rename" msgid="7678802479104285353">"Namakan semula"</string>
<string name="rename_error" msgid="4203041674883412606">"Gagal menamakan semula dokumen"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Keluarkan"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Sesetengah fail telah ditukarkan"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses kepada direktori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> di <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses kepada direktori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses kepada data anda, termasuk foto dan video pada <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Jangan tanya lagi"</string>
<string name="allow" msgid="7225948811296386551">"Benarkan"</string>
<string name="deny" msgid="2081879885755434506">"Nafi"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dipilih</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dipilih</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> item</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Padamkan \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Padamkan folder \"<xliff:g id="NAME">%1$s</xliff:g>\" dan kandungannya?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">Padamkan <xliff:g id="COUNT_1">%1$d</xliff:g> fail?</item>
+ <item quantity="one">Padamkan <xliff:g id="COUNT_0">%1$d</xliff:g> fail?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">Padamkan <xliff:g id="COUNT_1">%1$d</xliff:g> folder dan kandungannya?</item>
+ <item quantity="one">Padamkan <xliff:g id="COUNT_0">%1$d</xliff:g> folder dan kandungannya?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other">Padamkan <xliff:g id="COUNT_1">%1$d</xliff:g> item?</item>
+ <item quantity="one">Padamkan <xliff:g id="COUNT_0">%1$d</xliff:g> item?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-my-rMM/config.xml b/packages/DocumentsUI/res/values-my-rMM/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-my-rMM/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-my-rMM/strings.xml b/packages/DocumentsUI/res/values-my-rMM/strings.xml
index 4c36bd30a7a3..fef5e870a7bf 100644
--- a/packages/DocumentsUI/res/values-my-rMM/strings.xml
+++ b/packages/DocumentsUI/res/values-my-rMM/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"စာရွက်စာတန်းများ"</string>
- <string name="files_label" msgid="6051402950202690279">"ဖိုင်များ"</string>
<string name="downloads_label" msgid="959113951084633612">"ဒေါင်းလုဒ်များ"</string>
<string name="title_open" msgid="4353228937663917801">"မှ ဖွင့်ပါ"</string>
<string name="title_save" msgid="2433679664882857999">"သို့ သိမ်းပါ"</string>
@@ -26,22 +25,22 @@
<string name="menu_list" msgid="7279285939892417279">"အစဉ်လိုက်မြင်ကွင်း"</string>
<string name="menu_sort" msgid="7677740407158414452">"အစဉ်အလိုက် စီခြင်း"</string>
<string name="menu_search" msgid="3816712084502856974">"ရှာဖွေရန်"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"သိုလှောင်မှု ဆက်တင်များ"</string>
<string name="menu_open" msgid="432922957274920903">"ဖွင့်ရန်"</string>
- <string name="menu_save" msgid="2394743337684426338">"သိမ်းပါ"</string>
+ <string name="menu_save" msgid="2394743337684426338">"သိမ်းရန်"</string>
<string name="menu_share" msgid="3075149983979628146">"မျှဝေခြင်း"</string>
- <string name="menu_delete" msgid="8138799623850614177">"ဖျက်ပစ်ရန်"</string>
+ <string name="menu_delete" msgid="8138799623850614177">"ဖျက်ရန်"</string>
<string name="menu_select_all" msgid="8323579667348729928">"အားလုံးကို ရွေးရန်"</string>
- <string name="menu_copy" msgid="3612326052677229148">"သို့ကူးယူရန်…"</string>
+ <string name="menu_copy" msgid="3612326052677229148">"…သို့ကူးယူရန်"</string>
<string name="menu_move" msgid="1828090633118079817">"...သို့ ရွှေ့ရန်"</string>
<string name="menu_new_window" msgid="1226032889278727538">"ဝင်းဒိုးသစ်"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"ဖြတ်ယူရန်"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"ကူးယူရန်"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"ကပ်ရန်"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"စက်ရှိစတိုရုံ ပြပါ"</string>
<string name="menu_advanced_hide" msgid="4218809952721972589">"စက်ရှိစတိုရုံ ဖျောက်ထားပါ"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"ဖိုင်အရွယ်အစား ပြပါ"</string>
- <string name="menu_file_size_hide" msgid="8881975928502581042">"ဖိုင်အရွယ်အစား ဖျောက်ပါ"</string>
+ <string name="menu_file_size_hide" msgid="8881975928502581042">"ဖိုင်အရွယ်အစား ဝှက်ပါ"</string>
<string name="button_select" msgid="527196987259139214">"ရွေးရန်"</string>
<string name="button_copy" msgid="8706475544635021302">"ကူးယူရန်"</string>
<string name="button_move" msgid="2202666023104202232">"ရွေ့မည်"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"ဖိုဒါကို ပိတ်လိုက်ပါ"</string>
<string name="save_error" msgid="6167009778003223664">"စာရွက်စာတန်း သိမ်းဆည်းမှု မအောင်​မြင်ပါ"</string>
<string name="create_error" msgid="3735649141335444215">"အကန့်အသစ် ဖန်တီးခြင်း မအောင်မြင်ပါ"</string>
- <string name="query_error" msgid="1222448261663503501">"စာရွက်စာတန်း ရှာဖွေမှု မအောင်မြင်ပါ"</string>
+ <string name="query_error" msgid="5999895349602476581">"အကြောင်းအရာများကို လောလောဆယ်တွင် တင်၍မရသေးပါ"</string>
<string name="root_recent" msgid="4470053704320518133">"လတ်တလော"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> အသုံးချနိုင်ပါသည်"</string>
<string name="root_type_service" msgid="2178854894416775409">"သိုလှောင်ရန်ဆားဗစ်များ"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"နောက်ထပ်အပလီကေးရှင်းများ"</string>
<string name="empty" msgid="7858882803708117596">"ဘာမှ မရှိပါ"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s တွင်ကိုက်ညီမှုမရှိပါ"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"ဖိုင်အား ဖွင့်မရပါ"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"ဖိုင်ကိုဖွင့်၍မရပါ"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"တချို့ စာရွက်စာတန်းများ မဖျက်စီးနိုင်ပါ"</string>
<string name="share_via" msgid="8966594246261344259">"မှ ဝေမျှပါ"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"ဖိုင်များကူယူနေသည်"</string>
<string name="move_notification_title" msgid="6193835179777284805">"ဖိုင်များ ရွှေ့နေသည်"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"ဖိုင်များကို ဖျက်နေသည်"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> ကျန်ရှိသည်"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ဖိုင်များကို ကူးယူနေသည်။</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"မိတ္တူကူးရန်ပြင်ဆင်နေ..."</string>
<string name="move_preparing" msgid="2772219441375531410">"ရွှေ့ရန် ပြင်ဆင်နေသည်…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"ဖျက်ရန်အတွက် ပြင်ဆင်နေသည်..."</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <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>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="other">ဖိုင်<xliff:g id="COUNT_1">%1$d</xliff:g> ခုကိုကူးယူ၍မရခဲ့ပါ</item>
+ <item quantity="one">ဖိုင်<xliff:g id="COUNT_0">%1$d</xliff:g> ခုကိုကူးယူ၍မရခဲ့ပါ</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <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 name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="other">ဖိုင်<xliff:g id="COUNT_1">%1$d</xliff:g> ခုကိုရွှေ့၍မရခဲ့ပါ</item>
+ <item quantity="one">ဖိုင်<xliff:g id="COUNT_0">%1$d</xliff:g> ခုကိုရွှေ့၍မရခဲ့ပါ</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
- <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 name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+ <item quantity="other">ဖိုင်<xliff:g id="COUNT_1">%1$d</xliff:g> ခုကိုဖျက်၍မရခဲ့ပါ</item>
+ <item quantity="one">ဖိုင်<xliff:g id="COUNT_0">%1$d</xliff:g> ခုကိုဖျက်၍မရခဲ့ပါ</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"အသေးစိတ်ကြည့်ရန် တို့ပါ"</string>
<string name="close" msgid="3043722427445528732">"ပိတ်ပါ"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"ဤဖိုင်များ ကော်ပီကူးမထားပါ- <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"ဤဖိုင်များကို မရွှေ့ခဲ့ပါ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"ဤဖိုင်များကို မကူးယူခဲ့ပါ − <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"ဤဖိုင်များကို မရွှေ့ခဲ့ပါ − <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"ဤဖိုင်များကို ဖျက်၍မရခဲ့ပါ − <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"ဤဖိုင်များကို အခြားပုံစံစနစ်တစ်ခုသို့ ပြောင်းလဲခဲ့သည် − <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other"> ဖိုင် <xliff:g id="COUNT_1">%1$d</xliff:g> ဖိုင်ကိုအချက်အလက်သိမ်းတဲ့နေရာသို့ ကူးယူပါ။</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"ဤနေရာတွင် ရွေးချယ်ထားသည့် ဖိုင်များကို ကူးထည့်၍မရပါ။"</string>
<string name="menu_rename" msgid="7678802479104285353">"အမည်ပြောင်းရန်"</string>
<string name="rename_error" msgid="4203041674883412606">"စာရွက်စာတမ်းကို အမည်ပြောင်းခြင်း မအောင်မြင်ပါ"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"ထုတ်မည်"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"အချို့ဖိုင်များကို ပြောင်းလဲထားသည်"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ကို <xliff:g id="STORAGE"><i>^3</i></xliff:g> ရှိ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> လမ်းညွှန်အား အသုံးပြုခွင့်ပေးမလား။"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> အား <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> စာရင်းကို အသုံးပြုခွင့်ပေးမလား။"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> ရှိဓာတ်ပုံများနှင့် ဗီဒီယိုများအပါအဝင် သင့်ဒေတာများကို <xliff:g id="APPNAME"><b>^1</b></xliff:g> အားအသုံးပြုခွင့်ပေးမလား။"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"နောက်ထပ်မမေးပါနှင့်"</string>
<string name="allow" msgid="7225948811296386551">"ခွင့်ပြုသည်"</string>
<string name="deny" msgid="2081879885755434506">"ငြင်းပယ်သည်"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ခုရွေးချယ်ထားသည်</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ခုရွေးချယ်ထားသည်</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ခု</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ခု</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ကိုဖျက်မလား။"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ဖိုင်တွဲနှင့် ၎င်းတွင်ပါဝင်သည့် အကြောင်းအရာများကို ဖျက်မလား။"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">ဖိုင် <xliff:g id="COUNT_1">%1$d</xliff:g> ခုကိုဖျက်မလား။</item>
+ <item quantity="one">ဖိုင် <xliff:g id="COUNT_0">%1$d</xliff:g> ခုကိုဖျက်မလား။</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">ဖိုင်တွဲ <xliff:g id="COUNT_1">%1$d</xliff:g> ခုနှင့် ၎င်း၏အကြောင်းအရာများကို ဖျက်မလား။</item>
+ <item quantity="one">ဖိုင်တွဲ <xliff:g id="COUNT_0">%1$d</xliff:g> ခုနှင့် ၎င်း၏အကြောင်းအရာများကို ဖျက်မလား။</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <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>
</resources>
diff --git a/packages/DocumentsUI/res/values-nb/config.xml b/packages/DocumentsUI/res/values-nb/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-nb/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-nb/strings.xml b/packages/DocumentsUI/res/values-nb/strings.xml
index 4ff395e8e1e2..d3b199682b7e 100644
--- a/packages/DocumentsUI/res/values-nb/strings.xml
+++ b/packages/DocumentsUI/res/values-nb/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenter"</string>
- <string name="files_label" msgid="6051402950202690279">"Filer"</string>
<string name="downloads_label" msgid="959113951084633612">"Nedlastinger"</string>
<string name="title_open" msgid="4353228937663917801">"Åpne fra"</string>
<string name="title_save" msgid="2433679664882857999">"Lagre i"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Listevisning"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sortér etter"</string>
<string name="menu_search" msgid="3816712084502856974">"Søk"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Lagringsinnstillinger"</string>
<string name="menu_open" msgid="432922957274920903">"Åpne"</string>
<string name="menu_save" msgid="2394743337684426338">"Lagre"</string>
<string name="menu_share" msgid="3075149983979628146">"Del"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Kopiér til …"</string>
<string name="menu_move" msgid="1828090633118079817">"Flytt til"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Nytt vindu"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Klipp ut"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopiér"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Lim inn"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Vis den interne lagringen"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Skjul røtter"</string>
<string name="save_error" msgid="6167009778003223664">"Kunne ikke lagre dokumentet"</string>
<string name="create_error" msgid="3735649141335444215">"Kunne ikke opprette mappen"</string>
- <string name="query_error" msgid="1222448261663503501">"Kunne ikke undersøke dokumenter"</string>
+ <string name="query_error" msgid="5999895349602476581">"Kan ikke laste inn innholdet for øyeblikket"</string>
<string name="root_recent" msgid="4470053704320518133">"Siste"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ledig"</string>
<string name="root_type_service" msgid="2178854894416775409">"Lagringstjenester"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Flere apper"</string>
<string name="empty" msgid="7858882803708117596">"Ingen elementer"</string>
<string name="no_results" msgid="6622510343880730446">"Ingen treff i %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Kan ikke åpne filen"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Kan ikke åpne filen"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Enkelte dokumenter kunne ikke slettes"</string>
<string name="share_via" msgid="8966594246261344259">"Del via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopierer filer"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Flytter filer"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Sletter filene"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> gjenstår"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Kopierer <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Forbereder kopiering …"</string>
<string name="move_preparing" msgid="2772219441375531410">"Forbereder flytting …"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Gjøres klar for sletting …"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other">Kunne ikke kopiere <xliff:g id="COUNT_1">%1$d</xliff:g> filer</item>
<item quantity="one">Kunne ikke kopiere <xliff:g id="COUNT_0">%1$d</xliff:g> fil</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other">Kunne ikke flytte <xliff:g id="COUNT_1">%1$d</xliff:g> filer</item>
<item quantity="one">Kunne ikke flytte <xliff:g id="COUNT_0">%1$d</xliff:g> fil</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other">Kunne ikke slette <xliff:g id="COUNT_1">%1$d</xliff:g> filer</item>
<item quantity="one">Kunne ikke slette <xliff:g id="COUNT_0">%1$d</xliff:g> fil</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Trykk for å se detaljer"</string>
<string name="close" msgid="3043722427445528732">"Lukk"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Disse filene ble ikke kopiert: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Disse filene ble ikke flyttet: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Disse filene er ikke kopiert: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Disse filene er ikke flyttet: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Disse filene ble ikke slettet: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Disse filene er konvertert til et annet format: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">Kopierte <xliff:g id="COUNT_1">%1$d</xliff:g> filer til utklippstavlen.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Kan ikke lime inn de valgte filene her."</string>
<string name="menu_rename" msgid="7678802479104285353">"Gi nytt navn"</string>
<string name="rename_error" msgid="4203041674883412606">"Kunne ikke gi dokumentet nytt navn"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Løs ut"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Noen filer er konvertert"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Vil du gi <xliff:g id="APPNAME"><b>^1</b></xliff:g> tilgang til <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>-katalogen på <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Vil du gi <xliff:g id="APPNAME"><b>^1</b></xliff:g> tilgang til <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>-katalogen?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Vil du gi <xliff:g id="APPNAME"><b>^1</b></xliff:g> tilgang til dataene dine – inkludert bilder og videoer – på <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Ikke spør igjen"</string>
<string name="allow" msgid="7225948811296386551">"Tillat"</string>
<string name="deny" msgid="2081879885755434506">"Avslå"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> er valgt</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> er valgt</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> varer</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> vare</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Vil du slette «<xliff:g id="NAME">%1$s</xliff:g>»?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Vil du slette «<xliff:g id="NAME">%1$s</xliff:g>»-mappen og innholdet i den?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">Vil du slette <xliff:g id="COUNT_1">%1$d</xliff:g> filer?</item>
+ <item quantity="one">Vil du slette <xliff:g id="COUNT_0">%1$d</xliff:g> fil?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">Vil du slette <xliff:g id="COUNT_1">%1$d</xliff:g> mapper og innholdet i dem?</item>
+ <item quantity="one">Vil du slette <xliff:g id="COUNT_0">%1$d</xliff:g> mappe og innholdet i den?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other">Vil du slette <xliff:g id="COUNT_1">%1$d</xliff:g> elementer?</item>
+ <item quantity="one">Vil du slette <xliff:g id="COUNT_0">%1$d</xliff:g> element?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-ne-rNP/config.xml b/packages/DocumentsUI/res/values-ne-rNP/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-ne-rNP/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-ne-rNP/strings.xml b/packages/DocumentsUI/res/values-ne-rNP/strings.xml
index 45934ad1d53e..ab8f8b1c0291 100644
--- a/packages/DocumentsUI/res/values-ne-rNP/strings.xml
+++ b/packages/DocumentsUI/res/values-ne-rNP/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"कागजातहरू"</string>
- <string name="files_label" msgid="6051402950202690279">"फाइलहरू"</string>
<string name="downloads_label" msgid="959113951084633612">"डाउनलोडहरू"</string>
<string name="title_open" msgid="4353228937663917801">"यसबाट खोल्नुहोस्"</string>
<string name="title_save" msgid="2433679664882857999">"यसमा सुरक्षित गर्नुहोस्"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"सूची दृश्य"</string>
<string name="menu_sort" msgid="7677740407158414452">"यसद्वारा क्रमवद्घ गर्नुहोस्"</string>
<string name="menu_search" msgid="3816712084502856974">"खोज्नुहोस्"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"भण्डारण सेटिङहरू"</string>
<string name="menu_open" msgid="432922957274920903">"खोल्नुहोस्"</string>
<string name="menu_save" msgid="2394743337684426338">"सुरक्षित गर्नुहोस्"</string>
<string name="menu_share" msgid="3075149983979628146">"साझेदारी गर्नुहोस्"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"यसमा प्रतिलिपि गर्नुहोस् ..."</string>
<string name="menu_move" msgid="1828090633118079817">"…मा सार्नुहोस्"</string>
<string name="menu_new_window" msgid="1226032889278727538">"नयाँ विन्डो"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"काट्नुहोस्"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"प्रतिलिपि बनाउनुहोस्"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"टाँस्नुहोस्"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"आन्तरिक भण्डारण देखाउनुहोस्"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"मूलहरू लुकाउनुहोस्"</string>
<string name="save_error" msgid="6167009778003223664">"कागजात सुरक्षित गर्न विफल भयो"</string>
<string name="create_error" msgid="3735649141335444215">"फोल्डर सिर्जना गर्न असफल भयो"</string>
- <string name="query_error" msgid="1222448261663503501">"कागजातहरुको जिज्ञासा राख्न असफल भयो"</string>
+ <string name="query_error" msgid="5999895349602476581">"अहिले सामग्री लोड गर्न सक्दैन"</string>
<string name="root_recent" msgid="4470053704320518133">"हालैको"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> खाली"</string>
<string name="root_type_service" msgid="2178854894416775409">"भण्डारण सेवाहरू"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"थप अनुप्रयोगहरू"</string>
<string name="empty" msgid="7858882803708117596">"कुनै वस्तु छैन।"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s मा कुनै पनि मेल खानेहरू छैन"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"फाइल खोल्न सक्दैन"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"फाइल खोल्न सक्दैन"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"केही कागजातहरू मेट्न असमर्थ छ"</string>
<string name="share_via" msgid="8966594246261344259">"माध्यमबाट साझेदारी गर्नुहोस्"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"फाइलहरू प्रतिलिपि गर्दै:"</string>
<string name="move_notification_title" msgid="6193835179777284805">"फाइलहरू सार्दै"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"फाइलहरूलाई मेट्दै"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g>बाँकी"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g>फाइलहरू प्रतिलिप गर्दै।</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"प्रतिलिपिको लागि तयारी गर्दै ..."</string>
<string name="move_preparing" msgid="2772219441375531410">"सार्नको लागि तयारी गर्दै ..."</string>
<string name="delete_preparing" msgid="5655813182533491992">"मेटाउन तयारी गर्दै..."</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> फाइलहरू प्रतिलिपि गर्न सकेन</item>
<item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> फाइल प्रतिलिपि गर्न सकेन</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <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 name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> फाइलहरू सार्न सकेन</item>
+ <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> फाइल सार्न सकेन</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
- <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 name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> फाइलहरू मेटाउन सकेन</item>
+ <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> फाइल मेटाउन सकेन</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"विवरणहरू हेर्न ट्याप गर्नुहोस्"</string>
<string name="close" msgid="3043722427445528732">"बन्द गर्नुहोस्"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"यी फाइलहरू प्रतिलिपि गरिएको थिएनः <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"यी फाइलहरू सारिएनन्: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"यी फाइलहरू प्रतिलिपि गरिएको थिएनः <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"यी फाइलहरू सारिएको थिएन: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"यी फाइलहरूलाई मेटाइएको थिएन: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"यी फाइलहरू अर्को ढाँचामा परिणत गरिएका थिए: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other"> क्लिपबोर्डमा <xliff:g id="COUNT_1">%1$d</xliff:g> फाइलहरू प्रतिलिपि बनाइए।</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"यो स्थानमा चयन गरिएका फाइलहरू टाँस्न सकिँदैन।"</string>
<string name="menu_rename" msgid="7678802479104285353">"पुन: नामाकरण गर्नुहोस्"</string>
<string name="rename_error" msgid="4203041674883412606">"कागजात पुन: नामाकरण गर्न असफल भयो"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"निकाल्नुहोस्"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"केही फाइलहरू परिवर्तन गरिएका थिए"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> लाई <xliff:g id="STORAGE"><i>^3</i></xliff:g> मा भएको <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिकामा पहुँच गर्न अनुमति दिने हो?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> लाई <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिकामाथि पहुँच गर्न अनुमति प्रदान गर्ने हो?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> लाई <xliff:g id="STORAGE"><i>^2</i></xliff:g> मा भएका तस्बिर र भिडियोहरू लगायत तपाईँको डेटामा पहुँच गर्नका लागि अनुमति दिने हो?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"फेरि नसोध्नुहोस्"</string>
<string name="allow" msgid="7225948811296386551">"अनुमति दिनुहोस्"</string>
<string name="deny" msgid="2081879885755434506">"अस्वीकार गर्नुहोस्"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> लाई चयन गरियो</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> लाई चयन गरियो</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> वस्तुहरू</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> वस्तु</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" लाई मेट्ने हो?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"फोल्डर \"<xliff:g id="NAME">%1$s</xliff:g>\" र यसका सामग्रीहरूलाई मेट्ने हो?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फाइलहरूलाई मेट्ने हो?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> फाइललाई मेट्ने हो?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फोल्डरहरू र तिनीहरूका सामग्रीहरूलाई मेट्ने हो?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> फोल्डर र यसका सामग्रीहरूलाई मेट्ने हो?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <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>
</resources>
diff --git a/packages/DocumentsUI/res/values-nl/config.xml b/packages/DocumentsUI/res/values-nl/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-nl/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-nl/strings.xml b/packages/DocumentsUI/res/values-nl/strings.xml
index b613da3dd089..6eb9aac3f8ad 100644
--- a/packages/DocumentsUI/res/values-nl/strings.xml
+++ b/packages/DocumentsUI/res/values-nl/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documenten"</string>
- <string name="files_label" msgid="6051402950202690279">"Bestanden"</string>
<string name="downloads_label" msgid="959113951084633612">"Downloads"</string>
<string name="title_open" msgid="4353228937663917801">"Openen vanuit"</string>
<string name="title_save" msgid="2433679664882857999">"Opslaan in"</string>
@@ -35,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Kopiëren naar…"</string>
<string name="menu_move" msgid="1828090633118079817">"Verplaatsen naar…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Nieuw venster"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Knippen"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopiëren"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Plakken"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Interne opslag weergeven"</string>
@@ -53,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Roots verbergen"</string>
<string name="save_error" msgid="6167009778003223664">"Kan document niet opslaan"</string>
<string name="create_error" msgid="3735649141335444215">"Kan map niet maken"</string>
- <string name="query_error" msgid="1222448261663503501">"Kan geen query\'s voor documenten verzenden"</string>
+ <string name="query_error" msgid="5999895349602476581">"Kan content momenteel niet laden"</string>
<string name="root_recent" msgid="4470053704320518133">"Recent"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> vrij"</string>
<string name="root_type_service" msgid="2178854894416775409">"Opslagservices"</string>
@@ -62,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Meer apps"</string>
<string name="empty" msgid="7858882803708117596">"Geen items"</string>
<string name="no_results" msgid="6622510343880730446">"Geen overeenkomsten in %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Kan bestand niet openen"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Kan bestand niet openen"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Kan bepaalde documenten niet verwijderen"</string>
<string name="share_via" msgid="8966594246261344259">"Delen via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Bestanden kopiëren"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Bestanden verplaatsen"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Bestanden verwijderen"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> resterend"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> bestanden kopiëren.</item>
@@ -84,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Kopiëren voorbereiden…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Verplaatsen voorbereiden…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Verwijderen voorbereiden…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other">Kan <xliff:g id="COUNT_1">%1$d</xliff:g> bestanden niet kopiëren</item>
<item quantity="one">Kan <xliff:g id="COUNT_0">%1$d</xliff:g> bestand niet kopiëren</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other">Kan <xliff:g id="COUNT_1">%1$d</xliff:g> bestanden niet verplaatsen</item>
<item quantity="one">Kan <xliff:g id="COUNT_0">%1$d</xliff:g> bestand niet verplaatsen</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other">Kan <xliff:g id="COUNT_1">%1$d</xliff:g> bestanden niet verwijderen</item>
<item quantity="one">Kan <xliff:g id="COUNT_0">%1$d</xliff:g> bestand niet verwijderen</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Tik om details te bekijken"</string>
<string name="close" msgid="3043722427445528732">"Sluiten"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Deze bestanden zijn niet gekopieerd: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Deze bestanden zijn niet verplaatst: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Deze bestanden zijn niet gekopieerd: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Deze bestanden zijn niet verplaatst: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Deze bestanden zijn niet verwijderd: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Deze bestanden zijn geconverteerd vanuit een andere indeling: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> bestanden gekopieerd naar klembord.</item>
@@ -108,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Kan de geselecteerde bestanden niet plakken op deze locatie."</string>
<string name="menu_rename" msgid="7678802479104285353">"Naam wijzigen"</string>
<string name="rename_error" msgid="4203041674883412606">"Kan naam van document niet wijzigen"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Uitwerpen"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Sommige bestanden zijn geconverteerd"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang verlenen tot de map <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> op <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang verlenen tot de map <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang verlenen tot je gegevens, waaronder foto\'s en video\'s, op <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Niet meer vragen"</string>
<string name="allow" msgid="7225948811296386551">"Toestaan"</string>
<string name="deny" msgid="2081879885755434506">"Weigeren"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> geselecteerd</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> geselecteerd</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> items</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"<xliff:g id="NAME">%1$s</xliff:g> verwijderen?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Map <xliff:g id="NAME">%1$s</xliff:g> en de bijbehorende inhoud verwijderen?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> bestanden verwijderen?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> bestand verwijderen?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> mappen en de bijbehorende inhoud verwijderen?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> map en de bijbehorende inhoud verwijderen?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> items verwijderen?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> item verwijderen?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-pa-rIN/config.xml b/packages/DocumentsUI/res/values-pa-rIN/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-pa-rIN/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-pa-rIN/strings.xml b/packages/DocumentsUI/res/values-pa-rIN/strings.xml
index d5eeb66f9064..f53cccf93cb6 100644
--- a/packages/DocumentsUI/res/values-pa-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-pa-rIN/strings.xml
@@ -17,24 +17,24 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ਦਸਤਾਵੇਜ਼"</string>
- <string name="files_label" msgid="6051402950202690279">"ਫਾਈਲਾਂ"</string>
<string name="downloads_label" msgid="959113951084633612">"ਡਾਊਨਲੋਡ"</string>
<string name="title_open" msgid="4353228937663917801">"ਤੋਂ ਖੋਲ੍ਹੋ"</string>
- <string name="title_save" msgid="2433679664882857999">"ਇਸ ਵਿੱਚ ਸੁਰੱਖਿਅਤ ਕਰੋ"</string>
+ <string name="title_save" msgid="2433679664882857999">"ਇਸ ਵਿੱਚ ਰੱਖਿਅਤ ਕਰੋ"</string>
<string name="menu_create_dir" msgid="2547620241173881754">"ਨਵਾਂ ਫੋਲਡਰ"</string>
<string name="menu_grid" msgid="6878021334497835259">"ਗ੍ਰਿਡ ਵਿਊ"</string>
<string name="menu_list" msgid="7279285939892417279">"ਸੂਚੀ ਦ੍ਰਿਸ਼"</string>
- <string name="menu_sort" msgid="7677740407158414452">"ਇਸ ਅਨੁਸਾਰ ਛਾਂਟੋ"</string>
+ <string name="menu_sort" msgid="7677740407158414452">"ਇਸ ਮੁਤਾਬਕ ਛਾਂਟੋ"</string>
<string name="menu_search" msgid="3816712084502856974">"ਖੋਜੋ"</string>
<string name="menu_settings" msgid="8239065133341597825">"ਸਟੋਰੇਜ ਸੈਟਿੰਗਾਂ"</string>
<string name="menu_open" msgid="432922957274920903">"ਖੋਲ੍ਹੋ"</string>
- <string name="menu_save" msgid="2394743337684426338">"ਸੁਰੱਖਿਅਤ ਕਰੋ"</string>
- <string name="menu_share" msgid="3075149983979628146">"ਸ਼ੇਅਰ ਕਰੋ"</string>
+ <string name="menu_save" msgid="2394743337684426338">"ਰੱਖਿਅਤ ਕਰੋ"</string>
+ <string name="menu_share" msgid="3075149983979628146">"ਸਾਂਝਾ ਕਰੋ"</string>
<string name="menu_delete" msgid="8138799623850614177">"ਮਿਟਾਓ"</string>
- <string name="menu_select_all" msgid="8323579667348729928">"ਸਾਰੇ ਚੁਣੋ"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"ਸਭ ਚੁਣੋ"</string>
<string name="menu_copy" msgid="3612326052677229148">"ਇਸ ਵਿੱਚ ਕਾਪੀ ਕਰੋ…"</string>
- <string name="menu_move" msgid="1828090633118079817">"ਇਸ ਵਿੱਚ ਮੂਵ ਕਰੋ..."</string>
+ <string name="menu_move" msgid="1828090633118079817">"ਏਥੇ ਤਬਾਦਲਾ ਕਰੋ..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"ਨਵੀਂ ਵਿੰਡੋ"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"ਕੱਟੋ"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"ਕਾਪੀ ਕਰੋ"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"ਪੇਸਟ ਕਰੋ"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"ਅੰਦਰੂਨੀ ਸਟੋਰੇਜ ਦਿਖਾਓ"</string>
@@ -44,16 +44,16 @@
<string name="button_select" msgid="527196987259139214">"ਚੁਣੋ"</string>
<string name="button_copy" msgid="8706475544635021302">"ਕਾਪੀ ਕਰੋ"</string>
<string name="button_move" msgid="2202666023104202232">"ਮੂਵ ਕਰੋ"</string>
- <string name="button_dismiss" msgid="3714065566893946085">"ਬਰਖਾਸਤ ਕਰੋ"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"ਖਾਰਜ ਕਰੋ"</string>
<string name="button_retry" msgid="4392027584153752797">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
<string name="sort_name" msgid="9183560467917256779">"ਨਾਮ ਮੁਤਾਬਕ"</string>
- <string name="sort_date" msgid="586080032956151448">"ਤਾਰੀਖ ਮੁਤਾਬਕ ਸੰਸ਼ੋਧਿਤ"</string>
+ <string name="sort_date" msgid="586080032956151448">"ਸੋਧੇ ਜਾਣ ਦੀ ਤਾਰੀਖ਼ ਮੁਤਾਬਕ"</string>
<string name="sort_size" msgid="3350681319735474741">"ਆਕਾਰ ਮੁਤਾਬਕ"</string>
<string name="drawer_open" msgid="4545466532430226949">"ਰੂਟਸ ਦਿਖਾਓ"</string>
<string name="drawer_close" msgid="7602734368552123318">"ਰੂਟਸ ਲੁਕਾਓ"</string>
<string name="save_error" msgid="6167009778003223664">"ਦਸਾਤਵੇਜ਼ ਸੁਰੱਖਿਅਤ ਕਰਨ ਵਿੱਚ ਅਸਫਲ"</string>
<string name="create_error" msgid="3735649141335444215">"ਫੋਲਡਰ ਬਣਾਉਣ ਲਈ ਅਸਫਲ"</string>
- <string name="query_error" msgid="1222448261663503501">"ਦਸਤਾਵੇਜ਼ਾਂ ਦੀ ਪੁੱਛਗਿੱਛ ਕਰਨ ਵਿੱਚ ਅਸਫਲ"</string>
+ <string name="query_error" msgid="5999895349602476581">"ਇਸ ਵੇਲੇ ਸਮੱਗਰੀ ਨੂੰ ਲੋਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
<string name="root_recent" msgid="4470053704320518133">"ਹਾਲੀਆ"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ਖਾਲੀ"</string>
<string name="root_type_service" msgid="2178854894416775409">"ਸਟੋਰੇਜ ਸੇਵਾਵਾਂ"</string>
@@ -62,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"ਹੋਰ ਐਪਸ"</string>
<string name="empty" msgid="7858882803708117596">"ਕੋਈ ਆਈਟਮਾਂ ਨਹੀਂ"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s ਵਿੱਚ ਕੋਈ ਮੇਲ ਨਹੀਂ"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"ਫਾਈਲ ਨਹੀਂ ਖੋਲ੍ਹ ਸਕਦਾ"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"ਫ਼ਾਈਲ ਨੂੰ ਖੋਲ੍ਹਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"ਕੁਝ ਦਸਤਾਵੇਜ਼ ਮਿਟਾਉਣ ਵਿੱਚ ਅਸਮਰੱਥ"</string>
- <string name="share_via" msgid="8966594246261344259">"ਇਸ ਰਾਹੀਂ ਸ਼ੇਅਰ ਕਰੋ"</string>
+ <string name="share_via" msgid="8966594246261344259">"ਇਸ ਰਾਹੀਂ ਸਾਂਝਾ ਕਰੋ"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"ਫਾਈਲਾਂ ਕਾਪੀ ਕਰ ਰਿਹਾ ਹੈ"</string>
<string name="move_notification_title" msgid="6193835179777284805">"ਫ਼ਾਈਲਾਂ ਨੂੰ ਮੂਵ ਕਰ ਰਿਹਾ ਹੈ"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"ਫ਼ਾਈਲਾਂ ਨੂੰ ਮਿਟਾਇਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> ਬਾਕੀ"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> ਫਾਈਲਾਂ ਕਾਪੀ ਕਰ ਰਿਹਾ ਹੈ।</item>
@@ -80,26 +81,28 @@
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਮਿਟਾ ਰਿਹਾ ਹੈ।</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਮਿਟਾ ਰਿਹਾ ਹੈ।</item>
</plurals>
- <string name="undo" msgid="7905788502491742328">"ਪਹਿਲਾਂ ਵਰਗਾ ਕਰੋ"</string>
+ <string name="undo" msgid="7905788502491742328">"ਅਣਕੀਤਾ ਕਰੋ"</string>
<string name="copy_preparing" msgid="3896202461003039386">"ਕਾਪੀ ਲਈ ਤਿਆਰ ਕਰ ਰਿਹਾ ਹੈ…"</string>
<string name="move_preparing" msgid="2772219441375531410">"ਮੂਵ ਲਈ ਤਿਆਰ ਕਰ ਰਿਹਾ ਹੈ..."</string>
<string name="delete_preparing" msgid="5655813182533491992">"ਮਿਟਾਉਣ ਦੀ ਤਿਆਰੀ ਹੋ ਰਹੀ ਹੈ…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <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>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਕਾਪੀ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਕਾਪੀ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਮੂਵ ਨਹੀਂ ਕਰ ਸਕਿਆ</item>
- <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਮੂਵ ਨਹੀਂ ਕਰ ਸਕਿਆ</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਤਬਦੀਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਤਬਦੀਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਮਿਟਾਇਆ ਨਹੀਂ ਜਾ ਸਕਿਆ</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਮਿਟਾਇਆ ਨਹੀਂ ਜਾ ਸਕਿਆ</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"ਵੇਰਵਿਆਂ ਨੂੰ ਵੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
<string name="close" msgid="3043722427445528732">"ਬੰਦ ਕਰੋ"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"ਇਹਨਾਂ ਫ਼ਾਈਲਾਂ ਦੀ ਪ੍ਰਤੀਲਿਪੀ ਨਹੀਂ ਬਣਾਈ ਗਈ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"ਇਹਨਾਂ ਫ਼ਾਈਲਾਂ ਨੂੰ ਮੂਵ ਨਹੀਂ ਕੀਤਾ ਗਿਆ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"ਇਹ ਫ਼ਾਈਲਾਂ ਕਾਪੀ ਨਹੀਂ ਹੋਈਆਂ ਸਨ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"ਇਹ ਫ਼ਾਈਲਾਂ ਤਬਦੀਲ ਨਹੀਂ ਹੋਈਆਂ ਸਨ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"ਇਹਨਾਂ ਫ਼ਾਈਲਾਂ ਨੂੰ ਮਿਟਾਇਆ ਨਹੀਂ ਗਿਆ ਸੀ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"ਇਹ ਫ਼ਾਈਲਾਂ ਕਿਸੇ ਹੋਰ ਫੌਰਮੈਟ ਵਿੱਚ ਤਬਦੀਲ ਕੀਤੀਆਂ ਗਈਆਂ ਸਨ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one">ਕਲਿੱਪਬੋਰਡ ਵਿੱਚ <xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਦੀ ਪ੍ਰਤੀਲਿਪੀ ਬਣਾਈ ਗਈ।</item>
@@ -108,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"ਇਸ ਸਥਾਨ ਵਿੱਚ ਚੁਣੀਆਂ ਗਈਆਂ ਫ਼ਾਈਲਾਂ ਨੂੰ ਪੇਸਟ ਨਹੀਂ ਕਰ ਸਕਦਾ ਹੈ।"</string>
<string name="menu_rename" msgid="7678802479104285353">"ਮੁੜ-ਨਾਮਕਰਨ ਕਰੋ"</string>
<string name="rename_error" msgid="4203041674883412606">"ਦਸਤਾਵੇਜ਼ ਦਾ ਮੁੜ-ਨਾਮਕਰਨ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"ਬਾਹਰ ਕੱਢੋ"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ਕੁਝ ਫ਼ਾਈਲਾਂ ਤਬਦੀਲ ਕੀਤੀਆਂ ਗਈਆਂ ਸਨ"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"ਕੀ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ਨੂੰ <xliff:g id="STORAGE"><i>^3</i></xliff:g> \'ਤੇ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ਡਾਇਰੈਕਟਰੀ \'ਤੇ ਪਹੁੰਚ ਦੇਣੀ ਹੈ?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"ਕੀ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ਨੂੰ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ਡਾਇਰੈਕਟਰੀ \'ਤੇ ਪਹੁੰਚ ਦੇਣੀ ਹੈ?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"ਕੀ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ਨੂੰ <xliff:g id="STORAGE"><i>^2</i></xliff:g> \'ਤੇ ਫੋਟੋਆਂ ਅਤੇ ਵੀਡੀਓ ਸਮੇਤ, ਤੁਹਾਡੇ ਡੈਟੇ \'ਤੇ ਪਹੁੰਚ ਦੇਣੀ ਹੈ?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"ਦੁਬਾਰਾ ਨਾ ਪੁੱਛੋ"</string>
<string name="allow" msgid="7225948811296386551">"ਆਗਿਆ ਦਿਓ"</string>
<string name="deny" msgid="2081879885755434506">"ਅਸਵੀਕਾਰ ਕਰੋ"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਚੁਣੀ ਗਈ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਚੁਣੀਆਂ ਗਈਆਂ</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਆਈਟਮਾਂ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਆਈਟਮਾਂ</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"ਕੀ \"<xliff:g id="NAME">%1$s</xliff:g>\" ਨੂੰ ਮਿਟਾਉਣਾ ਹੈ?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"ਫੋਲਡਰ \"<xliff:g id="NAME">%1$s</xliff:g>\" ਅਤੇ ਉਸ ਦੀਆਂ ਸਮੱਗਰੀਆਂ ਨੂੰ ਮਿਟਾਉਣਾ ਹੈ?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one">ਕੀ <xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਮਿਟਾਉਣਾ ਹੈ?</item>
+ <item quantity="other">ਕੀ <xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਮਿਟਾਉਣਾ ਹੈ?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one">ਕੀ <xliff:g id="COUNT_1">%1$d</xliff:g> ਫੋਲਡਰਾਂ ਅਤੇ ਉਹਨਾਂ ਦੀਆਂ ਸਮੱਗਰੀਆਂ ਨੂੰ ਮਿਟਾਉਣਾ ਹੈ?</item>
+ <item quantity="other">ਕੀ <xliff:g id="COUNT_1">%1$d</xliff:g> ਫੋਲਡਰਾਂ ਅਤੇ ਉਹਨਾਂ ਦੀਆਂ ਸਮੱਗਰੀਆਂ ਨੂੰ ਮਿਟਾਉਣਾ ਹੈ?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one">ਕੀ <xliff:g id="COUNT_1">%1$d</xliff:g> ਆਈਟਮਾਂ ਨੂੰ ਮਿਟਾਉਣਾ ਹੈ?</item>
+ <item quantity="other">ਕੀ <xliff:g id="COUNT_1">%1$d</xliff:g> ਆਈਟਮਾਂ ਨੂੰ ਮਿਟਾਉਣਾ ਹੈ?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-pl/config.xml b/packages/DocumentsUI/res/values-pl/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-pl/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-pl/strings.xml b/packages/DocumentsUI/res/values-pl/strings.xml
index 90f2bdfc775e..33baba9940af 100644
--- a/packages/DocumentsUI/res/values-pl/strings.xml
+++ b/packages/DocumentsUI/res/values-pl/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenty"</string>
- <string name="files_label" msgid="6051402950202690279">"Pliki"</string>
<string name="downloads_label" msgid="959113951084633612">"Pobrane"</string>
<string name="title_open" msgid="4353228937663917801">"Otwórz z"</string>
<string name="title_save" msgid="2433679664882857999">"Zapisz w"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Widok listy"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sortuj według"</string>
<string name="menu_search" msgid="3816712084502856974">"Szukaj"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Ustawienia pamięci"</string>
<string name="menu_open" msgid="432922957274920903">"Otwórz"</string>
<string name="menu_save" msgid="2394743337684426338">"Zapisz"</string>
<string name="menu_share" msgid="3075149983979628146">"Udostępnij"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Kopiuj do…"</string>
<string name="menu_move" msgid="1828090633118079817">"Przenieś do…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Nowe okno"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Wytnij"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopiuj"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Wklej"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Pokaż pamięć wewnętrzną"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Ukryj elementy główne"</string>
<string name="save_error" msgid="6167009778003223664">"Nie udało się zapisać dokumentu"</string>
<string name="create_error" msgid="3735649141335444215">"Nie udało się utworzyć folderu"</string>
- <string name="query_error" msgid="1222448261663503501">"Nie udało się pobrać listy dokumentów"</string>
+ <string name="query_error" msgid="5999895349602476581">"Teraz nie można załadować zawartości"</string>
<string name="root_recent" msgid="4470053704320518133">"Ostatnie"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> wolne"</string>
<string name="root_type_service" msgid="2178854894416775409">"Usługi pamięci masowej"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Więcej aplikacji"</string>
<string name="empty" msgid="7858882803708117596">"Brak elementów"</string>
<string name="no_results" msgid="6622510343880730446">"Brak wyników w %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Nie można otworzyć pliku"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Nie można otworzyć pliku"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Nie można usunąć niektórych dokumentów"</string>
<string name="share_via" msgid="8966594246261344259">"Udostępnij przez:"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopiowanie plików"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Przenoszenie plików"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Usuwam pliki"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Pozostało: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="few">Kopiowanie <xliff:g id="COUNT_1">%1$d</xliff:g> plików.</item>
@@ -91,19 +91,20 @@
<string name="copy_preparing" msgid="3896202461003039386">"Przygotowuję do kopiowania…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Przygotowuję przenoszenie…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Przygotowuję do usunięcia…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <item quantity="few">Nie można skopiować <xliff:g id="COUNT_1">%1$d</xliff:g> plików</item>
- <item quantity="many">Nie można skopiować <xliff:g id="COUNT_1">%1$d</xliff:g> plików</item>
- <item quantity="other">Nie można skopiować <xliff:g id="COUNT_1">%1$d</xliff:g> pliku</item>
- <item quantity="one">Nie można skopiować <xliff:g id="COUNT_0">%1$d</xliff:g> pliku</item>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="few">Nie udało się skopiować <xliff:g id="COUNT_1">%1$d</xliff:g> plików</item>
+ <item quantity="many">Nie udało się skopiować <xliff:g id="COUNT_1">%1$d</xliff:g> plików</item>
+ <item quantity="other">Nie udało się skopiować <xliff:g id="COUNT_1">%1$d</xliff:g> pliku</item>
+ <item quantity="one">Nie udało się skopiować <xliff:g id="COUNT_0">%1$d</xliff:g> pliku</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="few">Nie udało się przenieść <xliff:g id="COUNT_1">%1$d</xliff:g> plików</item>
<item quantity="many">Nie udało się przenieść <xliff:g id="COUNT_1">%1$d</xliff:g> plików</item>
<item quantity="other">Nie udało się przenieść <xliff:g id="COUNT_1">%1$d</xliff:g> pliku</item>
<item quantity="one">Nie udało się przenieść <xliff:g id="COUNT_0">%1$d</xliff:g> pliku</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="few">Nie udało się usunąć <xliff:g id="COUNT_1">%1$d</xliff:g> plików</item>
<item quantity="many">Nie udało się usunąć <xliff:g id="COUNT_1">%1$d</xliff:g> plików</item>
<item quantity="other">Nie udało się usunąć <xliff:g id="COUNT_1">%1$d</xliff:g> pliku</item>
@@ -111,8 +112,9 @@
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Kliknij, by zobaczyć szczegóły"</string>
<string name="close" msgid="3043722427445528732">"Zamknij"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Te pliki nie zostały skopiowane: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Te pliki nie zostały przeniesione: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Te pliki nie zostały skopiowane: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Te pliki nie zostały przeniesione: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Te pliki nie zostały usunięte: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Te pliki zostały przekonwertowane na inny format: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="few">Skopiowano <xliff:g id="COUNT_1">%1$d</xliff:g> pliki do schowka.</item>
@@ -123,7 +125,44 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Nie można wkleić wybranych plików w tej lokalizacji."</string>
<string name="menu_rename" msgid="7678802479104285353">"Zmień nazwę"</string>
<string name="rename_error" msgid="4203041674883412606">"Nie udało się zmienić nazwy dokumentu"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Odłącz"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Niektóre pliki zostały przekonwertowane"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Zezwolić aplikacji <xliff:g id="APPNAME"><b>^1</b></xliff:g> na dostęp do katalogu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> w pamięci masowej <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Przyznać aplikacji <xliff:g id="APPNAME"><b>^1</b></xliff:g> dostęp do katalogu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Zezwolić aplikacji <xliff:g id="APPNAME"><b>^1</b></xliff:g> na dostęp do Twoich danych, w tym zdjęć i filmów, zapisanych w pamięci <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Nie pytaj ponownie"</string>
<string name="allow" msgid="7225948811296386551">"Zezwól"</string>
<string name="deny" msgid="2081879885755434506">"Odmów"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="few">Wybrano <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="many">Wybrano <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">Wybrano <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">Wybrano <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> elementy</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> elementów</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementu</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> element</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Usunąć „<xliff:g id="NAME">%1$s</xliff:g>”?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Usunąć folder „<xliff:g id="NAME">%1$s</xliff:g>” i jego zawartość?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="few">Usunąć <xliff:g id="COUNT_1">%1$d</xliff:g> pliki?</item>
+ <item quantity="many">Usunąć <xliff:g id="COUNT_1">%1$d</xliff:g> plików?</item>
+ <item quantity="other">Usunąć <xliff:g id="COUNT_1">%1$d</xliff:g> pliku?</item>
+ <item quantity="one">Usunąć <xliff:g id="COUNT_0">%1$d</xliff:g> plik?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="few">Usunąć <xliff:g id="COUNT_1">%1$d</xliff:g> foldery wraz z zawartością?</item>
+ <item quantity="many">Usunąć <xliff:g id="COUNT_1">%1$d</xliff:g> folderów wraz z zawartością?</item>
+ <item quantity="other">Usunąć <xliff:g id="COUNT_1">%1$d</xliff:g> folderu wraz z zawartością?</item>
+ <item quantity="one">Usunąć <xliff:g id="COUNT_0">%1$d</xliff:g> folder wraz z zawartością?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="few">Usunąć <xliff:g id="COUNT_1">%1$d</xliff:g> elementy?</item>
+ <item quantity="many">Usunąć <xliff:g id="COUNT_1">%1$d</xliff:g> elementów?</item>
+ <item quantity="other">Usunąć <xliff:g id="COUNT_1">%1$d</xliff:g> elementu?</item>
+ <item quantity="one">Usunąć <xliff:g id="COUNT_0">%1$d</xliff:g> element?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-pt-rBR/config.xml b/packages/DocumentsUI/res/values-pt-rBR/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-pt-rBR/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-pt-rBR/strings.xml b/packages/DocumentsUI/res/values-pt-rBR/strings.xml
index f72f43c57848..718d70f413c3 100644
--- a/packages/DocumentsUI/res/values-pt-rBR/strings.xml
+++ b/packages/DocumentsUI/res/values-pt-rBR/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documentos"</string>
- <string name="files_label" msgid="6051402950202690279">"Arquivos"</string>
<string name="downloads_label" msgid="959113951084633612">"Downloads"</string>
<string name="title_open" msgid="4353228937663917801">"Abrir de"</string>
<string name="title_save" msgid="2433679664882857999">"Salvar em"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Visualização em lista"</string>
<string name="menu_sort" msgid="7677740407158414452">"Classificar por"</string>
<string name="menu_search" msgid="3816712084502856974">"Pesquisar"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Configurações de armazenamento"</string>
<string name="menu_open" msgid="432922957274920903">"Abrir"</string>
<string name="menu_save" msgid="2394743337684426338">"Salvar"</string>
<string name="menu_share" msgid="3075149983979628146">"Compartilhar"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Copiar para..."</string>
<string name="menu_move" msgid="1828090633118079817">"Mover para..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"Nova janela"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Cortar"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copiar"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Colar"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Mostrar armaz. interno"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Ocultar raízes"</string>
<string name="save_error" msgid="6167009778003223664">"Falha ao salvar o documento"</string>
<string name="create_error" msgid="3735649141335444215">"Falha ao criar a pasta"</string>
- <string name="query_error" msgid="1222448261663503501">"Falha ao consultar documentos"</string>
+ <string name="query_error" msgid="5999895349602476581">"Não é possível carregar o conteúdo no momento"</string>
<string name="root_recent" msgid="4470053704320518133">"Recentes"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> livres"</string>
<string name="root_type_service" msgid="2178854894416775409">"Serviços de armazenamento"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Mais apps"</string>
<string name="empty" msgid="7858882803708117596">"Nenhum item"</string>
<string name="no_results" msgid="6622510343880730446">"Nenhum resultado em %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Não é possível abrir o arquivo"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Não é possível abrir o arquivo"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Não foi possível excluir alguns documentos"</string>
<string name="share_via" msgid="8966594246261344259">"Compartilhar via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Copiando arquivos"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Movendo arquivos"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Excluindo arquivos"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> restantes"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Copiando <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar..."</string>
<string name="move_preparing" msgid="2772219441375531410">"Preparando para mover..."</string>
<string name="delete_preparing" msgid="5655813182533491992">"Preparando-se para excluir..."</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="one">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
<item quantity="other">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="one">Não foi possível mover <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
<item quantity="other">Não foi possível mover <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="one">Não foi possível excluir <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
<item quantity="other">Não foi possível excluir <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Tocar para ver detalhes"</string>
<string name="close" msgid="3043722427445528732">"Fechar"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Estes arquivos não foram copiados: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Estes arquivos não foram movidos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Estes arquivos não foram copiados: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Estes arquivos não foram movidos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Estes arquivos não foram excluídos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Esses arquivos foram convertidos em outro formato: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> arquivos copiados para a área de transferência.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Não é possível colar os arquivos selecionados neste local."</string>
<string name="menu_rename" msgid="7678802479104285353">"Renomear"</string>
<string name="rename_error" msgid="4203041674883412606">"Falha ao renomear documento"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Ejetar"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Alguns arquivos foram convertidos"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Conceder ao <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> no <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Conceder acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> para <xliff:g id="APPNAME"><b>^1</b></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso aos seus dados, incluindo fotos e vídeos, no/na <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Não perguntar novamente"</string>
<string name="allow" msgid="7225948811296386551">"Permitir"</string>
<string name="deny" msgid="2081879885755434506">"Negar"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionado</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> itens</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> itens</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Excluir \" <xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Excluir pasta \"<xliff:g id="NAME">%1$s</xliff:g>\" e o respectivo conteúdo?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one">Excluir <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos?</item>
+ <item quantity="other">Excluir <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one">Excluir <xliff:g id="COUNT_1">%1$d</xliff:g> pastas e o respectivo conteúdo?</item>
+ <item quantity="other">Excluir <xliff:g id="COUNT_1">%1$d</xliff:g> pastas e o respectivo conteúdo?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one">Excluir <xliff:g id="COUNT_1">%1$d</xliff:g> itens?</item>
+ <item quantity="other">Excluir <xliff:g id="COUNT_1">%1$d</xliff:g> itens?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-pt-rPT/config.xml b/packages/DocumentsUI/res/values-pt-rPT/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-pt-rPT/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-pt-rPT/strings.xml b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
index 596474fde6ad..e382def3a18d 100644
--- a/packages/DocumentsUI/res/values-pt-rPT/strings.xml
+++ b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documentos"</string>
- <string name="files_label" msgid="6051402950202690279">"Ficheiros"</string>
<string name="downloads_label" msgid="959113951084633612">"Transferências"</string>
<string name="title_open" msgid="4353228937663917801">"Abrir de"</string>
<string name="title_save" msgid="2433679664882857999">"Guardar em"</string>
@@ -35,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Copiar para…"</string>
<string name="menu_move" msgid="1828090633118079817">"Mover para..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"Nova janela"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Cortar"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copiar"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Colar"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Mostrar mem. armaz. int."</string>
@@ -53,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Ocultar raízes"</string>
<string name="save_error" msgid="6167009778003223664">"Falha ao guardar o documento"</string>
<string name="create_error" msgid="3735649141335444215">"Falha ao criar a pasta"</string>
- <string name="query_error" msgid="1222448261663503501">"Falha ao consultar os documentos"</string>
+ <string name="query_error" msgid="5999895349602476581">"Não é possível carregar o conteúdo neste momento"</string>
<string name="root_recent" msgid="4470053704320518133">"Recentes"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> espaço livre"</string>
<string name="root_type_service" msgid="2178854894416775409">"Serv. de armazenamento"</string>
@@ -62,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Mais aplicações"</string>
<string name="empty" msgid="7858882803708117596">"Sem itens"</string>
<string name="no_results" msgid="6622510343880730446">"Sem correspondências para %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Não é possível abrir o ficheiro"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Não é possível abrir o ficheiro"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Não é possível eliminar alguns documentos"</string>
<string name="share_via" msgid="8966594246261344259">"Partilhar através de"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"A copiar ficheiros"</string>
<string name="move_notification_title" msgid="6193835179777284805">"A mover ficheiros"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Eliminar ficheiros"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Faltam <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">A copiar <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros.</item>
@@ -84,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"A preparar para copiar…"</string>
<string name="move_preparing" msgid="2772219441375531410">"A preparar para mover…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"A preparar para eliminar…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros</item>
<item quantity="one">Não foi possível copiar <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other">Não foi possível mover <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros</item>
<item quantity="one">Não foi possível mover <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other">Não foi possível eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros</item>
<item quantity="one">Não foi possível eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Toque para ver detalhes"</string>
<string name="close" msgid="3043722427445528732">"Fechar"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Os seguintes ficheiros não foram copiados: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Os seguintes ficheiros não foram movidos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Os seguintes ficheiros não foram copiados: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Os seguintes ficheiros não foram movidos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Estes ficheiros não foram eliminados: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Estes ficheiros foram convertidos para outro formato: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">Copiou <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros para a área de transferência.</item>
@@ -108,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Não é possível colar os ficheiros selecionados nesta localização."</string>
<string name="menu_rename" msgid="7678802479104285353">"Mudar o nome"</string>
<string name="rename_error" msgid="4203041674883412606">"Falha ao mudar o nome do documento"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Ejetar"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Alguns ficheiros foram convertidos"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Pretende conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> no(a) <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Pretende conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Pretende conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso aos seus dados, incluindo fotos e vídeos, no(a) <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Não perguntar novamente"</string>
<string name="allow" msgid="7225948811296386551">"Permitir"</string>
<string name="deny" msgid="2081879885755434506">"Recusar"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selecionado</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> itens</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> item</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Pretende eliminar \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Pretende eliminar a pasta \"<xliff:g id="NAME">%1$s</xliff:g>\" e os respetivos conteúdos?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">Pretende eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros?</item>
+ <item quantity="one">Pretende eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">Pretende eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> pastas e os respetivos conteúdos?</item>
+ <item quantity="one">Pretende eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> pasta e os respetivos conteúdos?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other">Pretende eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> itens?</item>
+ <item quantity="one">Pretende eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> item?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-pt/config.xml b/packages/DocumentsUI/res/values-pt/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-pt/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-pt/strings.xml b/packages/DocumentsUI/res/values-pt/strings.xml
index f72f43c57848..718d70f413c3 100644
--- a/packages/DocumentsUI/res/values-pt/strings.xml
+++ b/packages/DocumentsUI/res/values-pt/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documentos"</string>
- <string name="files_label" msgid="6051402950202690279">"Arquivos"</string>
<string name="downloads_label" msgid="959113951084633612">"Downloads"</string>
<string name="title_open" msgid="4353228937663917801">"Abrir de"</string>
<string name="title_save" msgid="2433679664882857999">"Salvar em"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Visualização em lista"</string>
<string name="menu_sort" msgid="7677740407158414452">"Classificar por"</string>
<string name="menu_search" msgid="3816712084502856974">"Pesquisar"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Configurações de armazenamento"</string>
<string name="menu_open" msgid="432922957274920903">"Abrir"</string>
<string name="menu_save" msgid="2394743337684426338">"Salvar"</string>
<string name="menu_share" msgid="3075149983979628146">"Compartilhar"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Copiar para..."</string>
<string name="menu_move" msgid="1828090633118079817">"Mover para..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"Nova janela"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Cortar"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copiar"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Colar"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Mostrar armaz. interno"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Ocultar raízes"</string>
<string name="save_error" msgid="6167009778003223664">"Falha ao salvar o documento"</string>
<string name="create_error" msgid="3735649141335444215">"Falha ao criar a pasta"</string>
- <string name="query_error" msgid="1222448261663503501">"Falha ao consultar documentos"</string>
+ <string name="query_error" msgid="5999895349602476581">"Não é possível carregar o conteúdo no momento"</string>
<string name="root_recent" msgid="4470053704320518133">"Recentes"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> livres"</string>
<string name="root_type_service" msgid="2178854894416775409">"Serviços de armazenamento"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Mais apps"</string>
<string name="empty" msgid="7858882803708117596">"Nenhum item"</string>
<string name="no_results" msgid="6622510343880730446">"Nenhum resultado em %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Não é possível abrir o arquivo"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Não é possível abrir o arquivo"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Não foi possível excluir alguns documentos"</string>
<string name="share_via" msgid="8966594246261344259">"Compartilhar via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Copiando arquivos"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Movendo arquivos"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Excluindo arquivos"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> restantes"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Copiando <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar..."</string>
<string name="move_preparing" msgid="2772219441375531410">"Preparando para mover..."</string>
<string name="delete_preparing" msgid="5655813182533491992">"Preparando-se para excluir..."</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="one">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
<item quantity="other">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="one">Não foi possível mover <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
<item quantity="other">Não foi possível mover <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="one">Não foi possível excluir <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
<item quantity="other">Não foi possível excluir <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Tocar para ver detalhes"</string>
<string name="close" msgid="3043722427445528732">"Fechar"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Estes arquivos não foram copiados: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Estes arquivos não foram movidos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Estes arquivos não foram copiados: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Estes arquivos não foram movidos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Estes arquivos não foram excluídos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Esses arquivos foram convertidos em outro formato: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> arquivos copiados para a área de transferência.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Não é possível colar os arquivos selecionados neste local."</string>
<string name="menu_rename" msgid="7678802479104285353">"Renomear"</string>
<string name="rename_error" msgid="4203041674883412606">"Falha ao renomear documento"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Ejetar"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Alguns arquivos foram convertidos"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Conceder ao <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> no <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Conceder acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> para <xliff:g id="APPNAME"><b>^1</b></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso aos seus dados, incluindo fotos e vídeos, no/na <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Não perguntar novamente"</string>
<string name="allow" msgid="7225948811296386551">"Permitir"</string>
<string name="deny" msgid="2081879885755434506">"Negar"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionado</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> itens</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> itens</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Excluir \" <xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Excluir pasta \"<xliff:g id="NAME">%1$s</xliff:g>\" e o respectivo conteúdo?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one">Excluir <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos?</item>
+ <item quantity="other">Excluir <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one">Excluir <xliff:g id="COUNT_1">%1$d</xliff:g> pastas e o respectivo conteúdo?</item>
+ <item quantity="other">Excluir <xliff:g id="COUNT_1">%1$d</xliff:g> pastas e o respectivo conteúdo?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one">Excluir <xliff:g id="COUNT_1">%1$d</xliff:g> itens?</item>
+ <item quantity="other">Excluir <xliff:g id="COUNT_1">%1$d</xliff:g> itens?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-ro/config.xml b/packages/DocumentsUI/res/values-ro/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-ro/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-ro/strings.xml b/packages/DocumentsUI/res/values-ro/strings.xml
index 07f25f63d462..8bf3880639f2 100644
--- a/packages/DocumentsUI/res/values-ro/strings.xml
+++ b/packages/DocumentsUI/res/values-ro/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documente"</string>
- <string name="files_label" msgid="6051402950202690279">"Fișiere"</string>
<string name="downloads_label" msgid="959113951084633612">"Descărcări"</string>
<string name="title_open" msgid="4353228937663917801">"Deschideți din"</string>
<string name="title_save" msgid="2433679664882857999">"Salvați în"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Afișare tip listă"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sortați după"</string>
<string name="menu_search" msgid="3816712084502856974">"Căutați"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Setări de stocare"</string>
<string name="menu_open" msgid="432922957274920903">"Deschideți"</string>
<string name="menu_save" msgid="2394743337684426338">"Salvați"</string>
<string name="menu_share" msgid="3075149983979628146">"Distribuiți"</string>
@@ -36,12 +34,13 @@
<string name="menu_copy" msgid="3612326052677229148">"Copiați în…"</string>
<string name="menu_move" msgid="1828090633118079817">"Mutați în…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Fereastră nouă"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Decupați"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copiați"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Inserați"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Afișați stocarea internă"</string>
<string name="menu_advanced_hide" msgid="4218809952721972589">"Ascundeți stocarea internă"</string>
- <string name="menu_file_size_show" msgid="3240323619260823076">"Afișați mărime fișiere"</string>
- <string name="menu_file_size_hide" msgid="8881975928502581042">"Ascundeți mărime fișiere"</string>
+ <string name="menu_file_size_show" msgid="3240323619260823076">"Afișați dimensiunea"</string>
+ <string name="menu_file_size_hide" msgid="8881975928502581042">"Ascundeți dimensiunea"</string>
<string name="button_select" msgid="527196987259139214">"Selectați"</string>
<string name="button_copy" msgid="8706475544635021302">"Copiați"</string>
<string name="button_move" msgid="2202666023104202232">"Mutați"</string>
@@ -54,20 +53,21 @@
<string name="drawer_close" msgid="7602734368552123318">"Ascundeți directoarele rădăcină"</string>
<string name="save_error" msgid="6167009778003223664">"Salvarea documentului nu a reușit"</string>
<string name="create_error" msgid="3735649141335444215">"Eroare la crearea dosarului"</string>
- <string name="query_error" msgid="1222448261663503501">"Interogarea referitoare la documente nu a reușit"</string>
+ <string name="query_error" msgid="5999895349602476581">"Momentan, conținutul nu poate fi încărcat"</string>
<string name="root_recent" msgid="4470053704320518133">"Recente"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> spațiu liber"</string>
<string name="root_type_service" msgid="2178854894416775409">"Servicii de stocare"</string>
<string name="root_type_shortcut" msgid="3318760609471618093">"Comenzi rapide"</string>
<string name="root_type_device" msgid="7121342474653483538">"Dispozitive"</string>
<string name="root_type_apps" msgid="8838065367985945189">"Alte aplicații"</string>
- <string name="empty" msgid="7858882803708117596">"Nu există elemente"</string>
+ <string name="empty" msgid="7858882803708117596">"Niciun element"</string>
<string name="no_results" msgid="6622510343880730446">"Niciun rezultat în %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Fișierul nu poate fi deschis"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Fișierul nu poate fi deschis"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Unele documente nu au putut fi șterse"</string>
<string name="share_via" msgid="8966594246261344259">"Trimiteți prin"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Se copiază fișierele"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Se mută fișierele"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Se șterg fișierele"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Timp rămas: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="few">Se copiază <xliff:g id="COUNT_1">%1$d</xliff:g> fișiere.</item>
@@ -88,25 +88,27 @@
<string name="copy_preparing" msgid="3896202461003039386">"Se pregătește copierea..."</string>
<string name="move_preparing" msgid="2772219441375531410">"Se pregătește mutarea…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Se pregătește ștergerea…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="few">Nu s-au putut copia <xliff:g id="COUNT_1">%1$d</xliff:g> fișiere</item>
<item quantity="other">Nu s-au putut copia <xliff:g id="COUNT_1">%1$d</xliff:g> de fișiere</item>
<item quantity="one">Nu s-a putut copia <xliff:g id="COUNT_0">%1$d</xliff:g> fișier</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="few">Nu s-au putut muta <xliff:g id="COUNT_1">%1$d</xliff:g> fișiere</item>
<item quantity="other">Nu s-au putut muta <xliff:g id="COUNT_1">%1$d</xliff:g> de fișiere</item>
<item quantity="one">Nu s-a putut muta <xliff:g id="COUNT_0">%1$d</xliff:g> fișier</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
- <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> fișiere nu au fost șterse</item>
- <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> de fișiere nu au fost șterse</item>
- <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fișier nu a fost șters</item>
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+ <item quantity="few">Nu s-au putut șterge <xliff:g id="COUNT_1">%1$d</xliff:g> fișiere</item>
+ <item quantity="other">Nu s-au putut șterge <xliff:g id="COUNT_1">%1$d</xliff:g> de fișiere</item>
+ <item quantity="one">Nu s-a putut șterge <xliff:g id="COUNT_0">%1$d</xliff:g> fișier</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Atingeți pentru a vedea detaliile"</string>
<string name="close" msgid="3043722427445528732">"Închideți"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Aceste fișiere nu au fost copiate: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Aceste fișiere nu au fost mutate: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Aceste fișiere nu au fost copiate: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Aceste fișiere nu au fost mutate: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Aceste fișiere nu au fost șterse: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Aceste fișiere au fost convertite în alt format: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="few">Au fost copiate <xliff:g id="COUNT_1">%1$d</xliff:g> fișiere în clipboard.</item>
@@ -116,7 +118,39 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Fișierele selectate nu au putut fi inserate în această locație."</string>
<string name="menu_rename" msgid="7678802479104285353">"Redenumiți"</string>
<string name="rename_error" msgid="4203041674883412606">"Documentul nu a putut fi redenumit"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Scoateți"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Unele fișiere au fost convertite"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Permiteți aplicației <xliff:g id="APPNAME"><b>^1</b></xliff:g> accesul la directorul <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> de pe <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Permiteți aplicației <xliff:g id="APPNAME"><b>^1</b></xliff:g> să acceseze directorul <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Permiteți aplicației <xliff:g id="APPNAME"><b>^1</b></xliff:g> să vă acceseze datele, inclusiv fotografiile și videoclipurile, de pe <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Nu mai întreba"</string>
<string name="allow" msgid="7225948811296386551">"Permiteți"</string>
- <string name="deny" msgid="2081879885755434506">"Refuzaţi"</string>
+ <string name="deny" msgid="2081879885755434506">"Refuzați"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> selectate</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selectate</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selectat</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> elemente</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> de elemente</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> element</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Ștergeți „<xliff:g id="NAME">%1$s</xliff:g>”?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Ștergeți dosarul „<xliff:g id="NAME">%1$s</xliff:g>” și conținutul acestuia?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="few">Ștergeți <xliff:g id="COUNT_1">%1$d</xliff:g> fișiere?</item>
+ <item quantity="other">Ștergeți <xliff:g id="COUNT_1">%1$d</xliff:g> de fișiere?</item>
+ <item quantity="one">Ștergeți <xliff:g id="COUNT_0">%1$d</xliff:g> fișier?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="few">Ștergeți <xliff:g id="COUNT_1">%1$d</xliff:g> dosare și conținutul acestora?</item>
+ <item quantity="other">Ștergeți <xliff:g id="COUNT_1">%1$d</xliff:g> de dosare și conținutul acestora?</item>
+ <item quantity="one">Ștergeți <xliff:g id="COUNT_0">%1$d</xliff:g> dosar și conținutul acestuia?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="few">Ștergeți <xliff:g id="COUNT_1">%1$d</xliff:g> elemente?</item>
+ <item quantity="other">Ștergeți <xliff:g id="COUNT_1">%1$d</xliff:g> de elemente?</item>
+ <item quantity="one">Ștergeți <xliff:g id="COUNT_0">%1$d</xliff:g> element?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-ru/config.xml b/packages/DocumentsUI/res/values-ru/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-ru/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-ru/strings.xml b/packages/DocumentsUI/res/values-ru/strings.xml
index 97bd4dd820bb..eb7278e54f6d 100644
--- a/packages/DocumentsUI/res/values-ru/strings.xml
+++ b/packages/DocumentsUI/res/values-ru/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Документы"</string>
- <string name="files_label" msgid="6051402950202690279">"Файлы"</string>
<string name="downloads_label" msgid="959113951084633612">"Загрузки"</string>
<string name="title_open" msgid="4353228937663917801">"Открыть"</string>
<string name="title_save" msgid="2433679664882857999">"Сохранить"</string>
@@ -26,16 +25,16 @@
<string name="menu_list" msgid="7279285939892417279">"Список"</string>
<string name="menu_sort" msgid="7677740407158414452">"Сортировать"</string>
<string name="menu_search" msgid="3816712084502856974">"Поиск"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Память"</string>
<string name="menu_open" msgid="432922957274920903">"Открыть"</string>
<string name="menu_save" msgid="2394743337684426338">"Сохранить"</string>
<string name="menu_share" msgid="3075149983979628146">"Поделиться"</string>
<string name="menu_delete" msgid="8138799623850614177">"Удалить"</string>
<string name="menu_select_all" msgid="8323579667348729928">"Выбрать все"</string>
<string name="menu_copy" msgid="3612326052677229148">"Копировать в…"</string>
- <string name="menu_move" msgid="1828090633118079817">"Переместить"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Переместить в…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Новое окно"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Вырезать"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Копировать"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Вставить"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Внутренняя память"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Скрыть"</string>
<string name="save_error" msgid="6167009778003223664">"Не удалось сохранить документ"</string>
<string name="create_error" msgid="3735649141335444215">"Не удалось создать папку"</string>
- <string name="query_error" msgid="1222448261663503501">"Не удалось отправить запрос"</string>
+ <string name="query_error" msgid="5999895349602476581">"Не удалось загрузить контент"</string>
<string name="root_recent" msgid="4470053704320518133">"Недавние"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"Свободно <xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="root_type_service" msgid="2178854894416775409">"Службы хранения"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Другие приложения"</string>
<string name="empty" msgid="7858882803708117596">"Ничего нет"</string>
<string name="no_results" msgid="6622510343880730446">"В \"%1$s\" ничего не найдено"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Не удалось открыть файл"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Не удалось открыть файл"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Не удалось удалить некоторые документы"</string>
<string name="share_via" msgid="8966594246261344259">"Поделиться"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Копирование файлов"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Перемещение файлов"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Удаление файлов…"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Осталось <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Копируется <xliff:g id="COUNT_1">%1$d</xliff:g> файл...</item>
@@ -91,28 +91,30 @@
<string name="copy_preparing" msgid="3896202461003039386">"Подготовка к копированию…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Подготовка…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Подготовка к удалению…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <item quantity="one">Не удалось скопировать <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
- <item quantity="few">Не удалось скопировать <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
- <item quantity="many">Не удалось скопировать <xliff:g id="COUNT_1">%1$d</xliff:g> файлов</item>
- <item quantity="other">Не удалось скопировать <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> из <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="one">Не удалось скопировать <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
+ <item quantity="few">Не удалось скопировать <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
+ <item quantity="many">Не удалось скопировать <xliff:g id="COUNT_1">%1$d</xliff:g> файлов</item>
+ <item quantity="other">Не удалось скопировать <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="one">Не удалось переместить <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
- <item quantity="few">Не удалось переместить <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
- <item quantity="many">Не удалось переместить <xliff:g id="COUNT_1">%1$d</xliff:g> файлов</item>
- <item quantity="other">Не удалось переместить <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="one">Не удалось переместить <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
+ <item quantity="few">Не удалось переместить <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
+ <item quantity="many">Не удалось переместить <xliff:g id="COUNT_1">%1$d</xliff:g> файлов</item>
+ <item quantity="other">Не удалось переместить <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
- <item quantity="one">Не удалось удалить <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
- <item quantity="few">Не удалось удалить <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
- <item quantity="many">Не удалось удалить <xliff:g id="COUNT_1">%1$d</xliff:g> файлов</item>
- <item quantity="other">Не удалось удалить <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+ <item quantity="one">Не удалось удалить <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
+ <item quantity="few">Не удалось удалить <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
+ <item quantity="many">Не удалось удалить <xliff:g id="COUNT_1">%1$d</xliff:g> файлов</item>
+ <item quantity="other">Не удалось удалить <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Нажмите, чтобы узнать подробности."</string>
<string name="close" msgid="3043722427445528732">"Закрыть"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Не удалось скопировать эти файлы: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Эти файлы не были перемещены: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Не удалось скопировать следующие файлы: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Не удалось переместить следующие файлы: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Следующие файлы не были удалены: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Формат этих файлов изменен: <xliff:g id="LIST">%1$s</xliff:g>."</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one">Скопирован <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
@@ -123,7 +125,44 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Не удается вставить сюда выбранные файлы"</string>
<string name="menu_rename" msgid="7678802479104285353">"Переименовать"</string>
<string name="rename_error" msgid="4203041674883412606">"Не удалось переименовать документ"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Извлечь"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Формат некоторых файлов изменен"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Открыть приложению \"<xliff:g id="APPNAME"><b>^1</b></xliff:g>\" доступ к папке \"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>\" на устройстве \"<xliff:g id="STORAGE"><i>^3</i></xliff:g>\"?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Открыть приложению \"<xliff:g id="APPNAME"><b>^1</b></xliff:g>\" доступ к папке \"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>\"?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Открыть приложению \"<xliff:g id="APPNAME"><b>^1</b></xliff:g>\" доступ к вашим данным, включая фото и видео, на носителе: <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Больше не спрашивать"</string>
<string name="allow" msgid="7225948811296386551">"Разрешить"</string>
<string name="deny" msgid="2081879885755434506">"Отклонить"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one">Выбрано: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="few">Выбрано: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="many">Выбрано: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">Выбрано: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> объект</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> объекта</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> объектов</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> объекта</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Удалить файл \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Удалить папку \"<xliff:g id="NAME">%1$s</xliff:g>\" со всем содержимым?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one">Удалить <xliff:g id="COUNT_1">%1$d</xliff:g> файл?</item>
+ <item quantity="few">Удалить <xliff:g id="COUNT_1">%1$d</xliff:g> файла?</item>
+ <item quantity="many">Удалить <xliff:g id="COUNT_1">%1$d</xliff:g> файлов?</item>
+ <item quantity="other">Удалить <xliff:g id="COUNT_1">%1$d</xliff:g> файла?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one">Удалить <xliff:g id="COUNT_1">%1$d</xliff:g> папку со всем содержимым?</item>
+ <item quantity="few">Удалить <xliff:g id="COUNT_1">%1$d</xliff:g> папки со всем содержимым?</item>
+ <item quantity="many">Удалить <xliff:g id="COUNT_1">%1$d</xliff:g> папок со всем содержимым?</item>
+ <item quantity="other">Удалить <xliff:g id="COUNT_1">%1$d</xliff:g> папки со всем содержимым?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one">Удалить <xliff:g id="COUNT_1">%1$d</xliff:g> объект?</item>
+ <item quantity="few">Удалить <xliff:g id="COUNT_1">%1$d</xliff:g> объекта?</item>
+ <item quantity="many">Удалить <xliff:g id="COUNT_1">%1$d</xliff:g> объектов?</item>
+ <item quantity="other">Удалить <xliff:g id="COUNT_1">%1$d</xliff:g> объекта?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-si-rLK/config.xml b/packages/DocumentsUI/res/values-si-rLK/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-si-rLK/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-si-rLK/strings.xml b/packages/DocumentsUI/res/values-si-rLK/strings.xml
index 19d8e897ef0a..956a59c696b4 100644
--- a/packages/DocumentsUI/res/values-si-rLK/strings.xml
+++ b/packages/DocumentsUI/res/values-si-rLK/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ලේඛන"</string>
- <string name="files_label" msgid="6051402950202690279">"ගොනු"</string>
<string name="downloads_label" msgid="959113951084633612">"බාගැනීම්"</string>
<string name="title_open" msgid="4353228937663917801">"විවෘත වන්නේ"</string>
<string name="title_save" msgid="2433679664882857999">"සුරකින්නේ"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"ලැයිස්තු පෙනුම"</string>
<string name="menu_sort" msgid="7677740407158414452">"අනුපිළිවෙලට සකසා ඇත්තේ"</string>
<string name="menu_search" msgid="3816712084502856974">"සෙවීම"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"ගබඩා සැකසීම්"</string>
<string name="menu_open" msgid="432922957274920903">"විවෘත කරන්න"</string>
<string name="menu_save" msgid="2394743337684426338">"සුරකින්න"</string>
<string name="menu_share" msgid="3075149983979628146">"බෙදාගන්න"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"වෙත පිටපත් කරන්න..."</string>
<string name="menu_move" msgid="1828090633118079817">"වෙත ගෙනයන්න..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"නව කවුළුව"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"කපන්න"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"පිටපත් කරන්න"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"අලවන්න"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"අභ්‍යන්තර ආචයනය පෙන්වන්න"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"මුල් සඟවන්න"</string>
<string name="save_error" msgid="6167009778003223664">"ලේඛනය සුරැකීමට අපොහොසත් විය"</string>
<string name="create_error" msgid="3735649141335444215">"ෆෝල්ඩරය සැදීම අසාර්ථක විය"</string>
- <string name="query_error" msgid="1222448261663503501">"ලේඛන විමසුම අසාර්ථක විය"</string>
+ <string name="query_error" msgid="5999895349602476581">"මේ මොහොතේ අන්තර්ගතය පූරණය කිරීමට නොහැකිය"</string>
<string name="root_recent" msgid="4470053704320518133">"මෑත"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ඉතිරියි"</string>
<string name="root_type_service" msgid="2178854894416775409">"ආචයන සේවා"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"තවත් යෙදුම්"</string>
<string name="empty" msgid="7858882803708117596">"අයිතම නැත"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s හි තරඟ නැත"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"ගොනුව විවෘත කළ නොහැක"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"ගොනුව විවෘත කළ නොහැකිය"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"සමහර ලේඛන මැකීමට නොහැකි විය"</string>
<string name="share_via" msgid="8966594246261344259">"හරහා බෙදාගන්න"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"ගොනු පිටපත් කරමින්"</string>
<string name="move_notification_title" msgid="6193835179777284805">"ගොනු ගෙන යාම"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"ගොනු මකමින්"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> ඉතිරියි"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g> ක් පිටපත් කරමින්.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"පිටපතක් සඳහා සූදානම් කරමින්..."</string>
<string name="move_preparing" msgid="2772219441375531410">"ගෙන යාම සඳහා පිළියෙළ කරමින් ..."</string>
<string name="delete_preparing" msgid="5655813182533491992">"මැකීම සඳහා සූදානම් කරමින්..."</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <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>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="one">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g>ක් පිටපත් කළ නොහැකි විය</item>
+ <item quantity="other">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g>ක් පිටපත් කළ නොහැකි විය</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="one">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g> ක් ගෙන යාමට නොහැකි විය</item>
- <item quantity="other">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g> ක් ගෙන යාමට නොහැකි විය</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="one">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g>ක් ගෙන යාමට නොහැකි විය</item>
+ <item quantity="other">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g>ක් ගෙන යාමට නොහැකි විය</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="one">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g>ක් මැකීමට නොහැකි විය</item>
<item quantity="other">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g>ක් මැකීමට නොහැකි විය</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"විස්තර බැලීමට තට්ටු කරන්න"</string>
<string name="close" msgid="3043722427445528732">"වසන්න"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"මෙම ගොනු පිටපත් නොකරන ලදී: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"මෙම ගොනු ගෙන නොයන ලදී: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"මෙම ගොනු පිටපත් නොකරන ලදී: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"මෙම ගොනු ගෙන නොයන ලදී: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"මෙම ගොනු නොමකන ලදී: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"මෙම ගොනු වෙනත් ආකෘතියකට පරිවර්තනය කරන ලදී: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one">පසුරු පුවරුවට ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g> ක් පිටපත් කරන ලදි.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"මෙම ස්ථානය තුළ තෝරාගත් ගොනු ඇලවිය නොහැක."</string>
<string name="menu_rename" msgid="7678802479104285353">"යළි නම් කරන්න"</string>
<string name="rename_error" msgid="4203041674883412606">"ලේඛනය යළි නම් කිරීම අසාර්ථක විය"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"පිටතට ගන්න"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"සමහර ගොනු පරිවර්තනය කරන ලදී"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> හට <xliff:g id="STORAGE"><i>^3</i></xliff:g> මත <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> නාමාවලිය වෙත ප්‍රවේශය දෙන්නද?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ප්‍රවේශය <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> නාමාවලිය වෙත ලබා දෙන්නද?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> හි, ඡායාරූප සහ වීඩියෝ ඇතුළුව, ඔබේ දත්තවලට <xliff:g id="APPNAME"><b>^1</b></xliff:g> හට ප්‍රවේශය ලබා දෙන්නද?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"නැවත අසන්න එපා"</string>
<string name="allow" msgid="7225948811296386551">"අවසර දෙන්න"</string>
<string name="deny" msgid="2081879885755434506">"ප්‍රතික්ෂේප කරන්න"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>ක් තෝරන ලදී</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ක් තෝරන ලදී</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one">අයිතම <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">අයිතම <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" මකන්නද?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ෆෝල්ඩරය හා එහි අන්තර්ගත මකන්නද?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g> ක් මකන්නද?</item>
+ <item quantity="other">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g> ක් මකන්නද?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one">ෆෝල්ඩර <xliff:g id="COUNT_1">%1$d</xliff:g> ක් හා එහි අන්තර්ගත මකන්නද?</item>
+ <item quantity="other">ෆෝල්ඩර <xliff:g id="COUNT_1">%1$d</xliff:g> ක් හා එහි අන්තර්ගත මකන්නද?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one">අයිතම <xliff:g id="COUNT_1">%1$d</xliff:g> ක් මකන්නද?</item>
+ <item quantity="other">අයිතම <xliff:g id="COUNT_1">%1$d</xliff:g> ක් මකන්නද?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-sk/config.xml b/packages/DocumentsUI/res/values-sk/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-sk/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-sk/strings.xml b/packages/DocumentsUI/res/values-sk/strings.xml
index cf74acfeaf84..c760868d5725 100644
--- a/packages/DocumentsUI/res/values-sk/strings.xml
+++ b/packages/DocumentsUI/res/values-sk/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenty"</string>
- <string name="files_label" msgid="6051402950202690279">"Súbory"</string>
<string name="downloads_label" msgid="959113951084633612">"Stiahnuté súbory"</string>
<string name="title_open" msgid="4353228937663917801">"Otvoriť z"</string>
<string name="title_save" msgid="2433679664882857999">"Uložiť do"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Zobrazenie zoznamu"</string>
<string name="menu_sort" msgid="7677740407158414452">"Zoradiť podľa"</string>
<string name="menu_search" msgid="3816712084502856974">"Hľadať"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Nastavenia úložiska"</string>
<string name="menu_open" msgid="432922957274920903">"Otvoriť"</string>
<string name="menu_save" msgid="2394743337684426338">"Uložiť"</string>
<string name="menu_share" msgid="3075149983979628146">"Zdieľať"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Kopírovať do…"</string>
<string name="menu_move" msgid="1828090633118079817">"Presunúť do…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Nové okno"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Vystrihnúť"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopírovať"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Prilepiť"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Zobraziť interné úložisko"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Skryť korene"</string>
<string name="save_error" msgid="6167009778003223664">"Dokument sa nepodarilo uložiť"</string>
<string name="create_error" msgid="3735649141335444215">"Priečinok sa nepodarilo vytvoriť"</string>
- <string name="query_error" msgid="1222448261663503501">"Zoznam dokumentov sa nepodarilo načítať"</string>
+ <string name="query_error" msgid="5999895349602476581">"Obsah momentálne nie je možné načítať"</string>
<string name="root_recent" msgid="4470053704320518133">"Nedávne"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"Voľné <xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="root_type_service" msgid="2178854894416775409">"Služby úložiska"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Ďalšie aplikácie"</string>
<string name="empty" msgid="7858882803708117596">"Žiadne položky"</string>
<string name="no_results" msgid="6622510343880730446">"Žiadne zhody – %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Súbor sa nepodarilo otvoriť"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Súbor nie je možné otvoriť"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Niektoré dokumenty sa nepodarilo odstrániť"</string>
<string name="share_via" msgid="8966594246261344259">"Zdieľať"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopírovanie súborov"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Presúvajú sa súbory"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Odstraňujú sa súbory"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Zostáva: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="few">Kopírujú sa <xliff:g id="COUNT_1">%1$d</xliff:g> súbory.</item>
@@ -91,19 +91,20 @@
<string name="copy_preparing" msgid="3896202461003039386">"Pripravuje sa na kopírovanie..."</string>
<string name="move_preparing" msgid="2772219441375531410">"Prebieha príprava na presunutie…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Príprava na odstránenie…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <item quantity="few">Zlyhalo kopírovanie <xliff:g id="COUNT_1">%1$d</xliff:g> súborov</item>
- <item quantity="many">Zlyhalo kopírovanie <xliff:g id="COUNT_1">%1$d</xliff:g> súboru</item>
- <item quantity="other">Zlyhalo kopírovanie <xliff:g id="COUNT_1">%1$d</xliff:g> súborov</item>
- <item quantity="one">Zlyhalo kopírovanie <xliff:g id="COUNT_0">%1$d</xliff:g> súboru</item>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="few">Nepodarilo sa skopírovať <xliff:g id="COUNT_1">%1$d</xliff:g> súbory</item>
+ <item quantity="many">Nepodarilo sa skopírovať <xliff:g id="COUNT_1">%1$d</xliff:g> súboru</item>
+ <item quantity="other">Nepodarilo sa skopírovať <xliff:g id="COUNT_1">%1$d</xliff:g> súborov</item>
+ <item quantity="one">Nepodarilo sa skopírovať <xliff:g id="COUNT_0">%1$d</xliff:g> súbor</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> súbory nie je možné presunúť</item>
<item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> súboru nie je možné presunúť</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> súborov nie je možné presunúť</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> súbor nie je možné presunúť</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="few">Nepodarilo sa odstrániť <xliff:g id="COUNT_1">%1$d</xliff:g> súbory</item>
<item quantity="many">Nepodarilo sa odstrániť <xliff:g id="COUNT_1">%1$d</xliff:g> súboru</item>
<item quantity="other">Nepodarilo sa odstrániť <xliff:g id="COUNT_1">%1$d</xliff:g> súborov</item>
@@ -111,8 +112,9 @@
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Klepnutím zobrazíte podrobnosti"</string>
<string name="close" msgid="3043722427445528732">"Zavrieť"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Tieto súbory neboli skopírované: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Tieto súbory neboli presunuté: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Tieto súbory neboli skopírované: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Tieto súbory neboli presunuté: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Tieto súbory neboli odstránené: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Tieto súbory boli konvertované do iného formátu: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="few">Do schránky boli skopírované <xliff:g id="COUNT_1">%1$d</xliff:g> súbory.</item>
@@ -123,7 +125,44 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Do tohto umiestnenia nie je možné prilepiť vybrané súbory"</string>
<string name="menu_rename" msgid="7678802479104285353">"Premenovať"</string>
<string name="rename_error" msgid="4203041674883412606">"Premenovanie dokumentu zlyhalo"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Odpojiť"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Niektoré súbory boli konvertované"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Udeliť aplikácii <xliff:g id="APPNAME"><b>^1</b></xliff:g> prístup k adresáru <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> v úložisku <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Udeliť aplikácii <xliff:g id="APPNAME"><b>^1</b></xliff:g> prístup k adresáru <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Chcete aplikácii <xliff:g id="APPNAME"><b>^1</b></xliff:g> udeliť prístup k dátam (vrátane fotiek a videí) v úložisku <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Nabudúce sa nepýtať"</string>
<string name="allow" msgid="7225948811296386551">"Povoliť"</string>
<string name="deny" msgid="2081879885755434506">"Zamietnuť"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="few">Vybraté: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="many">Vybraté: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">Vybraté: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">Vybraté: <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> položky</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> položky</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> položiek</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> položka</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Odstrániť <xliff:g id="NAME">%1$s</xliff:g>?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Odstrániť priečinok <xliff:g id="NAME">%1$s</xliff:g> a jeho obsah?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="few">Odstrániť <xliff:g id="COUNT_1">%1$d</xliff:g> súbory?</item>
+ <item quantity="many">Odstrániť <xliff:g id="COUNT_1">%1$d</xliff:g> súboru?</item>
+ <item quantity="other">Odstrániť <xliff:g id="COUNT_1">%1$d</xliff:g> súborov?</item>
+ <item quantity="one">Odstrániť <xliff:g id="COUNT_0">%1$d</xliff:g> súbor?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="few">Odstrániť <xliff:g id="COUNT_1">%1$d</xliff:g> priečinky a ich obsah?</item>
+ <item quantity="many">Odstrániť <xliff:g id="COUNT_1">%1$d</xliff:g> priečinka a jeho obsah?</item>
+ <item quantity="other">Odstrániť <xliff:g id="COUNT_1">%1$d</xliff:g> priečinkov a ich obsah?</item>
+ <item quantity="one">Odstrániť <xliff:g id="COUNT_0">%1$d</xliff:g> priečinok a jeho obsah?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="few">Odstrániť <xliff:g id="COUNT_1">%1$d</xliff:g> položky?</item>
+ <item quantity="many">Odstrániť <xliff:g id="COUNT_1">%1$d</xliff:g> položky?</item>
+ <item quantity="other">Odstrániť <xliff:g id="COUNT_1">%1$d</xliff:g> položiek?</item>
+ <item quantity="one">Odstrániť <xliff:g id="COUNT_0">%1$d</xliff:g> položku?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-sl/config.xml b/packages/DocumentsUI/res/values-sl/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-sl/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-sl/strings.xml b/packages/DocumentsUI/res/values-sl/strings.xml
index 7da4628910ab..5a46141d2900 100644
--- a/packages/DocumentsUI/res/values-sl/strings.xml
+++ b/packages/DocumentsUI/res/values-sl/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenti"</string>
- <string name="files_label" msgid="6051402950202690279">"Datoteke"</string>
<string name="downloads_label" msgid="959113951084633612">"Prenosi"</string>
<string name="title_open" msgid="4353228937663917801">"Odpri iz mape"</string>
<string name="title_save" msgid="2433679664882857999">"Shrani v"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Pogled seznama"</string>
<string name="menu_sort" msgid="7677740407158414452">"Razvrsti glede na"</string>
<string name="menu_search" msgid="3816712084502856974">"Iskanje"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Nastavitve shrambe"</string>
<string name="menu_open" msgid="432922957274920903">"Odpri"</string>
<string name="menu_save" msgid="2394743337684426338">"Shrani"</string>
<string name="menu_share" msgid="3075149983979628146">"Skupna raba"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Kopiraj v …"</string>
<string name="menu_move" msgid="1828090633118079817">"Premakni v ..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"Novo okno"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Izreži"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopiraj"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Prilepi"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Pokaži notranjo shrambo"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Skrij korene"</string>
<string name="save_error" msgid="6167009778003223664">"Dokumenta ni bilo mogoče shraniti"</string>
<string name="create_error" msgid="3735649141335444215">"Mape ni bilo mogoče ustvariti"</string>
- <string name="query_error" msgid="1222448261663503501">"Poizvedba za dokumente ni uspela"</string>
+ <string name="query_error" msgid="5999895349602476581">"Vsebine trenutno ni mogoče naložiti"</string>
<string name="root_recent" msgid="4470053704320518133">"Nedavno"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"Prosto: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="root_type_service" msgid="2178854894416775409">"Storitve shrambe"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Več aplikacij"</string>
<string name="empty" msgid="7858882803708117596">"Ni elementov"</string>
<string name="no_results" msgid="6622510343880730446">"Tukaj ni ujemanj: %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Datoteke ni mogoče odpreti"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Datoteke ni mogoče odpreti"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Nekaterih dokumentov ni mogoče izbrisati"</string>
<string name="share_via" msgid="8966594246261344259">"Deli z drugimi prek"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopiranje datotek"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Premikanje datotek"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Brisanje datotek"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Še <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Kopiranje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke.</item>
@@ -91,19 +91,20 @@
<string name="copy_preparing" msgid="3896202461003039386">"Pripravljanje na kopiranje …"</string>
<string name="move_preparing" msgid="2772219441375531410">"Priprava na premikanje …"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Pripravljanje na izbris …"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteke ni bilo mogoče kopirati</item>
<item quantity="two"><xliff:g id="COUNT_1">%1$d</xliff:g> datotek ni bilo mogoče kopirati</item>
<item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> datotek ni bilo mogoče kopirati</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> datotek ni bilo mogoče kopirati</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteke ni bilo mogoče premakniti</item>
<item quantity="two"><xliff:g id="COUNT_1">%1$d</xliff:g> datotek ni bilo mogoče premakniti</item>
<item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> datotek ni bilo mogoče premakniti</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> datotek ni bilo mogoče premakniti</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteke ni bilo mogoče izbrisati</item>
<item quantity="two"><xliff:g id="COUNT_1">%1$d</xliff:g> datotek ni bilo mogoče izbrisati</item>
<item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> datotek ni bilo mogoče izbrisati</item>
@@ -111,8 +112,9 @@
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Dotaknite se za prikaz podrobnosti"</string>
<string name="close" msgid="3043722427445528732">"Zapri"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Te datoteke niso bile kopirane: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Te datoteke niso bile premaknjene: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Te datoteke niso bile kopirane: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Te datoteke niso bile premaknjene: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Te datoteke niso bile izbrisane: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Te datoteke so bile spremenjene v drugo obliko zapisa: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one">V odložišče je bila kopirana <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka.</item>
@@ -123,7 +125,44 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Izbranih datotek ni mogoče prilepiti sem."</string>
<string name="menu_rename" msgid="7678802479104285353">"Preimenuj"</string>
<string name="rename_error" msgid="4203041674883412606">"Dokumenta ni bilo mogoče preimenovati"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Izvrzi"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Nekatere datoteke so bile pretvorjene"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Želite aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> dovoliti dostop do imenika <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> v shrambi <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Želite aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> dovoliti dostop do imenika <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Odobrite aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> dostop do podatkov, vključno s fotografijami in videoposnetki, v shrambi <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Ne sprašuj več"</string>
<string name="allow" msgid="7225948811296386551">"Dovoli"</string>
<string name="deny" msgid="2081879885755434506">"Zavrni"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> izbran</item>
+ <item quantity="two"><xliff:g id="COUNT_1">%1$d</xliff:g> izbrana</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> izbrani</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> izbranih</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> element</item>
+ <item quantity="two"><xliff:g id="COUNT_1">%1$d</xliff:g> elementa</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> elementi</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementov</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Ali želite izbrisati »<xliff:g id="NAME">%1$s</xliff:g>«?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Ali želite izbrisati mapo »<xliff:g id="NAME">%1$s</xliff:g>« in njeno vsebino?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one">Ali želite izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> datoteko?</item>
+ <item quantity="two">Ali želite izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> datoteki?</item>
+ <item quantity="few">Ali želite izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke?</item>
+ <item quantity="other">Ali želite izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> datotek?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one">Ali želite izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> mapo in njihovo vsebino?</item>
+ <item quantity="two">Ali želite izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> mapi in njihovo vsebino?</item>
+ <item quantity="few">Ali želite izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> mape in njihovo vsebino?</item>
+ <item quantity="other">Ali želite izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> map in njihovo vsebino?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one">Ali želite izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> element?</item>
+ <item quantity="two">Ali želite izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> elementa?</item>
+ <item quantity="few">Ali želite izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> elemente?</item>
+ <item quantity="other">Ali želite izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> elementov?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-sq-rAL/config.xml b/packages/DocumentsUI/res/values-sq-rAL/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-sq-rAL/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-sq-rAL/strings.xml b/packages/DocumentsUI/res/values-sq-rAL/strings.xml
index fec090cfd0dc..732996a130c3 100644
--- a/packages/DocumentsUI/res/values-sq-rAL/strings.xml
+++ b/packages/DocumentsUI/res/values-sq-rAL/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumente"</string>
- <string name="files_label" msgid="6051402950202690279">"Skedarët"</string>
<string name="downloads_label" msgid="959113951084633612">"Shkarkimet"</string>
<string name="title_open" msgid="4353228937663917801">"Hap nga"</string>
<string name="title_save" msgid="2433679664882857999">"Ruaje te"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Pamje liste"</string>
<string name="menu_sort" msgid="7677740407158414452">"Rendit sipas"</string>
<string name="menu_search" msgid="3816712084502856974">"Kërko"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Cilësimet e hapësirës ruajtëse"</string>
<string name="menu_open" msgid="432922957274920903">"Hap"</string>
<string name="menu_save" msgid="2394743337684426338">"Ruaj"</string>
<string name="menu_share" msgid="3075149983979628146">"Shpërnda"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Kopjo te..."</string>
<string name="menu_move" msgid="1828090633118079817">"Zhvendos te..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"Dritare e re"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Prit"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopjo"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Ngjit"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Trego hapësirën e brendshme ruajtëse"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Fshih rrënjët"</string>
<string name="save_error" msgid="6167009778003223664">"Ruajtja e dokumentit dështoi"</string>
<string name="create_error" msgid="3735649141335444215">"Krijimi i dosjes dështoi"</string>
- <string name="query_error" msgid="1222448261663503501">"Kërkesa për dokumentet dështoi"</string>
+ <string name="query_error" msgid="5999895349602476581">"Përmbajtja nuk mund të ngarkohet për momentin"</string>
<string name="root_recent" msgid="4470053704320518133">"Të kohëve të fundit"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"Të lirë: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="root_type_service" msgid="2178854894416775409">"Shërbimet e hapësirës ruajtëse"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Aplikacione të tjera"</string>
<string name="empty" msgid="7858882803708117596">"Nuk ka artikuj"</string>
<string name="no_results" msgid="6622510343880730446">"Nuk ka asnjë përputhje në %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Skedari nuk mund të hapet"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Skedari nuk mund të hapet"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"E pamundur të fshihen disa dokumente"</string>
<string name="share_via" msgid="8966594246261344259">"Shpërnda publikisht përmes"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Po kopjon skedarët"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Po zhvendos skedarët"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Po fshin skedarët"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> të mbetura"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Po kopjon <xliff:g id="COUNT_1">%1$d</xliff:g> skedarë.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Po përgatitet për kopjimin…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Po përgatitet për zhvendosjen…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Po përgatitet për fshirje…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> skedarë nuk mund të kopjoheshin</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> skedar nuk mund të kopjohej</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> skedarë nuk mund të zhvendoseshin</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> skedar nuk mund të zhvendosej</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> skedarë nuk mund të fshiheshin</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> skedar nuk mund të fshihej</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Trokit për të parë detajet"</string>
<string name="close" msgid="3043722427445528732">"Mbyll"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Këta skedarë nuk u kopjuan: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Këta skedarë nuk u zhvendosën: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Këta skedarë nuk u kopjuan: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Këta skedarë nuk u zhvendosën: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Këta skedarë nuk u fshinë: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Këta skedarë janë konvertuar në format tjetër: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">U kopjuan <xliff:g id="COUNT_1">%1$d</xliff:g> skedarë në kujtesën e fragmenteve.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Skedarët e zgjedhur nuk mund të ngjiten në këtë vendndodhje."</string>
<string name="menu_rename" msgid="7678802479104285353">"Riemërto"</string>
<string name="rename_error" msgid="4203041674883412606">"Riemërtimi i dokumentit dështoi"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Nxirr"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Disa skedarë u konvertuan"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Jepi aplikacionit <xliff:g id="APPNAME"><b>^1</b></xliff:g> qasje te direktoria <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> në <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"T\'i jepet aplikacionit <xliff:g id="APPNAME"><b>^1</b></xliff:g> qasje te direktoria <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"T\'i jepet aplikacionit <xliff:g id="APPNAME"><b>^1</b></xliff:g> qasje te të dhënat, duke përfshirë fotografitë dhe videot, në <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Mos pyet përsëri"</string>
<string name="allow" msgid="7225948811296386551">"Lejo"</string>
<string name="deny" msgid="2081879885755434506">"Moho"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> të zgjedhur</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> i zgjedhur</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> artikuj</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> artikull</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Të fshihet \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Të fshihet dosja \"<xliff:g id="NAME">%1$s</xliff:g>\" dhe përmbajtja e saj?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">Të fshihen <xliff:g id="COUNT_1">%1$d</xliff:g> skedarë?</item>
+ <item quantity="one">Të fshihet <xliff:g id="COUNT_0">%1$d</xliff:g> skedar?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">Të fshihen <xliff:g id="COUNT_1">%1$d</xliff:g> dosje dhe përmbajtjet e saj?</item>
+ <item quantity="one">Të fshihet <xliff:g id="COUNT_0">%1$d</xliff:g> dosje dhe përmbajtjet e saj?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other">Të fshihen <xliff:g id="COUNT_1">%1$d</xliff:g> artikuj?</item>
+ <item quantity="one">Të fshihet <xliff:g id="COUNT_0">%1$d</xliff:g> artikull?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-sr/config.xml b/packages/DocumentsUI/res/values-sr/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-sr/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-sr/strings.xml b/packages/DocumentsUI/res/values-sr/strings.xml
index b43a8d3e5127..21aadeee3b6d 100644
--- a/packages/DocumentsUI/res/values-sr/strings.xml
+++ b/packages/DocumentsUI/res/values-sr/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Документи"</string>
- <string name="files_label" msgid="6051402950202690279">"Датотеке"</string>
<string name="downloads_label" msgid="959113951084633612">"Преузимања"</string>
<string name="title_open" msgid="4353228937663917801">"Отвори са"</string>
<string name="title_save" msgid="2433679664882857999">"Сачувај у"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Приказ листе"</string>
<string name="menu_sort" msgid="7677740407158414452">"Сортирај према"</string>
<string name="menu_search" msgid="3816712084502856974">"Претражи"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Подешавања меморије"</string>
<string name="menu_open" msgid="432922957274920903">"Отвори"</string>
<string name="menu_save" msgid="2394743337684426338">"Сачувај"</string>
<string name="menu_share" msgid="3075149983979628146">"Дели"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Копирај на..."</string>
<string name="menu_move" msgid="1828090633118079817">"Премести у..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"Нови прозор"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Исеци"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Копирај"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Налепи"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Прикажи интерну меморију"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Сакриј основне елементе"</string>
<string name="save_error" msgid="6167009778003223664">"Чување документа није успело"</string>
<string name="create_error" msgid="3735649141335444215">"Директоријум није направљен"</string>
- <string name="query_error" msgid="1222448261663503501">"Слање упита за документе није успело"</string>
+ <string name="query_error" msgid="5999895349602476581">"Учитавање садржаја тренутно није могуће"</string>
<string name="root_recent" msgid="4470053704320518133">"Недавно"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"Слободно је <xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="root_type_service" msgid="2178854894416775409">"Услуге складиштења"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Још апликација"</string>
<string name="empty" msgid="7858882803708117596">"Нема ставки"</string>
<string name="no_results" msgid="6622510343880730446">"Нема подударања у %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Није могуће отворити датотеку"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Отварање датотеке није успело"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Није могуће избрисати неке документе"</string>
<string name="share_via" msgid="8966594246261344259">"Делите преко"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Копирање датотека"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Датотеке се премештају"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Датотеке се бришу"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Још <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Копирање <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке.</item>
@@ -88,25 +88,27 @@
<string name="copy_preparing" msgid="3896202461003039386">"Припрема се копирање…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Припрема се премештање..."</string>
<string name="delete_preparing" msgid="5655813182533491992">"Припрема се брисање…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="one">Нисмо успели да копирамо <xliff:g id="COUNT_1">%1$d</xliff:g> датотеку</item>
<item quantity="few">Нисмо успели да копирамо <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке</item>
<item quantity="other">Нисмо успели да копирамо <xliff:g id="COUNT_1">%1$d</xliff:g> датотека</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="one">Није успело премештање <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке</item>
- <item quantity="few">Није успело премештање <xliff:g id="COUNT_1">%1$d</xliff:g> датотекe</item>
- <item quantity="other">Није успело премештање <xliff:g id="COUNT_1">%1$d</xliff:g> датотека</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="one">Премештање <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке није успело</item>
+ <item quantity="few">Премештање <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке није успело</item>
+ <item quantity="other">Премештање <xliff:g id="COUNT_1">%1$d</xliff:g> датотека није успело</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="one">Брисање <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке није успело</item>
<item quantity="few">Брисање <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке није успело</item>
<item quantity="other">Брисање <xliff:g id="COUNT_1">%1$d</xliff:g> датотека није успело</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Додирните да бисте приказали детаље"</string>
<string name="close" msgid="3043722427445528732">"Затвори"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Следеће датотеке нису копиране: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Ове датотеке нису премештене: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Следеће датотеке нису копиране: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Следеће датотеке нису премештене: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Следеће датотеке нису избрисане: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Ове датотеке су конвертоване у други формат: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one">Копирали сте <xliff:g id="COUNT_1">%1$d</xliff:g> датотеку у привремену меморију.</item>
@@ -116,7 +118,39 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Изабране датотеке не могу да се налепе на овој локацији."</string>
<string name="menu_rename" msgid="7678802479104285353">"Преименуј"</string>
<string name="rename_error" msgid="4203041674883412606">"Преименовање документа није успело"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Избаци"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Неке датотеке су конвертоване"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Желите ли да апликацији <xliff:g id="APPNAME"><b>^1</b></xliff:g> одобрите приступ директоријуму <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> на меморијском простору <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Желите да дозволите да <xliff:g id="APPNAME"><b>^1</b></xliff:g> приступа директоријуму <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Желите да ли да дозволите да апликација <xliff:g id="APPNAME"><b>^1</b></xliff:g> приступа подацима, укључујући слике и видео снимке, на локацији <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Не питај поново"</string>
<string name="allow" msgid="7225948811296386551">"Дозволи"</string>
<string name="deny" msgid="2081879885755434506">"Одбиј"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one">Изабрана је <xliff:g id="COUNT_1">%1$d</xliff:g> ставка</item>
+ <item quantity="few">Изабране су <xliff:g id="COUNT_1">%1$d</xliff:g> ставке</item>
+ <item quantity="other">Изабрано је <xliff:g id="COUNT_1">%1$d</xliff:g> ставки</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ставка</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> ставке</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ставки</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Желите ли да избришете „<xliff:g id="NAME">%1$s</xliff:g>“?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Желите ли да избришете директоријум „<xliff:g id="NAME">%1$s</xliff:g>“ и његов садржај?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one">Желите ли да избришете <xliff:g id="COUNT_1">%1$d</xliff:g> датотеку?</item>
+ <item quantity="few">Желите ли да избришете <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке?</item>
+ <item quantity="other">Желите ли да избришете <xliff:g id="COUNT_1">%1$d</xliff:g> датотека?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one">Желите ли да избришете <xliff:g id="COUNT_1">%1$d</xliff:g> директоријум и њихов садржај?</item>
+ <item quantity="few">Желите ли да избришете <xliff:g id="COUNT_1">%1$d</xliff:g> директоријума и њихов садржај?</item>
+ <item quantity="other">Желите ли да избришете <xliff:g id="COUNT_1">%1$d</xliff:g> директоријума и њихов садржај?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one">Желите ли да избришете <xliff:g id="COUNT_1">%1$d</xliff:g> ставку?</item>
+ <item quantity="few">Желите ли да избришете <xliff:g id="COUNT_1">%1$d</xliff:g> ставке?</item>
+ <item quantity="other">Желите ли да избришете <xliff:g id="COUNT_1">%1$d</xliff:g> ставки?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-sv/config.xml b/packages/DocumentsUI/res/values-sv/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-sv/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-sv/strings.xml b/packages/DocumentsUI/res/values-sv/strings.xml
index 2d1d924f9a8a..5ef9ab2da829 100644
--- a/packages/DocumentsUI/res/values-sv/strings.xml
+++ b/packages/DocumentsUI/res/values-sv/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokument"</string>
- <string name="files_label" msgid="6051402950202690279">"Filer"</string>
<string name="downloads_label" msgid="959113951084633612">"Nedladdningar"</string>
<string name="title_open" msgid="4353228937663917801">"Öppna från"</string>
<string name="title_save" msgid="2433679664882857999">"Spara till"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Listvy"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sortera efter"</string>
<string name="menu_search" msgid="3816712084502856974">"Sök"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Lagringsinställningar"</string>
<string name="menu_open" msgid="432922957274920903">"Öppna"</string>
<string name="menu_save" msgid="2394743337684426338">"Spara"</string>
<string name="menu_share" msgid="3075149983979628146">"Dela"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Kopiera till …"</string>
<string name="menu_move" msgid="1828090633118079817">"Flytta till ..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"Nytt fönster"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Klipp ut"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopiera"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Klistra in"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Visa internminne"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Dölj rötter"</string>
<string name="save_error" msgid="6167009778003223664">"Det gick inte att spara dokumentet"</string>
<string name="create_error" msgid="3735649141335444215">"Det gick inte att skapa mappen"</string>
- <string name="query_error" msgid="1222448261663503501">"Det gick inte att söka efter dokument"</string>
+ <string name="query_error" msgid="5999895349602476581">"Det går inte att läsa in innehållet just nu"</string>
<string name="root_recent" msgid="4470053704320518133">"Senaste"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ledigt"</string>
<string name="root_type_service" msgid="2178854894416775409">"Lagringstjänster"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Fler appar"</string>
<string name="empty" msgid="7858882803708117596">"Inga objekt"</string>
<string name="no_results" msgid="6622510343880730446">"Det finns inga träffar i %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Det går inte att öppna filen"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Det går inte att öppna filen"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Det gick inte att ta bort vissa dokument"</string>
<string name="share_via" msgid="8966594246261344259">"Dela via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopierar filer"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Filer flyttas"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Filerna tas bort"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> återstår"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Kopierar <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Kopieringen förbereds …"</string>
<string name="move_preparing" msgid="2772219441375531410">"Förbereder för att flytta …"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Radering förbereds …"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer gick inte att kopiera</item>
- <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fil gick inte att kopiera</item>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="other">Det gick inte att kopiera <xliff:g id="COUNT_1">%1$d</xliff:g> filer</item>
+ <item quantity="one">Det gick inte att kopiera <xliff:g id="COUNT_0">%1$d</xliff:g> fil</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other">Det gick inte att flytta <xliff:g id="COUNT_1">%1$d</xliff:g> filer</item>
<item quantity="one">Det gick inte att flytta <xliff:g id="COUNT_0">%1$d</xliff:g> fil</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other">Det gick inte att radera <xliff:g id="COUNT_1">%1$d</xliff:g> filer</item>
<item quantity="one">Det gick inte att radera <xliff:g id="COUNT_0">%1$d</xliff:g> fil</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Tryck om du vill visa informationen"</string>
<string name="close" msgid="3043722427445528732">"Stäng"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Följande filer kopierades inte: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Följande filer har inte flyttats: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Följande filer kopierades inte: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Följande filer flyttades inte: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Följande filer raderades inte: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Filerna konverterades till ett annat format: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer har kopierats till Urklipp.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Det går inte att klistra in den valda filen på den här platsen."</string>
<string name="menu_rename" msgid="7678802479104285353">"Byt namn"</string>
<string name="rename_error" msgid="4203041674883412606">"Det gick inte att byta namn på dokumentet"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Mata ut"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Vissa filer konverterades"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Vill du ge <xliff:g id="APPNAME"><b>^1</b></xliff:g> åtkomst till katalogen <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> på <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Vill du ge <xliff:g id="APPNAME"><b>^1</b></xliff:g> åtkomst till katalogen <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Vill du ge <xliff:g id="APPNAME"><b>^1</b></xliff:g> åtkomst till din data (inklusive foton och videor) på <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Fråga inte igen"</string>
<string name="allow" msgid="7225948811296386551">"Tillåt"</string>
<string name="deny" msgid="2081879885755434506">"Neka"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> har valts</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> har valts</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> objekt</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> objekt</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Vill du radera <xliff:g id="NAME">%1$s</xliff:g>?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Vill du radera mappen <xliff:g id="NAME">%1$s</xliff:g> och dess innehåll?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">Vill du radera <xliff:g id="COUNT_1">%1$d</xliff:g> filer?</item>
+ <item quantity="one">Vill du radera <xliff:g id="COUNT_0">%1$d</xliff:g> fil?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">Vill du radera <xliff:g id="COUNT_1">%1$d</xliff:g> mappar och deras innehåll?</item>
+ <item quantity="one">Vill du radera <xliff:g id="COUNT_0">%1$d</xliff:g> mapp och dess innehåll?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other">Vill du radera <xliff:g id="COUNT_1">%1$d</xliff:g> objekt?</item>
+ <item quantity="one">Vill du radera <xliff:g id="COUNT_0">%1$d</xliff:g> objekt?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-sw/config.xml b/packages/DocumentsUI/res/values-sw/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-sw/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-sw/strings.xml b/packages/DocumentsUI/res/values-sw/strings.xml
index e28365dcdbd5..82bc4bbc267b 100644
--- a/packages/DocumentsUI/res/values-sw/strings.xml
+++ b/packages/DocumentsUI/res/values-sw/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Hati"</string>
- <string name="files_label" msgid="6051402950202690279">"Faili"</string>
<string name="downloads_label" msgid="959113951084633612">"Vipakuliwa"</string>
<string name="title_open" msgid="4353228937663917801">"Fungua kutoka"</string>
<string name="title_save" msgid="2433679664882857999">"Hifadhi kwenye"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Mwonekano orodha"</string>
<string name="menu_sort" msgid="7677740407158414452">"Panga kwa"</string>
<string name="menu_search" msgid="3816712084502856974">"Utafutaji"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Mipangilio ya hifadhi"</string>
<string name="menu_open" msgid="432922957274920903">"Fungua"</string>
<string name="menu_save" msgid="2394743337684426338">"Hifadhi"</string>
<string name="menu_share" msgid="3075149983979628146">"Shiriki"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Nakili kwenda..."</string>
<string name="menu_move" msgid="1828090633118079817">"Hamisha hadi..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"Dirisha jipya"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Kata"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Nakili"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Bandika"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Onyesha hifadhi ya ndani"</string>
@@ -54,20 +53,21 @@
<string name="drawer_close" msgid="7602734368552123318">"Ficha usuli"</string>
<string name="save_error" msgid="6167009778003223664">"Imeshindwa kuhifadhi hati"</string>
<string name="create_error" msgid="3735649141335444215">"Ilishindwa kuunda folda"</string>
- <string name="query_error" msgid="1222448261663503501">"Ilishindwa kuhoji hati"</string>
- <string name="root_recent" msgid="4470053704320518133">"Hivi karibuni"</string>
+ <string name="query_error" msgid="5999895349602476581">"Haiwezi kupakia maudhui kwa sasa"</string>
+ <string name="root_recent" msgid="4470053704320518133">"Za hivi karibuni"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> bila malipo"</string>
<string name="root_type_service" msgid="2178854894416775409">"Huduma za hifadhi"</string>
<string name="root_type_shortcut" msgid="3318760609471618093">"Njia za mkato"</string>
<string name="root_type_device" msgid="7121342474653483538">"Vifaa"</string>
<string name="root_type_apps" msgid="8838065367985945189">"Programu zaidi"</string>
- <string name="empty" msgid="7858882803708117596">"Hakuna vipengee"</string>
+ <string name="empty" msgid="7858882803708117596">"Hakuna chochote"</string>
<string name="no_results" msgid="6622510343880730446">"Hakuna zinazolingana katika %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Haiwezi kufungua faili"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Haiwezi kufungua faili"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Imeshindwa kufuta baadhi ya hati"</string>
<string name="share_via" msgid="8966594246261344259">"Shiriki kupitia"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Inanakili faili"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Inahamisha faili"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Inafuta faili"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Zimesalia <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Inanakili faili <xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Inaanda kunakili..."</string>
<string name="move_preparing" msgid="2772219441375531410">"Inatayarisha kuhamisha..."</string>
<string name="delete_preparing" msgid="5655813182533491992">"Inajitayarisha kufuta..."</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <item quantity="other">Haikuweza kunakili faili <xliff:g id="COUNT_1">%1$d</xliff:g> </item>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="other">Haikuweza kunakili faili <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="one">Haikuweza kunakili faili <xliff:g id="COUNT_0">%1$d</xliff:g></item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other">Haikuweza kuhamisha faili <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="one">Haikuweza kuhamisha faili <xliff:g id="COUNT_0">%1$d</xliff:g></item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other">Haikuweza kufuta faili <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="one">Haikuweza kufuta faili <xliff:g id="COUNT_0">%1$d</xliff:g></item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Gonga ili uangalie maelezo"</string>
<string name="close" msgid="3043722427445528732">"Funga"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Faili hizi hazikunakiliwa: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Faili hizi hazikuhamishwa: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Haikunakili faili zifuatazo: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Haikuhamisha faili zifuatazo: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Imeshindwa kufuta faili zifuatazo: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Faili hizi zimebadilishwa muundo. <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">Alinakili faili <xliff:g id="COUNT_1">%1$d</xliff:g> kwenye ubao wa kunakili.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Haiwezi kubandika faili zilizochaguliwa katika eneo hili."</string>
<string name="menu_rename" msgid="7678802479104285353">"Badilisha jina"</string>
<string name="rename_error" msgid="4203041674883412606">"Imeshindwa kubadilisha jina la hati"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Ondoa"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Baadhi ya faili zimebadilishwa muundo"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Ungependa kuruhusu <xliff:g id="APPNAME"><b>^1</b></xliff:g> ifikie saraka ya <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> kwenye <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Ungependa kuruhusu <xliff:g id="APPNAME"><b>^1</b></xliff:g> ifikie saraka ya <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Ungependa kuruhusu <xliff:g id="APPNAME"><b>^1</b></xliff:g> ifikie data yako, ikiwa ni pamoja na picha na video kwenye <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Usiniulize tena"</string>
<string name="allow" msgid="7225948811296386551">"Ruhusu"</string>
<string name="deny" msgid="2081879885755434506">"Kataza"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> zimechaguliwa</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> imechaguliwa</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other">Vipengee <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">Kipengee <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Ungependa kufuta \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Ungependa kufuta folda ya \"<xliff:g id="NAME">%1$s</xliff:g>\" na maudhui yake?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">Ungependa kufuta faili <xliff:g id="COUNT_1">%1$d</xliff:g>?</item>
+ <item quantity="one">Ungependa kufuta faili <xliff:g id="COUNT_0">%1$d</xliff:g>?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">Ungependa kufuta folda <xliff:g id="COUNT_1">%1$d</xliff:g> na maudhui yaliyomo?</item>
+ <item quantity="one">Ungependa kufuta folda <xliff:g id="COUNT_0">%1$d</xliff:g> na maudhui yaliyomo?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other">Ungependa kufuta vipengee <xliff:g id="COUNT_1">%1$d</xliff:g>?</item>
+ <item quantity="one">Ungependa kufuta kipengee <xliff:g id="COUNT_0">%1$d</xliff:g>?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-ta-rIN/config.xml b/packages/DocumentsUI/res/values-ta-rIN/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-ta-rIN/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-ta-rIN/strings.xml b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
index fed470d1e695..157329929c62 100644
--- a/packages/DocumentsUI/res/values-ta-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ஆவணங்கள்"</string>
- <string name="files_label" msgid="6051402950202690279">"கோப்புகள்"</string>
<string name="downloads_label" msgid="959113951084633612">"இறக்கங்கள்"</string>
<string name="title_open" msgid="4353228937663917801">"இதில் திற"</string>
<string name="title_save" msgid="2433679664882857999">"இதில் சேமி"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"பட்டியல்"</string>
<string name="menu_sort" msgid="7677740407158414452">"இதன்படி வரிசைப்படுத்து"</string>
<string name="menu_search" msgid="3816712084502856974">"தேடு"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"சேமிப்பிட அமைப்புகள்"</string>
<string name="menu_open" msgid="432922957274920903">"திற"</string>
<string name="menu_save" msgid="2394743337684426338">"சேமி"</string>
<string name="menu_share" msgid="3075149983979628146">"பகிர்"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"இங்கு நகலெடு…"</string>
<string name="menu_move" msgid="1828090633118079817">"இதற்கு நகர்த்து…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"புதிய சாளரம்"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"வெட்டு"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"நகலெடு"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"ஒட்டு"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"அகச் சேமிப்பகத்தைக் காட்டு"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"வழிகளை மறை"</string>
<string name="save_error" msgid="6167009778003223664">"ஆவணத்தைச் சேமிப்பதில் தோல்வி"</string>
<string name="create_error" msgid="3735649141335444215">"கோப்புறையை உருவாக்குவதில் தோல்வி"</string>
- <string name="query_error" msgid="1222448261663503501">"ஆவணங்களை வினவுவதில் தோல்வி"</string>
+ <string name="query_error" msgid="5999895349602476581">"தற்போது உள்ளடக்கத்தை ஏற்ற முடியாது"</string>
<string name="root_recent" msgid="4470053704320518133">"சமீபத்தியவை"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> இலவசம்"</string>
<string name="root_type_service" msgid="2178854894416775409">"சேமிப்பிட சாதனங்கள்"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"மேலும் பயன்பாடுகள்"</string>
<string name="empty" msgid="7858882803708117596">"எதுவும் இல்லை"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s இல் பொருந்தும் முடிவு இல்லை"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"கோப்பைத் திறக்க முடியவில்லை"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"கோப்பைத் திறக்க முடியாது"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"சில ஆவணங்களை நீக்க முடியவில்லை"</string>
<string name="share_via" msgid="8966594246261344259">"இதன் வழியாகப் பகிர்"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"கோப்புகளை நகலெடுத்தல்"</string>
<string name="move_notification_title" msgid="6193835179777284805">"கோப்புகளை நகர்த்துதல்"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"கோப்புகளை நீக்குகிறது"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> மீதமுள்ளது"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> கோப்புகளை நகலெடுக்கிறது.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"நகல் தயாராகிறது…"</string>
<string name="move_preparing" msgid="2772219441375531410">"நகர்த்துவதற்குத் தயார்படுத்துகிறது…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"நீக்கத் தயாராகிறது…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> கோப்புகளை நகலெடுக்க முடியவில்லை</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> கோப்பை நகலெடுக்க முடியவில்லை</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> கோப்புகளை நகர்த்த முடியவில்லை</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> கோப்பை நகர்த்த முடியவில்லை</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> கோப்புகளை நீக்க முடியவில்லை</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> கோப்பை நீக்க முடியவில்லை</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"விவரங்களைப் பார்க்க, தட்டவும்"</string>
<string name="close" msgid="3043722427445528732">"மூடு"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"நகலெடுக்கப்படாத கோப்புகள்: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"இந்தக் கோப்புகள் நகர்த்தப்படவில்லை: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"பின்வரும் கோப்புகள் நகலெடுக்கப்படவில்லை: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"பின்வரும் கோப்புகள் நகர்த்தப்படவில்லை: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"பின்வரும் கோப்புகள் நீக்கப்படவில்லை: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"இந்தக் கோப்புகள் வேறொரு வடிவத்திற்கு மாற்றப்பட்டன: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">கிளிப்போர்டிற்கு <xliff:g id="COUNT_1">%1$d</xliff:g> கோப்புகள் நகலெடுக்கப்பட்டன.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"தேர்ந்தெடுத்த கோப்புகளை இங்கு ஒட்ட முடியாது."</string>
<string name="menu_rename" msgid="7678802479104285353">"மறுபெயரிடு"</string>
<string name="rename_error" msgid="4203041674883412606">"ஆவணத்திற்கு மறுபெயரிடுவதில் தோல்வி"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"வெளியேற்று"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"சில கோப்புகள் மாற்றப்பட்டன"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> இல் உள்ள <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> கோப்பகத்தை அணுக <xliff:g id="APPNAME"><b>^1</b></xliff:g>ஐ அனுமதிக்கவா?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> கோப்பகத்தை அணுக, <xliff:g id="APPNAME"><b>^1</b></xliff:g>ஐ அனுமதிக்கவா?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> இல் உள்ள படங்கள், வீடியோக்கள் உட்பட எல்லா தரவையும் அணுக, <xliff:g id="APPNAME"><b>^1</b></xliff:g>ஐ அனுமதிக்கவா?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"மீண்டும் கேட்காதே"</string>
<string name="allow" msgid="7225948811296386551">"அனுமதி"</string>
<string name="deny" msgid="2081879885755434506">"நிராகரி"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> தேர்ந்தெடுக்கப்பட்டன</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> தேர்ந்தெடுக்கப்பட்டது</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> உருப்படிகள்</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> உருப்படி</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\"ஐ நீக்கவா?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" கோப்புறையையும் அதன் உள்ளடக்கத்தையும் நீக்கவா?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> கோப்புகளை நீக்கவா?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> கோப்பை நீக்கவா?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> கோப்புறைகளையும் அவற்றின் உள்ளடக்கத்தையும் நீக்கவா?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> கோப்புறையையும் அதன் உள்ளடக்கத்தையும் நீக்கவா?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <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>
</resources>
diff --git a/packages/DocumentsUI/res/values-te-rIN/config.xml b/packages/DocumentsUI/res/values-te-rIN/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-te-rIN/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-te-rIN/strings.xml b/packages/DocumentsUI/res/values-te-rIN/strings.xml
index 0d906272ca02..3bb9720f7e5b 100644
--- a/packages/DocumentsUI/res/values-te-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-te-rIN/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"పత్రాలు"</string>
- <string name="files_label" msgid="6051402950202690279">"ఫైల్‌లు"</string>
<string name="downloads_label" msgid="959113951084633612">"డౌన్‌లోడ్‌లు"</string>
<string name="title_open" msgid="4353228937663917801">"ఇక్కడి నుండి తెరువు"</string>
<string name="title_save" msgid="2433679664882857999">"ఇందులో సేవ్ చేయి"</string>
@@ -35,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"ఇక్కడికి కాపీ చేయి…"</string>
<string name="menu_move" msgid="1828090633118079817">"దీనికి తరలించు..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"కొత్త విండో"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"కత్తిరించు"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"కాపీ చేయి"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"అతికించు"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"అంతర్గత నిల్వను చూపు"</string>
@@ -53,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"మూలాలను దాచు"</string>
<string name="save_error" msgid="6167009778003223664">"పత్రాన్ని సేవ్ చేయడంలో విఫలమైంది"</string>
<string name="create_error" msgid="3735649141335444215">"ఫోల్డర్‌ను సృష్టించడంలో విఫలమైంది"</string>
- <string name="query_error" msgid="1222448261663503501">"పత్రాల కోసం ప్రశ్నించడంలో విఫలమైంది"</string>
+ <string name="query_error" msgid="5999895349602476581">"ఈ సమయంలో కంటెంట్‌ను లోడ్ చేయడం సాధ్యపడదు"</string>
<string name="root_recent" msgid="4470053704320518133">"ఇటీవల"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ఖాళీ"</string>
<string name="root_type_service" msgid="2178854894416775409">"నిల్వ పరికరాలు"</string>
@@ -62,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"మరిన్ని అనువర్తనాలు"</string>
<string name="empty" msgid="7858882803708117596">"అంశాలు లేవు"</string>
<string name="no_results" msgid="6622510343880730446">"%1$sలో సరిపోలినవి లేవు"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"ఫైల్‌ను తెరవడం సాధ్యపడదు"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"ఫైల్‌ను తెరవడం సాధ్యపడదు"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"కొన్ని పత్రాలను తొలగించడం సాధ్యపడలేదు"</string>
<string name="share_via" msgid="8966594246261344259">"దీని ద్వారా భాగస్వామ్యం చేయండి"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"ఫైల్‌లు కాపీ అవుతున్నాయి"</string>
<string name="move_notification_title" msgid="6193835179777284805">"ఫైల్‌లను తరలిస్తోంది"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"ఫైల్‌లను తొలగిస్తోంది"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> మిగిలి ఉంది"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ఫైల్‌లను కాపీ చేస్తోంది.</item>
@@ -84,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"కాపీ చేయడానికి సిద్ధం చేస్తోంది…"</string>
<string name="move_preparing" msgid="2772219441375531410">"తరలించడానికి సిద్ధమవుతోంది…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"తొలగించడానికి సిద్ధం చేస్తోంది…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <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>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ఫైల్‌లను కాపీ చేయడం సాధ్యపడలేదు</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ఫైల్‌ను కాపీ చేయడం సాధ్యపడలేదు</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <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 name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ఫైల్‌లను తరలించడం సాధ్యపడలేదు</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ఫైల్‌ను తరలించడం సాధ్యపడలేదు</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ఫైల్‌లను తొలగించడం సాధ్యపడలేదు</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ఫైల్‌ను తొలగించడం సాధ్యపడలేదు</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"వివరాలను వీక్షించడానికి నొక్కండి"</string>
<string name="close" msgid="3043722427445528732">"మూసివేయి"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"ఈ ఫైల్‌లు కాపీ చేయబడలేదు: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"ఈ ఫైల్‌లు తరలించబడలేదు: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"ఈ ఫైల్‌లు కాపీ చేయబడలేదు: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"ఈ ఫైల్‌లు తరలించబడలేదు: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"ఈ ఫైల్‌లు తొలగించబడలేదు: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"ఈ ఫైల్‌లు మరొక ఆకృతికి మార్చబడ్డాయి: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">క్లిప్‌బోర్డ్‌కి <xliff:g id="COUNT_1">%1$d</xliff:g> ఫైల్‌లను కాపీ చేసారు.</item>
@@ -108,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"ఎంచుకున్న ఫైల్‌లను ఈ స్థానంలోకి తీసుకురావడం సాధ్యపడదు."</string>
<string name="menu_rename" msgid="7678802479104285353">"పేరు మార్చు"</string>
<string name="rename_error" msgid="4203041674883412606">"పత్రం పేరు మార్చడంలో విఫలమైంది"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"తొలగించు"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"కొన్ని పైల్‌లు మార్చబడ్డాయి"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>కి <xliff:g id="STORAGE"><i>^3</i></xliff:g>లో <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> డైరెక్టరీ ప్రాప్యతను మంజూరు చేయాలా?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>కి <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> డైరెక్టరీ ప్రాప్యతను మంజూరు చేయాలా?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g>లో ఫోటోలు మరియు వీడియోలతో సహా మీ డేటా ప్రాప్యతను <xliff:g id="APPNAME"><b>^1</b></xliff:g>కి మంజూరు చేయాలా?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"మళ్లీ అడగవద్దు"</string>
<string name="allow" msgid="7225948811296386551">"అనుమతించండి"</string>
<string name="deny" msgid="2081879885755434506">"తిరస్కరించండి"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ఎంచుకోబడ్డాయి</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ఎంచుకోబడింది</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> అంశాలు</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> అంశం</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\"ని తొలగించాలా?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ఫోల్డర్‌ని మరియు అందులోని కంటెంట్‌లను తొలగించాలా?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ఫైల్‌లను తొలగించాలా?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ఫైల్‌ను తొలగించాలా?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ఫోల్డర్‌లు మరియు వీటిలోని కంటెంట్‌లను తొలగించాలా?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ఫోల్డర్ మరియు దీనిలోని కంటెంట్‌లను తొలగించాలా?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <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>
</resources>
diff --git a/packages/DocumentsUI/res/values-th/config.xml b/packages/DocumentsUI/res/values-th/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-th/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-th/strings.xml b/packages/DocumentsUI/res/values-th/strings.xml
index 25ab564d80aa..7c587c31d3fb 100644
--- a/packages/DocumentsUI/res/values-th/strings.xml
+++ b/packages/DocumentsUI/res/values-th/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"เอกสาร"</string>
- <string name="files_label" msgid="6051402950202690279">"ไฟล์"</string>
<string name="downloads_label" msgid="959113951084633612">"การดาวน์โหลด"</string>
<string name="title_open" msgid="4353228937663917801">"เปิดจาก"</string>
<string name="title_save" msgid="2433679664882857999">"บันทึกไปยัง"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"มุมมองรายการ"</string>
<string name="menu_sort" msgid="7677740407158414452">"จัดเรียงตาม"</string>
<string name="menu_search" msgid="3816712084502856974">"ค้นหา"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"การตั้งค่าที่เก็บข้อมูล"</string>
<string name="menu_open" msgid="432922957274920903">"เปิด"</string>
<string name="menu_save" msgid="2394743337684426338">"บันทึก"</string>
<string name="menu_share" msgid="3075149983979628146">"แชร์"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"คัดลอกไปยัง…"</string>
<string name="menu_move" msgid="1828090633118079817">"ย้ายไปที่…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"หน้าต่างใหม่"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"ตัด"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"คัดลอก"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"วาง"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"แสดงที่จัดเก็บภายใน"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"ซ่อนราก"</string>
<string name="save_error" msgid="6167009778003223664">"การบันทึกเอกสารล้มเหลว"</string>
<string name="create_error" msgid="3735649141335444215">"การสร้างโฟลเดอร์ล้มเหลว"</string>
- <string name="query_error" msgid="1222448261663503501">"การค้นหาเอกสารล้มเหลว"</string>
+ <string name="query_error" msgid="5999895349602476581">"โหลดเนื้อหาไม่ได้ในขณะนี้"</string>
<string name="root_recent" msgid="4470053704320518133">"ล่าสุด"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"ว่าง <xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="root_type_service" msgid="2178854894416775409">"บริการที่เก็บข้อมูล"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"แอปเพิ่มเติม"</string>
<string name="empty" msgid="7858882803708117596">"ไม่มีรายการ"</string>
<string name="no_results" msgid="6622510343880730446">"ไม่พบข้อมูลที่ตรงกันใน %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"ไม่สามารถเปิดไฟล์ได้"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"เปิดไฟล์ไม่ได้"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"ไม่สามารถลบเอกสารบางรายการ"</string>
<string name="share_via" msgid="8966594246261344259">"แชร์ผ่าน"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"กำลังคัดลอกไฟล์"</string>
<string name="move_notification_title" msgid="6193835179777284805">"กำลังย้ายไฟล์"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"กำลังลบไฟล์"</string>
<string name="copy_remaining" msgid="6283790937387975095">"เหลือ <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">กำลังคัดลอก <xliff:g id="COUNT_1">%1$d</xliff:g> ไฟล์</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"กำลังเตรียมการคัดลอก…"</string>
<string name="move_preparing" msgid="2772219441375531410">"กำลังเตรียมการย้าย…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"กำลังเตรียมลบ…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <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>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="other">คัดลอกไม่ได้ <xliff:g id="COUNT_1">%1$d</xliff:g> ไฟล์</item>
+ <item quantity="one">คัดลอกไม่ได้ <xliff:g id="COUNT_0">%1$d</xliff:g> ไฟล์</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <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 name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="other">ย้ายไม่ได้ <xliff:g id="COUNT_1">%1$d</xliff:g> ไฟล์</item>
+ <item quantity="one">ย้ายไม่ได้ <xliff:g id="COUNT_0">%1$d</xliff:g> ไฟล์</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
- <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 name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+ <item quantity="other">ลบไม่ได้ <xliff:g id="COUNT_1">%1$d</xliff:g> ไฟล์</item>
+ <item quantity="one">ลบไม่ได้ <xliff:g id="COUNT_0">%1$d</xliff:g> ไฟล์</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"แตะเพื่อดูรายละเอียด"</string>
<string name="close" msgid="3043722427445528732">"ปิด"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"ไม่มีการคัดลอกไฟล์เหล่านี้: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"ไม่มีการย้ายไฟล์เหล่านี้: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"ไม่ได้คัดลอกไฟล์เหล่านี้: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"ไม่ได้ย้ายไฟล์เหล่านี้: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"ไม่ได้ลบไฟล์เหล่านี้: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"ไฟล์ต่อไปนี้แปลงเป็นอีกรูปแบบหนึ่งแล้ว: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">คัดลอก <xliff:g id="COUNT_1">%1$d</xliff:g> ไฟล์ไปยังคลิปบอร์ดแล้ว</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"ไม่สามารถวางไฟล์ที่เลือกในตำแหน่งนี้"</string>
<string name="menu_rename" msgid="7678802479104285353">"เปลี่ยนชื่อ"</string>
<string name="rename_error" msgid="4203041674883412606">"ไม่สามารถเปลี่ยนชื่อเอกสาร"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"นำอุปกรณ์ออก"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"แปลงบางไฟล์แล้ว"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"ให้สิทธิ์ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ในการเข้าถึงไดเรกทอรี <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ใน <xliff:g id="STORAGE"><i>^3</i></xliff:g> ไหม"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"ให้สิทธิ์ <xliff:g id="APPNAME"><b>^1</b></xliff:g> เข้าถึงไดเรกทอรี <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ไหม"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"ให้สิทธิ์ <xliff:g id="APPNAME"><b>^1</b></xliff:g> เข้าถึงข้อมูลของคุณ รวมถึงรูปภาพและวิดีโอใน <xliff:g id="STORAGE"><i>^2</i></xliff:g> ไหม"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"ไม่ต้องถามอีก"</string>
<string name="allow" msgid="7225948811296386551">"อนุญาต"</string>
<string name="deny" msgid="2081879885755434506">"ปฏิเสธ"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other">เลือกไว้ <xliff:g id="COUNT_1">%1$d</xliff:g> รายการ</item>
+ <item quantity="one">เลือกไว้ <xliff:g id="COUNT_0">%1$d</xliff:g> รายการ</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> รายการ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> รายการ</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"ลบ \"<xliff:g id="NAME">%1$s</xliff:g>\" ไหม"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"ลบโฟลเดอร์ \"<xliff:g id="NAME">%1$s</xliff:g>\" และเนื้อหาข้างในไหม"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">ลบ <xliff:g id="COUNT_1">%1$d</xliff:g> ไฟล์ใช่ไหม</item>
+ <item quantity="one">ลบ <xliff:g id="COUNT_0">%1$d</xliff:g> ไฟล์ใช่ไหม</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">ลบ <xliff:g id="COUNT_1">%1$d</xliff:g> โฟลเดอร์และเนื้อหาข้างในใช่ไหม</item>
+ <item quantity="one">ลบ <xliff:g id="COUNT_0">%1$d</xliff:g> โฟลเดอร์และเนื้อหาข้างในใช่ไหม</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <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>
</resources>
diff --git a/packages/DocumentsUI/res/values-tl/config.xml b/packages/DocumentsUI/res/values-tl/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-tl/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-tl/strings.xml b/packages/DocumentsUI/res/values-tl/strings.xml
index 1baa5db75474..63c2334b9244 100644
--- a/packages/DocumentsUI/res/values-tl/strings.xml
+++ b/packages/DocumentsUI/res/values-tl/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Mga Dokumento"</string>
- <string name="files_label" msgid="6051402950202690279">"Mga File"</string>
<string name="downloads_label" msgid="959113951084633612">"Mga Download"</string>
<string name="title_open" msgid="4353228937663917801">"Buksan mula sa"</string>
<string name="title_save" msgid="2433679664882857999">"I-save sa"</string>
@@ -26,16 +25,16 @@
<string name="menu_list" msgid="7279285939892417279">"View na listahan"</string>
<string name="menu_sort" msgid="7677740407158414452">"Uriin ayon sa"</string>
<string name="menu_search" msgid="3816712084502856974">"Maghanap"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Mga setting ng storage"</string>
<string name="menu_open" msgid="432922957274920903">"Buksan"</string>
<string name="menu_save" msgid="2394743337684426338">"I-save"</string>
<string name="menu_share" msgid="3075149983979628146">"Ibahagi"</string>
- <string name="menu_delete" msgid="8138799623850614177">"Tanggalin"</string>
+ <string name="menu_delete" msgid="8138799623850614177">"I-delete"</string>
<string name="menu_select_all" msgid="8323579667348729928">"Piliin lahat"</string>
<string name="menu_copy" msgid="3612326052677229148">"Kopyahin sa..."</string>
<string name="menu_move" msgid="1828090633118079817">"Ilipat sa…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Bagong window"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"I-cut"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopyahin"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"I-paste"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Ipakita internal storage"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Itago ang mga root"</string>
<string name="save_error" msgid="6167009778003223664">"Hindi na-save ang dokumento"</string>
<string name="create_error" msgid="3735649141335444215">"Hindi nagawa ang folder"</string>
- <string name="query_error" msgid="1222448261663503501">"Hindi na-query ang mga dokumento"</string>
+ <string name="query_error" msgid="5999895349602476581">"Hindi ma-load ang content sa ngayon"</string>
<string name="root_recent" msgid="4470053704320518133">"Kamakailan"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ang libre"</string>
<string name="root_type_service" msgid="2178854894416775409">"Mga serbisyo ng storage"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Higit pang apps"</string>
<string name="empty" msgid="7858882803708117596">"Walang mga item"</string>
<string name="no_results" msgid="6622510343880730446">"Walang mga katugma sa %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Hindi mabuksan ang file"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Hindi mabuksan ang file"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Hindi matanggal ang ilang dokumento"</string>
<string name="share_via" msgid="8966594246261344259">"Ibahagi sa pamamagitan ng"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kinokopya ang mga file"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Inililipat ang mga file"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Pagde-delete ng mga file"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> na lang ang natitira"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Kumokopya ng <xliff:g id="COUNT_1">%1$d</xliff:g> file.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Naghahanda para sa pagkopya…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Naghahanda para sa paglilipat…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Naghahanda para sa pag-delete…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="one">Hindi makopya ang <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
<item quantity="other">Hindi makopya ang <xliff:g id="COUNT_1">%1$d</xliff:g> na file</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="one">Hindi nailipat ang <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
- <item quantity="other">Hindi nailipat ang <xliff:g id="COUNT_1">%1$d</xliff:g> na file</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="one">Hindi mailipat ang <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
+ <item quantity="other">Hindi mailipat ang <xliff:g id="COUNT_1">%1$d</xliff:g> na file</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="one">Hindi ma-delete ang <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
<item quantity="other">Hindi ma-delete ang <xliff:g id="COUNT_1">%1$d</xliff:g> na file</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"I-tap upang tingnan ang mga detalye"</string>
<string name="close" msgid="3043722427445528732">"Isara"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Hindi nakopya ang mga file na ito: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Hindi nailipat ang mga file na ito: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Hindi nakopya ang mga file na ito: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Hindi nailipat ang mga file na ito: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Hindi na-delete ang mga file na ito: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Na-convert ang mga file na ito sa ibang format: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one">Nakopya ang <xliff:g id="COUNT_1">%1$d</xliff:g> file sa clipboard.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Hindi mai-paste sa lokasyong ito ang mga piniling file."</string>
<string name="menu_rename" msgid="7678802479104285353">"Palitan ang pangalan"</string>
<string name="rename_error" msgid="4203041674883412606">"Hindi napalitan ang pangalan ng dokumento"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"I-eject"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Na-convert ang ilang file"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Bigyan ang <xliff:g id="APPNAME"><b>^1</b></xliff:g> ng access sa directory ng <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> sa <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Bibigyan ang <xliff:g id="APPNAME"><b>^1</b></xliff:g> ng access sa direktoryong <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Bigyan ang <xliff:g id="APPNAME"><b>^1</b></xliff:g> ng access sa iyong data, kabilang ang mga larawan at video, sa <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Huwag nang tatanunging muli"</string>
<string name="allow" msgid="7225948811296386551">"Payagan"</string>
<string name="deny" msgid="2081879885755434506">"Tanggihan"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ang napili</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ang napili</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> item</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> na item</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Gusto mo bang i-delete ang \"<xliff:g id="NAME">%1$s</xliff:g>?\""</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Gusto mo bang i-delete ang folder na \"<xliff:g id="NAME">%1$s</xliff:g>\" at ang mga content nito?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one">Gusto mo bang i-delete ang <xliff:g id="COUNT_1">%1$d</xliff:g> file?</item>
+ <item quantity="other">Gusto mo bang i-delete ang <xliff:g id="COUNT_1">%1$d</xliff:g> (na) file?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one">Gusto mo bang i-delete ang <xliff:g id="COUNT_1">%1$d</xliff:g> folder at mga content ng mga ito?</item>
+ <item quantity="other">Gusto mo bang i-delete ang <xliff:g id="COUNT_1">%1$d</xliff:g> na folder at mga content ng mga ito?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one">Gusto mo bang i-delete ang <xliff:g id="COUNT_1">%1$d</xliff:g> item?</item>
+ <item quantity="other">Gusto mo bang i-delete ang <xliff:g id="COUNT_1">%1$d</xliff:g> na item?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-tr/config.xml b/packages/DocumentsUI/res/values-tr/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-tr/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-tr/strings.xml b/packages/DocumentsUI/res/values-tr/strings.xml
index 500c37fe9edc..402d320328a8 100644
--- a/packages/DocumentsUI/res/values-tr/strings.xml
+++ b/packages/DocumentsUI/res/values-tr/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokümanlar"</string>
- <string name="files_label" msgid="6051402950202690279">"Dosyalar"</string>
<string name="downloads_label" msgid="959113951084633612">"İndirilenler"</string>
<string name="title_open" msgid="4353228937663917801">"Şuradan aç:"</string>
<string name="title_save" msgid="2433679664882857999">"Şuraya kaydet:"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Liste görünümü"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sıralama ölçütü"</string>
<string name="menu_search" msgid="3816712084502856974">"Ara"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Depolama ayarları"</string>
<string name="menu_open" msgid="432922957274920903">"Aç"</string>
<string name="menu_save" msgid="2394743337684426338">"Kaydet"</string>
<string name="menu_share" msgid="3075149983979628146">"Paylaş"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Kopyala…"</string>
<string name="menu_move" msgid="1828090633118079817">"Taşı..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"Yeni pencere"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Kes"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopyala"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Yapıştır"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Dahili depolamayı göster"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Kökleri sakla"</string>
<string name="save_error" msgid="6167009778003223664">"Doküman kaydedilemedi"</string>
<string name="create_error" msgid="3735649141335444215">"Klasör oluşturulamadı"</string>
- <string name="query_error" msgid="1222448261663503501">"Dokümanlar sorgulanamadı"</string>
+ <string name="query_error" msgid="5999895349602476581">"İçerik şu anda yüklenemiyor"</string>
<string name="root_recent" msgid="4470053704320518133">"En son"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> boş"</string>
<string name="root_type_service" msgid="2178854894416775409">"Depolama hizmetleri"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Diğer uygulamalar"</string>
<string name="empty" msgid="7858882803708117596">"Öğe yok"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s içinde eşleşme bulunamadı"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Dosya açılamıyor"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Dosya açılamıyor"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Bazı dokümanlar silinemiyor"</string>
<string name="share_via" msgid="8966594246261344259">"Şunu kullanarak paylaş:"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Dosyalar kopyalanıyor"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Dosyalar taşınıyor"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Dosyalar siliniyor"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> kaldı"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dosya kopyalanıyor.</item>
@@ -85,31 +85,60 @@
<string name="copy_preparing" msgid="3896202461003039386">"Kopyalanmak için hazırlanıyor…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Taşıma için hazırlanıyor…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Silmek için hazırlanıyor…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dosya kopyalanamadı</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dosya kopyalanamadı</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dosya taşınamadı</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dosya taşınamadı</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dosya silinemedi</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dosya silinemedi</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Ayrıntıları görmek için hafifçe dokunun"</string>
<string name="close" msgid="3043722427445528732">"Kapat"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Şu dosyalar kopyalanmadı: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Şu dosyalar taşınmadı: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Şu dosyalar kopyalanamadı: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Şu dosyalar taşınamadı: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Şu dosyalar silinemedi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Bu dosyalar başka bir biçime dönüştürüldü: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dosya panoya kopyalandı.</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dosya panoya kopyalandı.</item>
</plurals>
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Seçili dosyalar bu konuma yapıştırılamıyor."</string>
- <string name="menu_rename" msgid="7678802479104285353">"Yeniden Adlandır"</string>
+ <string name="menu_rename" msgid="7678802479104285353">"Yeniden adlandır"</string>
<string name="rename_error" msgid="4203041674883412606">"Dokümanın adı değiştirilemedi"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Çıkar"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Bazı dosyalar dönüştürüldü"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> uygulamasına <xliff:g id="STORAGE"><i>^3</i></xliff:g> depolama alanındaki <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> dizinine erişim izni verilsin mi?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> dizinine erişmek için <xliff:g id="APPNAME"><b>^1</b></xliff:g> uygulamasına izin verilsin mi?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> uygulamasının, fotoğraflar ve videolar dahil olmak üzere <xliff:g id="STORAGE"><i>^2</i></xliff:g> üzerindeki verilerinize erişmesine izin verilsin mi?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Tekrar sorma"</string>
<string name="allow" msgid="7225948811296386551">"İzin Ver"</string>
<string name="deny" msgid="2081879885755434506">"Reddet"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> öğe seçildi</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> öğe seçildi</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> öğe</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> öğe</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" silinsin mi?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" adlı klasör ve içindekiler silinsin mi?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dosya silinsin mi?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dosya silinsin mi?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> klasör ve içindekiler silinsin mi?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> klasör ve içindekiler silinsin mi?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> öğe silinsin mi?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> öğe silinsin mi?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-uk/config.xml b/packages/DocumentsUI/res/values-uk/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-uk/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-uk/strings.xml b/packages/DocumentsUI/res/values-uk/strings.xml
index c57ca6a94562..e95539f197f5 100644
--- a/packages/DocumentsUI/res/values-uk/strings.xml
+++ b/packages/DocumentsUI/res/values-uk/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Документи"</string>
- <string name="files_label" msgid="6051402950202690279">"Файли"</string>
<string name="downloads_label" msgid="959113951084633612">"Завантаження"</string>
<string name="title_open" msgid="4353228937663917801">"Відкрити"</string>
<string name="title_save" msgid="2433679664882857999">"Зберегти в"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Режим списку"</string>
<string name="menu_sort" msgid="7677740407158414452">"Параметри сортування"</string>
<string name="menu_search" msgid="3816712084502856974">"Пошук"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Налаштування пам’яті"</string>
<string name="menu_open" msgid="432922957274920903">"Відкрити"</string>
<string name="menu_save" msgid="2394743337684426338">"Зберегти"</string>
<string name="menu_share" msgid="3075149983979628146">"Поділитися"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Копіювати в…"</string>
<string name="menu_move" msgid="1828090633118079817">"Перемістити в…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Нове вікно"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Вирізати"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Копіювати"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Вставити"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Показати внутр. пам’ять"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Сховати кореневі каталоги"</string>
<string name="save_error" msgid="6167009778003223664">"Не вдалося зберегти документ"</string>
<string name="create_error" msgid="3735649141335444215">"Помилка створення папки"</string>
- <string name="query_error" msgid="1222448261663503501">"Помилка надсилання запиту на документи"</string>
+ <string name="query_error" msgid="5999895349602476581">"Зараз не вдається завантажити вміст"</string>
<string name="root_recent" msgid="4470053704320518133">"Останні"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> вільного місця"</string>
<string name="root_type_service" msgid="2178854894416775409">"Онлайн-сховища"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Інші програми"</string>
<string name="empty" msgid="7858882803708117596">"Нічого немає"</string>
<string name="no_results" msgid="6622510343880730446">"Немає збігів для запиту \"%1$s\""</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Не вдалося відкрити файл"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Не вдалося відкрити файл"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Не вдалося видалити деякі документи"</string>
<string name="share_via" msgid="8966594246261344259">"Надіслати через"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Копіювання файлів"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Переміщення файлів"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Видалення файлів"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Залишилося <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Копіювання <xliff:g id="COUNT_1">%1$d</xliff:g> файлу.</item>
@@ -91,19 +91,20 @@
<string name="copy_preparing" msgid="3896202461003039386">"Підготовка до копіювання…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Підготовка до переміщення…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Підготовка до видалення…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> з <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="one">Не вдалося скопіювати <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
<item quantity="few">Не вдалося скопіювати <xliff:g id="COUNT_1">%1$d</xliff:g> файли</item>
<item quantity="many">Не вдалося скопіювати <xliff:g id="COUNT_1">%1$d</xliff:g> файлів</item>
<item quantity="other">Не вдалося скопіювати <xliff:g id="COUNT_1">%1$d</xliff:g> файлу</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="one">Не вдалося перемістити <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
<item quantity="few">Не вдалося перемістити <xliff:g id="COUNT_1">%1$d</xliff:g> файли</item>
<item quantity="many">Не вдалося перемістити <xliff:g id="COUNT_1">%1$d</xliff:g> файлів</item>
<item quantity="other">Не вдалося перемістити <xliff:g id="COUNT_1">%1$d</xliff:g> файлу</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="one">Не вдалося видалити <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
<item quantity="few">Не вдалося видалити <xliff:g id="COUNT_1">%1$d</xliff:g> файли</item>
<item quantity="many">Не вдалося видалити <xliff:g id="COUNT_1">%1$d</xliff:g> файлів</item>
@@ -111,8 +112,9 @@
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Торкніться, щоб переглянути деталі"</string>
<string name="close" msgid="3043722427445528732">"Закрити"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Ці файли не скопійовано: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Не переміщено ці файли: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Ці файли не скопійовано: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Ці файли не переміщено: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Ці файли не видалено: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Ці файли конвертовано в інший формат: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one">У буфер обміну скопійовано <xliff:g id="COUNT_1">%1$d</xliff:g> файл.</item>
@@ -123,7 +125,44 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Не вдається вставити вибрані файли в цю папку."</string>
<string name="menu_rename" msgid="7678802479104285353">"Перейменувати"</string>
<string name="rename_error" msgid="4203041674883412606">"Не вдалося перейменувати документ"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Вийняти"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Деякі файли конвертовано"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Надати додатку <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ до каталогу <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> на пристрої пам’яті <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Надати додатку <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ до каталогу \"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>\"?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Надати додатку <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ до ваших даних, зокрема до фотографій і відео, які містить <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Не запитувати знову"</string>
<string name="allow" msgid="7225948811296386551">"Дозвол."</string>
<string name="deny" msgid="2081879885755434506">"Забор."</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one">Вибрано <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="few">Вибрано <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="many">Вибрано <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">Вибрано <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> елемент</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> елементи</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> елементів</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> елемента</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Видалити файл <xliff:g id="NAME">%1$s</xliff:g>?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Видалити папку \"<xliff:g id="NAME">%1$s</xliff:g>\" та її вміст?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one">Видалити <xliff:g id="COUNT_1">%1$d</xliff:g> файл?</item>
+ <item quantity="few">Видалити <xliff:g id="COUNT_1">%1$d</xliff:g> файли?</item>
+ <item quantity="many">Видалити <xliff:g id="COUNT_1">%1$d</xliff:g> файлів?</item>
+ <item quantity="other">Видалити <xliff:g id="COUNT_1">%1$d</xliff:g> файлу?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one">Видалити <xliff:g id="COUNT_1">%1$d</xliff:g> папку та їх вміст?</item>
+ <item quantity="few">Видалити <xliff:g id="COUNT_1">%1$d</xliff:g> папки та їх вміст?</item>
+ <item quantity="many">Видалити <xliff:g id="COUNT_1">%1$d</xliff:g> папок та їх вміст?</item>
+ <item quantity="other">Видалити <xliff:g id="COUNT_1">%1$d</xliff:g> папки та їх вміст?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one">Видалити <xliff:g id="COUNT_1">%1$d</xliff:g> елемент?</item>
+ <item quantity="few">Видалити <xliff:g id="COUNT_1">%1$d</xliff:g> елементи?</item>
+ <item quantity="many">Видалити <xliff:g id="COUNT_1">%1$d</xliff:g> елементів?</item>
+ <item quantity="other">Видалити <xliff:g id="COUNT_1">%1$d</xliff:g> елемента?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-ur-rPK/config.xml b/packages/DocumentsUI/res/values-ur-rPK/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-ur-rPK/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-ur-rPK/strings.xml b/packages/DocumentsUI/res/values-ur-rPK/strings.xml
index 90bce27cb971..7c81ebabfac7 100644
--- a/packages/DocumentsUI/res/values-ur-rPK/strings.xml
+++ b/packages/DocumentsUI/res/values-ur-rPK/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"دستاویزات"</string>
- <string name="files_label" msgid="6051402950202690279">"فائلیں"</string>
<string name="downloads_label" msgid="959113951084633612">"ڈاؤن لوڈز"</string>
<string name="title_open" msgid="4353228937663917801">"کھولیں از"</string>
<string name="title_save" msgid="2433679664882857999">"اس میں محفوظ کریں"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"فہرست منظر"</string>
<string name="menu_sort" msgid="7677740407158414452">"ترتیب دیں بلحاظ"</string>
<string name="menu_search" msgid="3816712084502856974">"تلاش کریں"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"اسٹوریج کی ترتیبات"</string>
<string name="menu_open" msgid="432922957274920903">"کھولیں"</string>
<string name="menu_save" msgid="2394743337684426338">"محفوظ کریں"</string>
<string name="menu_share" msgid="3075149983979628146">"اشتراک کریں"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"اس میں کاپی کریں…"</string>
<string name="menu_move" msgid="1828090633118079817">"اس میں منتقل کریں…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"نئی ونڈو"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"کٹ کریں"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"کاپی کریں"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"پیسٹ کریں"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"داخلی اسٹوریج دکھائیں"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"روٹس کو چھپائیں"</string>
<string name="save_error" msgid="6167009778003223664">"دستاویز کو محفوظ کرنے میں ناکام ہو گیا۔"</string>
<string name="create_error" msgid="3735649141335444215">"فولڈر بنانے میں ناکام ہو گیا"</string>
- <string name="query_error" msgid="1222448261663503501">"دستاویزات استفسار کرنے میں ناکام"</string>
+ <string name="query_error" msgid="5999895349602476581">"اس وقت مواد لوڈ نہیں ہو سکتا"</string>
<string name="root_recent" msgid="4470053704320518133">"حالیہ"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> خالی"</string>
<string name="root_type_service" msgid="2178854894416775409">"اسٹوریج سروسز"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"مزید ایپس"</string>
<string name="empty" msgid="7858882803708117596">"کوئی آئٹمز نہيں ہیں"</string>
<string name="no_results" msgid="6622510343880730446">"‏%1$s میں کوئی مماثل نہیں"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"فائل نہيں کھول سکتے ہیں"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"فائل نہیں کھل سکتی"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"کچھ دستاویزات کو حذف کرنے سے قاصر"</string>
<string name="share_via" msgid="8966594246261344259">"اشتراک کریں بذریعہ"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"فائلیں کاپی ہو رہی ہیں"</string>
<string name="move_notification_title" msgid="6193835179777284805">"فائلیں منتقل ہو رہی ہیں"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"فائلیں حذف کی جا رہی ہیں"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> باقی ہے"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فائلیں کاپی کی جا رہی ہیں۔</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"کاپی کیلئے تیار ہو رہا ہے…"</string>
<string name="move_preparing" msgid="2772219441375531410">"منتقلی کیلئے تیار ہو رہی ہیں…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"حذف کرنے کیلئے تیاری ہو رہی ہے…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <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>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فائلیں کاپی نہیں ہو سکیں</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> فائل کاپی نہیں ہو سکی</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فائلز منتقل نہیں ہو سکیں</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فائلیں منتقل نہیں ہو سکیں</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> فائل منتقل نہیں ہو سکی</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فائلیں حذف نہیں ہو سکیں</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> فائل حذف نہیں ہو سکی</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"تفصیلات دیکھنے کیلئے تھپتھپائیں"</string>
<string name="close" msgid="3043722427445528732">"بند کریں"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"یہ فائلز کاپی نہیں کی گئیں: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"یہ فائلیں منتقل نہیں ہوئیں: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"یہ فائلیں کاپی نہیں ہوئیں: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"یہ فائلیں منتقل نہیں ہوئیں: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"یہ فائلیں حذف نہیں ہوئیں: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"ان فائلوں کو ایک دوسرے فارمیٹ میں تبدیل کیا گیا تھا: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فائلز کلپ بورڈ پر کاپی کی گئیں۔</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"منتخب کردہ فائلز کو اس مقام پر پیسٹ نہیں کیا جا سکتا۔"</string>
<string name="menu_rename" msgid="7678802479104285353">"نام تبدیل کریں"</string>
<string name="rename_error" msgid="4203041674883412606">"دستاویز کا نام تبدیل کرنے میں ناکام"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"خارج کریں"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"کچھ فائلوں کو تبدیل کیا گیا تھا"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> کو <xliff:g id="STORAGE"><i>^3</i></xliff:g> پر <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ڈائرکٹری تک رسائی عطا کریں؟"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> کو <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ڈائرکٹری تک رسائی دیں؟"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> کو اپنے ڈیٹا بشمول <xliff:g id="STORAGE"><i>^2</i></xliff:g> پر موجود تصاویر اور ویڈیوز تک رسائی عطا کریں؟"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"دوبارہ نہ پوچھیں"</string>
<string name="allow" msgid="7225948811296386551">"اجازت دیں"</string>
<string name="deny" msgid="2081879885755434506">"مسترد کریں"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> منتخب کردہ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> منتخب کردہ</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> آئٹمز</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> آئٹم</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"\"<xliff:g id="NAME">%1$s</xliff:g>\" حذف کریں؟"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"\"<xliff:g id="NAME">%1$s</xliff:g>\" فولڈر اور اس کی مشمولات حذف کریں؟"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فائلیں حذف کریں؟</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> فائل حذف کریں؟</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فولڈرز اور ان کے مشمولات حذف کریں؟</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> فولڈر اور اس کے مشمولات حذف کریں؟</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <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>
</resources>
diff --git a/packages/DocumentsUI/res/values-uz-rUZ/config.xml b/packages/DocumentsUI/res/values-uz-rUZ/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-uz-rUZ/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
index 4a0aba2ebd84..50904097e6df 100644
--- a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
+++ b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
@@ -17,31 +17,30 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Hujjatlar"</string>
- <string name="files_label" msgid="6051402950202690279">"Fayllar"</string>
- <string name="downloads_label" msgid="959113951084633612">"Yuklanishlar"</string>
+ <string name="downloads_label" msgid="959113951084633612">"Yuklanmalar"</string>
<string name="title_open" msgid="4353228937663917801">"Ochish"</string>
<string name="title_save" msgid="2433679664882857999">"Saqlash"</string>
<string name="menu_create_dir" msgid="2547620241173881754">"Yangi jild"</string>
- <string name="menu_grid" msgid="6878021334497835259">"Katak ko‘rinishida"</string>
+ <string name="menu_grid" msgid="6878021334497835259">"To‘r ko‘rinishida"</string>
<string name="menu_list" msgid="7279285939892417279">"Ro‘yxat ko‘rinishida"</string>
<string name="menu_sort" msgid="7677740407158414452">"Saralash"</string>
<string name="menu_search" msgid="3816712084502856974">"Qidirish"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Xotira sozlamalari"</string>
<string name="menu_open" msgid="432922957274920903">"Ochish"</string>
<string name="menu_save" msgid="2394743337684426338">"Saqlash"</string>
- <string name="menu_share" msgid="3075149983979628146">"Ulashish"</string>
+ <string name="menu_share" msgid="3075149983979628146">"Baham ko‘rish"</string>
<string name="menu_delete" msgid="8138799623850614177">"O‘chirish"</string>
- <string name="menu_select_all" msgid="8323579667348729928">"Barchasini belgilash"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Hammasini belgilash"</string>
<string name="menu_copy" msgid="3612326052677229148">"Nusxalash…"</string>
<string name="menu_move" msgid="1828090633118079817">"Ko‘chirib o‘tkazish…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Yangi oyna"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Kesish"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Nusxalash"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Joylash"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Ichki xotirani ko‘rsatish"</string>
<string name="menu_advanced_hide" msgid="4218809952721972589">"Ichki xotirani berkitish"</string>
- <string name="menu_file_size_show" msgid="3240323619260823076">"Fayl hajmini ko‘rsatish"</string>
- <string name="menu_file_size_hide" msgid="8881975928502581042">"Fayl hajmini berkitish"</string>
+ <string name="menu_file_size_show" msgid="3240323619260823076">"Fayllar hajmi ko‘rsatilsin"</string>
+ <string name="menu_file_size_hide" msgid="8881975928502581042">"Fayllar hajmi ko‘rsatilmasin"</string>
<string name="button_select" msgid="527196987259139214">"Tanlash"</string>
<string name="button_copy" msgid="8706475544635021302">"Nusxalash"</string>
<string name="button_move" msgid="2202666023104202232">"Ko‘chirib o‘tkazish"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Asosiy jildlarni yashirish"</string>
<string name="save_error" msgid="6167009778003223664">"Hujjat saqlanmadi"</string>
<string name="create_error" msgid="3735649141335444215">"Jild yaratilmadi"</string>
- <string name="query_error" msgid="1222448261663503501">"Hujjatlar so‘rovi jo‘natilmadi"</string>
+ <string name="query_error" msgid="5999895349602476581">"Ayni paytda kontentni yuklab bo‘lmayapti"</string>
<string name="root_recent" msgid="4470053704320518133">"Yaqinda"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> bo‘sh"</string>
<string name="root_type_service" msgid="2178854894416775409">"Xotira xizmatlari"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Ko‘proq dasturlar"</string>
<string name="empty" msgid="7858882803708117596">"Hech narsa yo‘q"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s jildidan topilmadi"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Fayl ochilmadi"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Fayl ochilmadi"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Ba’zi hujjatlar o‘chirilmadi"</string>
- <string name="share_via" msgid="8966594246261344259">"Quyidagi orqali ulashish"</string>
+ <string name="share_via" msgid="8966594246261344259">"Baham ko‘rish"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Fayllar nusxalanmoqda"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Ko‘chirib o‘tkazilmoqda"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Fayllar o‘chirilmoqda"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> qoldi"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> ta fayl nusxalanmoqda</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Nuxsa olishga tayyorgarlik..."</string>
<string name="move_preparing" msgid="2772219441375531410">"Ko‘chirishga tayyorgarlik…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"O‘chirishga tayyorlanmoqda…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
- <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta fayldan nusxa olinmadi</item>
- <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta fayldan nusxa olinmadi</item>
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta fayldan nusxa olib bo‘lmadi</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta fayldan nusxa olib bo‘lmadi</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta fayl ko‘chirib o‘tkazilmadi</item>
- <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta fayl ko‘chirib o‘tkazilmadi</item>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta faylni ko‘chirib bo‘lmadi</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta faylni ko‘chirib bo‘lmadi</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta faylni o‘chirib bo‘lmadi</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta faylni o‘chirib bo‘lmadi</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Batafsil ma’lumot olish uchun bosing"</string>
<string name="close" msgid="3043722427445528732">"Yopish"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Ushbu fayllardan nusxa olinmadi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Ushbu fayllar ko‘chirib o‘tkazilmadi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Quyidagi fayllardan nusxa olinmadi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Quyidagi fayllar ko‘chirilmadi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Quyidagi fayllar o‘chirib tashlanmadi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Ushbu fayllar boshqa formatga o‘girildi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta fayldan vaqtinchalik xotiraga nusxa olindi.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Tanlangan fayllarni bu yerga joylab bo‘lmadi."</string>
<string name="menu_rename" msgid="7678802479104285353">"Qayta nomlash"</string>
<string name="rename_error" msgid="4203041674883412606">"Hujjatni qayta nomlab bo‘lmadi"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Chiqarish"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Bir nechta fayllar o‘girildi"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ilovasiga <xliff:g id="STORAGE"><i>^3</i></xliff:g> xotirasidagi “<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>” jildidan foydalanishiga ruxsat berilsinmi?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ilovasiga “<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>” jildidan foydalanishiga ruxsat berilsinmi?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ilovasiga <xliff:g id="STORAGE"><i>^2</i></xliff:g> xotirasidagi ma’lumotlardan, jumladan, rasmlar va videolardan foydalanishiga ruxsat berilsinmi?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Boshqa so‘ralmasin"</string>
<string name="allow" msgid="7225948811296386551">"Ruxsat berish"</string>
<string name="deny" msgid="2081879885755434506">"Rad qilish"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta belgilandi</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta belgilandi</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta element</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta element</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"“<xliff:g id="NAME">%1$s</xliff:g>” o‘chirib tashlansinmi?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"“<xliff:g id="NAME">%1$s</xliff:g>” jildi ichidagi kontentlari bilan o‘chirib tashlansinmi?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta fayl o‘chirilsinmi?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta fayl o‘chirib tashlansinmi?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta jild ichidagi kontentlari bilan o‘chirib tashlansinmi?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta jild ichidagi kontentlari bilan o‘chirib tashlansinmi?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta element o‘chirib tashlansinmi?</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta element o‘chirib tashlansinmi?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-vi/config.xml b/packages/DocumentsUI/res/values-vi/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-vi/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-vi/strings.xml b/packages/DocumentsUI/res/values-vi/strings.xml
index 48290d1d0362..b9c99b638cd9 100644
--- a/packages/DocumentsUI/res/values-vi/strings.xml
+++ b/packages/DocumentsUI/res/values-vi/strings.xml
@@ -17,8 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Tài liệu"</string>
- <string name="files_label" msgid="6051402950202690279">"Tệp"</string>
- <string name="downloads_label" msgid="959113951084633612">"Tài nguyên đã tải xuống"</string>
+ <string name="downloads_label" msgid="959113951084633612">"Tải xuống"</string>
<string name="title_open" msgid="4353228937663917801">"Mở từ"</string>
<string name="title_save" msgid="2433679664882857999">"Lưu vào"</string>
<string name="menu_create_dir" msgid="2547620241173881754">"Thư mục mới"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"Chế độ xem danh sách"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sắp xếp theo"</string>
<string name="menu_search" msgid="3816712084502856974">"Tìm kiếm"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Cài đặt bộ nhớ"</string>
<string name="menu_open" msgid="432922957274920903">"Mở"</string>
<string name="menu_save" msgid="2394743337684426338">"Lưu"</string>
<string name="menu_share" msgid="3075149983979628146">"Chia sẻ"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Sao chép vào…"</string>
<string name="menu_move" msgid="1828090633118079817">"Chuyển tới..."</string>
<string name="menu_new_window" msgid="1226032889278727538">"Cửa sổ mới"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Cắt"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Sao chép"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Dán"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Hiển thị bộ nhớ trong"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Ẩn gốc"</string>
<string name="save_error" msgid="6167009778003223664">"Không lưu tài liệu được"</string>
<string name="create_error" msgid="3735649141335444215">"Không thể tạo thư mục"</string>
- <string name="query_error" msgid="1222448261663503501">"Không truy vấn được tài liệu"</string>
+ <string name="query_error" msgid="5999895349602476581">"Không thể tải nội dung vào lúc này"</string>
<string name="root_recent" msgid="4470053704320518133">"Gần đây"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> còn trống"</string>
<string name="root_type_service" msgid="2178854894416775409">"Dịch vụ lưu trữ"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Các ứng dụng khác"</string>
<string name="empty" msgid="7858882803708117596">"Không có mục nào"</string>
<string name="no_results" msgid="6622510343880730446">"Không có kết quả phù hợp trong %1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Không thể mở tệp"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Không thể mở tệp"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Không thể xóa một số tài liệu"</string>
<string name="share_via" msgid="8966594246261344259">"Chia sẻ qua"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Đang sao chép tệp"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Đang di chuyển tệp"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Đang xóa tệp"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Còn <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Đang sao chép <xliff:g id="COUNT_1">%1$d</xliff:g> tệp.</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Đang chuẩn bị sao chép…"</string>
<string name="move_preparing" msgid="2772219441375531410">"Đang chuẩn bị di chuyển…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Đang chuẩn bị xóa…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other">Không thể sao chép <xliff:g id="COUNT_1">%1$d</xliff:g> tệp</item>
<item quantity="one">Không thể sao chép <xliff:g id="COUNT_0">%1$d</xliff:g> tệp</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other">Không thể di chuyển <xliff:g id="COUNT_1">%1$d</xliff:g> tệp</item>
<item quantity="one">Không thể di chuyển <xliff:g id="COUNT_0">%1$d</xliff:g> tệp</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other">Không thể xóa <xliff:g id="COUNT_1">%1$d</xliff:g> tệp</item>
<item quantity="one">Không thể xóa <xliff:g id="COUNT_0">%1$d</xliff:g> tệp</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Nhấn để xem chi tiết"</string>
<string name="close" msgid="3043722427445528732">"Đóng"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Những tệp này chưa được sao chép: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Những tệp này chưa được di chuyển: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Những tệp này chưa được sao chép: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Những tệp này chưa được di chuyển: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Những tệp này chưa được xóa: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Các tệp này đã được chuyển đổi sang định dạng khác: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">Đã sao chép <xliff:g id="COUNT_1">%1$d</xliff:g> tệp vào khay nhớ tạm.</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Không thể dán các tệp đã chọn vào vị trí này."</string>
<string name="menu_rename" msgid="7678802479104285353">"Đổi tên"</string>
<string name="rename_error" msgid="4203041674883412606">"Không đổi được tên tài liệu"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Đẩy ra"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Đã chuyển đổi một số tệp"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Cấp cho <xliff:g id="APPNAME"><b>^1</b></xliff:g> quyền truy cập vào thư mục <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> trong <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Cấp cho <xliff:g id="APPNAME"><b>^1</b></xliff:g> quyền truy cập thư mục <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Cấp cho <xliff:g id="APPNAME"><b>^1</b></xliff:g> quyền truy cập vào dữ liệu của bạn, kể cả ảnh và video trên <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Không hỏi lại"</string>
<string name="allow" msgid="7225948811296386551">"Cho phép"</string>
<string name="deny" msgid="2081879885755434506">"Từ chối"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other">Đã chọn <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">Đã chọn <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> mục</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> mục</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Xóa \"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Xóa thư mục \"<xliff:g id="NAME">%1$s</xliff:g>\" và nội dung của thư mục?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">Xóa <xliff:g id="COUNT_1">%1$d</xliff:g> tệp?</item>
+ <item quantity="one">Xóa <xliff:g id="COUNT_0">%1$d</xliff:g> tệp?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">Xóa <xliff:g id="COUNT_1">%1$d</xliff:g> thư mục và nội dung trong đó?</item>
+ <item quantity="one">Xóa <xliff:g id="COUNT_0">%1$d</xliff:g> thư mục và nội dung trong đó?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="other">Xóa <xliff:g id="COUNT_1">%1$d</xliff:g> mục?</item>
+ <item quantity="one">Xóa <xliff:g id="COUNT_0">%1$d</xliff:g> mục?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-zh-rCN/config.xml b/packages/DocumentsUI/res/values-zh-rCN/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-zh-rCN/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-zh-rCN/strings.xml b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
index f3d4e6cc854f..718ce0de65ca 100644
--- a/packages/DocumentsUI/res/values-zh-rCN/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"文档"</string>
- <string name="files_label" msgid="6051402950202690279">"文件"</string>
<string name="downloads_label" msgid="959113951084633612">"下载"</string>
<string name="title_open" msgid="4353228937663917801">"打开文件"</string>
<string name="title_save" msgid="2433679664882857999">"保存文件"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"列表视图"</string>
<string name="menu_sort" msgid="7677740407158414452">"排序依据"</string>
<string name="menu_search" msgid="3816712084502856974">"搜索"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"存储设置"</string>
<string name="menu_open" msgid="432922957274920903">"打开"</string>
<string name="menu_save" msgid="2394743337684426338">"保存"</string>
<string name="menu_share" msgid="3075149983979628146">"分享"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"复制到…"</string>
<string name="menu_move" msgid="1828090633118079817">"移动到…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"新建窗口"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"剪切"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"复制"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"粘贴"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"显示内部存储设备"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"隐藏根目录"</string>
<string name="save_error" msgid="6167009778003223664">"无法保存文档"</string>
<string name="create_error" msgid="3735649141335444215">"无法创建文件夹"</string>
- <string name="query_error" msgid="1222448261663503501">"无法查询文档"</string>
+ <string name="query_error" msgid="5999895349602476581">"暂时无法加载内容"</string>
<string name="root_recent" msgid="4470053704320518133">"最近"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"可用空间:<xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="root_type_service" msgid="2178854894416775409">"存储服务"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"更多应用"</string>
<string name="empty" msgid="7858882803708117596">"无任何文件"</string>
<string name="no_results" msgid="6622510343880730446">"%1$s中没有任何相符项"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"无法打开文件"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"无法打开文件"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"无法删除部分文档"</string>
<string name="share_via" msgid="8966594246261344259">"分享方式"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"正在复制文件"</string>
<string name="move_notification_title" msgid="6193835179777284805">"正在移动文件"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"正在删除文件"</string>
<string name="copy_remaining" msgid="6283790937387975095">"剩余时间:<xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">正在复制 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件。</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"正在准备复制…"</string>
<string name="move_preparing" msgid="2772219441375531410">"正在准备移动…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"正在准备删除…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other">无法复制 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件</item>
<item quantity="one">无法复制 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other">无法移动 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件</item>
<item quantity="one">无法移动 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other">无法删除 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件</item>
<item quantity="one">无法删除 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"点按即可查看详情"</string>
<string name="close" msgid="3043722427445528732">"关闭"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"以下文件无法复制:<xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"以下文件无法移动:<xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"无法复制以下文件:<xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"无法移动以下文件:<xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"未能删除以下文件:<xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"下列文件已转换成其他格式:<xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">已将 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件复制到剪贴板。</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"无法将所选文件粘贴到此位置。"</string>
<string name="menu_rename" msgid="7678802479104285353">"重命名"</string>
<string name="rename_error" msgid="4203041674883412606">"无法重命名文档"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"弹出"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"部分文件已转换成其他格式"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"要授权<xliff:g id="APPNAME"><b>^1</b></xliff:g>访问 <xliff:g id="STORAGE"><i>^3</i></xliff:g>上的“<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>”目录吗?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"要授权<xliff:g id="APPNAME"><b>^1</b></xliff:g>访问“<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>”目录吗?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"要授权<xliff:g id="APPNAME"><b>^1</b></xliff:g>访问您 <xliff:g id="STORAGE"><i>^2</i></xliff:g>上的数据(包括照片和视频)吗?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"不再询问"</string>
<string name="allow" msgid="7225948811296386551">"允许"</string>
<string name="deny" msgid="2081879885755434506">"拒绝"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other">已选择 <xliff:g id="COUNT_1">%1$d</xliff:g> 项</item>
+ <item quantity="one">已选择 <xliff:g id="COUNT_0">%1$d</xliff:g> 项</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> 项</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> 项</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"确定要删除“<xliff:g id="NAME">%1$s</xliff:g>”吗?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"要删除文件夹“<xliff:g id="NAME">%1$s</xliff:g>”及其中的内容吗?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">删除 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件?</item>
+ <item quantity="one">删除 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">删除 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件夹及其中的内容?</item>
+ <item quantity="one">删除 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件夹及其中的内容?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <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>
</resources>
diff --git a/packages/DocumentsUI/res/values-zh-rHK/config.xml b/packages/DocumentsUI/res/values-zh-rHK/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-zh-rHK/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-zh-rHK/strings.xml b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
index 3c55cd8ae059..552c85880b32 100644
--- a/packages/DocumentsUI/res/values-zh-rHK/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"文件"</string>
- <string name="files_label" msgid="6051402950202690279">"檔案"</string>
<string name="downloads_label" msgid="959113951084633612">"下載"</string>
<string name="title_open" msgid="4353228937663917801">"開啟檔案"</string>
<string name="title_save" msgid="2433679664882857999">"儲存至"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"清單檢視"</string>
<string name="menu_sort" msgid="7677740407158414452">"排序方式"</string>
<string name="menu_search" msgid="3816712084502856974">"搜尋"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"儲存空間設定"</string>
<string name="menu_open" msgid="432922957274920903">"開啟"</string>
<string name="menu_save" msgid="2394743337684426338">"儲存"</string>
<string name="menu_share" msgid="3075149983979628146">"分享"</string>
@@ -36,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"複製到…"</string>
<string name="menu_move" msgid="1828090633118079817">"移至…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"新視窗"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"剪下"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"複製"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"貼上"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"顯示內部儲存空間"</string>
@@ -54,8 +53,8 @@
<string name="drawer_close" msgid="7602734368552123318">"隱藏根目錄"</string>
<string name="save_error" msgid="6167009778003223664">"無法儲存文件"</string>
<string name="create_error" msgid="3735649141335444215">"無法建立資料夾"</string>
- <string name="query_error" msgid="1222448261663503501">"無法查詢文件"</string>
- <string name="root_recent" msgid="4470053704320518133">"近期用過"</string>
+ <string name="query_error" msgid="5999895349602476581">"目前無法載入內容"</string>
+ <string name="root_recent" msgid="4470053704320518133">"最近"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"可用空間:<xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="root_type_service" msgid="2178854894416775409">"儲存空間服務"</string>
<string name="root_type_shortcut" msgid="3318760609471618093">"捷徑"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"更多應用程式"</string>
<string name="empty" msgid="7858882803708117596">"沒有項目"</string>
<string name="no_results" msgid="6622510343880730446">"「%1$s」中沒有相符結果"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"無法開啟檔案"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"無法開啟檔案"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"無法刪除部分文件"</string>
<string name="share_via" msgid="8966594246261344259">"分享方式:"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"正在複製檔案"</string>
<string name="move_notification_title" msgid="6193835179777284805">"正在移動檔案"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"正在刪除檔案"</string>
<string name="copy_remaining" msgid="6283790937387975095">"剩餘 <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">正在複製 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案。</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"正在準備複製…"</string>
<string name="move_preparing" msgid="2772219441375531410">"正在準備移動…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"正在準備刪除…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"第 <xliff:g id="COUNT_0">%1$d</xliff:g> 個,共 <xliff:g id="TOTALCOUNT">%2$d</xliff:g> 個"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other">無法複製 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案</item>
<item quantity="one">無法複製 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
- <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 name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+ <item quantity="other">無法移動 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案</item>
+ <item quantity="one">無法移動 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other">無法刪除 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案</item>
<item quantity="one">無法刪除 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案</item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"輕按即可查看詳細資訊"</string>
<string name="close" msgid="3043722427445528732">"關閉"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"以下檔案未能複製:<xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"這些檔案並未移動:<xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"以下檔案未能複製:<xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"以下檔案未能移動:<xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"無法刪除以下檔案:<xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"這些檔案已轉換成其他格式:<xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">已複製 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案到剪貼簿。</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"無法在此位置貼上選取檔案。"</string>
<string name="menu_rename" msgid="7678802479104285353">"重新命名"</string>
<string name="rename_error" msgid="4203041674883412606">"無法重新命名文件"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"逐出"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"部分檔案已轉換成其他格式"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"要為「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」開放 <xliff:g id="STORAGE"><i>^3</i></xliff:g>上的「<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>」目錄存取權嗎?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"要為「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」開放「<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>」目錄的存取權嗎?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"要向「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」開放 <xliff:g id="STORAGE"><i>^2</i></xliff:g>上的相片和影片等資料的存取權嗎?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"不要再詢問"</string>
<string name="allow" msgid="7225948811296386551">"允許"</string>
<string name="deny" msgid="2081879885755434506">"拒絕"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other">已選取 <xliff:g id="COUNT_1">%1$d</xliff:g> 個項目</item>
+ <item quantity="one">已選取 <xliff:g id="COUNT_0">%1$d</xliff:g> 個項目</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> 個項目</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> 個項目</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"要刪除「<xliff:g id="NAME">%1$s</xliff:g>」嗎?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"要刪除「<xliff:g id="NAME">%1$s</xliff:g>」資料夾及其內容嗎?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">要刪除 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案嗎?</item>
+ <item quantity="one">要刪除 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案嗎?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">要刪除 <xliff:g id="COUNT_1">%1$d</xliff:g> 個資料夾及其內容嗎?</item>
+ <item quantity="one">要刪除 <xliff:g id="COUNT_0">%1$d</xliff:g> 個資料夾及其內容嗎?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <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>
</resources>
diff --git a/packages/DocumentsUI/res/values-zh-rTW/config.xml b/packages/DocumentsUI/res/values-zh-rTW/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-zh-rTW/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-zh-rTW/strings.xml b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
index f09899cc9c25..1a6a883d6bbb 100644
--- a/packages/DocumentsUI/res/values-zh-rTW/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
@@ -17,8 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"文件"</string>
- <string name="files_label" msgid="6051402950202690279">"檔案"</string>
- <string name="downloads_label" msgid="959113951084633612">"下載內容"</string>
+ <string name="downloads_label" msgid="959113951084633612">"下載"</string>
<string name="title_open" msgid="4353228937663917801">"開啟檔案"</string>
<string name="title_save" msgid="2433679664882857999">"儲存至"</string>
<string name="menu_create_dir" msgid="2547620241173881754">"新增資料夾"</string>
@@ -26,8 +25,7 @@
<string name="menu_list" msgid="7279285939892417279">"清單檢視"</string>
<string name="menu_sort" msgid="7677740407158414452">"排序依據"</string>
<string name="menu_search" msgid="3816712084502856974">"搜尋"</string>
- <!-- no translation found for menu_settings (8239065133341597825) -->
- <skip />
+ <string name="menu_settings" msgid="8239065133341597825">"Storage 設定"</string>
<string name="menu_open" msgid="432922957274920903">"開啟"</string>
<string name="menu_save" msgid="2394743337684426338">"儲存"</string>
<string name="menu_share" msgid="3075149983979628146">"共用"</string>
@@ -35,7 +33,8 @@
<string name="menu_select_all" msgid="8323579667348729928">"全選"</string>
<string name="menu_copy" msgid="3612326052677229148">"複製到…"</string>
<string name="menu_move" msgid="1828090633118079817">"移至…"</string>
- <string name="menu_new_window" msgid="1226032889278727538">"新視窗"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"新增視窗"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"剪下"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"複製"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"貼上"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"顯示內部儲存空間"</string>
@@ -54,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"隱藏根目錄"</string>
<string name="save_error" msgid="6167009778003223664">"無法儲存文件"</string>
<string name="create_error" msgid="3735649141335444215">"無法建立資料夾"</string>
- <string name="query_error" msgid="1222448261663503501">"無法查詢文件"</string>
+ <string name="query_error" msgid="5999895349602476581">"目前無法載入內容"</string>
<string name="root_recent" msgid="4470053704320518133">"最近"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"可用空間:<xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="root_type_service" msgid="2178854894416775409">"儲存空間服務"</string>
@@ -63,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"更多應用程式"</string>
<string name="empty" msgid="7858882803708117596">"沒有任何項目"</string>
<string name="no_results" msgid="6622510343880730446">"沒有與「%1$s」相符的結果"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"無法開啟檔案"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"無法開啟檔案"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"無法刪除部分文件"</string>
<string name="share_via" msgid="8966594246261344259">"分享方式:"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"複製檔案"</string>
<string name="move_notification_title" msgid="6193835179777284805">"正在移動檔案"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"正在刪除檔案"</string>
<string name="copy_remaining" msgid="6283790937387975095">"剩餘 <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">正在複製 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案。</item>
@@ -85,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"正在準備複製…"</string>
<string name="move_preparing" msgid="2772219441375531410">"準備移動…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"正在準備刪除…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="other">無法複製 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案</item>
<item quantity="one">無法複製 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案</item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="other">無法移動 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案</item>
<item quantity="one">無法移動 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案</item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="other">無法刪除 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案</item>
<item quantity="one">無法刪除 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案</item>
</plurals>
- <string name="notification_touch_for_details" msgid="6268189413228855582">"輕按即可查看詳細資訊"</string>
+ <string name="notification_touch_for_details" msgid="6268189413228855582">"輕觸即可查看詳細資訊"</string>
<string name="close" msgid="3043722427445528732">"關閉"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"未複製這些檔案:<xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"未移動以下檔案:<xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"未複製下列檔案:<xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"未移動下列檔案:<xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"未刪除下列檔案:<xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"下列檔案已轉換成其他格式:<xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="other">已將 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案複製到剪貼簿。</item>
@@ -109,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"無法將所選檔案貼到這個位置。"</string>
<string name="menu_rename" msgid="7678802479104285353">"重新命名"</string>
<string name="rename_error" msgid="4203041674883412606">"無法重新命名文件"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"退出"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"部分檔案已轉換成其他格式"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"要允許<xliff:g id="APPNAME"><b>^1</b></xliff:g>存取 <xliff:g id="STORAGE"><i>^3</i></xliff:g>上的「<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>」目錄嗎?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"要允許<xliff:g id="APPNAME"><b>^1</b></xliff:g>存取「<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>」目錄嗎?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"要允許「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」存取 <xliff:g id="STORAGE"><i>^2</i></xliff:g>上的資料 (包括相片和影片) 嗎?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"不要再詢問"</string>
<string name="allow" msgid="7225948811296386551">"允許"</string>
<string name="deny" msgid="2081879885755434506">"拒絕"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="other">已選取 <xliff:g id="COUNT_1">%1$d</xliff:g> 個項目</item>
+ <item quantity="one">已選取 <xliff:g id="COUNT_0">%1$d</xliff:g> 個項目</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> 個項目</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> 個項目</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"要刪除「<xliff:g id="NAME">%1$s</xliff:g>」嗎?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"要刪除「<xliff:g id="NAME">%1$s</xliff:g>」資料夾和當中的內容嗎?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="other">要刪除 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案嗎?</item>
+ <item quantity="one">要刪除 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案嗎?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="other">要刪除 <xliff:g id="COUNT_1">%1$d</xliff:g> 個資料夾和當中的內容嗎?</item>
+ <item quantity="one">要刪除 <xliff:g id="COUNT_0">%1$d</xliff:g> 個資料夾和當中的內容嗎?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <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>
</resources>
diff --git a/packages/DocumentsUI/res/values-zu/config.xml b/packages/DocumentsUI/res/values-zu/config.xml
deleted file mode 100644
index 843a8aad4051..000000000000
--- a/packages/DocumentsUI/res/values-zu/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
-</resources>
diff --git a/packages/DocumentsUI/res/values-zu/strings.xml b/packages/DocumentsUI/res/values-zu/strings.xml
index dffe2418aaea..285047e0a754 100644
--- a/packages/DocumentsUI/res/values-zu/strings.xml
+++ b/packages/DocumentsUI/res/values-zu/strings.xml
@@ -17,7 +17,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Amadokhumenti"</string>
- <string name="files_label" msgid="6051402950202690279">"Amafayela"</string>
<string name="downloads_label" msgid="959113951084633612">"Okulandiwe"</string>
<string name="title_open" msgid="4353228937663917801">"Vula kusuka ku-"</string>
<string name="title_save" msgid="2433679664882857999">"Londoloza ku-"</string>
@@ -35,6 +34,7 @@
<string name="menu_copy" msgid="3612326052677229148">"Kopishela ku…"</string>
<string name="menu_move" msgid="1828090633118079817">"Hambisa ku…"</string>
<string name="menu_new_window" msgid="1226032889278727538">"Iwindi elisha"</string>
+ <string name="menu_cut_to_clipboard" msgid="2467149185452488383">"Sika"</string>
<string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopisha"</string>
<string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Namathisela"</string>
<string name="menu_advanced_show" msgid="4693652895715631401">"Bonisa isitoreji sangaphakathi"</string>
@@ -53,7 +53,7 @@
<string name="drawer_close" msgid="7602734368552123318">"Fihla izimpande"</string>
<string name="save_error" msgid="6167009778003223664">"Yehlulekile ukulondoloza idokhumenti"</string>
<string name="create_error" msgid="3735649141335444215">"Yehlulekile ukudala ifolda"</string>
- <string name="query_error" msgid="1222448261663503501">"Ihlulekile ukubuza amadokhumenti"</string>
+ <string name="query_error" msgid="5999895349602476581">"Ayikwazanga ukulayisha okuqukethwe okwamanje"</string>
<string name="root_recent" msgid="4470053704320518133">"Okwakamuva"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> okhululekile"</string>
<string name="root_type_service" msgid="2178854894416775409">"Amasevisi wesitoreji"</string>
@@ -62,11 +62,12 @@
<string name="root_type_apps" msgid="8838065367985945189">"Izinhlelo zokusebenza eziningi"</string>
<string name="empty" msgid="7858882803708117596">"Azikho izinto"</string>
<string name="no_results" msgid="6622510343880730446">"Akukho okufanayo ku-%1$s"</string>
- <string name="toast_no_application" msgid="1339885974067891667">"Ayikwazi ukuvula ifayela"</string>
+ <string name="toast_no_application" msgid="4632640357724698144">"Ayikwazanga ukuvula ifayela"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Ayikwazi ukususa amanye amadokhumenti"</string>
<string name="share_via" msgid="8966594246261344259">"Yabelana nge-"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Ikopisha amafayela"</string>
<string name="move_notification_title" msgid="6193835179777284805">"Ihambisa amafayela"</string>
+ <string name="delete_notification_title" msgid="3329403967712437496">"Ukususa amafayela"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> okusele"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Ikopisha amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
@@ -84,22 +85,24 @@
<string name="copy_preparing" msgid="3896202461003039386">"Ilungiselela ukukopisha..."</string>
<string name="move_preparing" msgid="2772219441375531410">"Ilungiselela ukuhambisa…"</string>
<string name="delete_preparing" msgid="5655813182533491992">"Ilungiselela ukususa…"</string>
- <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <string name="delete_progress" msgid="5399405983046157222">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="TOTALCOUNT">%2$d</xliff:g>"</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
<item quantity="one">Ayikwazanga ukukopisha amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="other">Ayikwazanga ukukopisha amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g></item>
</plurals>
- <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
<item quantity="one">Ayikwazanga ukuhambisa amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="other">Ayikwazanga ukuhambisa amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g></item>
</plurals>
- <plurals name="delete_error_notification_title" formatted="false" msgid="7600379830348969563">
+ <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
<item quantity="one">Ayikwazanga ukususa amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="other">Ayikwazanga ukususa amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g></item>
</plurals>
<string name="notification_touch_for_details" msgid="6268189413228855582">"Thepha ukuze ubuke imininingwane"</string>
<string name="close" msgid="3043722427445528732">"Vala"</string>
- <string name="copy_failure_alert_content" msgid="3715575000297709082">"Lawa mafayela awazange akopishwe: <xliff:g id="LIST">%1$s</xliff:g>"</string>
- <string name="move_failure_alert_content" msgid="7151140279020481180">"Lawa mafayela awazange ahanjiswe: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="copy_failure_alert_content" msgid="4563147454522476183">"Lawo mafayela awakopishwanga: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="2635075788682922861">"Lawa mafayela awazange ahanjiswe: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="delete_failure_alert_content" msgid="892393767207938353">"Lawa mafayela awazange asuswe: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<string name="copy_converted_warning_content" msgid="5753861488218674361">"Lawo mafayela aguqulelwe kwenye ifomethi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
<plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
<item quantity="one">Kukopishwe amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g> kubhodi lokunamathisela.</item>
@@ -108,7 +111,34 @@
<string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Ayikwazi ukunamathisela amafayela akhethiwe kule ndawo."</string>
<string name="menu_rename" msgid="7678802479104285353">"Qamba kabusha"</string>
<string name="rename_error" msgid="4203041674883412606">"Yehlulekile ukuqamba kabusha idokhumenti"</string>
+ <string name="menu_eject_root" msgid="2768224615494227325">"Khipha"</string>
<string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Amanye amafayela aguqulelwe"</string>
+ <string name="open_external_dialog_request" msgid="5789329484285817629">"Nika i-<xliff:g id="APPNAME"><b>^1</b></xliff:g> ukufinyelela ekuqondiseni kwe-<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ku-<xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string>
+ <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Nika ukufinyelela kwe-<xliff:g id="APPNAME"><b>^1</b></xliff:g> kwinkomba ye-<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string>
+ <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Nikeza i-<xliff:g id="APPNAME"><b>^1</b></xliff:g> ukufinyelela kudatha yakho, okufaka izithombe namavidiyo, ku-<xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string>
+ <string name="never_ask_again" msgid="4295278542972859268">"Ungaphindi ubuze"</string>
<string name="allow" msgid="7225948811296386551">"Vumela"</string>
<string name="deny" msgid="2081879885755434506">"Yala"</string>
+ <plurals name="elements_selected" formatted="false" msgid="1376955402452875047">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> okukhethiwe</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> okukhethiwe</item>
+ </plurals>
+ <plurals name="elements_dragged" formatted="false" msgid="3727204615215602228">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> izinto</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> izinto</item>
+ </plurals>
+ <string name="delete_filename_confirmation_message" msgid="5312817725577537488">"Susa i-\"<xliff:g id="NAME">%1$s</xliff:g>\"?"</string>
+ <string name="delete_foldername_confirmation_message" msgid="5885501832257285329">"Susa ifolda engu-\"<xliff:g id="NAME">%1$s</xliff:g>\" nokuqukethwe kwalo?"</string>
+ <plurals name="delete_files_confirmation_message" formatted="false" msgid="8417505791395471802">
+ <item quantity="one">Susa amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g>?</item>
+ <item quantity="other">Susa amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g>?</item>
+ </plurals>
+ <plurals name="delete_folders_confirmation_message" formatted="false" msgid="9185648028213507769">
+ <item quantity="one">Susa amafolda angu-<xliff:g id="COUNT_1">%1$d</xliff:g> nokuqukethwe kwawo?</item>
+ <item quantity="other">Susa amafolda angu-<xliff:g id="COUNT_1">%1$d</xliff:g> nokuqukethwe kwawo?</item>
+ </plurals>
+ <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459">
+ <item quantity="one">Susa izinto ezingu-<xliff:g id="COUNT_1">%1$d</xliff:g>?</item>
+ <item quantity="other">Susa izinto ezingu-<xliff:g id="COUNT_1">%1$d</xliff:g>?</item>
+ </plurals>
</resources>
diff --git a/packages/DocumentsUI/res/values-ldrtl/config.xml b/packages/DocumentsUI/res/values/attrs.xml
index 22f8131474c4..46ca582e7fdf 100644
--- a/packages/DocumentsUI/res/values-ldrtl/config.xml
+++ b/packages/DocumentsUI/res/values/attrs.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -13,7 +13,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
<resources>
- <bool name="list_divider_inset_left">false</bool>
+ <declare-styleable name="HighlightedItemView">
+ <attr name="state_highlighted" format="boolean"/>
+ </declare-styleable>
</resources>
diff --git a/packages/DocumentsUI/res/values/colors.xml b/packages/DocumentsUI/res/values/colors.xml
index 366a8a42dd18..9da77420e0b8 100644
--- a/packages/DocumentsUI/res/values/colors.xml
+++ b/packages/DocumentsUI/res/values/colors.xml
@@ -37,5 +37,6 @@
<color name="item_doc_background">#fffafafa</color>
<color name="item_doc_background_disabled">#fff4f4f4</color>
<color name="item_doc_background_selected">@*android:color/accent_device_default_50</color>
+ <color name="item_breadcrumb_background_hovered">#1affffff</color>
</resources>
diff --git a/packages/DocumentsUI/res/values/config.xml b/packages/DocumentsUI/res/values/config.xml
index f0cab08723a8..f883164f120b 100644
--- a/packages/DocumentsUI/res/values/config.xml
+++ b/packages/DocumentsUI/res/values/config.xml
@@ -21,9 +21,6 @@
<!-- Intentionally unset. Vendors should set this in an overlay. -->
<string name="trusted_quick_viewer_package" translatable="false"></string>
- <!-- overridden for RTL langs -->
- <bool name="list_divider_inset_left">true</bool>
-
<!-- Flags setup as productivity oriented in which case Downloads app will be presented
as Files app. Including showing of the Documents and "advanced" roots. -->
<bool name="productivity_device">false</bool>
diff --git a/packages/DocumentsUI/res/values/dimens.xml b/packages/DocumentsUI/res/values/dimens.xml
index e682994749b9..5f1b349d58b7 100644
--- a/packages/DocumentsUI/res/values/dimens.xml
+++ b/packages/DocumentsUI/res/values/dimens.xml
@@ -33,12 +33,16 @@
<dimen name="grid_padding_vert">4dp</dimen>
<dimen name="list_item_height">72dp</dimen>
<dimen name="list_item_padding">16dp</dimen>
+ <dimen name="breadcrumb_item_padding">8dp</dimen>
+ <dimen name="breadcrumb_item_height">36dp</dimen>
<dimen name="list_divider_inset">72dp</dimen>
<dimen name="dir_elevation">8dp</dimen>
<dimen name="drag_shadow_size">120dp</dimen>
<dimen name="grid_item_elevation">2dp</dimen>
<dimen name="max_drawer_width">280dp</dimen>
+ <dimen name="drawer_edge_width">12dp</dimen>
+
<dimen name="drag_shadow_width">160dp</dimen>
<dimen name="drag_shadow_height">48dp</dimen>
diff --git a/packages/DocumentsUI/res/values/layouts.xml b/packages/DocumentsUI/res/values/layouts.xml
index c9308a19ebd8..a60ce87ba92c 100644
--- a/packages/DocumentsUI/res/values/layouts.xml
+++ b/packages/DocumentsUI/res/values/layouts.xml
@@ -17,5 +17,4 @@
<resources>
<item name="documents_activity" type="layout">@layout/drawer_layout</item>
<item name="files_activity" type="layout">@layout/drawer_layout</item>
- <item name="downloads_activity" type="layout">@layout/single_pane_layout</item>
</resources>
diff --git a/packages/DocumentsUI/res/values/strings.xml b/packages/DocumentsUI/res/values/strings.xml
index c2d4d04e6aa4..416bb6f4f1a1 100644
--- a/packages/DocumentsUI/res/values/strings.xml
+++ b/packages/DocumentsUI/res/values/strings.xml
@@ -56,6 +56,8 @@
<!-- Menu item title that creates a new window in the activity [CHAR LIMIT=24] -->
<string name="menu_new_window">New window</string>
+ <!-- Menu item title that cuts the selected documents to clipboard [CHAR LIMIT=24] -->
+ <string name="menu_cut_to_clipboard">Cut</string>
<!-- Menu item title that copies the selected documents to clipboard [CHAR LIMIT=24] -->
<string name="menu_copy_to_clipboard">Copy</string>
<!-- Menu item title that pastes files from the clipboard [CHAR LIMIT=24] -->
@@ -157,6 +159,8 @@
<string name="move_preparing">Preparing for move\u2026</string>
<!-- Text shown on the notification while DocumentsUI performs setup in preparation for deleting files [CHAR LIMIT=32] -->
<string name="delete_preparing">Preparing for delete\u2026</string>
+ <!-- Text progress shown on the notification while DocumentsUI is deleting files. -->
+ <string name="delete_progress"><xliff:g id="count" example="3">%1$d</xliff:g> / <xliff:g id="totalCount" example="5">%2$d</xliff:g></string>
<!-- Title of the copy error notification [CHAR LIMIT=48] -->
<plurals name="copy_error_notification_title">
<item quantity="one">Couldn\u2019t copy <xliff:g id="count" example="1">%1$d</xliff:g> file</item>
@@ -195,6 +199,8 @@
<string name="menu_rename">Rename</string>
<!-- Toast shown when renaming document failed with an error [CHAR LIMIT=48] -->
<string name="rename_error">Failed to rename document</string>
+ <!-- Context Menu item that ejects the root selected [CHAR LIMIT=24] -->
+ <string name="menu_eject_root">Eject</string>
<!-- First line for notifications saying that some files were converted to a different format
during a copy. [CHAR LIMIT=48] -->
<string name="notification_copy_files_converted_title">Some files were converted</string>
@@ -247,9 +253,4 @@
<item quantity="one">Delete <xliff:g id="count" example="1">%1$d</xliff:g> item?</item>
<item quantity="other">Delete <xliff:g id="count" example="3">%1$d</xliff:g> items?</item>
</plurals>
- <!-- Snackbar shown to users who wanted to select more than 1000 items (files or directories). -->
- <string name="too_many_selected">Sorry, you can only select up to 1000 items at a time</string>
- <!-- Snackbar shown to users who wanted to select all, but there were too many items (files or directories).
- Only the first 1000 items are selected in such case. -->
- <string name="too_many_in_select_all">Could only select 1000 items</string>
</resources>
diff --git a/packages/DocumentsUI/res/values-sw720dp-land/config.xml b/packages/DocumentsUI/res/values/tags.xml
index 6893d7a6735b..a7ff3d6c81cc 100644
--- a/packages/DocumentsUI/res/values-sw720dp-land/config.xml
+++ b/packages/DocumentsUI/res/values/tags.xml
@@ -15,4 +15,7 @@
-->
<resources>
-</resources>
+ <item name="drag_hovering_tag" type="id" />
+ <item name="item_position_tag" type="id" />
+ <item name="layout_id_tag" type="id" />
+</resources> \ No newline at end of file
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
index 1922773c9cb8..d8d8d3e56ec8 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
@@ -48,16 +48,20 @@ import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
-import android.widget.Spinner;
+import com.android.documentsui.MenuManager.DirectoryDetails;
+import com.android.documentsui.NavigationViewManager.Breadcrumb;
import com.android.documentsui.SearchViewManager.SearchManagerListener;
import com.android.documentsui.State.ViewMode;
import com.android.documentsui.dirlist.AnimationView;
import com.android.documentsui.dirlist.DirectoryFragment;
+import com.android.documentsui.dirlist.FragmentTuner;
import com.android.documentsui.dirlist.Model;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.DocumentStack;
import com.android.documentsui.model.RootInfo;
+import com.android.documentsui.services.FileOperationService;
+import com.android.documentsui.services.FileOperations;
import java.io.FileNotFoundException;
import java.util.ArrayList;
@@ -67,15 +71,42 @@ import java.util.List;
import java.util.concurrent.Executor;
public abstract class BaseActivity extends Activity
- implements SearchManagerListener, NavigationView.Environment {
+ implements SearchManagerListener, NavigationViewManager.Environment {
+
+ public final FileOperations.Callback fileOpCallback = (status, opType, docCount) -> {
+ if (status == FileOperations.Callback.STATUS_REJECTED) {
+ Snackbars.showPasteFailed(this);
+ return;
+ }
+
+ if (docCount == 0) {
+ // Nothing has been pasted, so there is no need to show a snackbar.
+ return;
+ }
+
+ switch (opType) {
+ case FileOperationService.OPERATION_MOVE:
+ Snackbars.showMove(this, docCount);
+ break;
+ case FileOperationService.OPERATION_COPY:
+ Snackbars.showCopy(this, docCount);
+ break;
+ case FileOperationService.OPERATION_DELETE:
+ // We don't show anything for deletion.
+ break;
+ default:
+ throw new UnsupportedOperationException("Unsupported Operation: " + opType);
+ }
+ };
private static final String BENCHMARK_TESTING_PACKAGE = "com.android.documentsui.appperftests";
State mState;
+ @Nullable RetainedState mRetainedState;
RootsCache mRoots;
SearchViewManager mSearchManager;
DrawerController mDrawer;
- NavigationView mNavigator;
+ NavigationViewManager mNavigator;
List<EventListener> mEventListeners = new ArrayList<>();
private final String mTag;
@@ -94,6 +125,9 @@ public abstract class BaseActivity extends Activity
public abstract void onDocumentPicked(DocumentInfo doc, Model model);
public abstract void onDocumentsPicked(List<DocumentInfo> docs);
+ public abstract FragmentTuner createFragmentTuner();
+ public abstract MenuManager getMenuManager();
+ public abstract DirectoryDetails getDirectoryDetails();
abstract void onTaskFinished(Uri... uris);
abstract void refreshDirectory(int anim);
@@ -123,6 +157,10 @@ public abstract class BaseActivity extends Activity
mState = getState(icicle);
Metrics.logActivityLaunch(this, mState, intent);
+ // we're really interested in retainining state in our very complex
+ // DirectoryFragment. So we do a little code yoga to extend
+ // support to that fragment.
+ mRetainedState = (RetainedState) getLastNonConfigurationInstance();
mRoots = DocumentsApplication.getRootsCache(this);
getContentResolver().registerContentObserver(
@@ -132,12 +170,12 @@ public abstract class BaseActivity extends Activity
DocumentsToolbar toolbar = (DocumentsToolbar) findViewById(R.id.toolbar);
setActionBar(toolbar);
- mNavigator = new NavigationView(
- mDrawer,
- toolbar,
- (Spinner) findViewById(R.id.stack),
- mState,
- this);
+
+ Breadcrumb breadcrumb =
+ Shared.findView(this, R.id.dropdown_breadcrumb, R.id.horizontal_breadcrumb);
+ assert(breadcrumb != null);
+
+ mNavigator = new NavigationViewManager(mDrawer, toolbar, mState, this, breadcrumb);
// Base classes must update result in their onCreate.
setResult(Activity.RESULT_CANCELED);
@@ -159,33 +197,7 @@ public abstract class BaseActivity extends Activity
@CallSuper
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
-
mSearchManager.showMenu(canSearchRoot());
-
- final boolean inRecents = getCurrentDirectory() == null;
-
- final MenuItem sort = menu.findItem(R.id.menu_sort);
- final MenuItem sortSize = menu.findItem(R.id.menu_sort_size);
- final MenuItem grid = menu.findItem(R.id.menu_grid);
- final MenuItem list = menu.findItem(R.id.menu_list);
- final MenuItem advanced = menu.findItem(R.id.menu_advanced);
- final MenuItem fileSize = menu.findItem(R.id.menu_file_size);
-
- // Search uses backend ranking; no sorting, recents doesn't support sort.
- sort.setEnabled(!inRecents && !mSearchManager.isSearching());
- sortSize.setVisible(mState.showSize); // Only sort by size when file sizes are visible
- fileSize.setVisible(!mState.forceSize);
-
- // grid/list is effectively a toggle.
- grid.setVisible(mState.derivedMode != State.MODE_GRID);
- list.setVisible(mState.derivedMode != State.MODE_LIST);
-
- advanced.setVisible(mState.showAdvancedOption);
- advanced.setTitle(mState.showAdvancedOption && mState.showAdvanced
- ? R.string.menu_advanced_hide : R.string.menu_advanced_show);
- fileSize.setTitle(LocalPreferences.getDisplayFileSize(this)
- ? R.string.menu_file_size_hide : R.string.menu_file_size_show);
-
return true;
}
@@ -297,13 +309,6 @@ public abstract class BaseActivity extends Activity
setViewMode(State.MODE_LIST);
return true;
- case R.id.menu_paste_from_clipboard:
- DirectoryFragment dir = getDirectoryFragment();
- if (dir != null) {
- dir.pasteFromClipboard();
- }
- return true;
-
case R.id.menu_advanced:
setDisplayAdvancedDevices(!mState.showAdvanced);
return true;
@@ -312,15 +317,6 @@ public abstract class BaseActivity extends Activity
setDisplayFileSize(!LocalPreferences.getDisplayFileSize(this));
return true;
- case R.id.menu_settings:
- Metrics.logUserAction(this, Metrics.USER_ACTION_SETTINGS);
-
- final RootInfo root = getCurrentRoot();
- final Intent intent = new Intent(DocumentsContract.ACTION_DOCUMENT_ROOT_SETTINGS);
- intent.setDataAndType(root.getUri(), DocumentsContract.Root.MIME_TYPE_ITEM);
- startActivity(intent);
- return true;
-
default:
return super.onOptionsItemSelected(item);
}
@@ -396,6 +392,13 @@ public abstract class BaseActivity extends Activity
}
/**
+ * This is called when user hovers over a doc for enough time during a drag n' drop, to open a
+ * folder that accepts drop. We should only open a container that's not an archive.
+ */
+ public void springOpenDirectory(DocumentInfo doc) {
+ }
+
+ /**
* Called when search results changed.
* Refreshes the content of the directory. It doesn't refresh elements on the action bar.
* e.g. The current directory name displayed on the action bar won't get updated.
@@ -573,6 +576,24 @@ public abstract class BaseActivity extends Activity
super.onRestoreInstanceState(state);
}
+ /**
+ * Delegate ths call to the current fragment so it can save selection.
+ * Feel free to expand on this with other useful state.
+ */
+ @Override
+ public RetainedState onRetainNonConfigurationInstance() {
+ RetainedState retained = new RetainedState();
+ DirectoryFragment fragment = DirectoryFragment.get(getFragmentManager());
+ if (fragment != null) {
+ fragment.retainState(retained);
+ }
+ return retained;
+ }
+
+ public @Nullable RetainedState getRetainedState() {
+ return mRetainedState;
+ }
+
@Override
public boolean isSearchExpanded() {
return mSearchManager.isExpanded();
@@ -713,17 +734,6 @@ public abstract class BaseActivity extends Activity
mNavDrawerHasFocus = !mNavDrawerHasFocus;
}
- DocumentInfo getRootDocumentBlocking(RootInfo root) {
- try {
- final Uri uri = DocumentsContract.buildDocumentUri(
- root.authority, root.documentId);
- return DocumentInfo.fromUri(getContentResolver(), uri);
- } catch (FileNotFoundException e) {
- Log.w(mTag, "Failed to find root", e);
- return null;
- }
- }
-
/**
* Pops the top entry off the directory stack, and returns the user to the previous directory.
* If the directory stack only contains one item, this method does nothing.
@@ -787,7 +797,7 @@ public abstract class BaseActivity extends Activity
@Override
protected DocumentInfo run(Void... params) {
- return mOwner.getRootDocumentBlocking(mRoot);
+ return mRoot.getRootDocumentBlocking(mOwner);
}
@Override
@@ -823,7 +833,7 @@ public abstract class BaseActivity extends Activity
final RootInfo defaultRoot = mOwner.mRoots.getDefaultRootBlocking(mOwner.mState);
assert(defaultRoot != null);
if (!defaultRoot.isRecents()) {
- mDefaultRootDocument = mOwner.getRootDocumentBlocking(defaultRoot);
+ mDefaultRootDocument = defaultRoot.getRootDocumentBlocking(mOwner);
}
return defaultRoot;
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/CheckedTask.java b/packages/DocumentsUI/src/com/android/documentsui/CheckedTask.java
new file mode 100644
index 000000000000..747eb9c51985
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/CheckedTask.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import android.os.AsyncTask;
+
+/**
+ * An {@link AsyncTask} that guards work with checks that a paired {@link Check}
+ * has not yet given signals to stop progress.
+ *
+ * <p>Use this type of task for greater safety when executing tasks that might complete
+ * after the owner of the task has explicitly given a signal to stop progress.
+ *
+ * <p>Also useful as tasks can be static, limiting scope, but still have access to
+ * signal from the owning class.
+ *
+ * @template Input input type
+ * @template Output output type
+ */
+abstract class CheckedTask<Input, Output>
+ extends AsyncTask<Input, Void, Output> {
+
+ private Check mCheck;
+
+ public CheckedTask(Check check) {
+ mCheck = check;
+ }
+
+ /** Called prior to run being executed. Analogous to {@link AsyncTask#onPreExecute} */
+ void prepare() {}
+
+ /** Analogous to {@link AsyncTask#doInBackground} */
+ abstract Output run(Input... input);
+
+ /** Analogous to {@link AsyncTask#onPostExecute} */
+ abstract void finish(Output output);
+
+ @Override
+ final protected void onPreExecute() {
+ if (mCheck.stop()) {
+ return;
+ }
+ prepare();
+ }
+
+ @Override
+ final protected Output doInBackground(Input... input) {
+ if (mCheck.stop()) {
+ return null;
+ }
+ return run(input);
+ }
+
+ @Override
+ final protected void onPostExecute(Output result) {
+ if (mCheck.stop()) {
+ return;
+ }
+ finish(result);
+ }
+
+ @FunctionalInterface
+ interface Check {
+ boolean stop();
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentClipper.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentClipper.java
deleted file mode 100644
index 72387de49682..000000000000
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentClipper.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.documentsui;
-
-import android.content.ClipData;
-import android.content.ClipboardManager;
-import android.content.ContentProviderClient;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.DocumentsContract;
-import android.support.annotation.Nullable;
-import android.util.Log;
-
-import com.android.documentsui.model.DocumentInfo;
-
-import libcore.io.IoUtils;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-
-/**
- * ClipboardManager wrapper class providing higher level logical
- * support for dealing with Documents.
- */
-public final class DocumentClipper {
-
- private static final String TAG = "DocumentClipper";
-
- private Context mContext;
- private ClipboardManager mClipboard;
-
- public DocumentClipper(Context context) {
- mContext = context;
- mClipboard = context.getSystemService(ClipboardManager.class);
- }
-
- public boolean hasItemsToPaste() {
- if (mClipboard.hasPrimaryClip()) {
- ClipData clipData = mClipboard.getPrimaryClip();
- int count = clipData.getItemCount();
- if (count > 0) {
- for (int i = 0; i < count; ++i) {
- ClipData.Item item = clipData.getItemAt(i);
- Uri uri = item.getUri();
- if (isDocumentUri(uri)) {
- return true;
- }
- }
- }
- }
- return false;
- }
-
- private boolean isDocumentUri(@Nullable Uri uri) {
- return uri != null && DocumentsContract.isDocumentUri(mContext, uri);
- }
-
- /**
- * Returns a list of Documents as decoded from Clipboard primary clipdata.
- * This should be run from inside an AsyncTask.
- */
- public List<DocumentInfo> getClippedDocuments() {
- ClipData data = mClipboard.getPrimaryClip();
- return data == null ? Collections.EMPTY_LIST : getDocumentsFromClipData(data);
- }
-
- /**
- * Returns a list of Documents as decoded in clipData.
- * This should be run from inside an AsyncTask.
- */
- public List<DocumentInfo> getDocumentsFromClipData(ClipData clipData) {
- assert(clipData != null);
- final List<DocumentInfo> srcDocs = new ArrayList<>();
-
- int count = clipData.getItemCount();
- if (count == 0) {
- return srcDocs;
- }
-
- ContentResolver resolver = mContext.getContentResolver();
- for (int i = 0; i < count; ++i) {
- ClipData.Item item = clipData.getItemAt(i);
- Uri itemUri = item.getUri();
- if (itemUri != null && DocumentsContract.isDocumentUri(mContext, itemUri)) {
- ContentProviderClient client = null;
- Cursor cursor = null;
- try {
- client = DocumentsApplication.acquireUnstableProviderOrThrow(
- resolver, itemUri.getAuthority());
- cursor = client.query(itemUri, null, null, null, null);
- cursor.moveToPosition(0);
- srcDocs.add(DocumentInfo.fromCursor(cursor, itemUri.getAuthority()));
- } catch (Exception e) {
- Log.e(TAG, e.getMessage());
- } finally {
- IoUtils.closeQuietly(cursor);
- ContentProviderClient.releaseQuietly(client);
- }
- }
- }
-
- return srcDocs;
- }
-
- /**
- * Returns ClipData representing the list of docs, or null if docs is empty,
- * or docs cannot be converted.
- */
- public @Nullable ClipData getClipDataForDocuments(List<DocumentInfo> docs) {
- final ContentResolver resolver = mContext.getContentResolver();
- final String[] mimeTypes = getMimeTypes(resolver, docs);
- ClipData clipData = null;
- for (DocumentInfo doc : docs) {
- if (clipData == null) {
- // TODO: figure out what this string should be.
- // Currently it is not displayed anywhere in the UI, but this might change.
- final String label = "";
- clipData = new ClipData(label, mimeTypes, new ClipData.Item(doc.derivedUri));
- } else {
- // TODO: update list of mime types in ClipData.
- clipData.addItem(new ClipData.Item(doc.derivedUri));
- }
- }
- return clipData;
- }
-
- private static String[] getMimeTypes(ContentResolver resolver, List<DocumentInfo> docs) {
- final HashSet<String> mimeTypes = new HashSet<>();
- for (DocumentInfo doc : docs) {
- assert(doc != null);
- assert(doc.derivedUri != null);
- final Uri uri = doc.derivedUri;
- if ("content".equals(uri.getScheme())) {
- mimeTypes.add(resolver.getType(uri));
- final String[] streamTypes = resolver.getStreamTypes(uri, "*/*");
- if (streamTypes != null) {
- mimeTypes.addAll(Arrays.asList(streamTypes));
- }
- }
- }
- return mimeTypes.toArray(new String[0]);
- }
-
- public void clipDocuments(List<DocumentInfo> docs) {
- ClipData data = getClipDataForDocuments(docs);
- mClipboard.setPrimaryClip(data);
- }
-}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index 7a7d3a1d0a98..05f36e86640a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -41,12 +41,14 @@ import android.provider.DocumentsContract;
import android.support.design.widget.Snackbar;
import android.util.Log;
import android.view.Menu;
-import android.view.MenuItem;
+import com.android.documentsui.MenuManager.DirectoryDetails;
import com.android.documentsui.RecentsProvider.RecentColumns;
import com.android.documentsui.RecentsProvider.ResumeColumns;
import com.android.documentsui.dirlist.AnimationView;
import com.android.documentsui.dirlist.DirectoryFragment;
+import com.android.documentsui.dirlist.FragmentTuner;
+import com.android.documentsui.dirlist.FragmentTuner.DocumentsTuner;
import com.android.documentsui.dirlist.Model;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.DurableUtils;
@@ -64,6 +66,8 @@ import java.util.List;
public class DocumentsActivity extends BaseActivity {
private static final int CODE_FORWARD = 42;
private static final String TAG = "DocumentsActivity";
+ private DocumentsMenuManager mMenuManager;
+ private DirectoryDetails mDetails;
public DocumentsActivity() {
super(R.layout.documents_activity, TAG);
@@ -72,6 +76,8 @@ public class DocumentsActivity extends BaseActivity {
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
+ mMenuManager = new DocumentsMenuManager(mSearchManager, getDisplayState());
+ mDetails = new DirectoryDetails(this);
if (mState.action == ACTION_CREATE) {
final String mimeType = getIntent().getType();
@@ -91,7 +97,7 @@ public class DocumentsActivity extends BaseActivity {
mState.action == ACTION_CREATE ||
mState.action == ACTION_OPEN_TREE ||
mState.action == ACTION_PICK_COPY_DESTINATION) {
- RootsFragment.show(getFragmentManager(), null);
+ RootsFragment.show(getFragmentManager(), (Intent) null);
}
if (mState.restored) {
@@ -149,7 +155,7 @@ public class DocumentsActivity extends BaseActivity {
state.directoryCopy = intent.getBooleanExtra(
Shared.EXTRA_DIRECTORY_COPY, false);
state.copyOperationSubType = intent.getIntExtra(
- FileOperationService.EXTRA_OPERATION,
+ FileOperationService.EXTRA_OPERATION_TYPE,
FileOperationService.OPERATION_COPY);
}
}
@@ -214,44 +220,15 @@ public class DocumentsActivity extends BaseActivity {
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
+ mMenuManager.updateOptionMenu(menu, mDetails);
final DocumentInfo cwd = getCurrentDirectory();
- boolean picking = mState.action == ACTION_CREATE
- || mState.action == ACTION_OPEN_TREE
- || mState.action == ACTION_PICK_COPY_DESTINATION;
-
- if (picking) {
- // May already be hidden because the root
- // doesn't support search.
- mSearchManager.showMenu(false);
- }
-
- final MenuItem createDir = menu.findItem(R.id.menu_create_dir);
- final MenuItem grid = menu.findItem(R.id.menu_grid);
- final MenuItem list = menu.findItem(R.id.menu_list);
- final MenuItem fileSize = menu.findItem(R.id.menu_file_size);
-
-
- createDir.setVisible(picking);
- createDir.setEnabled(canCreateDirectory());
-
- // No display options in recent directories
- boolean inRecents = cwd == null;
- if (picking && inRecents) {
- grid.setVisible(false);
- list.setVisible(false);
- }
-
- fileSize.setVisible(fileSize.isVisible() && !picking);
-
if (mState.action == ACTION_CREATE) {
final FragmentManager fm = getFragmentManager();
SaveFragment.get(fm).prepareForDirectory(cwd);
}
- Menus.disableHiddenItems(menu);
-
return true;
}
@@ -317,12 +294,6 @@ public class DocumentsActivity extends BaseActivity {
}
@Override
- void onRootPicked(RootInfo root) {
- super.onRootPicked(root);
- mNavigator.revealRootsDrawer(false);
- }
-
- @Override
public void onDocumentPicked(DocumentInfo doc, Model model) {
final FragmentManager fm = getFragmentManager();
if (doc.isContainer()) {
@@ -414,7 +385,7 @@ public class DocumentsActivity extends BaseActivity {
// Picking a copy destination is only used internally by us, so we
// don't need to extend permissions to the caller.
intent.putExtra(Shared.EXTRA_STACK, (Parcelable) mState.stack);
- intent.putExtra(FileOperationService.EXTRA_OPERATION, mState.copyOperationSubType);
+ intent.putExtra(FileOperationService.EXTRA_OPERATION_TYPE, mState.copyOperationSubType);
} else {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION
@@ -430,6 +401,23 @@ public class DocumentsActivity extends BaseActivity {
return (DocumentsActivity) fragment.getActivity();
}
+ @Override
+ public FragmentTuner createFragmentTuner() {
+ // Currently DocumentsTuner maintains a state specific to the fragment instance. Because of
+ // that, we create a new instance everytime it is needed
+ return new DocumentsTuner(this, getDisplayState());
+ }
+
+ @Override
+ public MenuManager getMenuManager() {
+ return mMenuManager;
+ }
+
+ @Override
+ public DirectoryDetails getDirectoryDetails() {
+ return mDetails;
+ }
+
/**
* Loads the last used path (stack) from Recents (history).
* The path selected is based on the calling package name. So the last
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsApplication.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsApplication.java
index 5ea6cfa73fcd..3b2529fd493b 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsApplication.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsApplication.java
@@ -24,30 +24,29 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.graphics.Point;
import android.net.Uri;
import android.os.RemoteException;
import android.text.format.DateUtils;
+import com.android.documentsui.clipping.ClipStorage;
+import com.android.documentsui.clipping.DocumentClipper;
+
public class DocumentsApplication extends Application {
private static final long PROVIDER_ANR_TIMEOUT = 20 * DateUtils.SECOND_IN_MILLIS;
private RootsCache mRoots;
- private Point mThumbnailsSize;
- private ThumbnailCache mThumbnails;
+
+ private ThumbnailCache mThumbnailCache;
+ private ClipStorage mClipStorage;
+ private DocumentClipper mClipper;
public static RootsCache getRootsCache(Context context) {
return ((DocumentsApplication) context.getApplicationContext()).mRoots;
}
- public static ThumbnailCache getThumbnailsCache(Context context, Point size) {
+ public static ThumbnailCache getThumbnailCache(Context context) {
final DocumentsApplication app = (DocumentsApplication) context.getApplicationContext();
- final ThumbnailCache thumbnails = app.mThumbnails;
- if (!size.equals(app.mThumbnailsSize)) {
- thumbnails.evictAll();
- app.mThumbnailsSize = size;
- }
- return thumbnails;
+ return app.mThumbnailCache;
}
public static ContentProviderClient acquireUnstableProviderOrThrow(
@@ -61,6 +60,14 @@ public class DocumentsApplication extends Application {
return client;
}
+ public static DocumentClipper getDocumentClipper(Context context) {
+ return ((DocumentsApplication) context.getApplicationContext()).mClipper;
+ }
+
+ public static ClipStorage getClipStorage(Context context) {
+ return ((DocumentsApplication) context.getApplicationContext()).mClipStorage;
+ }
+
@Override
public void onCreate() {
super.onCreate();
@@ -71,7 +78,12 @@ public class DocumentsApplication extends Application {
mRoots = new RootsCache(this);
mRoots.updateAsync(false);
- mThumbnails = new ThumbnailCache(memoryClassBytes / 4);
+ mThumbnailCache = new ThumbnailCache(memoryClassBytes / 4);
+
+ mClipStorage = new ClipStorage(
+ ClipStorage.prepareStorage(getCacheDir()),
+ getSharedPreferences(ClipStorage.PREF_NAME, 0));
+ mClipper = new DocumentClipper(this, mClipStorage);
final IntentFilter packageFilter = new IntentFilter();
packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
@@ -90,11 +102,7 @@ public class DocumentsApplication extends Application {
public void onTrimMemory(int level) {
super.onTrimMemory(level);
- if (level >= TRIM_MEMORY_MODERATE) {
- mThumbnails.evictAll();
- } else if (level >= TRIM_MEMORY_BACKGROUND) {
- mThumbnails.trimToSize(mThumbnails.size() / 2);
- }
+ mThumbnailCache.onTrimMemory(level);
}
private BroadcastReceiver mCacheReceiver = new BroadcastReceiver() {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsMenuManager.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsMenuManager.java
new file mode 100644
index 000000000000..9b07b4907e98
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsMenuManager.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import static com.android.documentsui.State.ACTION_CREATE;
+import static com.android.documentsui.State.ACTION_GET_CONTENT;
+import static com.android.documentsui.State.ACTION_OPEN;
+import static com.android.documentsui.State.ACTION_OPEN_TREE;
+import static com.android.documentsui.State.ACTION_PICK_COPY_DESTINATION;
+
+import android.view.Menu;
+import android.view.MenuItem;
+
+import com.android.documentsui.MenuManager.DirectoryDetails;
+
+final class DocumentsMenuManager extends MenuManager {
+
+ private boolean mPicking;
+
+ public DocumentsMenuManager(SearchViewManager searchManager, State displayState) {
+ super(searchManager, displayState);
+
+ mPicking = mState.action == ACTION_CREATE
+ || mState.action == ACTION_OPEN_TREE
+ || mState.action == ACTION_PICK_COPY_DESTINATION;
+ }
+
+ @Override
+ public void updateOptionMenu(Menu menu, DirectoryDetails details) {
+ super.updateOptionMenu(menu, details);
+ if (mPicking) {
+ // May already be hidden because the root
+ // doesn't support search.
+ mSearchManager.showMenu(false);
+ }
+ }
+
+ @Override
+ void updateModePicker(MenuItem grid, MenuItem list, DirectoryDetails directoryDetails) {
+ // No display options in recent directories
+ if (mPicking && directoryDetails.isInRecents()) {
+ grid.setVisible(false);
+ list.setVisible(false);
+ } else {
+ super.updateModePicker(grid, list, directoryDetails);
+ }
+ }
+
+ @Override
+ void updateFileSize(MenuItem fileSize, DirectoryDetails directoryDetails) {
+ super.updateFileSize(fileSize, directoryDetails);
+ fileSize.setVisible(fileSize.isVisible() && !mPicking);
+ }
+
+ @Override
+ void updateSelectAll(MenuItem selectAll, SelectionDetails selectionDetails) {
+ selectAll.setVisible(mState.allowMultiple);
+ }
+
+ @Override
+ void updateCreateDir(MenuItem createDir, DirectoryDetails directoryDetails) {
+ createDir.setVisible(mPicking);
+ createDir.setEnabled(mPicking && directoryDetails.canCreateDirectory());
+ }
+
+ @Override
+ void updateOpen(MenuItem open, SelectionDetails selectionDetails) {
+ open.setVisible(mState.action == ACTION_GET_CONTENT
+ || mState.action == ACTION_OPEN);
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DragOverTextView.java b/packages/DocumentsUI/src/com/android/documentsui/DragOverTextView.java
new file mode 100644
index 000000000000..e9fc2a0fe3a1
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/DragOverTextView.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View.OnDragListener;
+import android.widget.TextView;
+
+/**
+ * An {@link TextView} that uses drawable states to distinct between normal and highlighted states.
+ */
+
+public final class DragOverTextView extends TextView {
+ private static final int[] STATE_HIGHLIGHTED = {R.attr.state_highlighted};
+
+ private boolean mHighlighted = false;
+
+ public DragOverTextView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected int[] onCreateDrawableState(int extraSpace) {
+ final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
+
+ if (mHighlighted) {
+ mergeDrawableStates(drawableState, STATE_HIGHLIGHTED);
+ }
+
+ return drawableState;
+ }
+
+ public void setHighlight(boolean highlight) {
+ mHighlighted = highlight;
+ refreshDrawableState();
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java b/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java
index 14e6b69bfc19..97d459bf1862 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java
@@ -20,7 +20,7 @@ import static com.android.documentsui.Shared.DEBUG;
import android.annotation.IntDef;
import android.app.Activity;
-import android.content.Context;
+import android.support.annotation.ColorRes;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.DrawerLayout.DrawerListener;
@@ -120,7 +120,8 @@ abstract class DrawerController implements DrawerListener {
/**
* Runtime controller that manages a real drawer.
*/
- private static final class RuntimeDrawerController extends DrawerController {
+ private static final class RuntimeDrawerController extends DrawerController
+ implements ItemDragListener.DragHost {
private final ActionBarDrawerToggle mToggle;
private DrawerLayout mLayout;
private View mDrawer;
@@ -138,6 +139,30 @@ abstract class DrawerController implements DrawerListener {
mToggle = toggle;
mLayout.setDrawerListener(this);
+
+ View edge = layout.findViewById(R.id.drawer_edge);
+ edge.setOnDragListener(new ItemDragListener<>(this));
+ }
+
+ @Override
+ public void runOnUiThread(Runnable runnable) {
+ mDrawer.post(runnable);
+ }
+
+ @Override
+ public void setDropTargetHighlight(View v, boolean highlight) {
+ assert (v.getId() == R.id.drawer_edge);
+
+ @ColorRes int id = highlight ? R.color.item_doc_background_selected :
+ android.R.color.transparent;
+ v.setBackgroundColor(id);
+ }
+
+ @Override
+ public void onViewHovered(View v) {
+ assert (v.getId() == R.id.drawer_edge);
+
+ setOpen(true);
}
@Override
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DropdownBreadcrumb.java b/packages/DocumentsUI/src/com/android/documentsui/DropdownBreadcrumb.java
new file mode 100644
index 000000000000..71d7334960e8
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/DropdownBreadcrumb.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+import com.android.documentsui.NavigationViewManager.Breadcrumb;
+import com.android.documentsui.NavigationViewManager.Environment;
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.RootInfo;
+
+import java.util.function.Consumer;
+
+/**
+ * Dropdown implementation of breadcrumb used for phone device layouts
+ */
+
+public final class DropdownBreadcrumb extends Spinner implements Breadcrumb {
+
+ private DropdownAdapter mAdapter;
+
+ public DropdownBreadcrumb(
+ Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ public DropdownBreadcrumb(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public DropdownBreadcrumb(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public DropdownBreadcrumb(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void setup(Environment env, State state, Consumer<Integer> listener) {
+ mAdapter = new DropdownAdapter(state, env);
+ setOnItemSelectedListener(
+ new OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(
+ AdapterView<?> parent, View view, int position, long id) {
+ listener.accept(position);
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {}
+ });
+ }
+
+ @Override
+ public void show(boolean visibility) {
+ if (visibility) {
+ setVisibility(VISIBLE);
+ setAdapter(mAdapter);
+ } else {
+ setVisibility(GONE);
+ setAdapter(null);
+ }
+ }
+
+ @Override
+ public void postUpdate() {
+ setSelection(mAdapter.getCount() - 1, false);
+ }
+
+ private static final class DropdownAdapter extends BaseAdapter {
+ private Environment mEnv;
+ private State mState;
+
+ public DropdownAdapter(State state, Environment env) {
+ mState = state;
+ mEnv = env;
+ }
+
+ @Override
+ public int getCount() {
+ return mState.stack.size();
+ }
+
+ @Override
+ public DocumentInfo getItem(int position) {
+ return mState.stack.get(mState.stack.size() - position - 1);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ if (convertView == null) {
+ convertView = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.item_subdir_title, parent, false);
+ }
+
+ final TextView title = (TextView) convertView.findViewById(android.R.id.title);
+ final DocumentInfo doc = getItem(position);
+
+ if (position == 0) {
+ final RootInfo root = mEnv.getCurrentRoot();
+ title.setText(root.title);
+ } else {
+ title.setText(doc.displayName);
+ }
+
+ return convertView;
+ }
+
+ @Override
+ public View getDropDownView(int position, View convertView, ViewGroup parent) {
+ if (convertView == null) {
+ convertView = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.item_subdir, parent, false);
+ }
+
+ final TextView title = (TextView) convertView.findViewById(android.R.id.title);
+ final DocumentInfo doc = getItem(position);
+
+ if (position == 0) {
+ final RootInfo root = mEnv.getCurrentRoot();
+ title.setText(root.title);
+ } else {
+ title.setText(doc.displayName);
+ }
+
+ return convertView;
+ }
+ }
+
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/EjectRootTask.java b/packages/DocumentsUI/src/com/android/documentsui/EjectRootTask.java
new file mode 100644
index 000000000000..e47a262307d9
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/EjectRootTask.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.net.Uri;
+import android.provider.DocumentsContract;
+import android.util.Log;
+
+import java.util.function.BooleanSupplier;
+import java.util.function.Consumer;
+
+final class EjectRootTask extends CheckedTask<Void, Boolean> {
+ private final String mAuthority;
+ private final String mRootId;
+ private final Consumer<Boolean> mCallback;
+ private Context mContext;
+
+ /**
+ * @param ejectCanceledCheck The method reference we use to see whether eject should be stopped
+ * at any point
+ * @param finishCallback The end callback necessary when the eject task finishes
+ */
+ public EjectRootTask(Context context,
+ String authority,
+ String rootId,
+ BooleanSupplier ejectCanceledCheck,
+ Consumer<Boolean> finishCallback) {
+ super(ejectCanceledCheck::getAsBoolean);
+ mAuthority = authority;
+ mRootId = rootId;
+ mContext = context;
+ mCallback = finishCallback;
+ }
+
+ @Override
+ protected Boolean run(Void... params) {
+ final ContentResolver resolver = mContext.getContentResolver();
+
+ Uri rootUri = DocumentsContract.buildRootUri(mAuthority, mRootId);
+ ContentProviderClient client = null;
+ try {
+ client = DocumentsApplication.acquireUnstableProviderOrThrow(
+ resolver, mAuthority);
+ return DocumentsContract.ejectRoot(client, rootUri);
+ } catch (Exception e) {
+ Log.w(Shared.TAG, "Failed to eject root", e);
+ } finally {
+ ContentProviderClient.releaseQuietly(client);
+ }
+
+ return false;
+ }
+
+ @Override
+ protected void finish(Boolean ejected) {
+ mCallback.accept(ejected);
+ }
+} \ No newline at end of file
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Events.java b/packages/DocumentsUI/src/com/android/documentsui/Events.java
index 14d4e2d942d9..2d0dbe8ce321 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Events.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Events.java
@@ -16,8 +16,12 @@
package com.android.documentsui;
+import static com.android.documentsui.Shared.DEBUG;
+
import android.graphics.Point;
import android.support.v7.widget.RecyclerView;
+import android.util.Log;
+import android.util.Pools;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
@@ -111,7 +115,8 @@ public final class Events {
* A facade over MotionEvent primarily designed to permit for unit testing
* of related code.
*/
- public interface InputEvent {
+ public interface InputEvent extends AutoCloseable {
+ boolean isTouchEvent();
boolean isMouseEvent();
boolean isPrimaryButtonPressed();
boolean isSecondaryButtonPressed();
@@ -123,7 +128,15 @@ public final class Events {
/** Returns true if the action is the final release of a mouse or touch. */
boolean isActionUp();
+ // Eliminate the checked Exception from Autoclosable.
+ @Override
+ public void close();
+
Point getOrigin();
+ float getX();
+ float getY();
+ float getRawX();
+ float getRawY();
/** Returns true if the there is an item under the finger/cursor. */
boolean isOverItem();
@@ -133,17 +146,74 @@ public final class Events {
}
public static final class MotionInputEvent implements InputEvent {
- private final MotionEvent mEvent;
- private final int mPosition;
+ private static final String TAG = "MotionInputEvent";
+
+ private static final Pools.SimplePool<MotionInputEvent> sPool = new Pools.SimplePool<>(1);
+
+ private MotionEvent mEvent;
+ interface PositionProvider {
+ int get(MotionEvent e);
+ }
+
+ private int mPosition;
+
+ private MotionInputEvent() {
+ if (DEBUG) Log.i(TAG, "Created a new instance.");
+ }
+
+ public static MotionInputEvent obtain(MotionEvent event, RecyclerView view) {
+ Shared.checkMainLoop();
- public MotionInputEvent(MotionEvent event, RecyclerView view) {
- mEvent = event;
+ MotionInputEvent instance = sPool.acquire();
+ instance = (instance != null ? instance : new MotionInputEvent());
+
+ instance.mEvent = event;
// Consider determining position lazily as an optimization.
- View child = view.findChildViewUnder(mEvent.getX(), mEvent.getY());
- mPosition = (child!= null)
+ View child = view.findChildViewUnder(event.getX(), event.getY());
+ instance.mPosition = (child != null)
? view.getChildAdapterPosition(child)
: RecyclerView.NO_POSITION;
+
+ return instance;
+ }
+
+ public static MotionInputEvent obtain(
+ MotionEvent event, PositionProvider positionProvider) {
+ Shared.checkMainLoop();
+
+ MotionInputEvent instance = sPool.acquire();
+ instance = (instance != null ? instance : new MotionInputEvent());
+
+ instance.mEvent = event;
+ instance.mPosition = positionProvider.get(event);
+
+ return instance;
+ }
+
+ public void recycle() {
+ Shared.checkMainLoop();
+
+ mEvent = null;
+ mPosition = -1;
+
+ boolean released = sPool.release(this);
+ // This assert is used to guarantee we won't generate too many instances that can't be
+ // held in the pool, which indicates our pool size is too small.
+ //
+ // Right now one instance is enough because we expect all instances are only used in
+ // main thread.
+ assert(released);
+ }
+
+ @Override
+ public void close() {
+ recycle();
+ }
+
+ @Override
+ public boolean isTouchEvent() {
+ return Events.isTouchEvent(mEvent);
}
@Override
@@ -182,6 +252,26 @@ public final class Events {
}
@Override
+ public float getX() {
+ return mEvent.getX();
+ }
+
+ @Override
+ public float getY() {
+ return mEvent.getY();
+ }
+
+ @Override
+ public float getRawX() {
+ return mEvent.getRawX();
+ }
+
+ @Override
+ public float getRawY() {
+ return mEvent.getRawY();
+ }
+
+ @Override
public boolean isOverItem() {
return getItemPosition() != RecyclerView.NO_POSITION;
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Files.java b/packages/DocumentsUI/src/com/android/documentsui/Files.java
new file mode 100644
index 000000000000..009fecb4d719
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/Files.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import java.io.File;
+
+/**
+ * Utility class for working with {@link File} instances.
+ */
+public final class Files {
+
+ private Files() {} // no initialization for utility classes.
+
+ public static void deleteRecursively(File file) {
+ if (file.isDirectory()) {
+ for (File child : file.listFiles()) {
+ deleteRecursively(child);
+ }
+ }
+ file.delete();
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
index b82f8dd3d7a3..54f3e61ea308 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
@@ -36,10 +36,14 @@ import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
+import com.android.documentsui.MenuManager.DirectoryDetails;
import com.android.documentsui.OperationDialogFragment.DialogType;
import com.android.documentsui.RecentsProvider.ResumeColumns;
+import com.android.documentsui.clipping.DocumentClipper;
import com.android.documentsui.dirlist.AnimationView;
import com.android.documentsui.dirlist.DirectoryFragment;
+import com.android.documentsui.dirlist.FragmentTuner;
+import com.android.documentsui.dirlist.FragmentTuner.FilesTuner;
import com.android.documentsui.dirlist.Model;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.DocumentStack;
@@ -67,6 +71,8 @@ public class FilesActivity extends BaseActivity {
// We use the time gap to figure out whether to close app or reopen the drawer.
private long mDrawerLastFiddled;
private DocumentClipper mClipper;
+ private FilesMenuManager mMenuManager;
+ private DirectoryDetails mDetails;
public FilesActivity() {
super(R.layout.files_activity, TAG);
@@ -76,9 +82,16 @@ public class FilesActivity extends BaseActivity {
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
- mClipper = new DocumentClipper(this);
+ mClipper = DocumentsApplication.getDocumentClipper(this);
+ mMenuManager = new FilesMenuManager(mSearchManager, getDisplayState());
+ mDetails = new DirectoryDetails(this) {
+ @Override
+ public boolean hasItemsToPaste() {
+ return mClipper.hasItemsToPaste();
+ }
+ };
- RootsFragment.show(getFragmentManager(), null);
+ RootsFragment.show(getFragmentManager(), this::openRootSettings);
final Intent intent = getIntent();
final Uri uri = intent.getData();
@@ -127,7 +140,7 @@ public class FilesActivity extends BaseActivity {
// Only show it manually for the first time (icicle is null).
if (icicle == null && dialogType != DIALOG_TYPE_UNKNOWN) {
final int opType = intent.getIntExtra(
- FileOperationService.EXTRA_OPERATION,
+ FileOperationService.EXTRA_OPERATION_TYPE,
FileOperationService.OPERATION_COPY);
final ArrayList<DocumentInfo> srcList =
intent.getParcelableArrayListExtra(FileOperationService.EXTRA_SRC_LIST);
@@ -198,23 +211,7 @@ public class FilesActivity extends BaseActivity {
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
-
- final RootInfo root = getCurrentRoot();
-
- final MenuItem createDir = menu.findItem(R.id.menu_create_dir);
- final MenuItem pasteFromCb = menu.findItem(R.id.menu_paste_from_clipboard);
- final MenuItem settings = menu.findItem(R.id.menu_settings);
- final MenuItem newWindow = menu.findItem(R.id.menu_new_window);
-
- createDir.setVisible(true);
- createDir.setEnabled(canCreateDirectory());
- pasteFromCb.setEnabled(mClipper.hasItemsToPaste());
- settings.setVisible(root.hasSettings());
- newWindow.setVisible(Shared.shouldShowFancyFeatures(this));
-
- Menus.disableHiddenItems(menu, pasteFromCb);
- // It hides icon if searching in progress
- mSearchManager.updateMenu();
+ mMenuManager.updateOptionMenu(menu, mDetails);
return true;
}
@@ -234,12 +231,23 @@ public class FilesActivity extends BaseActivity {
dir.pasteFromClipboard();
}
break;
+ case R.id.menu_settings:
+ final RootInfo root = getCurrentRoot();
+ openRootSettings(root);
+ break;
default:
return super.onOptionsItemSelected(item);
}
return true;
}
+ void openRootSettings(RootInfo root) {
+ Metrics.logUserAction(this, Metrics.USER_ACTION_SETTINGS);
+ final Intent intent = new Intent(DocumentsContract.ACTION_DOCUMENT_ROOT_SETTINGS);
+ intent.setDataAndType(root.getUri(), DocumentsContract.Root.MIME_TYPE_ITEM);
+ startActivity(intent);
+ }
+
private void createNewWindow() {
Metrics.logUserAction(this, Metrics.USER_ACTION_NEW_WINDOW);
@@ -273,12 +281,6 @@ public class FilesActivity extends BaseActivity {
}
@Override
- void onRootPicked(RootInfo root) {
- super.onRootPicked(root);
- mDrawer.setOpen(false);
- }
-
- @Override
public void onDocumentsPicked(List<DocumentInfo> docs) {
throw new UnsupportedOperationException();
}
@@ -321,6 +323,13 @@ public class FilesActivity extends BaseActivity {
}
}
+ @Override
+ public void springOpenDirectory(DocumentInfo doc) {
+ assert(doc.isContainer());
+ assert(!doc.isArchive());
+ openContainerDocument(doc);
+ }
+
/**
* Launches an intent to view the specified document.
*/
@@ -368,6 +377,12 @@ public class FilesActivity extends BaseActivity {
dir.selectAllFiles();
}
return true;
+ case KeyEvent.KEYCODE_X:
+ dir = getDirectoryFragment();
+ if (dir != null) {
+ dir.cutSelectedToClipboard();
+ }
+ return true;
case KeyEvent.KEYCODE_C:
dir = getDirectoryFragment();
if (dir != null) {
@@ -455,6 +470,21 @@ public class FilesActivity extends BaseActivity {
finish();
}
+ @Override
+ public FragmentTuner createFragmentTuner() {
+ return new FilesTuner(this, getDisplayState());
+ }
+
+ @Override
+ public MenuManager getMenuManager() {
+ return mMenuManager;
+ }
+
+ @Override
+ public DirectoryDetails getDirectoryDetails() {
+ return mDetails;
+ }
+
/**
* Builds a stack for the specific Uris. Multi roots are not supported, as it's impossible
* to know which root to select. Also, the stack doesn't contain intermediate directories.
@@ -469,7 +499,7 @@ public class FilesActivity extends BaseActivity {
}
@Override
- protected Void run(Uri... params) {
+ public Void run(Uri... params) {
final Uri uri = params[0];
final RootsCache rootsCache = DocumentsApplication.getRootsCache(mOwner);
@@ -489,12 +519,12 @@ public class FilesActivity extends BaseActivity {
} catch (FileNotFoundException e) {
Log.e(TAG, "Failed to resolve DocumentInfo from Uri: " + uri);
}
- mState.stack.add(mOwner.getRootDocumentBlocking(root));
+ mState.stack.add(root.getRootDocumentBlocking(mOwner));
return null;
}
@Override
- protected void finish(Void result) {
+ public void finish(Void result) {
mOwner.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE);
}
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesMenuManager.java b/packages/DocumentsUI/src/com/android/documentsui/FilesMenuManager.java
new file mode 100644
index 000000000000..a7e490506954
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilesMenuManager.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import android.view.Menu;
+import android.view.MenuItem;
+
+import com.android.documentsui.model.RootInfo;
+
+final class FilesMenuManager extends MenuManager {
+
+ public FilesMenuManager(SearchViewManager searchManager, State displayState) {
+ super(searchManager, displayState);
+ }
+
+ @Override
+ public void updateOptionMenu(Menu menu, DirectoryDetails details) {
+ super.updateOptionMenu(menu, details);
+
+ // It hides icon if searching in progress
+ mSearchManager.updateMenu();
+ }
+
+ @Override
+ void updateSettings(MenuItem settings, RootInfo root) {
+ settings.setVisible(true);
+ settings.setEnabled(root.hasSettings());
+ }
+
+ @Override
+ void updateEject(MenuItem eject, RootInfo root) {
+ eject.setVisible(true);
+ eject.setEnabled(root.supportsEject() && !root.ejecting);
+ }
+
+ @Override
+ void updateSettings(MenuItem settings, DirectoryDetails directoryDetails) {
+ settings.setVisible(directoryDetails.hasRootSettings());
+ }
+
+ @Override
+ void updateNewWindow(MenuItem newWindow, DirectoryDetails directoryDetails) {
+ newWindow.setVisible(directoryDetails.shouldShowFancyFeatures());
+ }
+
+ @Override
+ void updateMoveTo(MenuItem moveTo, SelectionDetails selectionDetails) {
+ moveTo.setVisible(true);
+ moveTo.setEnabled(!selectionDetails.containsPartialFiles() && selectionDetails.canDelete());
+ }
+
+ @Override
+ void updateCopyTo(MenuItem copyTo, SelectionDetails selectionDetails) {
+ copyTo.setVisible(true);
+ copyTo.setEnabled(!selectionDetails.containsPartialFiles());
+ }
+
+ @Override
+ void updateSelectAll(MenuItem selectAll, SelectionDetails selectionDetails) {
+ selectAll.setVisible(true);
+ }
+
+ @Override
+ void updateCreateDir(MenuItem createDir, DirectoryDetails directoryDetails) {
+ createDir.setVisible(true);
+ createDir.setEnabled(directoryDetails.canCreateDirectory());
+ }
+
+ @Override
+ void updateShare(MenuItem share, SelectionDetails selectionDetails) {
+ share.setVisible(!selectionDetails.containsDirectories()
+ && !selectionDetails.containsPartialFiles());
+ }
+
+ @Override
+ void updateDelete(MenuItem delete, SelectionDetails selectionDetails) {
+ delete.setVisible(selectionDetails.canDelete());
+ }
+
+ @Override
+ void updateRename(MenuItem rename, SelectionDetails selectionDetails) {
+ rename.setVisible(true);
+ rename.setEnabled(!selectionDetails.containsPartialFiles() && selectionDetails.canRename());
+ }
+} \ No newline at end of file
diff --git a/packages/DocumentsUI/src/com/android/documentsui/HorizontalBreadcrumb.java b/packages/DocumentsUI/src/com/android/documentsui/HorizontalBreadcrumb.java
new file mode 100644
index 000000000000..7a08071fd76e
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/HorizontalBreadcrumb.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import android.content.Context;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.util.AttributeSet;
+import android.view.GestureDetector;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+
+import com.android.documentsui.NavigationViewManager.Breadcrumb;
+import com.android.documentsui.NavigationViewManager.Environment;
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.RootInfo;
+
+import java.util.function.Consumer;
+
+/**
+ * Horizontal implementation of breadcrumb used for tablet / desktop device layouts
+ */
+public final class HorizontalBreadcrumb extends RecyclerView
+ implements Breadcrumb, ItemDragListener.DragHost {
+
+ private static final int USER_NO_SCROLL_OFFSET_THRESHOLD = 5;
+
+ private LinearLayoutManager mLayoutManager;
+ private BreadcrumbAdapter mAdapter;
+ private Consumer<Integer> mListener;
+
+ public HorizontalBreadcrumb(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public HorizontalBreadcrumb(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public HorizontalBreadcrumb(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void setup(Environment env,
+ com.android.documentsui.State state,
+ Consumer<Integer> listener) {
+
+ mListener = listener;
+ mLayoutManager = new LinearLayoutManager(
+ getContext(), LinearLayoutManager.HORIZONTAL, false);
+ mAdapter = new BreadcrumbAdapter(
+ state, env, new ItemDragListener<>(this));
+
+ setLayoutManager(mLayoutManager);
+ addOnItemTouchListener(new ClickListener(getContext(), this::onSingleTapUp));
+ }
+
+ @Override
+ public void show(boolean visibility) {
+ if (visibility) {
+ setVisibility(VISIBLE);
+ boolean shouldScroll = !hasUserDefineScrollOffset();
+ if (getAdapter() == null) {
+ setAdapter(mAdapter);
+ } else {
+ int currentItemCount = mAdapter.getItemCount();
+ int lastItemCount = mAdapter.getLastItemSize();
+ if (currentItemCount > lastItemCount) {
+ mAdapter.notifyItemRangeInserted(lastItemCount,
+ currentItemCount - lastItemCount);
+ mAdapter.notifyItemChanged(lastItemCount - 1);
+ } else if (currentItemCount < lastItemCount) {
+ mAdapter.notifyItemRangeRemoved(currentItemCount,
+ lastItemCount - currentItemCount);
+ mAdapter.notifyItemChanged(currentItemCount - 1);
+ }
+ }
+ if (shouldScroll) {
+ mLayoutManager.scrollToPosition(mAdapter.getItemCount() - 1);
+ }
+ } else {
+ setVisibility(GONE);
+ setAdapter(null);
+ }
+ mAdapter.updateLastItemSize();
+ }
+
+ private boolean hasUserDefineScrollOffset() {
+ final int maxOffset = computeHorizontalScrollRange() - computeHorizontalScrollExtent();
+ return (maxOffset - computeHorizontalScrollOffset() > USER_NO_SCROLL_OFFSET_THRESHOLD);
+ }
+
+ @Override
+ public void postUpdate() {
+ }
+
+ @Override
+ public void runOnUiThread(Runnable runnable) {
+ post(runnable);
+ }
+
+ @Override
+ public void setDropTargetHighlight(View v, boolean highlight) {
+ RecyclerView.ViewHolder vh = getChildViewHolder(v);
+ if (vh instanceof BreadcrumbHolder) {
+ ((BreadcrumbHolder) vh).setHighlighted(highlight);
+ }
+ }
+
+ @Override
+ public void onViewHovered(View v) {
+ int pos = getChildAdapterPosition(v);
+ if (pos != mAdapter.getItemCount() - 1) {
+ mListener.accept(pos);
+ }
+ }
+
+ private void onSingleTapUp(MotionEvent e) {
+ View itemView = findChildViewUnder(e.getX(), e.getY());
+ int pos = getChildAdapterPosition(itemView);
+ if (pos != mAdapter.getItemCount() - 1) {
+ mListener.accept(pos);
+ }
+ }
+
+ private static final class BreadcrumbAdapter
+ extends RecyclerView.Adapter<BreadcrumbHolder> {
+
+ private final Environment mEnv;
+ private final com.android.documentsui.State mState;
+ private final OnDragListener mDragListener;
+ // We keep the old item size so the breadcrumb will only re-render views that are necessary
+ private int mLastItemSize;
+
+ public BreadcrumbAdapter(com.android.documentsui.State state,
+ Environment env,
+ OnDragListener dragListener) {
+ mState = state;
+ mEnv = env;
+ mDragListener = dragListener;
+ mLastItemSize = mState.stack.size();
+ }
+
+ @Override
+ public BreadcrumbHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ View v = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.navigation_breadcrumb_item, null);
+ return new BreadcrumbHolder(v);
+ }
+
+ @Override
+ public void onBindViewHolder(BreadcrumbHolder holder, int position) {
+ final DocumentInfo doc = getItem(position);
+ final int horizontalPadding = (int) holder.itemView.getResources()
+ .getDimension(R.dimen.breadcrumb_item_padding);
+
+ if (position == 0) {
+ final RootInfo root = mEnv.getCurrentRoot();
+ holder.title.setText(root.title);
+ holder.title.setPadding(0, 0, horizontalPadding, 0);
+ } else {
+ holder.title.setText(doc.displayName);
+ holder.title.setPadding(horizontalPadding, 0, horizontalPadding, 0);
+ }
+
+ if (position == getItemCount() - 1) {
+ holder.arrow.setVisibility(View.GONE);
+ } else {
+ holder.arrow.setVisibility(View.VISIBLE);
+ }
+ holder.itemView.setOnDragListener(mDragListener);
+ }
+
+ private DocumentInfo getItem(int position) {
+ return mState.stack.get(mState.stack.size() - position - 1);
+ }
+
+ @Override
+ public int getItemCount() {
+ return mState.stack.size();
+ }
+
+ public int getLastItemSize() {
+ return mLastItemSize;
+ }
+
+ public void updateLastItemSize() {
+ mLastItemSize = mState.stack.size();
+ }
+ }
+
+ private static class BreadcrumbHolder extends RecyclerView.ViewHolder {
+
+ protected DragOverTextView title;
+ protected ImageView arrow;
+
+ public BreadcrumbHolder(View itemView) {
+ super(itemView);
+ title = (DragOverTextView) itemView.findViewById(R.id.breadcrumb_text);
+ arrow = (ImageView) itemView.findViewById(R.id.breadcrumb_arrow);
+ }
+
+ /**
+ * Highlights the associated item view.
+ * @param highlighted
+ */
+ public void setHighlighted(boolean highlighted) {
+ title.setHighlight(highlighted);
+ }
+ }
+
+ private static final class ClickListener extends GestureDetector
+ implements OnItemTouchListener {
+
+ public ClickListener(Context context, Consumer<MotionEvent> listener) {
+ super(context, new SimpleOnGestureListener() {
+ @Override
+ public boolean onSingleTapUp(MotionEvent e) {
+ listener.accept(e);
+ return true;
+ }
+ });
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
+ onTouchEvent(e);
+ return false;
+ }
+
+ @Override
+ public void onTouchEvent(RecyclerView rv, MotionEvent e) {
+ onTouchEvent(e);
+ }
+
+ @Override
+ public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
+ }
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/ItemDragListener.java b/packages/DocumentsUI/src/com/android/documentsui/ItemDragListener.java
new file mode 100644
index 000000000000..152d3a0e03e3
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/ItemDragListener.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import android.content.ClipData;
+import android.graphics.drawable.Drawable;
+import android.util.Log;
+import android.view.DragEvent;
+import android.view.View;
+import android.view.View.OnDragListener;
+
+import com.android.documentsui.ItemDragListener.DragHost;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+/**
+ * An {@link OnDragListener} that adds support for "spring loading views". Use this when you want
+ * items to pop-open when user hovers on them during a drag n drop.
+ */
+public class ItemDragListener<H extends DragHost> implements OnDragListener {
+
+ private static final String TAG = "ItemDragListener";
+
+ @VisibleForTesting
+ static final int SPRING_TIMEOUT = 1000;
+
+ protected final H mDragHost;
+ private final Timer mHoverTimer;
+
+ public ItemDragListener(H dragHost) {
+ this(dragHost, new Timer());
+ }
+
+ @VisibleForTesting
+ protected ItemDragListener(H dragHost, Timer timer) {
+ mDragHost = dragHost;
+ mHoverTimer = timer;
+ }
+
+ @Override
+ public boolean onDrag(final View v, DragEvent event) {
+ switch (event.getAction()) {
+ case DragEvent.ACTION_DRAG_STARTED:
+ return true;
+ case DragEvent.ACTION_DRAG_ENTERED:
+ handleEnteredEvent(v);
+ return true;
+ case DragEvent.ACTION_DRAG_LOCATION:
+ handleLocationEvent(v, event.getX(), event.getY());
+ return true;
+ case DragEvent.ACTION_DRAG_EXITED:
+ case DragEvent.ACTION_DRAG_ENDED:
+ handleExitedEndedEvent(v);
+ return true;
+ case DragEvent.ACTION_DROP:
+ return handleDropEvent(v, event);
+ }
+
+ return false;
+ }
+
+ private void handleEnteredEvent(View v) {
+ mDragHost.setDropTargetHighlight(v, true);
+
+ TimerTask task = createOpenTask(v);
+ assert (task != null);
+ v.setTag(R.id.drag_hovering_tag, task);
+ mHoverTimer.schedule(task, SPRING_TIMEOUT);
+ }
+
+ private void handleLocationEvent(View v, float x, float y) {
+ Drawable background = v.getBackground();
+ if (background != null) {
+ background.setHotspot(x, y);
+ }
+ }
+
+ private void handleExitedEndedEvent(View v) {
+ mDragHost.setDropTargetHighlight(v, false);
+
+ TimerTask task = (TimerTask) v.getTag(R.id.drag_hovering_tag);
+ if (task != null) {
+ task.cancel();
+ }
+ }
+
+ private boolean handleDropEvent(View v, DragEvent event) {
+ ClipData clipData = event.getClipData();
+ if (clipData == null) {
+ Log.w(TAG, "Received invalid drop event with null clipdata. Ignoring.");
+ return false;
+ }
+
+ return handleDropEventChecked(v, event);
+ }
+
+ @VisibleForTesting
+ TimerTask createOpenTask(final View v) {
+ TimerTask task = new TimerTask() {
+ @Override
+ public void run() {
+ mDragHost.runOnUiThread(() -> {
+ mDragHost.onViewHovered(v);
+ });
+ }
+ };
+ return task;
+ }
+
+ /**
+ * Handles a drop event. Override it if you want to do something on drop event. It's called when
+ * {@link DragEvent#ACTION_DROP} happens. ClipData in DragEvent is guaranteed not null.
+ *
+ * @param v The view where user drops.
+ * @param event the drag event.
+ * @return true if this event is consumed; false otherwise
+ */
+ public boolean handleDropEventChecked(View v, DragEvent event) {
+ return false; // we didn't handle the drop
+ }
+
+ /**
+ * An interface {@link ItemDragListener} uses to make some callbacks.
+ */
+ public interface DragHost {
+
+ /**
+ * Runs this runnable in main thread.
+ */
+ void runOnUiThread(Runnable runnable);
+
+ /**
+ * Highlights/unhighlights the view to visually indicate this view is being hovered.
+ * @param v the view being hovered
+ * @param highlight true if highlight the view; false if unhighlight it
+ */
+ void setDropTargetHighlight(View v, boolean highlight);
+
+ /**
+ * Notifies hovering timeout has elapsed
+ * @param v the view being hovered
+ */
+ void onViewHovered(View v);
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/MenuManager.java b/packages/DocumentsUI/src/com/android/documentsui/MenuManager.java
new file mode 100644
index 000000000000..a23203b955be
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/MenuManager.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import android.annotation.Nullable;
+import android.provider.DocumentsContract.Root;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import com.android.documentsui.model.RootInfo;
+
+public abstract class MenuManager {
+
+ final State mState;
+ final SearchViewManager mSearchManager;
+
+ public MenuManager(SearchViewManager searchManager, State displayState) {
+ mSearchManager = searchManager;
+ mState = displayState;
+ }
+
+ /** @See DirectoryFragment.SelectionModeListener#updateActionMenu */
+ public void updateActionMenu(Menu menu, SelectionDetails selection) {
+ updateOpen(menu.findItem(R.id.menu_open), selection);
+ updateDelete(menu.findItem(R.id.menu_delete), selection);
+ updateShare(menu.findItem(R.id.menu_share), selection);
+ updateRename(menu.findItem(R.id.menu_rename), selection);
+ updateSelectAll(menu.findItem(R.id.menu_select_all), selection);
+ updateMoveTo(menu.findItem(R.id.menu_move_to), selection);
+ updateCopyTo(menu.findItem(R.id.menu_copy_to), selection);
+
+ Menus.disableHiddenItems(menu);
+ }
+
+ /** @See Activity#onPrepareOptionsMenu */
+ public void updateOptionMenu(Menu menu, DirectoryDetails directoryDetails) {
+ updateCreateDir(menu.findItem(R.id.menu_create_dir), directoryDetails);
+ updateSettings(menu.findItem(R.id.menu_settings), directoryDetails);
+ updateNewWindow(menu.findItem(R.id.menu_new_window), directoryDetails);
+ updateFileSize(menu.findItem(R.id.menu_file_size), directoryDetails);
+ updateModePicker(menu.findItem(
+ R.id.menu_grid), menu.findItem(R.id.menu_list), directoryDetails);
+ updateSort(menu.findItem(R.id.menu_sort),
+ menu.findItem(R.id.menu_sort_size),
+ directoryDetails);
+ updateAdvanced(menu.findItem(R.id.menu_advanced), directoryDetails);
+
+ Menus.disableHiddenItems(menu);
+ }
+
+ /** @See DirectoryFragment.onCreateContextMenu */
+ public void updateContextMenu(Menu menu,
+ @Nullable SelectionDetails selectionDetails,
+ DirectoryDetails directoryDetails) {
+
+ MenuItem cut = menu.findItem(R.id.menu_cut_to_clipboard);
+ MenuItem copy = menu.findItem(R.id.menu_copy_to_clipboard);
+ MenuItem paste = menu.findItem(R.id.menu_paste_from_clipboard);
+ MenuItem delete = menu.findItem(R.id.menu_delete);
+ MenuItem rename = menu.findItem(R.id.menu_rename);
+ MenuItem createDir = menu.findItem(R.id.menu_create_dir);
+
+ if (selectionDetails == null) {
+ cut.setEnabled(false);
+ copy.setEnabled(false);
+ rename.setEnabled(false);
+ delete.setEnabled(false);
+ } else {
+ copy.setEnabled(!selectionDetails.containsPartialFiles());
+ cut.setEnabled(
+ !selectionDetails.containsPartialFiles() && selectionDetails.canDelete());
+ updateRename(rename, selectionDetails);
+ updateDelete(delete, selectionDetails);
+ }
+ menu.findItem(R.id.menu_paste_from_clipboard)
+ .setEnabled(directoryDetails.hasItemsToPaste());
+ updateCreateDir(createDir, directoryDetails);
+
+ //Cut, Copy, Paste and Delete should always be visible
+ cut.setVisible(true);
+ copy.setVisible(true);
+ paste.setVisible(true);
+ delete.setVisible(true);
+ }
+
+ public void updateRootContextMenu(Menu menu, RootInfo root) {
+ MenuItem settings = menu.findItem(R.id.menu_settings);
+ MenuItem eject = menu.findItem(R.id.menu_eject_root);
+
+ updateSettings(settings, root);
+ updateEject(eject, root);
+ }
+
+ void updateModePicker(MenuItem grid, MenuItem list, DirectoryDetails directoryDetails) {
+ grid.setVisible(mState.derivedMode != State.MODE_GRID);
+ list.setVisible(mState.derivedMode != State.MODE_LIST);
+ }
+
+ void updateFileSize(MenuItem fileSize, DirectoryDetails directoryDetails) {
+ fileSize.setVisible(!mState.forceSize);
+ fileSize.setTitle(directoryDetails.getDisplayFileSize()
+ ? R.string.menu_file_size_hide : R.string.menu_file_size_show);
+ }
+
+ void updateSort(MenuItem sort, MenuItem sortSize, DirectoryDetails directoryDetails) {
+ // Search uses backend ranking; no sorting, recents doesn't support sort.
+ sort.setEnabled(!directoryDetails.isInRecents() && !mSearchManager.isSearching());
+ sort.setVisible(true);
+ sortSize.setVisible(mState.showSize); // Only sort by size when file sizes are visible
+ }
+
+ void updateAdvanced(MenuItem advanced, DirectoryDetails directoryDetails) {
+ advanced.setVisible(mState.showAdvancedOption);
+ advanced.setTitle(mState.showAdvancedOption && mState.showAdvanced
+ ? R.string.menu_advanced_hide : R.string.menu_advanced_show);
+ }
+
+ void updateSettings(MenuItem settings, DirectoryDetails directoryDetails) {
+ settings.setVisible(false);
+ }
+
+ void updateSettings(MenuItem settings, RootInfo root) {
+ settings.setVisible(false);
+ }
+
+ void updateEject(MenuItem eject, RootInfo root) {
+ eject.setVisible(false);
+ }
+
+ void updateNewWindow(MenuItem newWindow, DirectoryDetails directoryDetails) {
+ newWindow.setVisible(false);
+ }
+
+ void updateOpen(MenuItem open, SelectionDetails selectionDetails) {
+ open.setVisible(false);
+ }
+
+ void updateShare(MenuItem share, SelectionDetails selectionDetails) {
+ share.setVisible(false);
+ }
+
+ void updateDelete(MenuItem delete, SelectionDetails selectionDetails) {
+ delete.setVisible(false);
+ }
+
+ void updateRename(MenuItem rename, SelectionDetails selectionDetails) {
+ rename.setVisible(false);
+ }
+
+ void updateMoveTo(MenuItem moveTo, SelectionDetails selectionDetails) {
+ moveTo.setVisible(false);
+ }
+
+ void updateCopyTo(MenuItem copyTo, SelectionDetails selectionDetails) {
+ copyTo.setVisible(false);
+ }
+
+ abstract void updateSelectAll(MenuItem selectAll, SelectionDetails selectionDetails);
+ abstract void updateCreateDir(MenuItem createDir, DirectoryDetails directoryDetails);
+
+ /**
+ * Access to meta data about the selection.
+ */
+ public interface SelectionDetails {
+ boolean containsDirectories();
+
+ boolean containsPartialFiles();
+
+ // TODO: Update these to express characteristics instead of answering concrete questions,
+ // since the answer to those questions is (or can be) activity specific.
+ boolean canDelete();
+
+ boolean canRename();
+ }
+
+ public static class DirectoryDetails {
+ private final BaseActivity mActivity;
+
+ public DirectoryDetails(BaseActivity activity) {
+ mActivity = activity;
+ }
+
+ public boolean shouldShowFancyFeatures() {
+ return Shared.shouldShowFancyFeatures(mActivity);
+ }
+
+ public boolean hasRootSettings() {
+ return mActivity.getCurrentRoot().hasSettings();
+ }
+
+ public boolean hasItemsToPaste() {
+ return false;
+ }
+
+ public boolean isInRecents() {
+ return mActivity.getCurrentDirectory() == null;
+ }
+
+ public boolean canCreateDirectory() {
+ return mActivity.canCreateDirectory();
+ }
+
+ public boolean getDisplayFileSize() {
+ return LocalPreferences.getDisplayFileSize(mActivity);
+ }
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Metrics.java b/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
index 80671418b89e..3c45a934eb6c 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
@@ -29,7 +29,6 @@ import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.provider.DocumentsContract;
import android.util.Log;
-import android.view.KeyEvent;
import com.android.documentsui.State.ActionType;
import com.android.documentsui.model.DocumentInfo;
@@ -243,6 +242,7 @@ public final class Metrics {
public static final int USER_ACTION_COPY_CLIPBOARD = 23;
public static final int USER_ACTION_DRAG_N_DROP = 24;
public static final int USER_ACTION_DRAG_N_DROP_MULTI_WINDOW = 25;
+ public static final int USER_ACTION_CUT_CLIPBOARD = 26;
@IntDef(flag = false, value = {
USER_ACTION_OTHER,
@@ -269,7 +269,8 @@ public final class Metrics {
USER_ACTION_PASTE_CLIPBOARD,
USER_ACTION_COPY_CLIPBOARD,
USER_ACTION_DRAG_N_DROP,
- USER_ACTION_DRAG_N_DROP_MULTI_WINDOW
+ USER_ACTION_DRAG_N_DROP_MULTI_WINDOW,
+ USER_ACTION_CUT_CLIPBOARD
})
@Retention(RetentionPolicy.SOURCE)
public @interface UserAction {}
@@ -347,7 +348,7 @@ public final class Metrics {
}
/**
- * Logs a root visited event. Call this when the user clicks on a root in the RootsFragment.
+ * Logs a root visited event. Call this when the user visits on a root in the RootsFragment.
*
* @param context
* @param info
@@ -357,7 +358,7 @@ public final class Metrics {
}
/**
- * Logs an app visited event. Call this when the user clicks on an app in the RootsFragment.
+ * Logs an app visited event. Call this when the user visits on an app in the RootsFragment.
*
* @param context
* @param info
diff --git a/packages/DocumentsUI/src/com/android/documentsui/NavigationView.java b/packages/DocumentsUI/src/com/android/documentsui/NavigationView.java
deleted file mode 100644
index 3373c23ed212..000000000000
--- a/packages/DocumentsUI/src/com/android/documentsui/NavigationView.java
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.documentsui;
-
-import static android.view.View.GONE;
-import static android.view.View.VISIBLE;
-import static com.android.documentsui.Shared.DEBUG;
-
-import android.annotation.Nullable;
-import android.graphics.drawable.Drawable;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemSelectedListener;
-import android.widget.BaseAdapter;
-import android.widget.Spinner;
-import android.widget.TextView;
-
-import com.android.documentsui.dirlist.AnimationView;
-import com.android.documentsui.model.DocumentInfo;
-import com.android.documentsui.model.RootInfo;
-
-/**
- * A facade over the portions of the app and drawer toolbars.
- */
-class NavigationView {
-
- private static final String TAG = "NavigationView";
-
- private final DrawerController mDrawer;
- private final DocumentsToolbar mToolbar;
- private final Spinner mBreadcrumb;
- private final State mState;
- private final NavigationView.Environment mEnv;
- private final BreadcrumbAdapter mBreadcrumbAdapter;
-
- private boolean mIgnoreNextNavigation;
-
- public NavigationView(
- DrawerController drawer,
- DocumentsToolbar toolbar,
- Spinner breadcrumb,
- State state,
- NavigationView.Environment env) {
-
- mToolbar = toolbar;
- mBreadcrumb = breadcrumb;
- mDrawer = drawer;
- mState = state;
- mEnv = env;
-
- mBreadcrumbAdapter = new BreadcrumbAdapter(mState, mEnv);
- mToolbar.setNavigationOnClickListener(
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- onNavigationIconClicked();
- }
-
- });
-
- mBreadcrumb.setOnItemSelectedListener(
- new OnItemSelectedListener() {
- @Override
- public void onItemSelected(
- AdapterView<?> parent, View view, int position, long id) {
- onBreadcrumbItemSelected(position);
- }
-
- @Override
- public void onNothingSelected(AdapterView<?> parent) {}
- });
-
- }
-
- private void onNavigationIconClicked() {
- if (mDrawer.isPresent()) {
- mDrawer.setOpen(true, DrawerController.OPENED_HAMBURGER);
- }
- }
-
- private void onBreadcrumbItemSelected(int position) {
- if (mIgnoreNextNavigation) {
- mIgnoreNextNavigation = false;
- return;
- }
-
- while (mState.stack.size() > position + 1) {
- mState.popDocument();
- }
- mEnv.refreshCurrentRootAndDirectory(AnimationView.ANIM_LEAVE);
- }
-
- void update() {
-
- // TODO: Looks to me like this block is never getting hit.
- if (mEnv.isSearchExpanded()) {
- mToolbar.setTitle(null);
- mBreadcrumb.setVisibility(View.GONE);
- mBreadcrumb.setAdapter(null);
- return;
- }
-
- mDrawer.setTitle(mEnv.getDrawerTitle());
-
- mToolbar.setNavigationIcon(getActionBarIcon());
- mToolbar.setNavigationContentDescription(R.string.drawer_open);
-
- if (mState.stack.size() <= 1) {
- showBreadcrumb(false);
- String title = mEnv.getCurrentRoot().title;
- if (DEBUG) Log.d(TAG, "New toolbar title is: " + title);
- mToolbar.setTitle(title);
- } else {
- showBreadcrumb(true);
- mToolbar.setTitle(null);
- mIgnoreNextNavigation = true;
- mBreadcrumb.setSelection(mBreadcrumbAdapter.getCount() - 1, false);
- }
-
- if (DEBUG) Log.d(TAG, "Final toolbar title is: " + mToolbar.getTitle());
- }
-
- private void showBreadcrumb(boolean visibility) {
- if (visibility) {
- mBreadcrumb.setVisibility(VISIBLE);
- mBreadcrumb.setAdapter(mBreadcrumbAdapter);
- } else {
- mBreadcrumb.setVisibility(GONE);
- mBreadcrumb.setAdapter(null);
- }
- }
-
- // Hamburger if drawer is present, else sad nullness.
- private @Nullable Drawable getActionBarIcon() {
- if (mDrawer.isPresent()) {
- return mToolbar.getContext().getDrawable(R.drawable.ic_hamburger);
- } else {
- return null;
- }
- }
-
- void revealRootsDrawer(boolean open) {
- mDrawer.setOpen(open);
- }
-
- /**
- * Class providing toolbar with runtime access to useful activity data.
- */
- static final class BreadcrumbAdapter extends BaseAdapter {
-
- private Environment mEnv;
- private State mState;
-
- public BreadcrumbAdapter(State state, Environment env) {
- mState = state;
- mEnv = env;
- }
-
- @Override
- public int getCount() {
- return mState.stack.size();
- }
-
- @Override
- public DocumentInfo getItem(int position) {
- return mState.stack.get(mState.stack.size() - position - 1);
- }
-
- @Override
- public long getItemId(int position) {
- return position;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- if (convertView == null) {
- convertView = LayoutInflater.from(parent.getContext())
- .inflate(R.layout.item_subdir_title, parent, false);
- }
-
- final TextView title = (TextView) convertView.findViewById(android.R.id.title);
- final DocumentInfo doc = getItem(position);
-
- if (position == 0) {
- final RootInfo root = mEnv.getCurrentRoot();
- title.setText(root.title);
- } else {
- title.setText(doc.displayName);
- }
-
- return convertView;
- }
-
- @Override
- public View getDropDownView(int position, View convertView, ViewGroup parent) {
- if (convertView == null) {
- convertView = LayoutInflater.from(parent.getContext())
- .inflate(R.layout.item_subdir, parent, false);
- }
-
- final TextView title = (TextView) convertView.findViewById(android.R.id.title);
- final DocumentInfo doc = getItem(position);
-
- if (position == 0) {
- final RootInfo root = mEnv.getCurrentRoot();
- title.setText(root.title);
- } else {
- title.setText(doc.displayName);
- }
-
- return convertView;
- }
- }
-
- interface Environment {
- RootInfo getCurrentRoot();
- String getDrawerTitle();
- void refreshCurrentRootAndDirectory(int animation);
- boolean isSearchExpanded();
- }
-}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/NavigationViewManager.java b/packages/DocumentsUI/src/com/android/documentsui/NavigationViewManager.java
new file mode 100644
index 000000000000..25542461748a
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/NavigationViewManager.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import static com.android.documentsui.Shared.DEBUG;
+
+import android.annotation.Nullable;
+import android.graphics.drawable.Drawable;
+import android.util.Log;
+import android.view.View;
+
+import com.android.documentsui.dirlist.AnimationView;
+import com.android.documentsui.model.RootInfo;
+
+import java.util.function.Consumer;
+
+/**
+ * A facade over the portions of the app and drawer toolbars.
+ */
+public class NavigationViewManager {
+
+ private static final String TAG = "NavigationViewManager";
+
+ final DrawerController mDrawer;
+ final DocumentsToolbar mToolbar;
+ final State mState;
+ final NavigationViewManager.Environment mEnv;
+ final Breadcrumb mBreadcrumb;
+
+ public NavigationViewManager(
+ DrawerController drawer,
+ DocumentsToolbar toolbar,
+ State state,
+ NavigationViewManager.Environment env,
+ Breadcrumb breadcrumb) {
+
+ mToolbar = toolbar;
+ mDrawer = drawer;
+ mState = state;
+ mEnv = env;
+ mBreadcrumb = breadcrumb;
+ mBreadcrumb.setup(env, state, this::onNavigationItemSelected);
+
+ mToolbar.setNavigationOnClickListener(
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ onNavigationIconClicked();
+ }
+ });
+ }
+
+ private void onNavigationIconClicked() {
+ if (mDrawer.isPresent()) {
+ mDrawer.setOpen(true, DrawerController.OPENED_HAMBURGER);
+ }
+ }
+
+ void onNavigationItemSelected(int position) {
+ boolean changed = false;
+ while (mState.stack.size() > position + 1) {
+ changed = true;
+ mState.popDocument();
+ }
+ if (changed) {
+ mEnv.refreshCurrentRootAndDirectory(AnimationView.ANIM_LEAVE);
+ }
+ }
+
+ void update() {
+
+ // TODO: Looks to me like this block is never getting hit.
+ if (mEnv.isSearchExpanded()) {
+ mToolbar.setTitle(null);
+ mBreadcrumb.show(false);
+ return;
+ }
+
+ mDrawer.setTitle(mEnv.getDrawerTitle());
+
+ mToolbar.setNavigationIcon(getActionBarIcon());
+ mToolbar.setNavigationContentDescription(R.string.drawer_open);
+
+ if (mState.stack.size() <= 1) {
+ mBreadcrumb.show(false);
+ String title = mEnv.getCurrentRoot().title;
+ if (DEBUG) Log.d(TAG, "New toolbar title is: " + title);
+ mToolbar.setTitle(title);
+ } else {
+ mBreadcrumb.show(true);
+ mToolbar.setTitle(null);
+ mBreadcrumb.postUpdate();
+ }
+
+ if (DEBUG) Log.d(TAG, "Final toolbar title is: " + mToolbar.getTitle());
+ }
+
+ // Hamburger if drawer is present, else sad nullness.
+ private @Nullable Drawable getActionBarIcon() {
+ if (mDrawer.isPresent()) {
+ return mToolbar.getContext().getDrawable(R.drawable.ic_hamburger);
+ } else {
+ return null;
+ }
+ }
+
+ void revealRootsDrawer(boolean open) {
+ mDrawer.setOpen(open);
+ }
+
+ interface Breadcrumb {
+ void setup(Environment env, State state, Consumer<Integer> listener);
+ void show(boolean visibility);
+ void postUpdate();
+ }
+
+ interface Environment {
+ RootInfo getCurrentRoot();
+ String getDrawerTitle();
+ void refreshCurrentRootAndDirectory(int animation);
+ boolean isSearchExpanded();
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/OperationDialogFragment.java b/packages/DocumentsUI/src/com/android/documentsui/OperationDialogFragment.java
index 9a3f7a83ebb7..140baad0383c 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/OperationDialogFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/OperationDialogFragment.java
@@ -60,7 +60,7 @@ public class OperationDialogFragment extends DialogFragment {
@OpType int operationType) {
final Bundle args = new Bundle();
args.putInt(FileOperationService.EXTRA_DIALOG_TYPE, dialogType);
- args.putInt(FileOperationService.EXTRA_OPERATION, operationType);
+ args.putInt(FileOperationService.EXTRA_OPERATION_TYPE, operationType);
args.putParcelableArrayList(FileOperationService.EXTRA_SRC_LIST, failedSrcList);
final FragmentTransaction ft = fm.beginTransaction();
@@ -78,7 +78,7 @@ public class OperationDialogFragment extends DialogFragment {
final @DialogType int dialogType =
getArguments().getInt(FileOperationService.EXTRA_DIALOG_TYPE);
final @OpType int operationType =
- getArguments().getInt(FileOperationService.EXTRA_OPERATION);
+ getArguments().getInt(FileOperationService.EXTRA_OPERATION_TYPE);
final ArrayList<DocumentInfo> srcList = getArguments().getParcelableArrayList(
FileOperationService.EXTRA_SRC_LIST);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/PairedTask.java b/packages/DocumentsUI/src/com/android/documentsui/PairedTask.java
index b74acb8e38c3..7d2da0b536f8 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/PairedTask.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/PairedTask.java
@@ -20,58 +20,20 @@ import android.app.Activity;
import android.os.AsyncTask;
/**
- * An {@link AsyncTask} that guards work with checks that a paired {@link Activity}
+ * An {@link CheckedTask} that guards work with checks that a paired {@link Activity}
* is still alive. Instances of this class make no progress.
*
- * <p>Use this type of task for greater safety when executing tasks that might complete
- * after an Activity is destroyed.
- *
- * <p>Also useful as tasks can be static, limiting scope, but still have access to
- * the owning class (by way the A template and the mActivity field).
- *
* @template Owner Activity type.
* @template Input input type
* @template Output output type
*/
abstract class PairedTask<Owner extends Activity, Input, Output>
- extends AsyncTask<Input, Void, Output> {
+ extends CheckedTask<Input, Output> {
protected final Owner mOwner;
public PairedTask(Owner owner) {
+ super(owner::isDestroyed);
mOwner = owner;
}
-
- /** Called prior to run being executed. Analogous to {@link AsyncTask#onPreExecute} */
- void prepare() {}
-
- /** Analogous to {@link AsyncTask#doInBackground} */
- abstract Output run(Input... input);
-
- /** Analogous to {@link AsyncTask#onPostExecute} */
- abstract void finish(Output output);
-
- @Override
- final protected void onPreExecute() {
- if (mOwner.isDestroyed()) {
- return;
- }
- prepare();
- }
-
- @Override
- final protected Output doInBackground(Input... input) {
- if (mOwner.isDestroyed()) {
- return null;
- }
- return run(input);
- }
-
- @Override
- final protected void onPostExecute(Output result) {
- if (mOwner.isDestroyed()) {
- return;
- }
- finish(result);
- }
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
index 2be93b83fbae..019ca86bd3db 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
@@ -46,18 +46,19 @@ import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
+import com.android.documentsui.Events.MotionInputEvent;
import com.android.documentsui.RecentsProvider.RecentColumns;
import com.android.documentsui.model.DocumentStack;
import com.android.documentsui.model.DurableUtils;
import com.android.documentsui.model.RootInfo;
-import libcore.io.IoUtils;
-
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import libcore.io.IoUtils;
+
/**
* Display directories where recent creates took place.
*/
@@ -140,13 +141,14 @@ public class RecentsCreateFragment extends Fragment {
new RecyclerView.OnItemTouchListener() {
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
- Events.MotionInputEvent event = new Events.MotionInputEvent(e, mRecView);
- if (event.isOverItem() && event.isActionUp()) {
- final DocumentStack stack = mAdapter.getItem(event.getItemPosition());
- ((BaseActivity) getActivity()).onStackPicked(stack);
- return true;
+ try (MotionInputEvent event = MotionInputEvent.obtain(e, mRecView)) {
+ if (event.isOverItem() && event.isActionUp()) {
+ final DocumentStack stack = mAdapter.getItem(event.getItemPosition());
+ ((BaseActivity) getActivity()).onStackPicked(stack);
+ return true;
+ }
+ return false;
}
- return false;
}
@Override
@@ -241,7 +243,7 @@ public class RecentsCreateFragment extends Fragment {
final LayoutInflater inflater = LayoutInflater.from(context);
return new StackHolder(
- (View) inflater.inflate(R.layout.item_doc_list, parent, false));
+ inflater.inflate(R.layout.item_doc_list, parent, false));
}
@Override
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RetainedState.java b/packages/DocumentsUI/src/com/android/documentsui/RetainedState.java
new file mode 100644
index 000000000000..57cf3b438b65
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/RetainedState.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import android.support.annotation.Nullable;
+
+import com.android.documentsui.dirlist.MultiSelectManager.Selection;
+
+/**
+ * Object used to collect retained state from activity and fragments. Used
+ * with Activity#onRetainNonConfigurationInstance. Information stored in
+ * this class should be primarily ephemeral as instances of the class
+ * only last across configuration changes (like device rotation). When
+ * an application is fully town down, all instances are lost, fa-evah!
+ */
+public final class RetainedState {
+ public @Nullable Selection selection;
+
+ public boolean hasSelection() {
+ return selection != null;
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootItemView.java b/packages/DocumentsUI/src/com/android/documentsui/RootItemView.java
new file mode 100644
index 000000000000..93aa526aaa82
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootItemView.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.LinearLayout;
+
+public final class RootItemView extends LinearLayout {
+ private static final int[] STATE_HIGHLIGHTED = {R.attr.state_highlighted};
+
+ private boolean mHighlighted = false;
+
+ public RootItemView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public int[] onCreateDrawableState(int extraSpace) {
+ final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
+
+ if (mHighlighted) {
+ mergeDrawableStates(drawableState, STATE_HIGHLIGHTED);
+ }
+
+ return drawableState;
+ }
+
+ public void setHighlight(boolean highlight) {
+ mHighlighted = highlight;
+ refreshDrawableState();
+ }
+
+ /**
+ * Synthesizes pressed state to trick RippleDrawable starting a ripple effect.
+ */
+ public void drawRipple() {
+ setPressed(true);
+ setPressed(false);
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
index 88eeb49ec169..117bb01b1fec 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
@@ -36,6 +36,7 @@ import android.os.Handler;
import android.os.SystemClock;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Root;
+import android.provider.DocumentsProvider;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
@@ -350,11 +351,20 @@ public class RootsCache {
* waiting for all the other roots to come back.
*/
public RootInfo getRootOneshot(String authority, String rootId) {
+ return getRootOneshot(authority, rootId, false);
+ }
+
+ /**
+ * Return the requested {@link RootInfo}, but only loading the roots of the requested authority.
+ * It always fetches from {@link DocumentsProvider} if forceRefresh is true, which is used to
+ * get the most up-to-date free space before starting copy operations.
+ */
+ public RootInfo getRootOneshot(String authority, String rootId, boolean forceRefresh) {
synchronized (mLock) {
- RootInfo root = getRootLocked(authority, rootId);
+ RootInfo root = forceRefresh ? null : getRootLocked(authority, rootId);
if (root == null) {
- mRoots.putAll(authority,
- loadRootsForAuthority(mContext.getContentResolver(), authority, false));
+ mRoots.putAll(authority, loadRootsForAuthority(
+ mContext.getContentResolver(), authority, forceRefresh));
root = getRootLocked(authority, rootId);
}
return root;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
index 94edd832280a..ca28622327c8 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
@@ -18,27 +18,40 @@ package com.android.documentsui;
import static com.android.documentsui.Shared.DEBUG;
+import android.annotation.LayoutRes;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.app.LoaderManager.LoaderCallbacks;
+import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.content.Loader;
+import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Looper;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.util.Log;
+import android.view.ContextMenu;
+import android.view.DragEvent;
import android.view.LayoutInflater;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.MotionEvent;
import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnDragListener;
+import android.view.View.OnGenericMotionListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
+import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
@@ -46,29 +59,58 @@ import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
+import com.android.documentsui.CheckedTask.Check;
+import com.android.documentsui.clipping.DocumentClipper;
+import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.RootInfo;
+import com.android.documentsui.services.FileOperations;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
+import java.util.function.BooleanSupplier;
+import java.util.function.Consumer;
/**
* Display list of known storage backend roots.
*/
-public class RootsFragment extends Fragment {
+public class RootsFragment extends Fragment implements ItemDragListener.DragHost {
private static final String TAG = "RootsFragment";
private static final String EXTRA_INCLUDE_APPS = "includeApps";
+ private final OnDragListener mDragListener = new ItemDragListener<RootsFragment>(this) {
+ @Override
+ public boolean handleDropEventChecked(View v, DragEvent event) {
+ final int position = (Integer) v.getTag(R.id.item_position_tag);
+ final Item item = mAdapter.getItem(position);
+
+ assert(item.isDropTarget());
+
+ BaseActivity activity = getBaseActivity();
+ return item.dropOn(event.getClipData(), activity, RootsFragment.this::isDetached,
+ activity.fileOpCallback);
+ }
+ };
+
private ListView mList;
private RootsAdapter mAdapter;
private LoaderCallbacks<Collection<RootInfo>> mCallbacks;
+ private Consumer<RootInfo> mOpenSettings = (RootInfo) -> {
+ throw new UnsupportedOperationException("Can't open settings.");
+ };
+ public static void show(FragmentManager fm, Consumer<RootInfo> openSettings) {
+ RootsFragment fragment = show(fm, (Intent) null);
+ fragment.mOpenSettings = openSettings;
+ }
- public static void show(FragmentManager fm, Intent includeApps) {
+ public static RootsFragment show(FragmentManager fm, Intent includeApps) {
final Bundle args = new Bundle();
args.putParcelable(EXTRA_INCLUDE_APPS, includeApps);
@@ -78,6 +120,8 @@ public class RootsFragment extends Fragment {
final FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.container_roots, fragment);
ft.commitAllowingStateLoss();
+
+ return fragment;
}
public static RootsFragment get(FragmentManager fm) {
@@ -91,6 +135,26 @@ public class RootsFragment extends Fragment {
final View view = inflater.inflate(R.layout.fragment_roots, container, false);
mList = (ListView) view.findViewById(R.id.roots_list);
mList.setOnItemClickListener(mItemListener);
+ // ListView does not have right-click specific listeners, so we will have a
+ // GenericMotionListener to listen for it.
+ // Currently, right click is viewed the same as long press, so we will have to quickly
+ // register for context menu when we receive a right click event, and quickly unregister
+ // it afterwards to prevent context menus popping up upon long presses.
+ // All other motion events will then get passed to OnItemClickListener.
+ mList.setOnGenericMotionListener(
+ new OnGenericMotionListener() {
+ @Override
+ public boolean onGenericMotion(View v, MotionEvent event) {
+ if (Events.isMouseEvent(event)
+ && event.getButtonState() == MotionEvent.BUTTON_SECONDARY) {
+ registerForContextMenu(v);
+ v.showContextMenu(event.getX(), event.getY());
+ unregisterForContextMenu(v);
+ return true;
+ }
+ return false;
+ }
+ });
mList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
return view;
}
@@ -118,7 +182,8 @@ public class RootsFragment extends Fragment {
Intent handlerAppIntent = getArguments().getParcelable(EXTRA_INCLUDE_APPS);
- mAdapter = new RootsAdapter(context, result, handlerAppIntent, state);
+ mAdapter =
+ new RootsAdapter(context, result, handlerAppIntent, state, mDragListener);
mList.setAdapter(mAdapter);
onCurrentRootChanged();
@@ -164,7 +229,6 @@ public class RootsFragment extends Fragment {
final RootInfo testRoot = ((RootItem) item).root;
if (Objects.equals(testRoot, root)) {
mList.setItemChecked(i, true);
- mList.setSelection(i);
return;
}
}
@@ -185,25 +249,115 @@ public class RootsFragment extends Fragment {
startActivity(intent);
}
+ private BaseActivity getBaseActivity() {
+ return (BaseActivity) getActivity();
+ }
+
+ @Override
+ public void runOnUiThread(Runnable runnable) {
+ getActivity().runOnUiThread(runnable);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * In RootsFragment we open the hovered root.
+ */
+ @Override
+ public void onViewHovered(View v) {
+ // SpacerView doesn't have DragListener so this view is guaranteed to be a RootItemView.
+ RootItemView itemView = (RootItemView) v;
+ itemView.drawRipple();
+
+ final int position = (Integer) v.getTag(R.id.item_position_tag);
+ final Item item = mAdapter.getItem(position);
+ item.open(this);
+ }
+
+ @Override
+ public void setDropTargetHighlight(View v, boolean highlight) {
+ // SpacerView doesn't have DragListener so this view is guaranteed to be a RootItemView.
+ RootItemView itemView = (RootItemView) v;
+ itemView.setHighlight(highlight);
+ }
+
+ @Override
+ public void onCreateContextMenu(
+ ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
+ super.onCreateContextMenu(menu, v, menuInfo);
+ AdapterContextMenuInfo adapterMenuInfo = (AdapterContextMenuInfo) menuInfo;
+ final Item item = mAdapter.getItem(adapterMenuInfo.position);
+ if (item instanceof RootItem) {
+ RootItem rootItem = (RootItem) item;
+ MenuInflater inflater = getActivity().getMenuInflater();
+ inflater.inflate(R.menu.root_context_menu, menu);
+ (getBaseActivity()).getMenuManager().updateRootContextMenu(menu, rootItem.root);
+ }
+ }
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ AdapterContextMenuInfo adapterMenuInfo = (AdapterContextMenuInfo) item.getMenuInfo();
+ // There is a possibility that this is called from DirectoryFragment since
+ // all fragments' onContextItemSelected gets called when any menu item is selected
+ // This is to guard against it since DirectoryFragment's RecylerView does not have a
+ // menuInfo
+ if (adapterMenuInfo == null) {
+ return false;
+ }
+ final RootItem rootItem = (RootItem) mAdapter.getItem(adapterMenuInfo.position);
+ switch (item.getItemId()) {
+ case R.id.menu_eject_root:
+ final View ejectIcon = adapterMenuInfo.targetView.findViewById(R.id.eject_icon);
+ ejectClicked(ejectIcon, rootItem.root);
+ return true;
+ case R.id.menu_settings:
+ mOpenSettings.accept(rootItem.root);
+ return true;
+ default:
+ if (DEBUG) Log.d(TAG, "Unhandled menu item selected: " + item);
+ return false;
+ }
+ }
+
+ private static void ejectClicked(View ejectIcon, RootInfo root) {
+ assert(ejectIcon != null);
+ assert(ejectIcon.getContext() instanceof BaseActivity);
+ assert (!root.ejecting);
+ ejectIcon.setEnabled(false);
+ root.ejecting = true;
+ ejectRoot(
+ ejectIcon,
+ root.authority,
+ root.rootId,
+ new Consumer<Boolean>() {
+ @Override
+ public void accept(Boolean ejected) {
+ ejectIcon.setEnabled(!ejected);
+ root.ejecting = false;
+ }
+ });
+ }
+
+ static void ejectRoot(
+ View ejectIcon, String authority, String rootId, Consumer<Boolean> listener) {
+ BooleanSupplier predicate = () -> {
+ return !(ejectIcon.getVisibility() == View.VISIBLE);
+ };
+ new EjectRootTask(ejectIcon.getContext(),
+ authority,
+ rootId,
+ predicate,
+ listener).executeOnExecutor(ProviderExecutor.forAuthority(authority));
+ }
+
private OnItemClickListener mItemListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- Item item = mAdapter.getItem(position);
- if (item instanceof RootItem) {
- BaseActivity activity = BaseActivity.get(RootsFragment.this);
- RootInfo newRoot = ((RootItem) item).root;
- Metrics.logRootVisited(getActivity(), newRoot);
- activity.onRootPicked(newRoot);
- } else if (item instanceof AppItem) {
- DocumentsActivity activity = DocumentsActivity.get(RootsFragment.this);
- ResolveInfo info = ((AppItem) item).info;
- Metrics.logAppVisited(getActivity(), info);
- activity.onAppPicked(info);
- } else if (item instanceof SpacerItem) {
- if (DEBUG) Log.d(TAG, "Ignoring click on spacer item.");
- } else {
- throw new IllegalStateException("Unknown root: " + item);
- }
+ final Item item = mAdapter.getItem(position);
+ item.open(RootsFragment.this);
+
+ ((BaseActivity) getActivity()).setRootsDrawerOpen(false);
}
};
@@ -211,53 +365,88 @@ public class RootsFragment extends Fragment {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
final Item item = mAdapter.getItem(position);
- if (item instanceof AppItem) {
- showAppDetails(((AppItem) item).info);
- return true;
- } else {
- return false;
- }
+ return item.showAppDetails(RootsFragment.this);
}
};
private static abstract class Item {
- private final int mLayoutId;
+ private final @LayoutRes int mLayoutId;
+ private final String mStringId;
- public Item(int layoutId) {
+ public Item(@LayoutRes int layoutId, String stringId) {
mLayoutId = layoutId;
+ mStringId = stringId;
}
public View getView(View convertView, ViewGroup parent) {
- // Disable recycling views because 1) it's very unlikely a view can be recycled here;
- // 2) there is no easy way for us to know with which layout id the convertView was
- // inflated; and 3) simplicity is much appreciated at this time.
- convertView = LayoutInflater.from(parent.getContext())
+ if (convertView == null
+ || (Integer) convertView.getTag(R.id.layout_id_tag) != mLayoutId) {
+ convertView = LayoutInflater.from(parent.getContext())
.inflate(mLayoutId, parent, false);
+ }
+ convertView.setTag(R.id.layout_id_tag, mLayoutId);
bindView(convertView);
return convertView;
}
- public abstract void bindView(View convertView);
+ boolean showAppDetails(RootsFragment fragment) {
+ return false;
+ }
+
+ abstract void bindView(View convertView);
+
+ abstract boolean isDropTarget();
+
+ abstract void open(RootsFragment fragment);
+
+ boolean dropOn(ClipData data, Context context, Check check,
+ FileOperations.Callback callback) {
+ return false;
+ }
}
private static class RootItem extends Item {
+ private static final String STRING_ID_FORMAT = "RootItem{%s/%s}";
+
public final RootInfo root;
public RootItem(RootInfo root) {
- super(R.layout.item_root);
+ super(R.layout.item_root, getStringId(root));
this.root = root;
}
+ private static String getStringId(RootInfo root) {
+ // Empty URI authority is invalid, so we can use empty string if root.authority is null.
+ // Directly passing null to String.format() will write "null" which can be a valid URI
+ // authority.
+ String authority = (root.authority == null ? "" : root.authority);
+ return String.format(STRING_ID_FORMAT, authority, root.rootId);
+ }
+
@Override
public void bindView(View convertView) {
final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon);
final TextView title = (TextView) convertView.findViewById(android.R.id.title);
final TextView summary = (TextView) convertView.findViewById(android.R.id.summary);
+ final ImageView ejectIcon = (ImageView) convertView.findViewById(R.id.eject_icon);
final Context context = convertView.getContext();
icon.setImageDrawable(root.loadDrawerIcon(context));
title.setText(root.title);
+ if (root.supportsEject()) {
+ ejectIcon.setVisibility(View.VISIBLE);
+ ejectIcon.setImageDrawable(root.loadEjectIcon(context));
+ ejectIcon.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View unmountIcon) {
+ RootsFragment.ejectClicked(unmountIcon, root);
+ }
+ });
+ } else {
+ ejectIcon.setVisibility(View.GONE);
+ ejectIcon.setOnClickListener(null);
+ }
// Show available space if no summary
String summaryText = root.summary;
if (TextUtils.isEmpty(summaryText) && root.availableBytes >= 0) {
@@ -268,29 +457,78 @@ public class RootsFragment extends Fragment {
summary.setText(summaryText);
summary.setVisibility(TextUtils.isEmpty(summaryText) ? View.GONE : View.VISIBLE);
}
+
+ @Override
+ boolean isDropTarget() {
+ return root.supportsCreate() && !root.isLibrary();
+ }
+
+ @Override
+ void open(RootsFragment fragment) {
+ BaseActivity activity = BaseActivity.get(fragment);
+ Metrics.logRootVisited(fragment.getActivity(), root);
+ activity.onRootPicked(root);
+ }
+
+ @Override
+ boolean dropOn(
+ ClipData data, Context context, Check check, FileOperations.Callback callback) {
+ ProviderExecutor executor = ProviderExecutor.forAuthority(root.authority);
+ new DropOnRootTask(data, root, context, check, callback).executeOnExecutor(executor);
+ return true;
+ }
}
private static class SpacerItem extends Item {
+ private static final String STRING_ID = "SpacerItem";
+
public SpacerItem() {
- super(R.layout.item_root_spacer);
+ // Multiple spacer items can share the same string id as they're identical.
+ super(R.layout.item_root_spacer, STRING_ID);
}
@Override
- public void bindView(View convertView) {
+ void bindView(View convertView) {
// Nothing to bind
}
+
+ @Override
+ boolean isDropTarget() {
+ return false;
+ }
+
+ @Override
+ void open(RootsFragment fragment) {
+ if (DEBUG) Log.d(TAG, "Ignoring click/hover on spacer item.");
+ }
}
private static class AppItem extends Item {
+ private static final String STRING_ID_FORMAT = "AppItem{%s/%s}";
+
public final ResolveInfo info;
public AppItem(ResolveInfo info) {
- super(R.layout.item_root);
+ super(R.layout.item_root, getStringId(info));
this.info = info;
}
+ private static String getStringId(ResolveInfo info) {
+ ActivityInfo activityInfo = info.activityInfo;
+
+ String component = String.format(
+ STRING_ID_FORMAT, activityInfo.applicationInfo.packageName, activityInfo.name);
+ return component;
+ }
+
@Override
- public void bindView(View convertView) {
+ boolean showAppDetails(RootsFragment fragment) {
+ fragment.showAppDetails(info);
+ return true;
+ }
+
+ @Override
+ void bindView(View convertView) {
final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon);
final TextView title = (TextView) convertView.findViewById(android.R.id.title);
final TextView summary = (TextView) convertView.findViewById(android.R.id.summary);
@@ -302,16 +540,66 @@ public class RootsFragment extends Fragment {
// TODO: match existing summary behavior from disambig dialog
summary.setVisibility(View.GONE);
}
+
+ @Override
+ boolean isDropTarget() {
+ // We won't support drag n' drop in DocumentsActivity, and apps only show up there.
+ return false;
+ }
+
+ @Override
+ void open(RootsFragment fragment) {
+ DocumentsActivity activity = DocumentsActivity.get(fragment);
+ Metrics.logAppVisited(fragment.getActivity(), info);
+ activity.onAppPicked(info);
+ }
+ }
+
+ private static class DropOnRootTask extends CheckedTask<Void, DocumentInfo> {
+ private ClipData mData;
+ private RootInfo mDstRoot;
+ private Context mContext;
+ private FileOperations.Callback mCallback;
+
+ private DropOnRootTask(ClipData data, RootInfo dstRoot, Context context, Check check,
+ FileOperations.Callback callback) {
+ super(check);
+ mData = data;
+ mDstRoot = dstRoot;
+ mContext = context;
+ mCallback = callback;
+ }
+
+ @Override
+ public DocumentInfo run(Void... args) {
+ return mDstRoot.getRootDocumentBlocking(mContext);
+ }
+
+ @Override
+ public void finish(DocumentInfo doc) {
+ if (doc != null) {
+ DocumentClipper clipper =
+ DocumentsApplication.getDocumentClipper(mContext);
+ clipper.copyFromClipData(mDstRoot, doc, mData, mCallback);
+ } else {
+ Log.e(TAG, "Failed to get doc.");
+ }
+ }
}
private static class RootsAdapter extends ArrayAdapter<Item> {
+ private static final Map<String, Long> sIdMap = new HashMap<String, Long>();
+ // the next available id to associate with a new string id
+ private static long sNextAvailableId;
+
+ private OnDragListener mDragListener;
/**
- * @param handlerAppIntent When not null, apps capable of handling the original
- * intent will be included in list of roots (in special section at bottom).
+ * @param handlerAppIntent When not null, apps capable of handling the original intent will
+ * be included in list of roots (in special section at bottom).
*/
public RootsAdapter(Context context, Collection<RootInfo> roots,
- @Nullable Intent handlerAppIntent, State state) {
+ @Nullable Intent handlerAppIntent, State state, OnDragListener dragListener) {
super(context, 0);
final List<RootItem> libraries = new ArrayList<>();
@@ -321,7 +609,8 @@ public class RootsFragment extends Fragment {
final RootItem item = new RootItem(root);
if (root.isHome() &&
- !Shared.shouldShowDocumentsRoot(context, ((Activity) context).getIntent())) {
+ !Shared.shouldShowDocumentsRoot(context,
+ ((Activity) context).getIntent())) {
continue;
} else if (root.isLibrary()) {
if (DEBUG) Log.d(TAG, "Adding " + root + " as library.");
@@ -347,11 +636,13 @@ public class RootsFragment extends Fragment {
if (handlerAppIntent != null) {
includeHandlerApps(context, handlerAppIntent);
}
+
+ mDragListener = dragListener;
}
/**
- * Adds apps capable of handling the original intent will be included
- * in list of roots (in special section at bottom).
+ * Adds apps capable of handling the original intent will be included in list of roots (in
+ * special section at bottom).
*/
private void includeHandlerApps(Context context, Intent handlerAppIntent) {
final PackageManager pm = context.getPackageManager();
@@ -374,9 +665,42 @@ public class RootsFragment extends Fragment {
}
@Override
+ public boolean hasStableIds() {
+ return true;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ // Ensure this method is only called in main thread because we don't have any
+ // concurrency protection.
+ assert(Looper.myLooper() == Looper.getMainLooper());
+
+ String stringId = getItem(position).mStringId;
+
+ long id;
+ if (sIdMap.containsKey(stringId)) {
+ id = sIdMap.get(stringId);
+ } else {
+ id = sNextAvailableId++;
+ sIdMap.put(stringId, id);
+ }
+
+ return id;
+ }
+
+ @Override
public View getView(int position, View convertView, ViewGroup parent) {
final Item item = getItem(position);
- return item.getView(convertView, parent);
+ final View view = item.getView(convertView, parent);
+
+ if (item.isDropTarget()) {
+ view.setTag(R.id.item_position_tag, position);
+ view.setOnDragListener(mDragListener);
+ } else {
+ view.setTag(R.id.item_position_tag, null);
+ view.setOnDragListener(null);
+ }
+ return view;
}
@Override
diff --git a/packages/DocumentsUI/src/com/android/documentsui/SearchViewManager.java b/packages/DocumentsUI/src/com/android/documentsui/SearchViewManager.java
index 11b8891b0b12..46a14e644b03 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/SearchViewManager.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/SearchViewManager.java
@@ -37,7 +37,7 @@ import com.android.documentsui.model.RootInfo;
/**
* Manages searching UI behavior.
*/
-final class SearchViewManager implements
+public class SearchViewManager implements
SearchView.OnCloseListener, OnQueryTextListener, OnClickListener, OnFocusChangeListener,
OnActionExpandListener {
@@ -46,7 +46,7 @@ final class SearchViewManager implements
void onSearchFinished();
}
- public static final String TAG = "SearchManger";
+ private static final String TAG = "SearchManager";
private SearchManagerListener mListener;
private boolean mSearchExpanded;
@@ -129,7 +129,7 @@ final class SearchViewManager implements
&& ((root.flags & Root.FLAG_SUPPORTS_SEARCH) != 0));
}
- void showMenu(boolean visible) {
+ protected void showMenu(boolean visible) {
if (mMenuItem == null) {
if (DEBUG) Log.d(TAG, "showMenu called before Search MenuItem installed.");
return;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Shared.java b/packages/DocumentsUI/src/com/android/documentsui/Shared.java
index 145637c6fafe..0cd568a72f94 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Shared.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Shared.java
@@ -21,22 +21,31 @@ import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
+import android.net.Uri;
+import android.os.Looper;
import android.provider.DocumentsContract;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.format.Time;
+import android.util.Log;
import android.view.WindowManager;
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.RootInfo;
+
+import java.io.FileNotFoundException;
import java.text.Collator;
import java.util.ArrayList;
import java.util.List;
+import javax.annotation.Nullable;
+
/** @hide */
public final class Shared {
public static final String TAG = "Documents";
- public static final boolean DEBUG = false;
+ public static final boolean DEBUG = true;
/** Intent action name to pick a copy destination. */
public static final String ACTION_PICK_COPY_DESTINATION =
@@ -108,7 +117,7 @@ public final class Shared {
/**
* Maximum number of items in a Binder transaction packet.
*/
- public static final int MAX_DOCS_IN_INTENT = 1000;
+ public static final int MAX_DOCS_IN_INTENT = 500;
private static final Collator sCollator;
@@ -213,4 +222,21 @@ public final class Shared {
return isProductivityMode(activity, intent)
|| intent.getBooleanExtra(DocumentsContract.EXTRA_FANCY_FEATURES, false);
}
+
+ public static void checkMainLoop() {
+ if (Looper.getMainLooper() != Looper.myLooper()) {
+ Log.e(TAG, "Calling from non-UI thread!");
+ }
+ }
+
+ public static @Nullable <T> T findView(Activity activity, int... resources) {
+ for (int id : resources) {
+ @SuppressWarnings("unchecked")
+ T r = (T) activity.findViewById(id);
+ if (r != null) {
+ return r;
+ }
+ }
+ return null;
+ }
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Snackbars.java b/packages/DocumentsUI/src/com/android/documentsui/Snackbars.java
index b4d79715d479..c3a82d779555 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Snackbars.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Snackbars.java
@@ -16,6 +16,7 @@
package com.android.documentsui;
+import android.annotation.StringRes;
import android.app.Activity;
import android.support.design.widget.Snackbar;
import android.view.View;
@@ -23,7 +24,28 @@ import android.view.View;
public final class Snackbars {
private Snackbars() {}
- public static final Snackbar makeSnackbar(Activity activity, int messageId, int duration) {
+ public static final void showDocumentsClipped(Activity activity, int docCount) {
+ String msg = Shared.getQuantityString(
+ activity, R.plurals.clipboard_files_clipped, docCount);
+ Snackbars.makeSnackbar(activity, msg, Snackbar.LENGTH_SHORT).show();
+ }
+
+ public static final void showMove(Activity activity, int docCount) {
+ CharSequence message = Shared.getQuantityString(activity, R.plurals.move_begin, docCount);
+ makeSnackbar(activity, message, Snackbar.LENGTH_SHORT).show();
+ }
+
+ public static final void showCopy(Activity activity, int docCount) {
+ CharSequence message = Shared.getQuantityString(activity, R.plurals.copy_begin, docCount);
+ makeSnackbar(activity, message, Snackbar.LENGTH_SHORT).show();
+ }
+
+ public static final void showPasteFailed(Activity activity) {
+ makeSnackbar(activity, R.string.clipboard_files_cannot_paste, Snackbar.LENGTH_SHORT).show();
+ }
+
+ public static final Snackbar makeSnackbar(Activity activity, @StringRes int messageId,
+ int duration) {
return Snackbars.makeSnackbar(
activity, activity.getResources().getText(messageId), duration);
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/State.java b/packages/DocumentsUI/src/com/android/documentsui/State.java
index f239eb45552b..9cdf1a804ced 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/State.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/State.java
@@ -25,7 +25,6 @@ import android.os.Parcelable;
import android.util.Log;
import android.util.SparseArray;
-import com.android.documentsui.dirlist.MultiSelectManager.Selection;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.DocumentStack;
import com.android.documentsui.model.DurableUtils;
@@ -123,9 +122,6 @@ public class State implements android.os.Parcelable {
/** Instance state for every shown directory */
public HashMap<String, SparseArray<Parcelable>> dirState = new HashMap<>();
- /** Currently copying file */
- public List<DocumentInfo> selectedDocumentsForCopy = new ArrayList<>();
-
/** Name of the package that started DocsUI */
public List<String> excludedAuthorities = new ArrayList<>();
@@ -199,7 +195,6 @@ public class State implements android.os.Parcelable {
out.writeInt(external ? 1 : 0);
DurableUtils.writeToParcel(out, stack);
out.writeMap(dirState);
- out.writeList(selectedDocumentsForCopy);
out.writeList(excludedAuthorities);
out.writeInt(openableOnly ? 1 : 0);
out.writeInt(mStackTouched ? 1 : 0);
@@ -229,7 +224,6 @@ public class State implements android.os.Parcelable {
state.external = in.readInt() != 0;
DurableUtils.readFromParcel(in, state.stack);
in.readMap(state.dirState, loader);
- in.readList(state.selectedDocumentsForCopy, loader);
in.readList(state.excludedAuthorities, loader);
state.openableOnly = in.readInt() != 0;
state.mStackTouched = in.readInt() != 0;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/ThumbnailCache.java b/packages/DocumentsUI/src/com/android/documentsui/ThumbnailCache.java
index ad7cbf697301..ecde685d29c4 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/ThumbnailCache.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/ThumbnailCache.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 The Android Open Source Project
+ * 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.
@@ -16,17 +16,277 @@
package com.android.documentsui;
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+import android.content.ComponentCallbacks2;
import android.graphics.Bitmap;
+import android.graphics.Point;
import android.net.Uri;
import android.util.LruCache;
+import android.util.Pair;
+import android.util.Pools;
-public class ThumbnailCache extends LruCache<Uri, Bitmap> {
- public ThumbnailCache(int maxSizeBytes) {
- super(maxSizeBytes);
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.TreeMap;
+
+/**
+ * An LRU cache that supports finding the thumbnail of the requested uri with a different size than
+ * the requested one.
+ */
+public class ThumbnailCache {
+
+ private static final SizeComparator SIZE_COMPARATOR = new SizeComparator();
+
+ /**
+ * A 2-dimensional index into {@link #mCache} entries. Pair<Uri, Point> is the key to
+ * {@link #mCache}. TreeMap is used to search the closest size to a given size and a given uri.
+ */
+ private final HashMap<Uri, TreeMap<Point, Pair<Uri, Point>>> mSizeIndex;
+ private final Cache mCache;
+
+ /**
+ * Creates a thumbnail LRU cache.
+ *
+ * @param maxCacheSizeInBytes the maximum size of thumbnails in bytes this cache can hold.
+ */
+ public ThumbnailCache(int maxCacheSizeInBytes) {
+ mSizeIndex = new HashMap<>();
+ mCache = new Cache(maxCacheSizeInBytes);
+ }
+
+ /**
+ * Obtains thumbnail given a uri and a size.
+ *
+ * @param uri the uri of the thumbnail in need
+ * @param size the desired size of the thumbnail
+ * @return the thumbnail result
+ */
+ public Result getThumbnail(Uri uri, Point size) {
+ TreeMap<Point, Pair<Uri, Point>> sizeMap;
+ sizeMap = mSizeIndex.get(uri);
+ if (sizeMap == null || sizeMap.isEmpty()) {
+ // There is not any thumbnail for this uri.
+ return Result.obtainMiss();
+ }
+
+ // Look for thumbnail of the same size.
+ Pair<Uri, Point> cacheKey = sizeMap.get(size);
+ if (cacheKey != null) {
+ Entry entry = mCache.get(cacheKey);
+ if (entry != null) {
+ return Result.obtain(Result.CACHE_HIT_EXACT, size, entry);
+ }
+ }
+
+ // Look for thumbnail of bigger sizes.
+ Point otherSize = sizeMap.higherKey(size);
+ if (otherSize != null) {
+ cacheKey = sizeMap.get(otherSize);
+
+ if (cacheKey != null) {
+ Entry entry = mCache.get(cacheKey);
+ if (entry != null) {
+ return Result.obtain(Result.CACHE_HIT_LARGER, otherSize, entry);
+ }
+ }
+ }
+
+ // Look for thumbnail of smaller sizes.
+ otherSize = sizeMap.lowerKey(size);
+ if (otherSize != null) {
+ cacheKey = sizeMap.get(otherSize);
+
+ if (cacheKey != null) {
+ Entry entry = mCache.get(cacheKey);
+ if (entry != null) {
+ return Result.obtain(Result.CACHE_HIT_SMALLER, otherSize, entry);
+ }
+ }
+ }
+
+ // Cache miss.
+ return Result.obtainMiss();
+ }
+
+ public void putThumbnail(Uri uri, Point size, Bitmap thumbnail, long lastModified) {
+ Pair<Uri, Point> cacheKey = Pair.create(uri, size);
+
+ TreeMap<Point, Pair<Uri, Point>> sizeMap;
+ synchronized (mSizeIndex) {
+ sizeMap = mSizeIndex.get(uri);
+ if (sizeMap == null) {
+ sizeMap = new TreeMap<>(SIZE_COMPARATOR);
+ mSizeIndex.put(uri, sizeMap);
+ }
+ }
+
+ Entry entry = new Entry(thumbnail, lastModified);
+ mCache.put(cacheKey, entry);
+ synchronized (sizeMap) {
+ sizeMap.put(size, cacheKey);
+ }
+ }
+
+ private void removeKey(Uri uri, Point size) {
+ TreeMap<Point, Pair<Uri, Point>> sizeMap;
+ synchronized (mSizeIndex) {
+ sizeMap = mSizeIndex.get(uri);
+ }
+
+ // LruCache tells us to remove a key, which should exist, so sizeMap can't be null.
+ assert (sizeMap != null);
+ synchronized (sizeMap) {
+ sizeMap.remove(size);
+ }
+ }
+
+ public void onTrimMemory(int level) {
+ if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {
+ mCache.evictAll();
+ } else if (level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) {
+ mCache.trimToSize(mCache.size() / 2);
+ }
+ }
+
+ /**
+ * A class that holds thumbnail and cache status.
+ */
+ public static final class Result {
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({CACHE_MISS, CACHE_HIT_EXACT, CACHE_HIT_SMALLER, CACHE_HIT_LARGER})
+ @interface Status {}
+ /**
+ * Indicates there is no thumbnail for the requested uri. The thumbnail will be null.
+ */
+ public static final int CACHE_MISS = 0;
+ /**
+ * Indicates the thumbnail matches the requested size and requested uri.
+ */
+ public static final int CACHE_HIT_EXACT = 1;
+ /**
+ * Indicates the thumbnail is in a smaller size than the requested one from the requested
+ * uri.
+ */
+ public static final int CACHE_HIT_SMALLER = 2;
+ /**
+ * Indicates the thumbnail is in a larger size than the requested one from the requested
+ * uri.
+ */
+ public static final int CACHE_HIT_LARGER = 3;
+
+ private static final Pools.SimplePool<Result> sPool = new Pools.SimplePool<>(1);
+
+ private @Status int mStatus;
+ private @Nullable Bitmap mThumbnail;
+ private @Nullable Point mSize;
+ private long mLastModified;
+
+ private static Result obtainMiss() {
+ return obtain(CACHE_MISS, null, null, 0);
+ }
+
+ private static Result obtain(@Status int status, Point size, Entry entry) {
+ return obtain(status, entry.mThumbnail, size, entry.mLastModified);
+ }
+
+ private static Result obtain(@Status int status, @Nullable Bitmap thumbnail,
+ @Nullable Point size, long lastModified) {
+ Shared.checkMainLoop();
+
+ Result instance = sPool.acquire();
+ instance = (instance != null ? instance : new Result());
+
+ instance.mStatus = status;
+ instance.mThumbnail = thumbnail;
+ instance.mSize = size;
+ instance.mLastModified = lastModified;
+
+ return instance;
+ }
+
+ private Result() {}
+
+ public void recycle() {
+ Shared.checkMainLoop();
+
+ mStatus = -1;
+ mThumbnail = null;
+ mSize = null;
+ mLastModified = -1;
+
+ boolean released = sPool.release(this);
+ // This assert is used to guarantee we won't generate too many instances that can't be
+ // held in the pool, which indicates our pool size is too small.
+ //
+ // Right now one instance is enough because we expect all instances are only used in
+ // main thread.
+ assert (released);
+ }
+
+ public @Status int getStatus() {
+ return mStatus;
+ }
+
+ public @Nullable Bitmap getThumbnail() {
+ return mThumbnail;
+ }
+
+ public @Nullable Point getSize() {
+ return mSize;
+ }
+
+ public long getLastModified() {
+ return mLastModified;
+ }
+
+ public boolean isHit() {
+ return (mStatus != CACHE_MISS);
+ }
+
+ public boolean isExactHit() {
+ return (mStatus == CACHE_HIT_EXACT);
+ }
+ }
+
+ private static final class Entry {
+ private final Bitmap mThumbnail;
+ private final long mLastModified;
+
+ private Entry(Bitmap thumbnail, long lastModified) {
+ mThumbnail = thumbnail;
+ mLastModified = lastModified;
+ }
+ }
+
+ private final class Cache extends LruCache<Pair<Uri, Point>, Entry> {
+
+ private Cache(int maxSizeBytes) {
+ super(maxSizeBytes);
+ }
+
+ @Override
+ protected int sizeOf(Pair<Uri, Point> key, Entry value) {
+ return value.mThumbnail.getByteCount();
+ }
+
+ @Override
+ protected void entryRemoved(
+ boolean evicted, Pair<Uri, Point> key, Entry oldValue, Entry newValue) {
+ if (newValue == null) {
+ removeKey(key.first, key.second);
+ }
+ }
}
- @Override
- protected int sizeOf(Uri key, Bitmap value) {
- return value.getByteCount();
+ private static final class SizeComparator implements Comparator<Point> {
+ @Override
+ public int compare(Point size0, Point size1) {
+ // Assume all sizes are roughly square, so we only compare them in one dimension.
+ return size0.x - size1.x;
+ }
}
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/clipping/ClipStorage.java b/packages/DocumentsUI/src/com/android/documentsui/clipping/ClipStorage.java
new file mode 100644
index 000000000000..49edbcf904d5
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/clipping/ClipStorage.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.clipping;
+
+import android.content.SharedPreferences;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.support.annotation.VisibleForTesting;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.util.Log;
+
+import com.android.documentsui.Files;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.channels.FileLock;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Provides support for storing lists of documents identified by Uri.
+ *
+ * This class uses a ring buffer to recycle clip file slots, to mitigate the issue of clip file
+ * deletions. Below is the directory layout:
+ * [cache dir]
+ * - [dir] 1
+ * - [dir] 2
+ * - ... to {@link #NUM_OF_SLOTS}
+ * When a clip data is actively being used:
+ * [cache dir]
+ * - [dir] 1
+ * - [file] primary
+ * - [symlink] 1 > primary # copying to location X
+ * - [symlink] 2 > primary # copying to location Y
+ */
+public final class ClipStorage {
+
+ public static final int NO_SELECTION_TAG = -1;
+
+ public static final String PREF_NAME = "ClipStoragePref";
+
+ @VisibleForTesting
+ static final int NUM_OF_SLOTS = 20;
+
+ private static final String TAG = "ClipStorage";
+
+ private static final long STALENESS_THRESHOLD = TimeUnit.DAYS.toMillis(2);
+
+ private static final String NEXT_POS_TAG = "NextPosTag";
+ private static final String PRIMARY_DATA_FILE_NAME = "primary";
+
+ private static final byte[] LINE_SEPARATOR = System.lineSeparator().getBytes();
+
+ private final File mOutDir;
+ private final SharedPreferences mPref;
+
+ private final File[] mSlots = new File[NUM_OF_SLOTS];
+ private int mNextPos;
+
+ /**
+ * @param outDir see {@link #prepareStorage(File)}.
+ */
+ public ClipStorage(File outDir, SharedPreferences pref) {
+ assert(outDir.isDirectory());
+ mOutDir = outDir;
+ mPref = pref;
+
+ mNextPos = mPref.getInt(NEXT_POS_TAG, 0);
+ }
+
+ /**
+ * Tries to get the next available clip slot. It's guaranteed to return one. If none of
+ * slots is available, it returns the next slot of the most recently returned slot by this
+ * method.
+ *
+ * <p>This is not a perfect solution, but should be enough for most regular use. There are
+ * several situations this method may not work:
+ * <ul>
+ * <li>Making {@link #NUM_OF_SLOTS} - 1 times of large drag and drop or moveTo/copyTo/delete
+ * operations after cutting a primary clip, then the primary clip is overwritten.</li>
+ * <li>Having more than {@link #NUM_OF_SLOTS} queued jumbo file operations, one or more clip
+ * file may be overwritten.</li>
+ * </ul>
+ */
+ synchronized int claimStorageSlot() {
+ int curPos = mNextPos;
+ for (int i = 0; i < NUM_OF_SLOTS; ++i, curPos = (curPos + 1) % NUM_OF_SLOTS) {
+ createSlotFileObject(curPos);
+
+ if (!mSlots[curPos].exists()) {
+ break;
+ }
+
+ // No file or only primary file exists, we deem it available.
+ if (mSlots[curPos].list().length <= 1) {
+ break;
+ }
+ // This slot doesn't seem available, but still need to check if it's a legacy of
+ // service being killed or a service crash etc. If it's stale, it's available.
+ else if (checkStaleFiles(curPos)) {
+ break;
+ }
+ }
+
+ prepareSlot(curPos);
+
+ mNextPos = (curPos + 1) % NUM_OF_SLOTS;
+ mPref.edit().putInt(NEXT_POS_TAG, mNextPos).commit();
+ return curPos;
+ }
+
+ private boolean checkStaleFiles(int pos) {
+ File slotData = toSlotDataFile(pos);
+
+ // No need to check if the file exists. File.lastModified() returns 0L if the file doesn't
+ // exist.
+ return slotData.lastModified() + STALENESS_THRESHOLD <= System.currentTimeMillis();
+ }
+
+ private void prepareSlot(int pos) {
+ assert(mSlots[pos] != null);
+
+ Files.deleteRecursively(mSlots[pos]);
+ mSlots[pos].mkdir();
+ assert(mSlots[pos].isDirectory());
+ }
+
+ /**
+ * Returns a writer. Callers must close the writer when finished.
+ */
+ private Writer createWriter(int tag) throws IOException {
+ File file = toSlotDataFile(tag);
+ return new Writer(file);
+ }
+
+ /**
+ * Gets a {@link File} instance given a tag.
+ *
+ * This method creates a symbolic link in the slot folder to the data file as a reference
+ * counting method. When someone is done using this symlink, it's responsible to delete it.
+ * Therefore we can have a neat way to track how many things are still using this slot.
+ */
+ public synchronized File getFile(int tag) throws IOException {
+ createSlotFileObject(tag);
+
+ File primary = toSlotDataFile(tag);
+
+ String linkFileName = Integer.toString(mSlots[tag].list().length);
+ File link = new File(mSlots[tag], linkFileName);
+
+ try {
+ Os.symlink(primary.getAbsolutePath(), link.getAbsolutePath());
+ } catch (ErrnoException e) {
+ e.rethrowAsIOException();
+ }
+ return link;
+ }
+
+ /**
+ * Returns a Reader. Callers must close the reader when finished.
+ */
+ ClipStorageReader createReader(File file) throws IOException {
+ assert(file.getParentFile().getParentFile().equals(mOutDir));
+ return new ClipStorageReader(file);
+ }
+
+ private File toSlotDataFile(int pos) {
+ assert(mSlots[pos] != null);
+ return new File(mSlots[pos], PRIMARY_DATA_FILE_NAME);
+ }
+
+ private void createSlotFileObject(int pos) {
+ if (mSlots[pos] == null) {
+ mSlots[pos] = new File(mOutDir, Integer.toString(pos));
+ }
+ }
+
+ /**
+ * Provides initialization of the clip data storage directory.
+ */
+ public static File prepareStorage(File cacheDir) {
+ File clipDir = getClipDir(cacheDir);
+ clipDir.mkdir();
+
+ assert(clipDir.isDirectory());
+ return clipDir;
+ }
+
+ private static File getClipDir(File cacheDir) {
+ return new File(cacheDir, "clippings");
+ }
+
+ private static final class Writer implements Closeable {
+
+ private final FileOutputStream mOut;
+ private final FileLock mLock;
+
+ private Writer(File file) throws IOException {
+ assert(!file.exists());
+
+ mOut = new FileOutputStream(file);
+
+ // Lock the file here so copy tasks would wait until everything is flushed to disk
+ // before start to run.
+ mLock = mOut.getChannel().lock();
+ }
+
+ public void write(Uri uri) throws IOException {
+ mOut.write(uri.toString().getBytes());
+ mOut.write(LINE_SEPARATOR);
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (mLock != null) {
+ mLock.release();
+ }
+
+ if (mOut != null) {
+ mOut.close();
+ }
+ }
+ }
+
+ /**
+ * An {@link AsyncTask} that persists doc uris in {@link ClipStorage}.
+ */
+ static final class PersistTask extends AsyncTask<Void, Void, Void> {
+
+ private final ClipStorage mClipStorage;
+ private final Iterable<Uri> mUris;
+ private final int mTag;
+
+ PersistTask(ClipStorage clipStorage, Iterable<Uri> uris, int tag) {
+ mClipStorage = clipStorage;
+ mUris = uris;
+ mTag = tag;
+ }
+
+ @Override
+ protected Void doInBackground(Void... params) {
+ try(Writer writer = mClipStorage.createWriter(mTag)){
+ for (Uri uri: mUris) {
+ assert(uri != null);
+ writer.write(uri);
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "Caught exception trying to write jumbo clip to disk.", e);
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/clipping/ClipStorageReader.java b/packages/DocumentsUI/src/com/android/documentsui/clipping/ClipStorageReader.java
new file mode 100644
index 000000000000..2bae0f8424ff
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/clipping/ClipStorageReader.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.clipping;
+
+import android.net.Uri;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.channels.FileLock;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Scanner;
+
+/**
+ * Reader class used to read uris from clip files stored in {@link ClipStorage}. It provides
+ * synchronization within a single process as an addition to {@link FileLock} which is for
+ * cross-process synchronization.
+ */
+class ClipStorageReader implements Iterable<Uri>, Closeable {
+
+ /**
+ * FileLock can't be held multiple times in a single JVM, but it's possible to have multiple
+ * readers reading the same clip file. Share the FileLock here so that it can be released
+ * when it's not needed.
+ */
+ private static final Map<String, FileLockEntry> sLocks = new HashMap<>();
+
+ private final String mCanonicalPath;
+ private final Scanner mScanner;
+
+ ClipStorageReader(File file) throws IOException {
+ FileInputStream inStream = new FileInputStream(file);
+ mScanner = new Scanner(inStream);
+
+ mCanonicalPath = file.getCanonicalPath(); // Resolve symlink
+ synchronized (sLocks) {
+ if (sLocks.containsKey(mCanonicalPath)) {
+ // Read lock is already held by someone in this JVM, just increment the ref
+ // count.
+ sLocks.get(mCanonicalPath).mCount++;
+ } else {
+ // No map entry, need to lock the file so it won't pass this line until the
+ // corresponding writer is done writing.
+ FileLock lock = inStream.getChannel().lock(0L, Long.MAX_VALUE, true);
+ sLocks.put(mCanonicalPath, new FileLockEntry(1, lock, mScanner));
+ }
+ }
+ }
+
+ @Override
+ public Iterator iterator() {
+ return new Iterator(mScanner);
+ }
+
+ @Override
+ public void close() throws IOException {
+ FileLockEntry ref;
+ synchronized (sLocks) {
+ ref = sLocks.get(mCanonicalPath);
+
+ assert(ref.mCount > 0);
+ if (--ref.mCount == 0) {
+ // If ref count is 0 now, then there is no one who needs to hold the read lock.
+ // Release the lock, and remove the entry.
+ ref.mLock.release();
+ ref.mScanner.close();
+ sLocks.remove(mCanonicalPath);
+ }
+ }
+
+ if (mScanner != ref.mScanner) {
+ mScanner.close();
+ }
+ }
+
+ private static final class Iterator implements java.util.Iterator {
+ private final Scanner mScanner;
+
+ private Iterator(Scanner scanner) {
+ mScanner = scanner;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return mScanner.hasNextLine();
+ }
+
+ @Override
+ public Uri next() {
+ String line = mScanner.nextLine();
+ return Uri.parse(line);
+ }
+ }
+
+ private static final class FileLockEntry {
+ private final FileLock mLock;
+ // We need to keep this scanner here because if the scanner is closed, the file lock is
+ // closed too.
+ private final Scanner mScanner;
+
+ private int mCount;
+
+ private FileLockEntry(int count, FileLock lock, Scanner scanner) {
+ mCount = count;
+ mLock = lock;
+ mScanner = scanner;
+ }
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/clipping/DocumentClipper.java b/packages/DocumentsUI/src/com/android/documentsui/clipping/DocumentClipper.java
new file mode 100644
index 000000000000..bdc1836f2688
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/clipping/DocumentClipper.java
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.clipping;
+
+import android.content.ClipData;
+import android.content.ClipDescription;
+import android.content.ClipboardManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.net.Uri;
+import android.os.PersistableBundle;
+import android.provider.DocumentsContract;
+import android.support.annotation.Nullable;
+import android.util.Log;
+
+import com.android.documentsui.Shared;
+import com.android.documentsui.dirlist.MultiSelectManager.Selection;
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.DocumentStack;
+import com.android.documentsui.model.RootInfo;
+import com.android.documentsui.services.FileOperation;
+import com.android.documentsui.services.FileOperationService;
+import com.android.documentsui.services.FileOperationService.OpType;
+import com.android.documentsui.services.FileOperations;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Function;
+
+/**
+ * ClipboardManager wrapper class providing higher level logical
+ * support for dealing with Documents.
+ */
+public final class DocumentClipper {
+
+ private static final String TAG = "DocumentClipper";
+
+ static final String SRC_PARENT_KEY = "srcParent";
+ static final String OP_TYPE_KEY = "opType";
+ static final String OP_JUMBO_SELECTION_SIZE = "jumboSelection-size";
+ static final String OP_JUMBO_SELECTION_TAG = "jumboSelection-tag";
+
+ private final Context mContext;
+ private final ClipStorage mClipStorage;
+ private final ClipboardManager mClipboard;
+
+ public DocumentClipper(Context context, ClipStorage storage) {
+ mContext = context;
+ mClipStorage = storage;
+ mClipboard = context.getSystemService(ClipboardManager.class);
+ }
+
+ public boolean hasItemsToPaste() {
+ if (mClipboard.hasPrimaryClip()) {
+ ClipData clipData = mClipboard.getPrimaryClip();
+
+ int count = clipData.getItemCount();
+ if (count > 0) {
+ for (int i = 0; i < count; ++i) {
+ ClipData.Item item = clipData.getItemAt(i);
+ Uri uri = item.getUri();
+ if (isDocumentUri(uri)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean isDocumentUri(@Nullable Uri uri) {
+ return uri != null && DocumentsContract.isDocumentUri(mContext, uri);
+ }
+
+ /**
+ * Returns {@link ClipData} representing the selection, or null if selection is empty,
+ * or cannot be converted.
+ */
+ public ClipData getClipDataForDocuments(
+ Function<String, Uri> uriBuilder, Selection selection, @OpType int opType) {
+
+ assert(selection != null);
+
+ if (selection.isEmpty()) {
+ Log.w(TAG, "Attempting to clip empty selection. Ignoring.");
+ return null;
+ }
+
+ return (selection.size() > Shared.MAX_DOCS_IN_INTENT)
+ ? createJumboClipData(uriBuilder, selection, opType)
+ : createStandardClipData(uriBuilder, selection, opType);
+ }
+
+ /**
+ * Returns ClipData representing the selection.
+ */
+ private ClipData createStandardClipData(
+ Function<String, Uri> uriBuilder, Selection selection, @OpType int opType) {
+
+ assert(!selection.isEmpty());
+ assert(selection.size() <= Shared.MAX_DOCS_IN_INTENT);
+
+ final ContentResolver resolver = mContext.getContentResolver();
+ final ArrayList<ClipData.Item> clipItems = new ArrayList<>();
+ final Set<String> clipTypes = new HashSet<>();
+
+ PersistableBundle bundle = new PersistableBundle();
+ bundle.putInt(OP_TYPE_KEY, opType);
+
+ for (String id : selection) {
+ assert(id != null);
+ Uri uri = uriBuilder.apply(id);
+ DocumentInfo.addMimeTypes(resolver, uri, clipTypes);
+ clipItems.add(new ClipData.Item(uri));
+ }
+
+ ClipDescription description = new ClipDescription(
+ "", // Currently "label" is not displayed anywhere in the UI.
+ clipTypes.toArray(new String[0]));
+ description.setExtras(bundle);
+
+ return new ClipData(description, clipItems);
+ }
+
+ /**
+ * Returns ClipData representing the list of docs
+ */
+ private ClipData createJumboClipData(
+ Function<String, Uri> uriBuilder, Selection selection, @OpType int opType) {
+
+ assert(!selection.isEmpty());
+ assert(selection.size() > Shared.MAX_DOCS_IN_INTENT);
+
+ final List<Uri> uris = new ArrayList<>(selection.size());
+
+ final int capacity = Math.min(selection.size(), Shared.MAX_DOCS_IN_INTENT);
+ final ArrayList<ClipData.Item> clipItems = new ArrayList<>(capacity);
+
+ // Set up mime types for the first Shared.MAX_DOCS_IN_INTENT
+ final ContentResolver resolver = mContext.getContentResolver();
+ final Set<String> clipTypes = new HashSet<>();
+ int docCount = 0;
+ for (String id : selection) {
+ assert(id != null);
+ Uri uri = uriBuilder.apply(id);
+ if (docCount++ < Shared.MAX_DOCS_IN_INTENT) {
+ DocumentInfo.addMimeTypes(resolver, uri, clipTypes);
+ clipItems.add(new ClipData.Item(uri));
+ }
+
+ uris.add(uri);
+ }
+
+ // Prepare metadata
+ PersistableBundle bundle = new PersistableBundle();
+ bundle.putInt(OP_TYPE_KEY, opType);
+ bundle.putInt(OP_JUMBO_SELECTION_SIZE, selection.size());
+
+ // Creates a clip tag
+ int tag = mClipStorage.claimStorageSlot();
+ bundle.putInt(OP_JUMBO_SELECTION_TAG, tag);
+
+ ClipDescription description = new ClipDescription(
+ "", // Currently "label" is not displayed anywhere in the UI.
+ clipTypes.toArray(new String[0]));
+ description.setExtras(bundle);
+
+ // Persists clip items
+ new ClipStorage.PersistTask(mClipStorage, uris, tag).execute();
+
+ return new ClipData(description, clipItems);
+ }
+
+ /**
+ * Puts {@code ClipData} in a primary clipboard, describing a copy operation
+ */
+ public void clipDocumentsForCopy(Function<String, Uri> uriBuilder, Selection selection) {
+ ClipData data =
+ getClipDataForDocuments(uriBuilder, selection, FileOperationService.OPERATION_COPY);
+ assert(data != null);
+
+ mClipboard.setPrimaryClip(data);
+ }
+
+ /**
+ * Puts {@Code ClipData} in a primary clipboard, describing a cut operation
+ */
+ public void clipDocumentsForCut(
+ Function<String, Uri> uriBuilder, Selection selection, DocumentInfo parent) {
+ assert(!selection.isEmpty());
+ assert(parent.derivedUri != null);
+
+ ClipData data = getClipDataForDocuments(uriBuilder, selection,
+ FileOperationService.OPERATION_MOVE);
+ assert(data != null);
+
+ PersistableBundle bundle = data.getDescription().getExtras();
+ bundle.putString(SRC_PARENT_KEY, parent.derivedUri.toString());
+
+ mClipboard.setPrimaryClip(data);
+ }
+
+ /**
+ * Copies documents from clipboard. It's the same as {@link #copyFromClipData} with clipData
+ * returned from {@link ClipboardManager#getPrimaryClip()}.
+ *
+ * @param destination destination document.
+ * @param docStack the document stack to the destination folder,
+ * @param callback callback to notify when operation finishes.
+ */
+ public void copyFromClipboard(
+ DocumentInfo destination,
+ DocumentStack docStack,
+ FileOperations.Callback callback) {
+
+ copyFromClipData(destination, docStack, mClipboard.getPrimaryClip(), callback);
+ }
+
+ /**
+ * Copied documents from given clip data to a root directory.
+ * @param root the root which root directory to copy to
+ * @param destination the root directory
+ * @param clipData the clipData to copy from
+ * @param callback callback to notify when operation finishes
+ */
+ public void copyFromClipData(
+ final RootInfo root,
+ final DocumentInfo destination,
+ final @Nullable ClipData clipData,
+ final FileOperations.Callback callback) {
+ DocumentStack dstStack = new DocumentStack(root, destination);
+ copyFromClipData(dstStack, clipData, callback);
+ }
+
+ /**
+ * Copies documents from given clip data to a folder.
+ *
+ * @param destination destination folder
+ * @param docStack the document stack to the destination folder (not including the destination
+ * folder)
+ * @param clipData the clipData to copy from
+ * @param callback callback to notify when operation finishes
+ */
+ public void copyFromClipData(
+ final DocumentInfo destination,
+ final DocumentStack docStack,
+ final @Nullable ClipData clipData,
+ final FileOperations.Callback callback) {
+
+ DocumentStack dstStack = new DocumentStack(docStack, destination);
+ copyFromClipData(dstStack, clipData, callback);
+ }
+
+ private void copyFromClipData(
+ final DocumentStack dstStack,
+ final @Nullable ClipData clipData,
+ final FileOperations.Callback callback) {
+
+ if (clipData == null) {
+ Log.i(TAG, "Received null clipData. Ignoring.");
+ return;
+ }
+
+ PersistableBundle bundle = clipData.getDescription().getExtras();
+ @OpType int opType = getOpType(bundle);
+ try {
+ if (!canCopy(dstStack.peek())) {
+ callback.onOperationResult(
+ FileOperations.Callback.STATUS_REJECTED, getOpType(clipData), 0);
+ return;
+ }
+
+ UrisSupplier uris = UrisSupplier.create(clipData, mContext);
+ if (uris.getItemCount() == 0) {
+ callback.onOperationResult(
+ FileOperations.Callback.STATUS_ACCEPTED, opType, 0);
+ return;
+ }
+
+ String srcParentString = bundle.getString(SRC_PARENT_KEY);
+ Uri srcParent = srcParentString == null ? null : Uri.parse(srcParentString);
+
+ FileOperation operation = new FileOperation.Builder()
+ .withOpType(opType)
+ .withSrcParent(srcParent)
+ .withDestination(dstStack)
+ .withSrcs(uris)
+ .build();
+
+ FileOperations.start(mContext, operation, callback);
+ } catch(IOException e) {
+ Log.e(TAG, "Cannot create uris supplier.", e);
+ callback.onOperationResult(FileOperations.Callback.STATUS_REJECTED, opType, 0);
+ return;
+ }
+ }
+
+ /**
+ * Returns true if the list of files can be copied to destination. Note that this
+ * is a policy check only. Currently the method does not attempt to verify
+ * available space or any other environmental aspects possibly resulting in
+ * failure to copy.
+ *
+ * @return true if the list of files can be copied to destination.
+ */
+ private static boolean canCopy(DocumentInfo dest) {
+ if (dest == null || !dest.isDirectory() || !dest.isCreateSupported()) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public static @OpType int getOpType(ClipData data) {
+ PersistableBundle bundle = data.getDescription().getExtras();
+ return getOpType(bundle);
+ }
+
+ private static @OpType int getOpType(PersistableBundle bundle) {
+ return bundle.getInt(OP_TYPE_KEY);
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/clipping/UrisSupplier.java b/packages/DocumentsUI/src/com/android/documentsui/clipping/UrisSupplier.java
new file mode 100644
index 000000000000..7b1ba3498da9
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/clipping/UrisSupplier.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.clipping;
+
+import static com.android.documentsui.clipping.DocumentClipper.OP_JUMBO_SELECTION_SIZE;
+import static com.android.documentsui.clipping.DocumentClipper.OP_JUMBO_SELECTION_TAG;
+
+import android.content.ClipData;
+import android.content.Context;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.PersistableBundle;
+import android.support.annotation.VisibleForTesting;
+import android.util.Log;
+
+import com.android.documentsui.DocumentsApplication;
+import com.android.documentsui.Shared;
+import com.android.documentsui.dirlist.MultiSelectManager.Selection;
+import com.android.documentsui.services.FileOperation;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Function;
+
+/**
+ * UrisSupplier provides doc uri list to {@link FileOperation}.
+ *
+ * <p>Under the hood it provides cross-process synchronization support such that its consumer doesn't
+ * need to explicitly synchronize its access.
+ */
+public abstract class UrisSupplier implements Parcelable {
+
+ public abstract int getItemCount();
+
+ /**
+ * Gets doc list. This may only be called once because it may read a file
+ * to get the list.
+ *
+ * @param context We need context to obtain {@link ClipStorage}. It can't be sent in a parcel.
+ */
+ public Iterable<Uri> getUris(Context context) throws IOException {
+ return getUris(DocumentsApplication.getClipStorage(context));
+ }
+
+ @VisibleForTesting
+ abstract Iterable<Uri> getUris(ClipStorage storage) throws IOException;
+
+ public void dispose() {}
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public static UrisSupplier create(ClipData clipData, Context context) throws IOException {
+ UrisSupplier uris;
+ PersistableBundle bundle = clipData.getDescription().getExtras();
+ if (bundle.containsKey(OP_JUMBO_SELECTION_TAG)) {
+ uris = new JumboUrisSupplier(clipData, context);
+ } else {
+ uris = new StandardUrisSupplier(clipData);
+ }
+
+ return uris;
+ }
+
+ public static UrisSupplier create(
+ Selection selection, Function<String, Uri> uriBuilder, Context context)
+ throws IOException {
+
+ ClipStorage storage = DocumentsApplication.getClipStorage(context);
+
+ List<Uri> uris = new ArrayList<>(selection.size());
+ for (String id : selection) {
+ uris.add(uriBuilder.apply(id));
+ }
+
+ return create(uris, storage);
+ }
+
+ @VisibleForTesting
+ static UrisSupplier create(List<Uri> uris, ClipStorage storage) throws IOException {
+ UrisSupplier urisSupplier = (uris.size() > Shared.MAX_DOCS_IN_INTENT)
+ ? new JumboUrisSupplier(uris, storage)
+ : new StandardUrisSupplier(uris);
+
+ return urisSupplier;
+ }
+
+ private static class JumboUrisSupplier extends UrisSupplier {
+ private static final String TAG = "JumboUrisSupplier";
+
+ private final File mFile;
+ private final int mSelectionSize;
+
+ private final transient AtomicReference<ClipStorageReader> mReader =
+ new AtomicReference<>();
+
+ private JumboUrisSupplier(ClipData clipData, Context context) throws IOException {
+ PersistableBundle bundle = clipData.getDescription().getExtras();
+ final int tag = bundle.getInt(OP_JUMBO_SELECTION_TAG, ClipStorage.NO_SELECTION_TAG);
+ assert(tag != ClipStorage.NO_SELECTION_TAG);
+ mFile = DocumentsApplication.getClipStorage(context).getFile(tag);
+ assert(mFile.exists());
+
+ mSelectionSize = bundle.getInt(OP_JUMBO_SELECTION_SIZE);
+ assert(mSelectionSize > Shared.MAX_DOCS_IN_INTENT);
+ }
+
+ private JumboUrisSupplier(Collection<Uri> uris, ClipStorage storage) throws IOException {
+ final int tag = storage.claimStorageSlot();
+ new ClipStorage.PersistTask(storage, uris, tag).execute();
+
+ // There is a tiny race condition here. A job may starts to read before persist task
+ // starts to write, but it has to beat an IPC and background task schedule, which is
+ // pretty rare. Creating a symlink doesn't need that file to exist, but we can't assert
+ // on its existence.
+ mFile = storage.getFile(tag);
+ mSelectionSize = uris.size();
+ }
+
+ @Override
+ public int getItemCount() {
+ return mSelectionSize;
+ }
+
+ @Override
+ Iterable<Uri> getUris(ClipStorage storage) throws IOException {
+ ClipStorageReader reader = mReader.getAndSet(storage.createReader(mFile));
+ if (reader != null) {
+ reader.close();
+ mReader.get().close();
+ throw new IllegalStateException("This method can only be called once.");
+ }
+
+ return mReader.get();
+ }
+
+ @Override
+ public void dispose() {
+ try {
+ ClipStorageReader reader = mReader.get();
+ if (reader != null) {
+ reader.close();
+ }
+ } catch (IOException e) {
+ Log.w(TAG, "Failed to close the reader.", e);
+ }
+
+ // mFile is a symlink to the actual data file. Delete the symlink here so that we know
+ // there is one fewer referrer that needs the data file. The actual data file will be
+ // cleaned up during file slot rotation. See ClipStorage for more details.
+ mFile.delete();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("JumboUrisSupplier{");
+ builder.append("file=").append(mFile.getAbsolutePath());
+ builder.append(", selectionSize=").append(mSelectionSize);
+ builder.append("}");
+ return builder.toString();
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mFile.getAbsolutePath());
+ dest.writeInt(mSelectionSize);
+ }
+
+ private JumboUrisSupplier(Parcel in) {
+ mFile = new File(in.readString());
+ mSelectionSize = in.readInt();
+ }
+
+ public static final Parcelable.Creator<JumboUrisSupplier> CREATOR =
+ new Parcelable.Creator<JumboUrisSupplier>() {
+
+ @Override
+ public JumboUrisSupplier createFromParcel(Parcel source) {
+ return new JumboUrisSupplier(source);
+ }
+
+ @Override
+ public JumboUrisSupplier[] newArray(int size) {
+ return new JumboUrisSupplier[size];
+ }
+ };
+ }
+
+ /**
+ * This class and its constructor is visible for testing to create test doubles of
+ * {@link UrisSupplier}.
+ */
+ @VisibleForTesting
+ public static class StandardUrisSupplier extends UrisSupplier {
+ private final List<Uri> mDocs;
+
+ private StandardUrisSupplier(ClipData clipData) {
+ mDocs = listDocs(clipData);
+ }
+
+ @VisibleForTesting
+ public StandardUrisSupplier(List<Uri> docs) {
+ mDocs = docs;
+ }
+
+ private List<Uri> listDocs(ClipData clipData) {
+ ArrayList<Uri> docs = new ArrayList<>(clipData.getItemCount());
+
+ for (int i = 0; i < clipData.getItemCount(); ++i) {
+ Uri uri = clipData.getItemAt(i).getUri();
+ assert(uri != null);
+ docs.add(uri);
+ }
+
+ return docs;
+ }
+
+ @Override
+ public int getItemCount() {
+ return mDocs.size();
+ }
+
+ @Override
+ Iterable<Uri> getUris(ClipStorage storage) {
+ return mDocs;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("StandardUrisSupplier{");
+ builder.append("docs=").append(mDocs.toString());
+ builder.append("}");
+ return builder.toString();
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeTypedList(mDocs);
+ }
+
+ private StandardUrisSupplier(Parcel in) {
+ mDocs = in.createTypedArrayList(Uri.CREATOR);
+ }
+
+ public static final Parcelable.Creator<StandardUrisSupplier> CREATOR =
+ new Parcelable.Creator<StandardUrisSupplier>() {
+
+ @Override
+ public StandardUrisSupplier createFromParcel(Parcel source) {
+ return new StandardUrisSupplier(source);
+ }
+
+ @Override
+ public StandardUrisSupplier[] newArray(int size) {
+ return new StandardUrisSupplier[size];
+ }
+ };
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/BandController.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/BandController.java
new file mode 100644
index 000000000000..8f520367e602
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/BandController.java
@@ -0,0 +1,1264 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.dirlist;
+
+import static com.android.documentsui.Shared.DEBUG;
+import static com.android.documentsui.dirlist.ModelBackedDocumentsAdapter.ITEM_TYPE_DIRECTORY;
+import static com.android.documentsui.dirlist.ModelBackedDocumentsAdapter.ITEM_TYPE_DOCUMENT;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.util.Log;
+import android.util.SparseArray;
+import android.util.SparseBooleanArray;
+import android.util.SparseIntArray;
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.android.documentsui.Events;
+import com.android.documentsui.Events.InputEvent;
+import com.android.documentsui.Events.MotionInputEvent;
+import com.android.documentsui.R;
+import com.android.documentsui.dirlist.MultiSelectManager.Selection;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Provides mouse driven band-select support when used in conjunction with {@link RecyclerView}
+ * and {@link MultiSelectManager}. This class is responsible for rendering the band select
+ * overlay and selecting overlaid items via MultiSelectManager.
+ */
+public class BandController extends RecyclerView.OnScrollListener {
+
+ private static final int NOT_SET = -1;
+
+ private static final String TAG = "BandController";
+
+ private final Runnable mModelBuilder;
+ private final SelectionEnvironment mEnvironment;
+ private final DocumentsAdapter mAdapter;
+ private final MultiSelectManager mSelectionManager;
+ private final Runnable mViewScroller = new ViewScroller();
+ private final GridModel.OnSelectionChangedListener mGridListener;
+
+ @Nullable private Rect mBounds;
+ @Nullable private Point mCurrentPosition;
+ @Nullable private Point mOrigin;
+ @Nullable private BandController.GridModel mModel;
+
+ // The time at which the current band selection-induced scroll began. If no scroll is in
+ // progress, the value is NOT_SET.
+ private long mScrollStartTime = NOT_SET;
+ private Selection mSelection;
+
+ public BandController(
+ final RecyclerView view,
+ DocumentsAdapter adapter,
+ MultiSelectManager selectionManager) {
+ this(new RuntimeSelectionEnvironment(view), adapter, selectionManager);
+
+ view.addOnItemTouchListener(
+ new RecyclerView.OnItemTouchListener() {
+ @Override
+ public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
+ try (MotionInputEvent event = MotionInputEvent.obtain(e, view)) {
+ return handleEvent(event);
+ }
+ }
+ @Override
+ public void onTouchEvent(RecyclerView rv, MotionEvent e) {
+ if (Events.isMouseEvent(e)) {
+ try (MotionInputEvent event = MotionInputEvent.obtain(e, view)) {
+ processInputEvent(event);
+ }
+ }
+ }
+ @Override
+ public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
+ });
+ }
+
+ private BandController(
+ SelectionEnvironment env,
+ DocumentsAdapter adapter,
+ MultiSelectManager selectionManager) {
+
+ selectionManager.bindContoller(this);
+
+ mEnvironment = env;
+ mAdapter = adapter;
+ mSelectionManager = selectionManager;
+
+ mEnvironment.addOnScrollListener(this);
+
+ mAdapter.registerAdapterDataObserver(
+ new RecyclerView.AdapterDataObserver() {
+ @Override
+ public void onChanged() {
+ if (isActive()) {
+ endBandSelect();
+ }
+ }
+
+ @Override
+ public void onItemRangeChanged(
+ int startPosition, int itemCount, Object payload) {
+ // No change in position. Ignoring.
+ }
+
+ @Override
+ public void onItemRangeInserted(int startPosition, int itemCount) {
+ if (isActive()) {
+ endBandSelect();
+ }
+ }
+
+ @Override
+ public void onItemRangeRemoved(int startPosition, int itemCount) {
+ assert(startPosition >= 0);
+ assert(itemCount > 0);
+
+ // TODO: Should update grid model.
+ }
+
+ @Override
+ public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
+ throw new UnsupportedOperationException();
+ }
+ });
+
+ mGridListener = new GridModel.OnSelectionChangedListener() {
+
+ @Override
+ public void onSelectionChanged(Set<String> updatedSelection) {
+ BandController.this.onSelectionChanged(updatedSelection);
+ }
+
+ @Override
+ public boolean onBeforeItemStateChange(String id, boolean nextState) {
+ return BandController.this.onBeforeItemStateChange(id, nextState);
+ }
+ };
+
+ mModelBuilder = new Runnable() {
+ @Override
+ public void run() {
+ mModel = new GridModel(mEnvironment, mAdapter);
+ mModel.addOnSelectionChangedListener(mGridListener);
+ }
+ };
+ }
+
+ void bindSelection(Selection selection) {
+ mSelection = selection;
+ }
+
+ private boolean handleEvent(MotionInputEvent e) {
+ // Don't start, or extend bands on right click.
+ if (e.isSecondaryButtonPressed()) {
+ return false;
+ }
+
+ if (!e.isMouseEvent() && isActive()) {
+ // Weird things happen if we keep up band select
+ // when touch events happen.
+ endBandSelect();
+ return false;
+ }
+
+ // b/23793622 notes the fact that we *never* receive ACTION_DOWN
+ // events in onTouchEvent. Where it not for this issue, we'd
+ // push start handling down into handleInputEvent.
+ if (shouldStart(e)) {
+ // endBandSelect is handled in handleInputEvent.
+ startBandSelect(e.getOrigin());
+ } else if (isActive() && e.isActionUp()) {
+ // Same issue here w b/23793622. The ACTION_UP event
+ // is only evert dispatched to onTouchEvent when
+ // there is some associated motion. If a user taps
+ // mouse, but doesn't move, then band select gets
+ // started BUT not ended. Causing phantom
+ // bands to appear when the user later clicks to start
+ // band select.
+ if (e.isMouseEvent()) {
+ processInputEvent(e);
+ }
+ }
+
+ return isActive();
+ }
+
+ private boolean isActive() {
+ return mModel != null;
+ }
+
+ /**
+ * Handle a change in layout by cleaning up and getting rid of the old model and creating
+ * a new model which will track the new layout.
+ */
+ public void handleLayoutChanged() {
+ if (mModel != null) {
+ mModel.removeOnSelectionChangedListener(mGridListener);
+ mModel.stopListening();
+
+ // build a new model, all fresh and happy.
+ mModelBuilder.run();
+ }
+ }
+
+ boolean shouldStart(MotionInputEvent e) {
+ return !isActive()
+ && e.isActionDown() // the initial button press
+ && mAdapter.getItemCount() > 0
+ && e.getItemPosition() == RecyclerView.NO_ID; // in empty space
+ }
+
+ boolean shouldStop(InputEvent input) {
+ return isActive()
+ && input.isMouseEvent()
+ && input.isActionUp();
+ }
+
+ /**
+ * Processes a MotionEvent by starting, ending, or resizing the band select overlay.
+ * @param input
+ */
+ private void processInputEvent(InputEvent input) {
+ assert(input.isMouseEvent());
+
+ if (shouldStop(input)) {
+ endBandSelect();
+ return;
+ }
+
+ // We shouldn't get any events in this method when band select is not active,
+ // but it turns some guests show up late to the party.
+ if (!isActive()) {
+ return;
+ }
+
+ mCurrentPosition = input.getOrigin();
+ mModel.resizeSelection(input.getOrigin());
+ scrollViewIfNecessary();
+ resizeBandSelectRectangle();
+ }
+
+ /**
+ * Starts band select by adding the drawable to the RecyclerView's overlay.
+ */
+ private void startBandSelect(Point origin) {
+ if (DEBUG) Log.d(TAG, "Starting band select @ " + origin);
+
+ mOrigin = origin;
+ mModelBuilder.run(); // Creates a new selection model.
+ mModel.startSelection(mOrigin);
+ }
+
+ /**
+ * Scrolls the view if necessary.
+ */
+ private void scrollViewIfNecessary() {
+ mEnvironment.removeCallback(mViewScroller);
+ mViewScroller.run();
+ mEnvironment.invalidateView();
+ }
+
+ /**
+ * Resizes the band select rectangle by using the origin and the current pointer position as
+ * two opposite corners of the selection.
+ */
+ private void resizeBandSelectRectangle() {
+ mBounds = new Rect(Math.min(mOrigin.x, mCurrentPosition.x),
+ Math.min(mOrigin.y, mCurrentPosition.y),
+ Math.max(mOrigin.x, mCurrentPosition.x),
+ Math.max(mOrigin.y, mCurrentPosition.y));
+ mEnvironment.showBand(mBounds);
+ }
+
+ /**
+ * Ends band select by removing the overlay.
+ */
+ private void endBandSelect() {
+ if (DEBUG) Log.d(TAG, "Ending band select.");
+
+ mEnvironment.hideBand();
+ mSelection.applyProvisionalSelection();
+ mModel.endSelection();
+ int firstSelected = mModel.getPositionNearestOrigin();
+ if (firstSelected != NOT_SET) {
+ if (mSelection.contains(mAdapter.getModelId(firstSelected))) {
+ // TODO: firstSelected should really be lastSelected, we want to anchor the item
+ // where the mouse-up occurred.
+ mSelectionManager.setSelectionRangeBegin(firstSelected);
+ } else {
+ // TODO: Check if this is really happening.
+ Log.w(TAG, "First selected by band is NOT in selection!");
+ }
+ }
+
+ mModel = null;
+ mOrigin = null;
+ }
+
+ private void onSelectionChanged(Set<String> updatedSelection) {
+ Map<String, Boolean> delta = mSelection.setProvisionalSelection(updatedSelection);
+ for (Map.Entry<String, Boolean> entry: delta.entrySet()) {
+ mSelectionManager.notifyItemStateChanged(entry.getKey(), entry.getValue());
+ }
+ mSelectionManager.notifySelectionChanged();
+ }
+
+ private boolean onBeforeItemStateChange(String id, boolean nextState) {
+ return mSelectionManager.notifyBeforeItemStateChange(id, nextState);
+ }
+
+ private class ViewScroller implements Runnable {
+ /**
+ * The number of milliseconds of scrolling at which scroll speed continues to increase.
+ * At first, the scroll starts slowly; then, the rate of scrolling increases until it
+ * reaches its maximum value at after this many milliseconds.
+ */
+ private static final long SCROLL_ACCELERATION_LIMIT_TIME_MS = 2000;
+
+ @Override
+ public void run() {
+ // Compute the number of pixels the pointer's y-coordinate is past the view.
+ // Negative values mean the pointer is at or before the top of the view, and
+ // positive values mean that the pointer is at or after the bottom of the view. Note
+ // that one additional pixel is added here so that the view still scrolls when the
+ // pointer is exactly at the top or bottom.
+ int pixelsPastView = 0;
+ if (mCurrentPosition.y <= 0) {
+ pixelsPastView = mCurrentPosition.y - 1;
+ } else if (mCurrentPosition.y >= mEnvironment.getHeight() - 1) {
+ pixelsPastView = mCurrentPosition.y - mEnvironment.getHeight() + 1;
+ }
+
+ if (!isActive() || pixelsPastView == 0) {
+ // If band selection is inactive, or if it is active but not at the edge of the
+ // view, no scrolling is necessary.
+ mScrollStartTime = NOT_SET;
+ return;
+ }
+
+ if (mScrollStartTime == NOT_SET) {
+ // If the pointer was previously not at the edge of the view but now is, set the
+ // start time for the scroll.
+ mScrollStartTime = System.currentTimeMillis();
+ }
+
+ // Compute the number of pixels to scroll, and scroll that many pixels.
+ final int numPixels = computeScrollDistance(
+ pixelsPastView, System.currentTimeMillis() - mScrollStartTime);
+ mEnvironment.scrollBy(numPixels);
+
+ mEnvironment.removeCallback(mViewScroller);
+ mEnvironment.runAtNextFrame(this);
+ }
+
+ /**
+ * Computes the number of pixels to scroll based on how far the pointer is past the end
+ * of the view and how long it has been there. Roughly based on ItemTouchHelper's
+ * algorithm for computing the number of pixels to scroll when an item is dragged to the
+ * end of a {@link RecyclerView}.
+ * @param pixelsPastView
+ * @param scrollDuration
+ * @return
+ */
+ private int computeScrollDistance(int pixelsPastView, long scrollDuration) {
+ final int maxScrollStep = mEnvironment.getHeight();
+ final int direction = (int) Math.signum(pixelsPastView);
+ final int absPastView = Math.abs(pixelsPastView);
+
+ // Calculate the ratio of how far out of the view the pointer currently resides to
+ // the entire height of the view.
+ final float outOfBoundsRatio = Math.min(
+ 1.0f, (float) absPastView / mEnvironment.getHeight());
+ // Interpolate this ratio and use it to compute the maximum scroll that should be
+ // possible for this step.
+ final float cappedScrollStep =
+ direction * maxScrollStep * smoothOutOfBoundsRatio(outOfBoundsRatio);
+
+ // Likewise, calculate the ratio of the time spent in the scroll to the limit.
+ final float timeRatio = Math.min(
+ 1.0f, (float) scrollDuration / SCROLL_ACCELERATION_LIMIT_TIME_MS);
+ // Interpolate this ratio and use it to compute the final number of pixels to
+ // scroll.
+ final int numPixels = (int) (cappedScrollStep * smoothTimeRatio(timeRatio));
+
+ // If the final number of pixels to scroll ends up being 0, the view should still
+ // scroll at least one pixel.
+ return numPixels != 0 ? numPixels : direction;
+ }
+
+ /**
+ * Interpolates the given out of bounds ratio on a curve which starts at (0,0) and ends
+ * at (1,1) and quickly approaches 1 near the start of that interval. This ensures that
+ * drags that are at the edge or barely past the edge of the view still cause sufficient
+ * scrolling. The equation y=(x-1)^5+1 is used, but this could also be tweaked if
+ * needed.
+ * @param ratio A ratio which is in the range [0, 1].
+ * @return A "smoothed" value, also in the range [0, 1].
+ */
+ private float smoothOutOfBoundsRatio(float ratio) {
+ return (float) Math.pow(ratio - 1.0f, 5) + 1.0f;
+ }
+
+ /**
+ * Interpolates the given time ratio on a curve which starts at (0,0) and ends at (1,1)
+ * and stays close to 0 for most input values except those very close to 1. This ensures
+ * that scrolls start out very slowly but speed up drastically after the scroll has been
+ * in progress close to SCROLL_ACCELERATION_LIMIT_TIME_MS. The equation y=x^5 is used,
+ * but this could also be tweaked if needed.
+ * @param ratio A ratio which is in the range [0, 1].
+ * @return A "smoothed" value, also in the range [0, 1].
+ */
+ private float smoothTimeRatio(float ratio) {
+ return (float) Math.pow(ratio, 5);
+ }
+ };
+
+ @Override
+ public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+ if (!isActive()) {
+ return;
+ }
+
+ // Adjust the y-coordinate of the origin the opposite number of pixels so that the
+ // origin remains in the same place relative to the view's items.
+ mOrigin.y -= dy;
+ resizeBandSelectRectangle();
+ }
+
+ /**
+ * Provides a band selection item model for views within a RecyclerView. This class queries the
+ * RecyclerView to determine where its items are placed; then, once band selection is underway,
+ * it alerts listeners of which items are covered by the selections.
+ */
+ @VisibleForTesting
+ static final class GridModel extends RecyclerView.OnScrollListener {
+
+ public static final int NOT_SET = -1;
+
+ // Enum values used to determine the corner at which the origin is located within the
+ private static final int UPPER = 0x00;
+ private static final int LOWER = 0x01;
+ private static final int LEFT = 0x00;
+ private static final int RIGHT = 0x02;
+ private static final int UPPER_LEFT = UPPER | LEFT;
+ private static final int UPPER_RIGHT = UPPER | RIGHT;
+ private static final int LOWER_LEFT = LOWER | LEFT;
+ private static final int LOWER_RIGHT = LOWER | RIGHT;
+
+ private final SelectionEnvironment mHelper;
+ private final DocumentsAdapter mAdapter;
+
+ private final List<GridModel.OnSelectionChangedListener> mOnSelectionChangedListeners =
+ new ArrayList<>();
+
+ // Map from the x-value of the left side of a SparseBooleanArray of adapter positions, keyed
+ // by their y-offset. For example, if the first column of the view starts at an x-value of 5,
+ // mColumns.get(5) would return an array of positions in that column. Within that array, the
+ // value for key y is the adapter position for the item whose y-offset is y.
+ private final SparseArray<SparseIntArray> mColumns = new SparseArray<>();
+
+ // List of limits along the x-axis (columns).
+ // This list is sorted from furthest left to furthest right.
+ private final List<GridModel.Limits> mColumnBounds = new ArrayList<>();
+
+ // List of limits along the y-axis (rows). Note that this list only contains items which
+ // have been in the viewport.
+ private final List<GridModel.Limits> mRowBounds = new ArrayList<>();
+
+ // The adapter positions which have been recorded so far.
+ private final SparseBooleanArray mKnownPositions = new SparseBooleanArray();
+
+ // Array passed to registered OnSelectionChangedListeners. One array is created and reused
+ // throughout the lifetime of the object.
+ private final Set<String> mSelection = new HashSet<>();
+
+ // The current pointer (in absolute positioning from the top of the view).
+ private Point mPointer = null;
+
+ // The bounds of the band selection.
+ private RelativePoint mRelativeOrigin;
+ private RelativePoint mRelativePointer;
+
+ private boolean mIsActive;
+
+ // Tracks where the band select originated from. This is used to determine where selections
+ // should expand from when Shift+click is used.
+ private int mPositionNearestOrigin = NOT_SET;
+
+ GridModel(SelectionEnvironment helper, DocumentsAdapter adapter) {
+ mHelper = helper;
+ mAdapter = adapter;
+ mHelper.addOnScrollListener(this);
+ }
+
+ /**
+ * Stops listening to the view's scrolls. Call this function before discarding a
+ * BandSelecModel object to prevent memory leaks.
+ */
+ void stopListening() {
+ mHelper.removeOnScrollListener(this);
+ }
+
+ /**
+ * Start a band select operation at the given point.
+ * @param relativeOrigin The origin of the band select operation, relative to the viewport.
+ * For example, if the view is scrolled to the bottom, the top-left of the viewport
+ * would have a relative origin of (0, 0), even though its absolute point has a higher
+ * y-value.
+ */
+ void startSelection(Point relativeOrigin) {
+ recordVisibleChildren();
+ if (isEmpty()) {
+ // The selection band logic works only if there is at least one visible child.
+ return;
+ }
+
+ mIsActive = true;
+ mPointer = mHelper.createAbsolutePoint(relativeOrigin);
+ mRelativeOrigin = new RelativePoint(mPointer);
+ mRelativePointer = new RelativePoint(mPointer);
+ computeCurrentSelection();
+ notifyListeners();
+ }
+
+ /**
+ * Resizes the selection by adjusting the pointer (i.e., the corner of the selection
+ * opposite the origin.
+ * @param relativePointer The pointer (opposite of the origin) of the band select operation,
+ * relative to the viewport. For example, if the view is scrolled to the bottom, the
+ * top-left of the viewport would have a relative origin of (0, 0), even though its
+ * absolute point has a higher y-value.
+ */
+ @VisibleForTesting
+ void resizeSelection(Point relativePointer) {
+ mPointer = mHelper.createAbsolutePoint(relativePointer);
+ updateModel();
+ }
+
+ /**
+ * Ends the band selection.
+ */
+ void endSelection() {
+ mIsActive = false;
+ }
+
+ /**
+ * @return The adapter position for the item nearest the origin corresponding to the latest
+ * band select operation, or NOT_SET if the selection did not cover any items.
+ */
+ int getPositionNearestOrigin() {
+ return mPositionNearestOrigin;
+ }
+
+ @Override
+ public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+ if (!mIsActive) {
+ return;
+ }
+
+ mPointer.x += dx;
+ mPointer.y += dy;
+ recordVisibleChildren();
+ updateModel();
+ }
+
+ /**
+ * Queries the view for all children and records their location metadata.
+ */
+ private void recordVisibleChildren() {
+ for (int i = 0; i < mHelper.getVisibleChildCount(); i++) {
+ int adapterPosition = mHelper.getAdapterPositionAt(i);
+ // Sometimes the view is not attached, as we notify the multi selection manager
+ // synchronously, while views are attached asynchronously. As a result items which
+ // are in the adapter may not actually have a corresponding view (yet).
+ if (mHelper.hasView(adapterPosition) &&
+ !mHelper.isLayoutItem(adapterPosition) &&
+ !mKnownPositions.get(adapterPosition)) {
+ mKnownPositions.put(adapterPosition, true);
+ recordItemData(mHelper.getAbsoluteRectForChildViewAt(i), adapterPosition);
+ }
+ }
+ }
+
+ /**
+ * Checks if there are any recorded children.
+ */
+ private boolean isEmpty() {
+ return mColumnBounds.size() == 0 || mRowBounds.size() == 0;
+ }
+
+ /**
+ * Updates the limits lists and column map with the given item metadata.
+ * @param absoluteChildRect The absolute rectangle for the child view being processed.
+ * @param adapterPosition The position of the child view being processed.
+ */
+ private void recordItemData(Rect absoluteChildRect, int adapterPosition) {
+ if (mColumnBounds.size() != mHelper.getColumnCount()) {
+ // If not all x-limits have been recorded, record this one.
+ recordLimits(
+ mColumnBounds, new Limits(absoluteChildRect.left, absoluteChildRect.right));
+ }
+
+ recordLimits(mRowBounds, new Limits(absoluteChildRect.top, absoluteChildRect.bottom));
+
+ SparseIntArray columnList = mColumns.get(absoluteChildRect.left);
+ if (columnList == null) {
+ columnList = new SparseIntArray();
+ mColumns.put(absoluteChildRect.left, columnList);
+ }
+ columnList.put(absoluteChildRect.top, adapterPosition);
+ }
+
+ /**
+ * Ensures limits exists within the sorted list limitsList, and adds it to the list if it
+ * does not exist.
+ */
+ private void recordLimits(List<GridModel.Limits> limitsList, GridModel.Limits limits) {
+ int index = Collections.binarySearch(limitsList, limits);
+ if (index < 0) {
+ limitsList.add(~index, limits);
+ }
+ }
+
+ /**
+ * Handles a moved pointer; this function determines whether the pointer movement resulted
+ * in a selection change and, if it has, notifies listeners of this change.
+ */
+ private void updateModel() {
+ RelativePoint old = mRelativePointer;
+ mRelativePointer = new RelativePoint(mPointer);
+ if (old != null && mRelativePointer.equals(old)) {
+ return;
+ }
+
+ computeCurrentSelection();
+ notifyListeners();
+ }
+
+ /**
+ * Computes the currently-selected items.
+ */
+ private void computeCurrentSelection() {
+ if (areItemsCoveredByBand(mRelativePointer, mRelativeOrigin)) {
+ updateSelection(computeBounds());
+ } else {
+ mSelection.clear();
+ mPositionNearestOrigin = NOT_SET;
+ }
+ }
+
+ /**
+ * Notifies all listeners of a selection change. Note that this function simply passes
+ * mSelection, so computeCurrentSelection() should be called before this
+ * function.
+ */
+ private void notifyListeners() {
+ for (GridModel.OnSelectionChangedListener listener : mOnSelectionChangedListeners) {
+ listener.onSelectionChanged(mSelection);
+ }
+ }
+
+ /**
+ * @param rect Rectangle including all covered items.
+ */
+ private void updateSelection(Rect rect) {
+ int columnStart =
+ Collections.binarySearch(mColumnBounds, new Limits(rect.left, rect.left));
+ assert(columnStart >= 0);
+ int columnEnd = columnStart;
+
+ for (int i = columnStart; i < mColumnBounds.size()
+ && mColumnBounds.get(i).lowerLimit <= rect.right; i++) {
+ columnEnd = i;
+ }
+
+ int rowStart = Collections.binarySearch(mRowBounds, new Limits(rect.top, rect.top));
+ if (rowStart < 0) {
+ mPositionNearestOrigin = NOT_SET;
+ return;
+ }
+
+ int rowEnd = rowStart;
+ for (int i = rowStart; i < mRowBounds.size()
+ && mRowBounds.get(i).lowerLimit <= rect.bottom; i++) {
+ rowEnd = i;
+ }
+
+ updateSelection(columnStart, columnEnd, rowStart, rowEnd);
+ }
+
+ /**
+ * Computes the selection given the previously-computed start- and end-indices for each
+ * row and column.
+ */
+ private void updateSelection(
+ int columnStartIndex, int columnEndIndex, int rowStartIndex, int rowEndIndex) {
+ if (DEBUG) Log.d(TAG, String.format("updateSelection: %d, %d, %d, %d",
+ columnStartIndex, columnEndIndex, rowStartIndex, rowEndIndex));
+
+ mSelection.clear();
+ for (int column = columnStartIndex; column <= columnEndIndex; column++) {
+ SparseIntArray items = mColumns.get(mColumnBounds.get(column).lowerLimit);
+ for (int row = rowStartIndex; row <= rowEndIndex; row++) {
+ // The default return value for SparseIntArray.get is 0, which is a valid
+ // position. Use a sentry value to prevent erroneously selecting item 0.
+ final int rowKey = mRowBounds.get(row).lowerLimit;
+ int position = items.get(rowKey, NOT_SET);
+ if (position != NOT_SET) {
+ String id = mAdapter.getModelId(position);
+ if (id != null) {
+ // The adapter inserts items for UI layout purposes that aren't associated
+ // with files. Those will have a null model ID. Don't select them.
+ if (canSelect(id)) {
+ mSelection.add(id);
+ }
+ }
+ if (isPossiblePositionNearestOrigin(column, columnStartIndex, columnEndIndex,
+ row, rowStartIndex, rowEndIndex)) {
+ // If this is the position nearest the origin, record it now so that it
+ // can be returned by endSelection() later.
+ mPositionNearestOrigin = position;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @return True if the item is selectable.
+ */
+ private boolean canSelect(String id) {
+ // TODO: Simplify the logic, so the check whether we can select is done in one place.
+ // Consider injecting FragmentTuner, or move the checks from MultiSelectManager to
+ // Selection.
+ for (GridModel.OnSelectionChangedListener listener : mOnSelectionChangedListeners) {
+ if (!listener.onBeforeItemStateChange(id, true)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @return Returns true if the position is the nearest to the origin, or, in the case of the
+ * lower-right corner, whether it is possible that the position is the nearest to the
+ * origin. See comment below for reasoning for this special case.
+ */
+ private boolean isPossiblePositionNearestOrigin(int columnIndex, int columnStartIndex,
+ int columnEndIndex, int rowIndex, int rowStartIndex, int rowEndIndex) {
+ int corner = computeCornerNearestOrigin();
+ switch (corner) {
+ case UPPER_LEFT:
+ return columnIndex == columnStartIndex && rowIndex == rowStartIndex;
+ case UPPER_RIGHT:
+ return columnIndex == columnEndIndex && rowIndex == rowStartIndex;
+ case LOWER_LEFT:
+ return columnIndex == columnStartIndex && rowIndex == rowEndIndex;
+ case LOWER_RIGHT:
+ // Note that in some cases, the last row will not have as many items as there
+ // are columns (e.g., if there are 4 items and 3 columns, the second row will
+ // only have one item in the first column). This function is invoked for each
+ // position from left to right, so return true for any position in the bottom
+ // row and only the right-most position in the bottom row will be recorded.
+ return rowIndex == rowEndIndex;
+ default:
+ throw new RuntimeException("Invalid corner type.");
+ }
+ }
+
+ /**
+ * Listener for changes in which items have been band selected.
+ */
+ static interface OnSelectionChangedListener {
+ public void onSelectionChanged(Set<String> updatedSelection);
+ public boolean onBeforeItemStateChange(String id, boolean nextState);
+ }
+
+ void addOnSelectionChangedListener(GridModel.OnSelectionChangedListener listener) {
+ mOnSelectionChangedListeners.add(listener);
+ }
+
+ void removeOnSelectionChangedListener(GridModel.OnSelectionChangedListener listener) {
+ mOnSelectionChangedListeners.remove(listener);
+ }
+
+ /**
+ * Limits of a view item. For example, if an item's left side is at x-value 5 and its right side
+ * is at x-value 10, the limits would be from 5 to 10. Used to record the left- and right sides
+ * of item columns and the top- and bottom sides of item rows so that it can be determined
+ * whether the pointer is located within the bounds of an item.
+ */
+ private static class Limits implements Comparable<GridModel.Limits> {
+ int lowerLimit;
+ int upperLimit;
+
+ Limits(int lowerLimit, int upperLimit) {
+ this.lowerLimit = lowerLimit;
+ this.upperLimit = upperLimit;
+ }
+
+ @Override
+ public int compareTo(GridModel.Limits other) {
+ return lowerLimit - other.lowerLimit;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof GridModel.Limits)) {
+ return false;
+ }
+
+ return ((GridModel.Limits) other).lowerLimit == lowerLimit &&
+ ((GridModel.Limits) other).upperLimit == upperLimit;
+ }
+
+ @Override
+ public String toString() {
+ return "(" + lowerLimit + ", " + upperLimit + ")";
+ }
+ }
+
+ /**
+ * The location of a coordinate relative to items. This class represents a general area of the
+ * view as it relates to band selection rather than an explicit point. For example, two
+ * different points within an item are considered to have the same "location" because band
+ * selection originating within the item would select the same items no matter which point
+ * was used. Same goes for points between items as well as those at the very beginning or end
+ * of the view.
+ *
+ * Tracking a coordinate (e.g., an x-value) as a CoordinateLocation instead of as an int has the
+ * advantage of tying the value to the Limits of items along that axis. This allows easy
+ * selection of items within those Limits as opposed to a search through every item to see if a
+ * given coordinate value falls within those Limits.
+ */
+ private static class RelativeCoordinate
+ implements Comparable<GridModel.RelativeCoordinate> {
+ /**
+ * Location describing points after the last known item.
+ */
+ static final int AFTER_LAST_ITEM = 0;
+
+ /**
+ * Location describing points before the first known item.
+ */
+ static final int BEFORE_FIRST_ITEM = 1;
+
+ /**
+ * Location describing points between two items.
+ */
+ static final int BETWEEN_TWO_ITEMS = 2;
+
+ /**
+ * Location describing points within the limits of one item.
+ */
+ static final int WITHIN_LIMITS = 3;
+
+ /**
+ * The type of this coordinate, which is one of AFTER_LAST_ITEM, BEFORE_FIRST_ITEM,
+ * BETWEEN_TWO_ITEMS, or WITHIN_LIMITS.
+ */
+ final int type;
+
+ /**
+ * The limits before the coordinate; only populated when type == WITHIN_LIMITS or type ==
+ * BETWEEN_TWO_ITEMS.
+ */
+ GridModel.Limits limitsBeforeCoordinate;
+
+ /**
+ * The limits after the coordinate; only populated when type == BETWEEN_TWO_ITEMS.
+ */
+ GridModel.Limits limitsAfterCoordinate;
+
+ // Limits of the first known item; only populated when type == BEFORE_FIRST_ITEM.
+ GridModel.Limits mFirstKnownItem;
+ // Limits of the last known item; only populated when type == AFTER_LAST_ITEM.
+ GridModel.Limits mLastKnownItem;
+
+ /**
+ * @param limitsList The sorted limits list for the coordinate type. If this
+ * CoordinateLocation is an x-value, mXLimitsList should be passed; otherwise,
+ * mYLimitsList should be pased.
+ * @param value The coordinate value.
+ */
+ RelativeCoordinate(List<GridModel.Limits> limitsList, int value) {
+ int index = Collections.binarySearch(limitsList, new Limits(value, value));
+
+ if (index >= 0) {
+ this.type = WITHIN_LIMITS;
+ this.limitsBeforeCoordinate = limitsList.get(index);
+ } else if (~index == 0) {
+ this.type = BEFORE_FIRST_ITEM;
+ this.mFirstKnownItem = limitsList.get(0);
+ } else if (~index == limitsList.size()) {
+ GridModel.Limits lastLimits = limitsList.get(limitsList.size() - 1);
+ if (lastLimits.lowerLimit <= value && value <= lastLimits.upperLimit) {
+ this.type = WITHIN_LIMITS;
+ this.limitsBeforeCoordinate = lastLimits;
+ } else {
+ this.type = AFTER_LAST_ITEM;
+ this.mLastKnownItem = lastLimits;
+ }
+ } else {
+ GridModel.Limits limitsBeforeIndex = limitsList.get(~index - 1);
+ if (limitsBeforeIndex.lowerLimit <= value && value <= limitsBeforeIndex.upperLimit) {
+ this.type = WITHIN_LIMITS;
+ this.limitsBeforeCoordinate = limitsList.get(~index - 1);
+ } else {
+ this.type = BETWEEN_TWO_ITEMS;
+ this.limitsBeforeCoordinate = limitsList.get(~index - 1);
+ this.limitsAfterCoordinate = limitsList.get(~index);
+ }
+ }
+ }
+
+ int toComparisonValue() {
+ if (type == BEFORE_FIRST_ITEM) {
+ return mFirstKnownItem.lowerLimit - 1;
+ } else if (type == AFTER_LAST_ITEM) {
+ return mLastKnownItem.upperLimit + 1;
+ } else if (type == BETWEEN_TWO_ITEMS) {
+ return limitsBeforeCoordinate.upperLimit + 1;
+ } else {
+ return limitsBeforeCoordinate.lowerLimit;
+ }
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof GridModel.RelativeCoordinate)) {
+ return false;
+ }
+
+ GridModel.RelativeCoordinate otherCoordinate = (GridModel.RelativeCoordinate) other;
+ return toComparisonValue() == otherCoordinate.toComparisonValue();
+ }
+
+ @Override
+ public int compareTo(GridModel.RelativeCoordinate other) {
+ return toComparisonValue() - other.toComparisonValue();
+ }
+ }
+
+ /**
+ * The location of a point relative to the Limits of nearby items; consists of both an x- and
+ * y-RelativeCoordinateLocation.
+ */
+ private class RelativePoint {
+ final GridModel.RelativeCoordinate xLocation;
+ final GridModel.RelativeCoordinate yLocation;
+
+ RelativePoint(Point point) {
+ this.xLocation = new RelativeCoordinate(mColumnBounds, point.x);
+ this.yLocation = new RelativeCoordinate(mRowBounds, point.y);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof RelativePoint)) {
+ return false;
+ }
+
+ RelativePoint otherPoint = (RelativePoint) other;
+ return xLocation.equals(otherPoint.xLocation) && yLocation.equals(otherPoint.yLocation);
+ }
+ }
+
+ /**
+ * Generates a rectangle which contains the items selected by the pointer and origin.
+ * @return The rectangle, or null if no items were selected.
+ */
+ private Rect computeBounds() {
+ Rect rect = new Rect();
+ rect.left = getCoordinateValue(
+ min(mRelativeOrigin.xLocation, mRelativePointer.xLocation),
+ mColumnBounds,
+ true);
+ rect.right = getCoordinateValue(
+ max(mRelativeOrigin.xLocation, mRelativePointer.xLocation),
+ mColumnBounds,
+ false);
+ rect.top = getCoordinateValue(
+ min(mRelativeOrigin.yLocation, mRelativePointer.yLocation),
+ mRowBounds,
+ true);
+ rect.bottom = getCoordinateValue(
+ max(mRelativeOrigin.yLocation, mRelativePointer.yLocation),
+ mRowBounds,
+ false);
+ return rect;
+ }
+
+ /**
+ * Computes the corner of the selection nearest the origin.
+ * @return
+ */
+ private int computeCornerNearestOrigin() {
+ int cornerValue = 0;
+
+ if (mRelativeOrigin.yLocation ==
+ min(mRelativeOrigin.yLocation, mRelativePointer.yLocation)) {
+ cornerValue |= UPPER;
+ } else {
+ cornerValue |= LOWER;
+ }
+
+ if (mRelativeOrigin.xLocation ==
+ min(mRelativeOrigin.xLocation, mRelativePointer.xLocation)) {
+ cornerValue |= LEFT;
+ } else {
+ cornerValue |= RIGHT;
+ }
+
+ return cornerValue;
+ }
+
+ private GridModel.RelativeCoordinate min(GridModel.RelativeCoordinate first, GridModel.RelativeCoordinate second) {
+ return first.compareTo(second) < 0 ? first : second;
+ }
+
+ private GridModel.RelativeCoordinate max(GridModel.RelativeCoordinate first, GridModel.RelativeCoordinate second) {
+ return first.compareTo(second) > 0 ? first : second;
+ }
+
+ /**
+ * @return The absolute coordinate (i.e., the x- or y-value) of the given relative
+ * coordinate.
+ */
+ private int getCoordinateValue(GridModel.RelativeCoordinate coordinate,
+ List<GridModel.Limits> limitsList, boolean isStartOfRange) {
+ switch (coordinate.type) {
+ case RelativeCoordinate.BEFORE_FIRST_ITEM:
+ return limitsList.get(0).lowerLimit;
+ case RelativeCoordinate.AFTER_LAST_ITEM:
+ return limitsList.get(limitsList.size() - 1).upperLimit;
+ case RelativeCoordinate.BETWEEN_TWO_ITEMS:
+ if (isStartOfRange) {
+ return coordinate.limitsAfterCoordinate.lowerLimit;
+ } else {
+ return coordinate.limitsBeforeCoordinate.upperLimit;
+ }
+ case RelativeCoordinate.WITHIN_LIMITS:
+ return coordinate.limitsBeforeCoordinate.lowerLimit;
+ }
+
+ throw new RuntimeException("Invalid coordinate value.");
+ }
+
+ private boolean areItemsCoveredByBand(
+ RelativePoint first, RelativePoint second) {
+ return doesCoordinateLocationCoverItems(first.xLocation, second.xLocation) &&
+ doesCoordinateLocationCoverItems(first.yLocation, second.yLocation);
+ }
+
+ private boolean doesCoordinateLocationCoverItems(
+ GridModel.RelativeCoordinate pointerCoordinate,
+ GridModel.RelativeCoordinate originCoordinate) {
+ if (pointerCoordinate.type == RelativeCoordinate.BEFORE_FIRST_ITEM &&
+ originCoordinate.type == RelativeCoordinate.BEFORE_FIRST_ITEM) {
+ return false;
+ }
+
+ if (pointerCoordinate.type == RelativeCoordinate.AFTER_LAST_ITEM &&
+ originCoordinate.type == RelativeCoordinate.AFTER_LAST_ITEM) {
+ return false;
+ }
+
+ if (pointerCoordinate.type == RelativeCoordinate.BETWEEN_TWO_ITEMS &&
+ originCoordinate.type == RelativeCoordinate.BETWEEN_TWO_ITEMS &&
+ pointerCoordinate.limitsBeforeCoordinate.equals(
+ originCoordinate.limitsBeforeCoordinate) &&
+ pointerCoordinate.limitsAfterCoordinate.equals(
+ originCoordinate.limitsAfterCoordinate)) {
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ /**
+ * Provides functionality for BandController. Exists primarily to tests that are
+ * fully isolated from RecyclerView.
+ */
+ interface SelectionEnvironment {
+ void showBand(Rect rect);
+ void hideBand();
+ void addOnScrollListener(RecyclerView.OnScrollListener listener);
+ void removeOnScrollListener(RecyclerView.OnScrollListener listener);
+ void scrollBy(int dy);
+ int getHeight();
+ void invalidateView();
+ void runAtNextFrame(Runnable r);
+ void removeCallback(Runnable r);
+ Point createAbsolutePoint(Point relativePoint);
+ Rect getAbsoluteRectForChildViewAt(int index);
+ int getAdapterPositionAt(int index);
+ int getColumnCount();
+ int getChildCount();
+ int getVisibleChildCount();
+ /**
+ * Layout items are excluded from the GridModel.
+ */
+ boolean isLayoutItem(int adapterPosition);
+ /**
+ * Items may be in the adapter, but without an attached view.
+ */
+ boolean hasView(int adapterPosition);
+ }
+
+ /** Recycler view facade implementation backed by good ol' RecyclerView. */
+ private static final class RuntimeSelectionEnvironment implements SelectionEnvironment {
+
+ private final RecyclerView mView;
+ private final Drawable mBand;
+
+ private boolean mIsOverlayShown = false;
+
+ RuntimeSelectionEnvironment(RecyclerView view) {
+ mView = view;
+ mBand = mView.getContext().getTheme().getDrawable(R.drawable.band_select_overlay);
+ }
+
+ @Override
+ public int getAdapterPositionAt(int index) {
+ return mView.getChildAdapterPosition(mView.getChildAt(index));
+ }
+
+ @Override
+ public void addOnScrollListener(RecyclerView.OnScrollListener listener) {
+ mView.addOnScrollListener(listener);
+ }
+
+ @Override
+ public void removeOnScrollListener(RecyclerView.OnScrollListener listener) {
+ mView.removeOnScrollListener(listener);
+ }
+
+ @Override
+ public Point createAbsolutePoint(Point relativePoint) {
+ return new Point(relativePoint.x + mView.computeHorizontalScrollOffset(),
+ relativePoint.y + mView.computeVerticalScrollOffset());
+ }
+
+ @Override
+ public Rect getAbsoluteRectForChildViewAt(int index) {
+ final View child = mView.getChildAt(index);
+ final Rect childRect = new Rect();
+ child.getHitRect(childRect);
+ childRect.left += mView.computeHorizontalScrollOffset();
+ childRect.right += mView.computeHorizontalScrollOffset();
+ childRect.top += mView.computeVerticalScrollOffset();
+ childRect.bottom += mView.computeVerticalScrollOffset();
+ return childRect;
+ }
+
+ @Override
+ public int getChildCount() {
+ return mView.getAdapter().getItemCount();
+ }
+
+ @Override
+ public int getVisibleChildCount() {
+ return mView.getChildCount();
+ }
+
+ @Override
+ public int getColumnCount() {
+ RecyclerView.LayoutManager layoutManager = mView.getLayoutManager();
+ if (layoutManager instanceof GridLayoutManager) {
+ return ((GridLayoutManager) layoutManager).getSpanCount();
+ }
+
+ // Otherwise, it is a list with 1 column.
+ return 1;
+ }
+
+ @Override
+ public int getHeight() {
+ return mView.getHeight();
+ }
+
+ @Override
+ public void invalidateView() {
+ mView.invalidate();
+ }
+
+ @Override
+ public void runAtNextFrame(Runnable r) {
+ mView.postOnAnimation(r);
+ }
+
+ @Override
+ public void removeCallback(Runnable r) {
+ mView.removeCallbacks(r);
+ }
+
+ @Override
+ public void scrollBy(int dy) {
+ mView.scrollBy(0, dy);
+ }
+
+ @Override
+ public void showBand(Rect rect) {
+ mBand.setBounds(rect);
+
+ if (!mIsOverlayShown) {
+ mView.getOverlay().add(mBand);
+ }
+ }
+
+ @Override
+ public void hideBand() {
+ mView.getOverlay().remove(mBand);
+ }
+
+ @Override
+ public boolean isLayoutItem(int pos) {
+ // The band selection model only operates on documents and directories. Exclude other
+ // types of adapter items (e.g. whitespace items like dividers).
+ RecyclerView.ViewHolder vh = mView.findViewHolderForAdapterPosition(pos);
+ switch (vh.getItemViewType()) {
+ case ITEM_TYPE_DOCUMENT:
+ case ITEM_TYPE_DIRECTORY:
+ return false;
+ default:
+ return true;
+ }
+ }
+
+ @Override
+ public boolean hasView(int pos) {
+ return mView.findViewHolderForAdapterPosition(pos) != null;
+ }
+ }
+} \ No newline at end of file
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryDragListener.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryDragListener.java
new file mode 100644
index 000000000000..0860f4ca14bb
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryDragListener.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.dirlist;
+
+import android.view.DragEvent;
+import android.view.View;
+
+import com.android.documentsui.ItemDragListener;
+
+class DirectoryDragListener extends ItemDragListener<DirectoryFragment> {
+
+ DirectoryDragListener(DirectoryFragment fragment) {
+ super(fragment);
+ }
+
+ @Override
+ public boolean onDrag(View v, DragEvent event) {
+ final boolean result = super.onDrag(v, event);
+
+ if (event.getAction() == DragEvent.ACTION_DRAG_STARTED) {
+ mDragHost.dragStarted();
+ } else if (event.getAction() == DragEvent.ACTION_DRAG_ENDED) {
+ // getResult() is true if drag was accepted
+ mDragHost.dragStopped(event.getResult());
+ }
+
+ return result;
+ }
+
+ @Override
+ public boolean handleDropEventChecked(View v, DragEvent event) {
+ return mDragHost.handleDropEvent(v, event);
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
index 47df940bb1b5..ca7b2ca6a7ba 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -17,7 +17,6 @@
package com.android.documentsui.dirlist;
import static com.android.documentsui.Shared.DEBUG;
-import static com.android.documentsui.Shared.MAX_DOCS_IN_INTENT;
import static com.android.documentsui.State.MODE_GRID;
import static com.android.documentsui.State.MODE_LIST;
import static com.android.documentsui.State.SORT_ORDER_UNKNOWN;
@@ -39,24 +38,18 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
-import android.graphics.Canvas;
-import android.graphics.Point;
-import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
-import android.os.Parcel;
import android.os.Parcelable;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
-import android.support.annotation.Nullable;
-import android.support.design.widget.Snackbar;
import android.support.v13.view.DragStartHelper;
+import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.GridLayoutManager.SpanSizeLookup;
import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.OnItemTouchListener;
import android.support.v7.widget.RecyclerView.RecyclerListener;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.text.BidiFormatter;
@@ -64,12 +57,12 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
import android.view.ActionMode;
+import android.view.ContextMenu;
import android.view.DragEvent;
-import android.view.GestureDetector;
import android.view.HapticFeedbackConstants;
-import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
+import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
@@ -81,46 +74,52 @@ import android.widget.Toolbar;
import com.android.documentsui.BaseActivity;
import com.android.documentsui.DirectoryLoader;
import com.android.documentsui.DirectoryResult;
-import com.android.documentsui.DocumentClipper;
+import com.android.documentsui.clipping.DocumentClipper;
import com.android.documentsui.DocumentsActivity;
import com.android.documentsui.DocumentsApplication;
-import com.android.documentsui.Events;
+import com.android.documentsui.Events.InputEvent;
import com.android.documentsui.Events.MotionInputEvent;
+import com.android.documentsui.ItemDragListener;
+import com.android.documentsui.MenuManager;
import com.android.documentsui.Menus;
import com.android.documentsui.MessageBar;
import com.android.documentsui.Metrics;
import com.android.documentsui.MimePredicate;
import com.android.documentsui.R;
import com.android.documentsui.RecentsLoader;
+import com.android.documentsui.RetainedState;
import com.android.documentsui.RootsCache;
import com.android.documentsui.Shared;
import com.android.documentsui.Snackbars;
import com.android.documentsui.State;
import com.android.documentsui.State.ViewMode;
+import com.android.documentsui.clipping.UrisSupplier;
import com.android.documentsui.dirlist.MultiSelectManager.Selection;
+import com.android.documentsui.dirlist.UserInputHandler.DocumentDetails;
import com.android.documentsui.model.DocumentInfo;
-import com.android.documentsui.model.DocumentStack;
import com.android.documentsui.model.RootInfo;
+import com.android.documentsui.services.FileOperation;
import com.android.documentsui.services.FileOperationService;
import com.android.documentsui.services.FileOperationService.OpType;
import com.android.documentsui.services.FileOperations;
-import com.google.common.collect.Lists;
-
+import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashSet;
import java.util.List;
import java.util.Objects;
-import java.util.Set;
+import java.util.function.Function;
+
+import javax.annotation.Nullable;
/**
* Display the documents inside a single directory.
*/
public class DirectoryFragment extends Fragment
- implements DocumentsAdapter.Environment, LoaderCallbacks<DirectoryResult> {
+ implements DocumentsAdapter.Environment, LoaderCallbacks<DirectoryResult>,
+ ItemDragListener.DragHost, SwipeRefreshLayout.OnRefreshListener {
@IntDef(flag = true, value = {
TYPE_NORMAL,
@@ -142,13 +141,15 @@ public class DirectoryFragment extends Fragment
private static final int LOADER_ID = 42;
private Model mModel;
- private MultiSelectManager mSelectionManager;
+ private MultiSelectManager mSelectionMgr;
private Model.UpdateListener mModelUpdateListener = new ModelUpdateListener();
- private ItemEventListener mItemEventListener = new ItemEventListener();
+ private UserInputHandler<InputEvent> mInputHandler;
+ private SelectionModeListener mSelectionModeListener;
private FocusManager mFocusManager;
private IconHelper mIconHelper;
+ private SwipeRefreshLayout mRefreshLayout;
private View mEmptyView;
private RecyclerView mRecView;
private ListeningGestureDetector mGestureDetector;
@@ -171,11 +172,20 @@ public class DirectoryFragment extends Fragment
private RootInfo mRoot;
private DocumentInfo mDocument;
private String mQuery = null;
- // Save selection found during creation so it can be restored during directory loading.
- private Selection mSelection = null;
+ // Note, we use !null to indicate that selection was restored (from rotation).
+ // So don't fiddle with this field unless you've got the bigger picture in mind.
+ private @Nullable Selection mRestoredSelection = null;
+ // Here we save the clip details of moveTo/copyTo actions when picker shows up.
+ // This will be written to saved instance.
+ private @Nullable FileOperation mPendingOperation;
private boolean mSearchMode = false;
+
+ private @Nullable BandController mBandController;
private @Nullable ActionMode mActionMode;
+ private DirectoryDragListener mOnDragListener;
+ private MenuManager mMenuManager;
+
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@@ -184,6 +194,10 @@ public class DirectoryFragment extends Fragment
mMessageBar = MessageBar.create(getChildFragmentManager());
mProgressBar = view.findViewById(R.id.progressbar);
+
+ mRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.refresh_layout);
+ mRefreshLayout.setOnRefreshListener(this);
+
mEmptyView = view.findViewById(android.R.id.empty);
mRecView = (RecyclerView) view.findViewById(R.id.dir_list);
mRecView.setRecyclerListener(
@@ -196,6 +210,8 @@ public class DirectoryFragment extends Fragment
mRecView.setItemAnimator(new DirectoryItemAnimator(getActivity()));
+ mOnDragListener = new DirectoryDragListener(this);
+
// Make the recycler and the empty views responsive to drop events.
mRecView.setOnDragListener(mOnDragListener);
mEmptyView.setOnDragListener(mOnDragListener);
@@ -205,7 +221,7 @@ public class DirectoryFragment extends Fragment
@Override
public void onDestroyView() {
- mSelectionManager.clearSelection();
+ mSelectionMgr.clearSelection();
// Cancel any outstanding thumbnail requests
final int count = mRecView.getChildCount();
@@ -232,9 +248,17 @@ public class DirectoryFragment extends Fragment
mStateKey = buildStateKey(mRoot, mDocument);
mQuery = args.getString(Shared.EXTRA_QUERY);
mType = args.getInt(Shared.EXTRA_TYPE);
- final Selection selection = args.getParcelable(Shared.EXTRA_SELECTION);
- mSelection = selection != null ? selection : new Selection();
mSearchMode = args.getBoolean(Shared.EXTRA_SEARCH_MODE);
+ mPendingOperation = args.getParcelable(FileOperationService.EXTRA_OPERATION);
+
+ // Restore any selection we may have squirreled away in retained state.
+ @Nullable RetainedState retained = getBaseActivity().getRetainedState();
+ if (retained != null && retained.hasSelection()) {
+ // We claim the selection for ourselves and null it out once used
+ // so we don't have a rando selection hanging around in RetainedState.
+ mRestoredSelection = retained.selection;
+ retained.selection = null;
+ }
mIconHelper = new IconHelper(context, MODE_GRID);
@@ -250,33 +274,56 @@ public class DirectoryFragment extends Fragment
}
mRecView.setLayoutManager(mLayout);
- mGestureDetector =
- new ListeningGestureDetector(this.getContext(), mDragHelper, new GestureListener());
-
- mRecView.addOnItemTouchListener(mGestureDetector);
-
// TODO: instead of inserting the view into the constructor, extract listener-creation code
// and set the listener on the view after the fact. Then the view doesn't need to be passed
// into the selection manager.
- mSelectionManager = new MultiSelectManager(
- mRecView,
+ mSelectionMgr = new MultiSelectManager(
mAdapter,
state.allowMultiple
? MultiSelectManager.MODE_MULTIPLE
- : MultiSelectManager.MODE_SINGLE,
- null);
+ : MultiSelectManager.MODE_SINGLE);
+
+ // Make sure this is done after the RecyclerView is set up.
+ mFocusManager = new FocusManager(context, mRecView, mModel);
+
+ mInputHandler = new UserInputHandler<>(
+ mSelectionMgr,
+ mFocusManager,
+ new Function<MotionEvent, InputEvent>() {
+ @Override
+ public InputEvent apply(MotionEvent t) {
+ return MotionInputEvent.obtain(t, mRecView);
+ }
+ },
+ this::getTarget,
+ this::canSelect,
+ this::onRightClick,
+ this::onActivate,
+ (DocumentDetails ignored) -> {
+ return onDeleteSelectedDocuments();
+ });
+
+ mGestureDetector =
+ new ListeningGestureDetector(this.getContext(), mDragHelper, mInputHandler);
- mSelectionManager.addCallback(new SelectionModeListener());
+ mRecView.addOnItemTouchListener(mGestureDetector);
+ mEmptyView.setOnTouchListener(mGestureDetector);
+
+ if (state.allowMultiple) {
+ mBandController = new BandController(mRecView, mAdapter, mSelectionMgr);
+ }
+
+ mSelectionModeListener = new SelectionModeListener();
+ mSelectionMgr.addCallback(mSelectionModeListener);
mModel = new Model();
mModel.addUpdateListener(mAdapter);
mModel.addUpdateListener(mModelUpdateListener);
- // Make sure this is done after the RecyclerView is set up.
- mFocusManager = new FocusManager(context, mRecView, mModel);
-
- mTuner = FragmentTuner.pick(getContext(), state);
- mClipper = new DocumentClipper(context);
+ final BaseActivity activity = getBaseActivity();
+ mTuner = activity.createFragmentTuner();
+ mMenuManager = activity.getMenuManager();
+ mClipper = DocumentsApplication.getDocumentClipper(getContext());
final ActivityManager am = (ActivityManager) context.getSystemService(
Context.ACTIVITY_SERVICE);
@@ -287,30 +334,20 @@ public class DirectoryFragment extends Fragment
getLoaderManager().restartLoader(LOADER_ID, null, this);
}
+ public void retainState(RetainedState state) {
+ state.selection = mSelectionMgr.getSelection(new Selection());
+ }
+
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
- mSelectionManager.getSelection(mSelection);
-
outState.putInt(Shared.EXTRA_TYPE, mType);
outState.putParcelable(Shared.EXTRA_ROOT, mRoot);
outState.putParcelable(Shared.EXTRA_DOC, mDocument);
outState.putString(Shared.EXTRA_QUERY, mQuery);
-
- // Workaround. To avoid crash, write only up to 512 KB of selection.
- // If more files are selected, then the selection will be lost.
- final Parcel parcel = Parcel.obtain();
- try {
- mSelection.writeToParcel(parcel, 0);
- if (parcel.dataSize() <= 512 * 1024) {
- outState.putParcelable(Shared.EXTRA_SELECTION, mSelection);
- }
- } finally {
- parcel.recycle();
- }
-
outState.putBoolean(Shared.EXTRA_SEARCH_MODE, mSearchMode);
+ outState.putParcelable(FileOperationService.EXTRA_OPERATION, mPendingOperation);
}
@Override
@@ -324,33 +361,81 @@ public class DirectoryFragment extends Fragment
}
}
+ @Override
+ public void onCreateContextMenu(ContextMenu menu,
+ View v,
+ ContextMenu.ContextMenuInfo menuInfo) {
+ super.onCreateContextMenu(menu, v, menuInfo);
+ MenuInflater inflater = getActivity().getMenuInflater();
+ inflater.inflate(R.menu.context_menu, menu);
+
+ menu.add(Menu.NONE, R.id.menu_create_dir, Menu.NONE, R.string.menu_create_dir);
+ menu.add(Menu.NONE, R.id.menu_delete, Menu.NONE, R.string.menu_delete);
+ menu.add(Menu.NONE, R.id.menu_rename, Menu.NONE, R.string.menu_rename);
+
+ if (v == mRecView || v == mEmptyView) {
+ mMenuManager.updateContextMenu(menu, null, getBaseActivity().getDirectoryDetails());
+ } else {
+ mMenuManager.updateContextMenu(menu, mSelectionModeListener,
+ getBaseActivity().getDirectoryDetails());
+ }
+ }
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ return handleMenuItemClick(item);
+ }
+
private void handleCopyResult(int resultCode, Intent data) {
+
+ FileOperation operation = mPendingOperation;
+ mPendingOperation = null;
+
if (resultCode == Activity.RESULT_CANCELED || data == null) {
// User pressed the back button or otherwise cancelled the destination pick. Don't
// proceed with the copy.
+ operation.dispose();
return;
}
- @OpType int operationType = data.getIntExtra(
- FileOperationService.EXTRA_OPERATION,
- FileOperationService.OPERATION_COPY);
+ operation.setDestination(data.getParcelableExtra(Shared.EXTRA_STACK));
- FileOperations.start(
- getActivity(),
- getDisplayState().selectedDocumentsForCopy,
- getDisplayState().stack.peek(),
- (DocumentStack) data.getParcelableExtra(Shared.EXTRA_STACK),
- operationType);
+ BaseActivity activity = getBaseActivity();
+ FileOperations.start(activity, operation, activity.fileOpCallback);
}
- protected boolean onDoubleTap(MotionEvent e) {
- if (Events.isMouseEvent(e)) {
- String id = getModelId(e);
- if (id != null) {
- return handleViewItem(id);
+ protected boolean onRightClick(InputEvent e) {
+ if (e.getItemPosition() != RecyclerView.NO_POSITION) {
+ final DocumentHolder doc = getTarget(e);
+ if (!mSelectionMgr.getSelection().contains(doc.modelId)) {
+ mSelectionMgr.replaceSelection(Collections.singleton(doc.modelId));
}
+
+ // We are registering for context menu here so long-press doesn't trigger this
+ // floating context menu, and then quickly unregister right afterwards
+ registerForContextMenu(doc.itemView);
+ mRecView.showContextMenuForChild(doc.itemView,
+ e.getX() - doc.itemView.getLeft(), e.getY() - doc.itemView.getTop());
+ unregisterForContextMenu(doc.itemView);
+ return true;
}
- return false;
+
+ // If there was no corresponding item pos, that means user right-clicked on the blank
+ // pane
+ // We would want to show different options then, and not select any item
+ // The blank pane could be the recyclerView or the emptyView, so we need to register
+ // according to whichever one is visible
+ if (mEmptyView.getVisibility() == View.VISIBLE) {
+ registerForContextMenu(mEmptyView);
+ mEmptyView.showContextMenu(e.getX(), e.getY());
+ unregisterForContextMenu(mEmptyView);
+ return true;
+ }
+
+ registerForContextMenu(mRecView);
+ mRecView.showContextMenu(e.getX(), e.getY());
+ unregisterForContextMenu(mRecView);
+ return true;
}
private boolean handleViewItem(String id) {
@@ -365,8 +450,8 @@ public class DirectoryFragment extends Fragment
final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
if (mTuner.isDocumentEnabled(docMimeType, docFlags)) {
final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor);
- ((BaseActivity) getActivity()).onDocumentPicked(doc, mModel);
- mSelectionManager.clearSelection();
+ getBaseActivity().onDocumentPicked(doc, mModel);
+ mSelectionMgr.clearSelection();
return true;
}
return false;
@@ -417,7 +502,9 @@ public class DirectoryFragment extends Fragment
int pad = getDirectoryPadding(mode);
mRecView.setPadding(pad, pad, pad, pad);
mRecView.requestLayout();
- mSelectionManager.handleLayoutChanged(); // RecyclerView doesn't do this for us
+ if (mBandController != null) {
+ mBandController.handleLayoutChanged();
+ }
mIconHelper.setViewMode(mode);
}
@@ -455,13 +542,19 @@ public class DirectoryFragment extends Fragment
return mColumnCount;
}
+ // Support method to replace getOwner().foo() with something
+ // slightly less clumsy like: getOwner().foo().
+ private BaseActivity getBaseActivity() {
+ return (BaseActivity) getActivity();
+ }
+
/**
* Manages the integration between our ActionMode and MultiSelectManager, initiating
* ActionMode when there is a selection, canceling it when there is no selection,
* and clearing selection when action mode is explicitly exited by the user.
*/
private final class SelectionModeListener implements MultiSelectManager.Callback,
- ActionMode.Callback, FragmentTuner.SelectionDetails {
+ ActionMode.Callback, MenuManager.SelectionDetails {
private Selection mSelected = new Selection();
@@ -487,15 +580,7 @@ public class DirectoryFragment extends Fragment
if (!mTuner.canSelectType(docMimeType, docFlags)) {
return false;
}
-
- if (mSelected.size() >= MAX_DOCS_IN_INTENT) {
- Snackbars.makeSnackbar(
- getActivity(),
- R.string.too_many_selected,
- Snackbar.LENGTH_SHORT)
- .show();
- return false;
- }
+ return mTuner.canSelectType(docMimeType, docFlags);
}
return true;
}
@@ -531,7 +616,7 @@ public class DirectoryFragment extends Fragment
@Override
public void onSelectionChanged() {
- mSelectionManager.getSelection(mSelected);
+ mSelectionMgr.getSelection(mSelected);
if (mSelected.size() > 0) {
if (DEBUG) Log.d(TAG, "Maybe starting action mode.");
if (mActionMode == null) {
@@ -561,7 +646,7 @@ public class DirectoryFragment extends Fragment
if (DEBUG) Log.d(TAG, "Handling action mode destroyed.");
mActionMode = null;
// clear selection
- mSelectionManager.clearSelection();
+ mSelectionMgr.clearSelection();
mSelected.clear();
mDirectoryCount = 0;
@@ -582,9 +667,17 @@ public class DirectoryFragment extends Fragment
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
- mRecView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+ if (mRestoredSelection != null) {
+ // This is a careful little song and dance to avoid haptic feedback
+ // when selection has been restored after rotation. We're
+ // also responsible for cleaning up restored selection so the
+ // object dones't unnecessarily hang around.
+ mRestoredSelection = null;
+ } else {
+ mRecView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+ }
- int size = mSelectionManager.getSelection().size();
+ int size = mSelectionMgr.getSelection().size();
mode.getMenuInflater().inflate(R.menu.mode_directory, menu);
mode.setTitle(TextUtils.formatSelectedCount(size));
@@ -632,76 +725,92 @@ public class DirectoryFragment extends Fragment
@Override
public boolean canRename() {
- return mNoRenameCount == 0 && mSelectionManager.getSelection().size() == 1;
+ return mNoRenameCount == 0 && mSelectionMgr.getSelection().size() == 1;
}
private void updateActionMenu() {
assert(mMenu != null);
- mTuner.updateActionMenu(mMenu, this);
+ mMenuManager.updateActionMenu(mMenu, this);
Menus.disableHiddenItems(mMenu);
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
- Selection selection = mSelectionManager.getSelection(new Selection());
+ return handleMenuItemClick(item);
+ }
+ }
- switch (item.getItemId()) {
- case R.id.menu_open:
- openDocuments(selection);
- mode.finish();
- return true;
+ private boolean handleMenuItemClick(MenuItem item) {
+ Selection selection = mSelectionMgr.getSelection(new Selection());
- case R.id.menu_share:
- shareDocuments(selection);
- // TODO: Only finish selection if share action is completed.
- mode.finish();
- return true;
+ switch (item.getItemId()) {
+ case R.id.menu_open:
+ openDocuments(selection);
+ mActionMode.finish();
+ return true;
- case R.id.menu_delete:
- // deleteDocuments will end action mode if the documents are deleted.
- // It won't end action mode if user cancels the delete.
- deleteDocuments(selection);
- return true;
+ case R.id.menu_share:
+ shareDocuments(selection);
+ // TODO: Only finish selection if share action is completed.
+ mActionMode.finish();
+ return true;
- case R.id.menu_copy_to:
- transferDocuments(selection, FileOperationService.OPERATION_COPY);
- // TODO: Only finish selection mode if copy-to is not canceled.
- // Need to plum down into handling the way we do with deleteDocuments.
- mode.finish();
- return true;
+ case R.id.menu_delete:
+ // deleteDocuments will end action mode if the documents are deleted.
+ // It won't end action mode if user cancels the delete.
+ deleteDocuments(selection);
+ return true;
- case R.id.menu_move_to:
- // Exit selection mode first, so we avoid deselecting deleted documents.
- mode.finish();
- transferDocuments(selection, FileOperationService.OPERATION_MOVE);
- return true;
+ case R.id.menu_copy_to:
+ transferDocuments(selection, FileOperationService.OPERATION_COPY);
+ // TODO: Only finish selection mode if copy-to is not canceled.
+ // Need to plum down into handling the way we do with deleteDocuments.
+ mActionMode.finish();
+ return true;
- case R.id.menu_copy_to_clipboard:
- copySelectedToClipboard();
- return true;
+ case R.id.menu_move_to:
+ // Exit selection mode first, so we avoid deselecting deleted documents.
+ mActionMode.finish();
+ transferDocuments(selection, FileOperationService.OPERATION_MOVE);
+ return true;
- case R.id.menu_select_all:
- selectAllFiles();
- return true;
+ case R.id.menu_cut_to_clipboard:
+ cutSelectedToClipboard();
+ return true;
- case R.id.menu_rename:
- // Exit selection mode first, so we avoid deselecting deleted
- // (renamed) documents.
- mode.finish();
- renameDocuments(selection);
- return true;
+ case R.id.menu_copy_to_clipboard:
+ copySelectedToClipboard();
+ return true;
+
+ case R.id.menu_paste_from_clipboard:
+ pasteFromClipboard();
+ return true;
+
+ case R.id.menu_select_all:
+ selectAllFiles();
+ return true;
+
+ case R.id.menu_rename:
+ // Exit selection mode first, so we avoid deselecting deleted
+ // (renamed) documents.
+ mActionMode.finish();
+ renameDocuments(selection);
+ return true;
- default:
+ default:
+ // See if BaseActivity can handle this particular MenuItem
+ if (!getBaseActivity().onOptionsItemSelected(item)) {
if (DEBUG) Log.d(TAG, "Unhandled menu item selected: " + item);
return false;
- }
+ }
+ return true;
}
}
public final boolean onBackPressed() {
- if (mSelectionManager.hasSelection()) {
+ if (mSelectionMgr.hasSelection()) {
if (DEBUG) Log.d(TAG, "Clearing selection on selection manager.");
- mSelectionManager.clearSelection();
+ mSelectionMgr.clearSelection();
return true;
}
return false;
@@ -813,6 +922,29 @@ public class DirectoryFragment extends Fragment
return message;
}
+ private boolean onDeleteSelectedDocuments() {
+ if (mSelectionMgr.hasSelection()) {
+ deleteDocuments(mSelectionMgr.getSelection(new Selection()));
+ }
+ return false;
+ }
+
+ private boolean onActivate(DocumentDetails doc) {
+ // Toggle selection if we're in selection mode, othewise, view item.
+ if (mSelectionMgr.hasSelection()) {
+ mSelectionMgr.toggleSelection(doc.getModelId());
+ } else {
+ handleViewItem(doc.getModelId());
+ }
+ return true;
+ }
+
+// private boolean onSelect(DocumentDetails doc) {
+// mSelectionMgr.toggleSelection(doc.getModelId());
+// mSelectionMgr.setSelectionRangeBegin(doc.getAdapterPosition());
+// return true;
+// }
+
private void deleteDocuments(final Selection selected) {
Metrics.logUserAction(getContext(), Metrics.USER_ACTION_DELETE);
@@ -827,12 +959,7 @@ public class DirectoryFragment extends Fragment
(TextView) mInflater.inflate(R.layout.dialog_delete_confirmation, null);
message.setText(generateDeleteMessage(docs));
- // This "insta-hides" files that are being deleted, because
- // the delete operation may be not execute immediately (it
- // may be queued up on the FileOperationService.)
- // To hide the files locally, we call the hide method on the adapter
- // ...which a live object...cannot be parceled.
- // For that reason, for now, we implement this dialog NOT
+ // For now, we implement this dialog NOT
// as a fragment (which can survive rotation and have its own state),
// but as a simple runtime dialog. So rotating a device with an
// active delete dialog...results in that dialog disappearing.
@@ -840,8 +967,9 @@ public class DirectoryFragment extends Fragment
new AlertDialog.Builder(getActivity())
.setView(message)
.setPositiveButton(
- android.R.string.yes,
+ android.R.string.ok,
new DialogInterface.OnClickListener() {
+ @Override
public void onClick(DialogInterface dialog, int id) {
// Finish selection mode first which clears selection so we
// don't end up trying to deselect deleted documents.
@@ -853,15 +981,29 @@ public class DirectoryFragment extends Fragment
} else {
Log.w(TAG, "Action mode is null before deleting documents.");
}
- // Hide the files in the UI...since the operation
- // might be queued up on FileOperationService.
- // We're walking a line here.
- mAdapter.hide(selected.getAll());
- FileOperations.delete(
- getActivity(), docs, srcParent, getDisplayState().stack);
+
+ UrisSupplier srcs;
+ try {
+ srcs = UrisSupplier.create(
+ selected,
+ mModel::getItemUri,
+ getContext());
+ } catch(IOException e) {
+ throw new RuntimeException("Failed to create uri supplier.", e);
+ }
+
+ FileOperation operation = new FileOperation.Builder()
+ .withOpType(FileOperationService.OPERATION_DELETE)
+ .withDestination(getDisplayState().stack)
+ .withSrcs(srcs)
+ .withSrcParent(srcParent.derivedUri)
+ .build();
+
+ BaseActivity activity = getBaseActivity();
+ FileOperations.start(activity, operation, activity.fileOpCallback);
}
})
- .setNegativeButton(android.R.string.no, null)
+ .setNegativeButton(android.R.string.cancel, null)
.show();
}
}.execute(selected);
@@ -882,6 +1024,19 @@ public class DirectoryFragment extends Fragment
getActivity(),
DocumentsActivity.class);
+ UrisSupplier srcs;
+ try {
+ srcs = UrisSupplier.create(selected, mModel::getItemUri, getContext());
+ } catch(IOException e) {
+ throw new RuntimeException("Failed to create uri supplier.", e);
+ }
+
+ Uri srcParent = getDisplayState().stack.peek().derivedUri;
+ mPendingOperation = new FileOperation.Builder()
+ .withOpType(mode)
+ .withSrcParent(srcParent)
+ .withSrcs(srcs)
+ .build();
// Relay any config overrides bits present in the original intent.
Intent original = getActivity().getIntent();
@@ -901,15 +1056,12 @@ public class DirectoryFragment extends Fragment
new GetDocumentsTask() {
@Override
void onDocumentsReady(List<DocumentInfo> docs) {
- // TODO: Can this move to Fragment bundle state?
- getDisplayState().selectedDocumentsForCopy = docs;
-
// Determine if there is a directory in the set of documents
// to be copied? Why? Directory creation isn't supported by some roots
// (like Downloads). This informs DocumentsActivity (the "picker")
// to restrict available roots to just those with support.
intent.putExtra(Shared.EXTRA_DIRECTORY_COPY, hasDirectory(docs));
- intent.putExtra(FileOperationService.EXTRA_OPERATION, mode);
+ intent.putExtra(FileOperationService.EXTRA_OPERATION_TYPE, mode);
// This just identifies the type of request...we'll check it
// when we reveive a response.
@@ -945,7 +1097,7 @@ public class DirectoryFragment extends Fragment
@Override
public void initDocumentHolder(DocumentHolder holder) {
- holder.addEventListener(mItemEventListener);
+ holder.addKeyEventListener(mInputHandler);
holder.itemView.setOnFocusChangeListener(mFocusManager);
}
@@ -956,7 +1108,7 @@ public class DirectoryFragment extends Fragment
@Override
public State getDisplayState() {
- return ((BaseActivity) getActivity()).getDisplayState();
+ return getBaseActivity().getDisplayState();
}
@Override
@@ -1028,138 +1180,50 @@ public class DirectoryFragment extends Fragment
return commonType[0] + "/" + commonType[1];
}
- private void copyFromClipboard() {
- new AsyncTask<Void, Void, List<DocumentInfo>>() {
-
- @Override
- protected List<DocumentInfo> doInBackground(Void... params) {
- return mClipper.getClippedDocuments();
- }
-
- @Override
- protected void onPostExecute(List<DocumentInfo> docs) {
- DocumentInfo destination =
- ((BaseActivity) getActivity()).getCurrentDirectory();
- copyDocuments(docs, destination);
- }
- }.execute();
- }
-
- private void copyFromClipData(final ClipData clipData, final DocumentInfo destination) {
- assert(clipData != null);
-
- new AsyncTask<Void, Void, List<DocumentInfo>>() {
-
- @Override
- protected List<DocumentInfo> doInBackground(Void... params) {
- return mClipper.getDocumentsFromClipData(clipData);
- }
-
- @Override
- protected void onPostExecute(List<DocumentInfo> docs) {
- copyDocuments(docs, destination);
- }
- }.execute();
- }
-
- private void copyDocuments(final List<DocumentInfo> docs, final DocumentInfo destination) {
- BaseActivity activity = (BaseActivity) getActivity();
- if (!canCopy(docs, activity.getCurrentRoot(), destination)) {
- Snackbars.makeSnackbar(
- getActivity(),
- R.string.clipboard_files_cannot_paste,
- Snackbar.LENGTH_SHORT)
- .show();
- return;
- }
+ public void copySelectedToClipboard() {
+ Metrics.logUserAction(getContext(), Metrics.USER_ACTION_COPY_CLIPBOARD);
- if (docs.isEmpty()) {
+ Selection selection = mSelectionMgr.getSelection(new Selection());
+ if (selection.isEmpty()) {
return;
}
+ mSelectionMgr.clearSelection();
- final DocumentStack curStack = getDisplayState().stack;
- DocumentStack tmpStack = new DocumentStack();
- if (destination != null) {
- tmpStack.push(destination);
- tmpStack.addAll(curStack);
- } else {
- tmpStack = curStack;
- }
+ mClipper.clipDocumentsForCopy(mModel::getItemUri, selection);
- FileOperations.copy(getActivity(), docs, tmpStack);
+ Snackbars.showDocumentsClipped(getActivity(), selection.size());
}
- public void copySelectedToClipboard() {
- Metrics.logUserAction(getContext(), Metrics.USER_ACTION_COPY_CLIPBOARD);
+ public void cutSelectedToClipboard() {
+ Metrics.logUserAction(getContext(), Metrics.USER_ACTION_CUT_CLIPBOARD);
- Selection selection = mSelectionManager.getSelection(new Selection());
- if (!selection.isEmpty()) {
- copySelectionToClipboard(selection);
- mSelectionManager.clearSelection();
+ Selection selection = mSelectionMgr.getSelection(new Selection());
+ if (selection.isEmpty()) {
+ return;
}
- }
+ mSelectionMgr.clearSelection();
- void copySelectionToClipboard(Selection selection) {
- assert(!selection.isEmpty());
- new GetDocumentsTask() {
- @Override
- void onDocumentsReady(List<DocumentInfo> docs) {
- mClipper.clipDocuments(docs);
- Activity activity = getActivity();
- Snackbars.makeSnackbar(activity,
- activity.getResources().getQuantityString(
- R.plurals.clipboard_files_clipped, docs.size(), docs.size()),
- Snackbar.LENGTH_SHORT).show();
- }
- }.execute(selection);
+ mClipper.clipDocumentsForCut(mModel::getItemUri, selection, getDisplayState().stack.peek());
+
+ Snackbars.showDocumentsClipped(getActivity(), selection.size());
}
public void pasteFromClipboard() {
Metrics.logUserAction(getContext(), Metrics.USER_ACTION_PASTE_CLIPBOARD);
- copyFromClipboard();
+ BaseActivity activity = (BaseActivity) getActivity();
+ DocumentInfo destination = activity.getCurrentDirectory();
+ mClipper.copyFromClipboard(
+ destination, activity.getDisplayState().stack, activity.fileOpCallback);
getActivity().invalidateOptionsMenu();
}
- /**
- * Returns true if the list of files can be copied to destination. Note that this
- * is a policy check only. Currently the method does not attempt to verify
- * available space or any other environmental aspects possibly resulting in
- * failure to copy.
- *
- * @return true if the list of files can be copied to destination.
- */
- private boolean canCopy(List<DocumentInfo> files, RootInfo root, DocumentInfo dest) {
- if (dest == null || !dest.isDirectory() || !dest.isCreateSupported()) {
- return false;
- }
-
- // Can't copy folders to downloads, because we don't show folders there.
- if (root.isDownloads()) {
- for (DocumentInfo docs : files) {
- if (docs.isDirectory()) {
- return false;
- }
- }
- }
-
- return true;
- }
-
public void selectAllFiles() {
Metrics.logUserAction(getContext(), Metrics.USER_ACTION_SELECT_ALL);
- // Exclude disabled files.
- Set<String> enabled = new HashSet<String>();
- List<String> modelIds = mAdapter.getModelIds();
-
- // Get the current selection.
- String[] alreadySelected = mSelectionManager.getSelection().getAll();
- for (String id : alreadySelected) {
- enabled.add(id);
- }
-
- for (String id : modelIds) {
+ // Exclude disabled files
+ List<String> enabled = new ArrayList<String>();
+ for (String id : mAdapter.getModelIds()) {
Cursor cursor = getModel().getItem(id);
if (cursor == null) {
Log.w(TAG, "Skipping selection. Can't obtain cursor for modeId: " + id);
@@ -1167,21 +1231,13 @@ public class DirectoryFragment extends Fragment
}
String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
- if (mTuner.canSelectType(docMimeType, docFlags)) {
- if (enabled.size() >= MAX_DOCS_IN_INTENT) {
- Snackbars.makeSnackbar(
- getActivity(),
- R.string.too_many_in_select_all,
- Snackbar.LENGTH_SHORT)
- .show();
- break;
- }
+ if (isDocumentEnabled(docMimeType, docFlags)) {
enabled.add(id);
}
}
// Only select things currently visible in the adapter.
- boolean changed = mSelectionManager.setItemsSelected(enabled, true);
+ boolean changed = mSelectionMgr.setItemsSelected(enabled, true);
if (changed) {
updateDisplayState();
}
@@ -1208,108 +1264,107 @@ public class DirectoryFragment extends Fragment
}
}
- private View.OnDragListener mOnDragListener = new View.OnDragListener() {
- @Override
- public boolean onDrag(View v, DragEvent event) {
- switch (event.getAction()) {
- case DragEvent.ACTION_DRAG_STARTED:
- // TODO: Check if the event contains droppable data.
- return true;
+ void dragStarted() {
+ // When files are selected for dragging, ActionMode is started. This obscures the breadcrumb
+ // with an ActionBar. In order to make drag and drop to the breadcrumb possible, we first
+ // end ActionMode so the breadcrumb is visible to the user.
+ if (mActionMode != null) {
+ mActionMode.finish();
+ }
+ }
- // TODO: Expand drop target directory on hover?
- case DragEvent.ACTION_DRAG_ENTERED:
- setDropTargetHighlight(v, true);
- return true;
- case DragEvent.ACTION_DRAG_EXITED:
- setDropTargetHighlight(v, false);
- return true;
+ void dragStopped(boolean result) {
+ if (result) {
+ mSelectionMgr.clearSelection();
+ }
+ }
- case DragEvent.ACTION_DRAG_LOCATION:
- return true;
+ @Override
+ public void runOnUiThread(Runnable runnable) {
+ getActivity().runOnUiThread(runnable);
+ }
- case DragEvent.ACTION_DRAG_ENDED:
- if (event.getResult()) {
- // Exit selection mode if the drop was handled.
- mSelectionManager.clearSelection();
- }
- return true;
+ /**
+ * {@inheritDoc}
+ *
+ * In DirectoryFragment, we spring loads the hovered folder.
+ */
+ @Override
+ public void onViewHovered(View view) {
+ BaseActivity activity = (BaseActivity) getActivity();
+ if (getModelId(view) != null) {
+ activity.springOpenDirectory(getDestination(view));
+ }
- case DragEvent.ACTION_DROP:
- // After a drop event, always stop highlighting the target.
- setDropTargetHighlight(v, false);
+ activity.setRootsDrawerOpen(false);
+ }
- ClipData clipData = event.getClipData();
- if (clipData == null) {
- Log.w(TAG, "Received invalid drop event with null clipdata. Ignoring.");
- return false;
- }
+ boolean handleDropEvent(View v, DragEvent event) {
+ BaseActivity activity = (BaseActivity) getActivity();
+ activity.setRootsDrawerOpen(false);
- // Don't copy from the cwd into the cwd. Note: this currently doesn't work for
- // multi-window drag, because localState isn't carried over from one process to
- // another.
- Object src = event.getLocalState();
- DocumentInfo dst = getDestination(v);
- if (Objects.equals(src, dst)) {
- if (DEBUG) Log.d(TAG, "Drop target same as source. Ignoring.");
- return false;
- }
+ ClipData clipData = event.getClipData();
+ assert (clipData != null);
- // Recognize multi-window drag and drop based on the fact that localState is not
- // carried between processes. It will stop working when the localsState behavior
- // is changed. The info about window should be passed in the localState then.
- // The localState could also be null for copying from Recents in single window
- // mode, but Recents doesn't offer this functionality (no directories).
- Metrics.logUserAction(getContext(),
- src == null ? Metrics.USER_ACTION_DRAG_N_DROP_MULTI_WINDOW
- : Metrics.USER_ACTION_DRAG_N_DROP);
+ assert(DocumentClipper.getOpType(clipData) == FileOperationService.OPERATION_COPY);
- copyFromClipData(clipData, dst);
- return true;
- }
+ // Don't copy from the cwd into the cwd. Note: this currently doesn't work for
+ // multi-window drag, because localState isn't carried over from one process to
+ // another.
+ Object src = event.getLocalState();
+ DocumentInfo dst = getDestination(v);
+ if (Objects.equals(src, dst)) {
+ if (DEBUG) Log.d(TAG, "Drop target same as source. Ignoring.");
return false;
}
- private DocumentInfo getDestination(View v) {
- String id = getModelId(v);
- if (id != null) {
- Cursor dstCursor = mModel.getItem(id);
- if (dstCursor == null) {
- Log.w(TAG, "Invalid destination. Can't obtain cursor for modelId: " + id);
- return null;
- }
- return DocumentInfo.fromDirectoryCursor(dstCursor);
- }
+ // Recognize multi-window drag and drop based on the fact that localState is not
+ // carried between processes. It will stop working when the localsState behavior
+ // is changed. The info about window should be passed in the localState then.
+ // The localState could also be null for copying from Recents in single window
+ // mode, but Recents doesn't offer this functionality (no directories).
+ Metrics.logUserAction(getContext(),
+ src == null ? Metrics.USER_ACTION_DRAG_N_DROP_MULTI_WINDOW
+ : Metrics.USER_ACTION_DRAG_N_DROP);
- if (v == mRecView || v == mEmptyView) {
- return getDisplayState().stack.peek();
+ mClipper.copyFromClipData(dst, getDisplayState().stack, clipData, activity.fileOpCallback);
+ return true;
+ }
+
+ private DocumentInfo getDestination(View v) {
+ String id = getModelId(v);
+ if (id != null) {
+ Cursor dstCursor = mModel.getItem(id);
+ if (dstCursor == null) {
+ Log.w(TAG, "Invalid destination. Can't obtain cursor for modelId: " + id);
+ return null;
}
+ return DocumentInfo.fromDirectoryCursor(dstCursor);
+ }
- return null;
+ if (v == mRecView || v == mEmptyView) {
+ return getDisplayState().stack.peek();
}
- private void setDropTargetHighlight(View v, boolean highlight) {
- // Note: use exact comparison - this code is searching for views which are children of
- // the RecyclerView instance in the UI.
- if (v.getParent() == mRecView) {
- RecyclerView.ViewHolder vh = mRecView.getChildViewHolder(v);
- if (vh instanceof DocumentHolder) {
- ((DocumentHolder) vh).setHighlighted(highlight);
- }
+ return null;
+ }
+
+ @Override
+ public void setDropTargetHighlight(View v, boolean highlight) {
+ // Note: use exact comparison - this code is searching for views which are children of
+ // the RecyclerView instance in the UI.
+ if (v.getParent() == mRecView) {
+ RecyclerView.ViewHolder vh = mRecView.getChildViewHolder(v);
+ if (vh instanceof DocumentHolder) {
+ ((DocumentHolder) vh).setHighlighted(highlight);
}
}
- };
+ }
- /**
- * Gets the model ID for a given motion event (using the event position)
- */
- private String getModelId(MotionEvent e) {
- View view = mRecView.findChildViewUnder(e.getX(), e.getY());
- if (view == null) {
- return null;
- }
- RecyclerView.ViewHolder vh = mRecView.getChildViewHolder(view);
- if (vh instanceof DocumentHolder) {
- return ((DocumentHolder) vh).modelId;
+ private @Nullable DocumentHolder getTarget(InputEvent e) {
+ View childView = mRecView.findChildViewUnder(e.getX(), e.getY());
+ if (childView != null) {
+ return (DocumentHolder) mRecView.getChildViewHolder(childView);
} else {
return null;
}
@@ -1321,7 +1376,7 @@ public class DirectoryFragment extends Fragment
* @return The Model ID for the given document, or null if the given view is not associated with
* a document item view.
*/
- private String getModelId(View view) {
+ protected @Nullable String getModelId(View view) {
View itemView = mRecView.findContainingItemView(view);
if (itemView != null) {
RecyclerView.ViewHolder vh = mRecView.getChildViewHolder(itemView);
@@ -1332,94 +1387,6 @@ public class DirectoryFragment extends Fragment
return null;
}
- private List<DocumentInfo> getDraggableDocuments(View currentItemView) {
- String modelId = getModelId(currentItemView);
- if (modelId == null) {
- return Collections.EMPTY_LIST;
- }
-
- final List<DocumentInfo> selectedDocs =
- mModel.getDocuments(mSelectionManager.getSelection());
- if (!selectedDocs.isEmpty()) {
- if (!isSelected(modelId)) {
- // There is a selection that does not include the current item, drag nothing.
- return Collections.EMPTY_LIST;
- }
- return selectedDocs;
- }
-
- final Cursor cursor = mModel.getItem(modelId);
- if (cursor == null) {
- Log.w(TAG, "Undraggable document. Can't obtain cursor for modelId " + modelId);
- return Collections.EMPTY_LIST;
- }
-
- return Lists.newArrayList(
- DocumentInfo.fromDirectoryCursor(cursor));
- }
-
- private static class DragShadowBuilder extends View.DragShadowBuilder {
-
- private final Context mContext;
- private final IconHelper mIconHelper;
- private final LayoutInflater mInflater;
- private final View mShadowView;
- private final TextView mTitle;
- private final ImageView mIcon;
- private final int mWidth;
- private final int mHeight;
-
- public DragShadowBuilder(Context context, IconHelper iconHelper, List<DocumentInfo> docs) {
- mContext = context;
- mIconHelper = iconHelper;
- mInflater = LayoutInflater.from(context);
-
- mWidth = mContext.getResources().getDimensionPixelSize(R.dimen.drag_shadow_width);
- mHeight= mContext.getResources().getDimensionPixelSize(R.dimen.drag_shadow_height);
-
- mShadowView = mInflater.inflate(R.layout.drag_shadow_layout, null);
- mTitle = (TextView) mShadowView.findViewById(android.R.id.title);
- mIcon = (ImageView) mShadowView.findViewById(android.R.id.icon);
-
- mTitle.setText(getTitle(docs));
- mIcon.setImageDrawable(getIcon(docs));
- }
-
- private Drawable getIcon(List<DocumentInfo> docs) {
- if (docs.size() == 1) {
- final DocumentInfo doc = docs.get(0);
- return mIconHelper.getDocumentIcon(mContext, doc.authority, doc.documentId,
- doc.mimeType, doc.icon);
- }
- return mContext.getDrawable(com.android.internal.R.drawable.ic_doc_generic);
- }
-
- private String getTitle(List<DocumentInfo> docs) {
- if (docs.size() == 1) {
- final DocumentInfo doc = docs.get(0);
- return doc.displayName;
- }
- return Shared.getQuantityString(mContext, R.plurals.elements_dragged, docs.size());
- }
-
- @Override
- public void onProvideShadowMetrics(
- Point shadowSize, Point shadowTouchPoint) {
- shadowSize.set(mWidth, mHeight);
- shadowTouchPoint.set(mWidth, mHeight);
- }
-
- @Override
- public void onDrawShadow(Canvas canvas) {
- Rect r = canvas.getClipBounds();
- // Calling measure is necessary in order for all child views to get correctly laid out.
- mShadowView.measure(
- View.MeasureSpec.makeMeasureSpec(r.right- r.left, View.MeasureSpec.EXACTLY),
- View.MeasureSpec.makeMeasureSpec(r.top- r.bottom, View.MeasureSpec.EXACTLY));
- mShadowView.layout(r.left, r.top, r.right, r.bottom);
- mShadowView.draw(canvas);
- }
- }
/**
* Abstract task providing support for loading documents *off*
* the main thread. And if it isn't obvious, creating a list
@@ -1442,100 +1409,7 @@ public class DirectoryFragment extends Fragment
@Override
public boolean isSelected(String modelId) {
- return mSelectionManager.getSelection().contains(modelId);
- }
-
- private class ItemEventListener implements DocumentHolder.EventListener {
- @Override
- public boolean onActivate(DocumentHolder doc) {
- // Toggle selection if we're in selection mode, othewise, view item.
- if (mSelectionManager.hasSelection()) {
- mSelectionManager.toggleSelection(doc.modelId);
- } else {
- handleViewItem(doc.modelId);
- }
- return true;
- }
-
- @Override
- public boolean onSelect(DocumentHolder doc) {
- mSelectionManager.toggleSelection(doc.modelId);
- mSelectionManager.setSelectionRangeBegin(doc.getAdapterPosition());
- return true;
- }
-
- @Override
- public boolean onKey(DocumentHolder doc, int keyCode, KeyEvent event) {
- // Only handle key-down events. This is simpler, consistent with most other UIs, and
- // enables the handling of repeated key events from holding down a key.
- if (event.getAction() != KeyEvent.ACTION_DOWN) {
- return false;
- }
-
- // Ignore tab key events. Those should be handled by the top-level key handler.
- if (keyCode == KeyEvent.KEYCODE_TAB) {
- return false;
- }
-
- if (mFocusManager.handleKey(doc, keyCode, event)) {
- // Handle range selection adjustments. Extending the selection will adjust the
- // bounds of the in-progress range selection. Each time an unshifted navigation
- // event is received, the range selection is restarted.
- if (shouldExtendSelection(doc, event)) {
- if (!mSelectionManager.isRangeSelectionActive()) {
- // Start a range selection if one isn't active
- mSelectionManager.startRangeSelection(doc.getAdapterPosition());
- }
- mSelectionManager.snapRangeSelection(mFocusManager.getFocusPosition());
- } else {
- mSelectionManager.endRangeSelection();
- }
- return true;
- }
-
- // Handle enter key events
- switch (keyCode) {
- case KeyEvent.KEYCODE_ENTER:
- if (event.isShiftPressed()) {
- return onSelect(doc);
- }
- // For non-shifted enter keypresses, fall through.
- case KeyEvent.KEYCODE_DPAD_CENTER:
- case KeyEvent.KEYCODE_BUTTON_A:
- return onActivate(doc);
- case KeyEvent.KEYCODE_FORWARD_DEL:
- // This has to be handled here instead of in a keyboard shortcut, because
- // keyboard shortcuts all have to be modified with the 'Ctrl' key.
- if (mSelectionManager.hasSelection()) {
- Selection selection = mSelectionManager.getSelection(new Selection());
- deleteDocuments(selection);
- }
- // Always handle the key, even if there was nothing to delete. This is a
- // precaution to prevent other handlers from potentially picking up the event
- // and triggering extra behaviours.
- return true;
- }
-
- return false;
- }
-
- private boolean shouldExtendSelection(DocumentHolder doc, KeyEvent event) {
- if (!Events.isNavigationKeyCode(event.getKeyCode()) || !event.isShiftPressed()) {
- return false;
- }
-
- // TODO: Combine this method with onBeforeItemStateChange, as both of them are almost
- // the same, and responsible for the same thing (whether to select or not).
- final Cursor cursor = mModel.getItem(doc.modelId);
- if (cursor == null) {
- Log.w(TAG, "Couldn't obtain cursor for modelId: " + doc.modelId);
- return false;
- }
-
- final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
- final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
- return mTuner.canSelectType(docMimeType, docFlags);
- }
+ return mSelectionMgr.getSelection().contains(modelId);
}
private final class ModelUpdateListener implements Model.UpdateListener {
@@ -1561,7 +1435,7 @@ public class DirectoryFragment extends Fragment
}
if (!model.isLoading()) {
- ((BaseActivity) getActivity()).notifyDirectoryLoaded(
+ getBaseActivity().notifyDirectoryLoaded(
model.doc != null ? model.doc.derivedUri : null);
}
}
@@ -1572,139 +1446,95 @@ public class DirectoryFragment extends Fragment
}
}
- private DragStartHelper.OnDragStartListener mOnDragStartListener =
- new DragStartHelper.OnDragStartListener() {
- @Override
- public boolean onDragStart(View v, DragStartHelper helper) {
- if (isSelected(getModelId(v))) {
- List<DocumentInfo> docs = getDraggableDocuments(v);
- if (docs.isEmpty()) {
- return false;
- }
- v.startDragAndDrop(
- mClipper.getClipDataForDocuments(docs),
- new DragShadowBuilder(getActivity(), mIconHelper, docs),
- getDisplayState().stack.peek(),
- View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ |
- View.DRAG_FLAG_GLOBAL_URI_WRITE
- );
- return true;
- }
-
- return false;
+ private Drawable getDragIcon(Selection selection) {
+ if (selection.size() == 1) {
+ DocumentInfo doc = getSingleSelectedDocument(selection);
+ return mIconHelper.getDocumentIcon(getContext(), doc);
}
- };
-
- private DragStartHelper mDragHelper = new DragStartHelper(null, mOnDragStartListener);
+ return getContext().getDrawable(com.android.internal.R.drawable.ic_doc_generic);
+ }
- private View.OnLongClickListener onLongClickListener = new View.OnLongClickListener() {
- @Override
- public boolean onLongClick(View v) {
- return mDragHelper.onLongClick(v);
+ private String getDragTitle(Selection selection) {
+ assert (!selection.isEmpty());
+ if (selection.size() == 1) {
+ DocumentInfo doc = getSingleSelectedDocument(selection);
+ return doc.displayName;
}
- };
- // Previously we listened to events with one class, only to bounce them forward
- // to GestureDetector. We're still doing that here, but with a single class
- // that reduces overall complexity in our glue code.
- private static final class ListeningGestureDetector extends GestureDetector
- implements OnItemTouchListener {
+ return Shared.getQuantityString(getContext(), R.plurals.elements_dragged, selection.size());
+ }
- private int mLastTool = -1;
- private DragStartHelper mDragHelper;
+ private DocumentInfo getSingleSelectedDocument(Selection selection) {
+ assert (selection.size() == 1);
+ final List<DocumentInfo> docs = mModel.getDocuments(mSelectionMgr.getSelection());
+ assert (docs.size() == 1);
+ return docs.get(0);
+ }
- public ListeningGestureDetector(
- Context context, DragStartHelper dragHelper, GestureListener listener) {
- super(context, listener);
- mDragHelper = dragHelper;
- setOnDoubleTapListener(listener);
- }
+ private DragStartHelper.OnDragStartListener mOnDragStartListener =
+ new DragStartHelper.OnDragStartListener() {
+ @Override
+ public boolean onDragStart(View v, DragStartHelper helper) {
+ Selection selection = mSelectionMgr.getSelection();
- boolean mouseSpawnedLastEvent() {
- return Events.isMouseType(mLastTool);
- }
+ if (v == null) {
+ Log.d(TAG, "Ignoring drag event, null view");
+ return false;
+ }
+ if (!isSelected(getModelId(v))) {
+ Log.d(TAG, "Ignoring drag event, unselected view.");
+ return false;
+ }
- boolean touchSpawnedLastEvent() {
- return Events.isTouchType(mLastTool);
- }
+ // NOTE: Preparation of the ClipData object can require a lot of time
+ // and ideally should be done in the background. Unfortunately
+ // the current code layout and framework assumptions don't support
+ // this. So for now, we could end up doing a bunch of i/o on main thread.
+ v.startDragAndDrop(
+ mClipper.getClipDataForDocuments(
+ mModel::getItemUri,
+ selection,
+ FileOperationService.OPERATION_COPY),
+ new DragShadowBuilder(
+ getActivity(),
+ getDragTitle(selection),
+ getDragIcon(selection)),
+ getDisplayState().stack.peek(),
+ View.DRAG_FLAG_GLOBAL
+ | View.DRAG_FLAG_GLOBAL_URI_READ
+ | View.DRAG_FLAG_GLOBAL_URI_WRITE);
- @Override
- public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
- mLastTool = e.getToolType(0);
+ return true;
+ }
+ };
- // Detect drag events. When a drag is detected, intercept the rest of the gesture.
- View itemView = rv.findChildViewUnder(e.getX(), e.getY());
- if (itemView != null && mDragHelper.onTouch(itemView, e)) {
- return true;
- }
- // Forward unhandled events to the GestureDetector.
- onTouchEvent(e);
- return false;
- }
+ private DragStartHelper mDragHelper = new DragStartHelper(null, mOnDragStartListener);
+ private View.OnLongClickListener onLongClickListener = new View.OnLongClickListener() {
@Override
- public void onTouchEvent(RecyclerView rv, MotionEvent e) {
- View itemView = rv.findChildViewUnder(e.getX(), e.getY());
- mDragHelper.onTouch(itemView, e);
- // Note: even though this event is being handled as part of a drag gesture, continue
- // forwarding to the GestureDetector. The detector needs to see the entire cluster of
- // events in order to properly interpret gestures.
- onTouchEvent(e);
+ public boolean onLongClick(View v) {
+ return mDragHelper.onLongClick(v);
}
+ };
- @Override
- public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
+ private boolean canSelect(DocumentDetails doc) {
+ return canSelect(doc.getModelId());
}
- /**
- * The gesture listener for items in the list/grid view. Interprets gestures and sends the
- * events to the target DocumentHolder, whence they are routed to the appropriate listener.
- */
- private class GestureListener extends GestureDetector.SimpleOnGestureListener {
- @Override
- public boolean onSingleTapUp(MotionEvent e) {
- // Single tap logic:
- // If the selection manager is active, it gets first whack at handling tap
- // events. Otherwise, tap events are routed to the target DocumentHolder.
- boolean handled = mSelectionManager.onSingleTapUp(
- new MotionInputEvent(e, mRecView));
-
- if (handled) {
- return handled;
- }
+ private boolean canSelect(String modelId) {
- // Give the DocumentHolder a crack at the event.
- DocumentHolder holder = getTarget(e);
- if (holder != null) {
- handled = holder.onSingleTapUp(e);
- }
-
- return handled;
- }
-
- @Override
- public void onLongPress(MotionEvent e) {
- // Long-press events get routed directly to the selection manager. They can be
- // changed to route through the DocumentHolder if necessary.
- mSelectionManager.onLongPress(new MotionInputEvent(e, mRecView));
- }
-
- @Override
- public boolean onDoubleTap(MotionEvent e) {
- // Double-tap events are handled directly by the DirectoryFragment. They can be changed
- // to route through the DocumentHolder if necessary.
- return DirectoryFragment.this.onDoubleTap(e);
+ // TODO: Combine this method with onBeforeItemStateChange, as both of them are almost
+ // the same, and responsible for the same thing (whether to select or not).
+ final Cursor cursor = mModel.getItem(modelId);
+ if (cursor == null) {
+ Log.w(TAG, "Couldn't obtain cursor for modelId: " + modelId);
+ return false;
}
- private @Nullable DocumentHolder getTarget(MotionEvent e) {
- View childView = mRecView.findChildViewUnder(e.getX(), e.getY());
- if (childView != null) {
- return (DocumentHolder) mRecView.getChildViewHolder(childView);
- } else {
- return null;
- }
- }
+ final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
+ final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
+ return mTuner.canSelectType(docMimeType, docFlags);
}
public static void showDirectory(
@@ -1778,6 +1608,11 @@ public class DirectoryFragment extends Fragment
}
@Override
+ public void onRefresh() {
+ getLoaderManager().restartLoader(LOADER_ID, null, this);
+ }
+
+ @Override
public Loader<DirectoryResult> onCreateLoader(int id, Bundle args) {
Context context = getActivity();
State state = getDisplayState();
@@ -1821,9 +1656,11 @@ public class DirectoryFragment extends Fragment
updateLayout(state.derivedMode);
- if (mSelection != null) {
- mSelectionManager.setItemsSelected(mSelection.toList(), true);
- mSelection.clear();
+ if (mRestoredSelection != null) {
+ mSelectionMgr.restoreSelection(mRestoredSelection);
+ // Note, we'll take care of cleaning up retained selection
+ // in the selection handler where we already have some
+ // specialized code to handle when selection was restored.
}
// Restore any previous instance state
@@ -1841,10 +1678,13 @@ public class DirectoryFragment extends Fragment
mTuner.onModelLoaded(mModel, mType, mSearchMode);
+ mRefreshLayout.setRefreshing(false);
}
@Override
public void onLoaderReset(Loader<DirectoryResult> loader) {
mModel.update(null);
+
+ mRefreshLayout.setRefreshing(false);
}
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentHolder.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentHolder.java
index 2288fe74184f..c2b0bf21ff74 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentHolder.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentHolder.java
@@ -24,28 +24,31 @@ import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.view.KeyEvent;
import android.view.LayoutInflater;
-import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
-import com.android.documentsui.Events;
+import com.android.documentsui.Events.InputEvent;
import com.android.documentsui.R;
import com.android.documentsui.State;
+import com.android.documentsui.dirlist.UserInputHandler.DocumentDetails;
public abstract class DocumentHolder
extends RecyclerView.ViewHolder
- implements View.OnKeyListener {
+ implements View.OnKeyListener,
+ DocumentDetails {
static final float DISABLED_ALPHA = 0.3f;
+ @Deprecated // Public access is deprecated, use #getModelId.
public @Nullable String modelId;
final Context mContext;
final @ColorInt int mDefaultBgColor;
final @ColorInt int mSelectedBgColor;
- DocumentHolder.EventListener mEventListener;
- private View.OnKeyListener mKeyListener;
+ // See #addKeyEventListener for details on the need for this field.
+ KeyboardEventListener mKeyEventListener;
+
private View mSelectionHotspot;
@@ -74,6 +77,11 @@ public abstract class DocumentHolder
*/
public abstract void bind(Cursor cursor, String modelId, State state);
+ @Override
+ public String getModelId() {
+ return modelId;
+ }
+
/**
* Makes the associated item view appear selected. Note that this merely affects the appearance
* of the view, it doesn't actually select the item.
@@ -107,54 +115,36 @@ public abstract class DocumentHolder
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
- // Event listener should always be set.
- assert(mEventListener != null);
-
- return mEventListener.onKey(this, keyCode, event);
- }
-
- public void addEventListener(DocumentHolder.EventListener listener) {
- // Just handle one for now; switch to a list if necessary.
- assert(mEventListener == null);
- mEventListener = listener;
+ assert(mKeyEventListener != null);
+ return mKeyEventListener.onKey(this, keyCode, event);
}
- public void addOnKeyListener(View.OnKeyListener listener) {
- // Just handle one for now; switch to a list if necessary.
- assert(mKeyListener == null);
- mKeyListener = listener;
+ /**
+ * Installs a delegate to receive keyboard input events. This arrangement is necessitated
+ * by the fact that a single listener cannot listen to all keyboard events
+ * on RecyclerView (our parent view). Not sure why this is, but have been
+ * assured it is the case.
+ *
+ * <p>Ideally we'd not involve DocumentHolder in propagation of events like this.
+ */
+ public void addKeyEventListener(KeyboardEventListener listener) {
+ assert(mKeyEventListener == null);
+ mKeyEventListener = listener;
}
- public boolean onSingleTapUp(MotionEvent event) {
- if (Events.isMouseEvent(event)) {
- // Mouse clicks select.
- // TODO: && input.isPrimaryButtonPressed(), but it is returning false.
- if (mEventListener != null) {
- return mEventListener.onSelect(this);
- }
- } else if (Events.isTouchEvent(event)) {
- // Touch events select if they occur in the selection hotspot, otherwise they activate.
- if (mEventListener == null) {
- return false;
- }
-
- // Do everything in global coordinates - it makes things simpler.
- int[] coords = new int[2];
- mSelectionHotspot.getLocationOnScreen(coords);
- Rect rect = new Rect(coords[0], coords[1], coords[0] + mSelectionHotspot.getWidth(),
- coords[1] + mSelectionHotspot.getHeight());
-
- // If the tap occurred within the icon rect, consider it a selection.
- if (rect.contains((int) event.getRawX(), (int) event.getRawY())) {
- return mEventListener.onSelect(this);
- } else {
- return mEventListener.onActivate(this);
- }
- }
- return false;
+ @Override
+ public boolean isInSelectionHotspot(InputEvent event) {
+ // Do everything in global coordinates - it makes things simpler.
+ int[] coords = new int[2];
+ mSelectionHotspot.getLocationOnScreen(coords);
+ Rect rect = new Rect(coords[0], coords[1], coords[0] + mSelectionHotspot.getWidth(),
+ coords[1] + mSelectionHotspot.getHeight());
+
+ // If the tap occurred within the icon rect, consider it a selection.
+ return rect.contains((int) event.getRawX(), (int) event.getRawY());
}
- static void setEnabledRecursive(View itemView, boolean enabled) {
+ static void setEnabledRecursive(View itemView, boolean enabled) {
if (itemView == null) return;
if (itemView.isEnabled() == enabled) return;
itemView.setEnabled(enabled);
@@ -174,23 +164,9 @@ public abstract class DocumentHolder
/**
* Implement this in order to be able to respond to events coming from DocumentHolders.
+ * TODO: Make this bubble up logic events rather than having imperative commands.
*/
- interface EventListener {
- /**
- * Handles activation events on the document holder.
- *
- * @param doc The target DocumentHolder
- * @return Whether the event was handled.
- */
- public boolean onActivate(DocumentHolder doc);
-
- /**
- * Handles selection events on the document holder.
- *
- * @param doc The target DocumentHolder
- * @return Whether the event was handled.
- */
- public boolean onSelect(DocumentHolder doc);
+ interface KeyboardEventListener {
/**
* Handles key events on the document holder.
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentsAdapter.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentsAdapter.java
index 0bbecf9b289c..4b354479936e 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentsAdapter.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentsAdapter.java
@@ -23,7 +23,6 @@ import android.database.Cursor;
import android.provider.DocumentsContract.Document;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
-import android.util.SparseArray;
import com.android.documentsui.State;
@@ -65,15 +64,6 @@ abstract class DocumentsAdapter
abstract String getModelId(int position);
/**
- * Hides a set of items from the associated RecyclerView.
- *
- * @param ids The Model IDs of the items to hide.
- * @return A SparseArray that maps the hidden IDs to their old positions. This can be used
- * to {@link #unhide} the items if necessary.
- */
- abstract public SparseArray<String> hide(String... ids);
-
- /**
* Returns a class that yields the span size for a particular element. This is
* primarily useful in {@link SectionBreakDocumentsAdapterWrapper} where
* we adjust sizes.
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DragShadowBuilder.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DragShadowBuilder.java
new file mode 100644
index 000000000000..c7d7a64c21e4
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DragShadowBuilder.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.dirlist;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.documentsui.R;
+
+final class DragShadowBuilder extends View.DragShadowBuilder {
+
+ private final View mShadowView;
+ private final TextView mTitle;
+ private final ImageView mIcon;
+ private final int mWidth;
+ private final int mHeight;
+
+ public DragShadowBuilder(Context context, String title, Drawable icon) {
+ mWidth = context.getResources().getDimensionPixelSize(R.dimen.drag_shadow_width);
+ mHeight= context.getResources().getDimensionPixelSize(R.dimen.drag_shadow_height);
+
+ mShadowView = LayoutInflater.from(context).inflate(R.layout.drag_shadow_layout, null);
+ mTitle = (TextView) mShadowView.findViewById(android.R.id.title);
+ mIcon = (ImageView) mShadowView.findViewById(android.R.id.icon);
+
+ mTitle.setText(title);
+ mIcon.setImageDrawable(icon);
+ }
+
+ @Override
+ public void onProvideShadowMetrics(
+ Point shadowSize, Point shadowTouchPoint) {
+ shadowSize.set(mWidth, mHeight);
+ shadowTouchPoint.set(mWidth, mHeight);
+ }
+
+ @Override
+ public void onDrawShadow(Canvas canvas) {
+ Rect r = canvas.getClipBounds();
+ // Calling measure is necessary in order for all child views to get correctly laid out.
+ mShadowView.measure(
+ View.MeasureSpec.makeMeasureSpec(r.right- r.left, View.MeasureSpec.EXACTLY),
+ View.MeasureSpec.makeMeasureSpec(r.top- r.bottom, View.MeasureSpec.EXACTLY));
+ mShadowView.layout(r.left, r.top, r.right, r.bottom);
+ mShadowView.draw(canvas);
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FocusHandler.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FocusHandler.java
new file mode 100644
index 000000000000..ba26d65065f2
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FocusHandler.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.dirlist;
+
+import android.view.KeyEvent;
+import android.view.View;
+
+/**
+ * A class that handles navigation and focus within the DirectoryFragment.
+ */
+interface FocusHandler extends View.OnFocusChangeListener {
+
+ /**
+ * Handles navigation (setting focus, adjusting selection if needed) arising from incoming key
+ * events.
+ *
+ * @param doc The DocumentHolder receiving the key event.
+ * @param keyCode
+ * @param event
+ * @return Whether the event was handled.
+ */
+ boolean handleKey(DocumentHolder doc, int keyCode, KeyEvent event);
+
+ @Override
+ void onFocusChange(View v, boolean hasFocus);
+
+ /**
+ * Requests focus on the item that last had focus. Scrolls to that item if necessary.
+ */
+ void restoreLastFocus();
+
+ /**
+ * @return The adapter position of the last focused item.
+ */
+ int getFocusPosition();
+
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FocusManager.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FocusManager.java
index f274df37f916..1be2f65796f4 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FocusManager.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FocusManager.java
@@ -49,7 +49,7 @@ import java.util.TimerTask;
/**
* A class that handles navigation and focus within the DirectoryFragment.
*/
-class FocusManager implements View.OnFocusChangeListener {
+final class FocusManager implements FocusHandler {
private static final String TAG = "FocusManager";
private RecyclerView mView;
@@ -70,15 +70,7 @@ class FocusManager implements View.OnFocusChangeListener {
mSearchHelper = new TitleSearchHelper(context);
}
- /**
- * Handles navigation (setting focus, adjusting selection if needed) arising from incoming key
- * events.
- *
- * @param doc The DocumentHolder receiving the key event.
- * @param keyCode
- * @param event
- * @return Whether the event was handled.
- */
+ @Override
public boolean handleKey(DocumentHolder doc, int keyCode, KeyEvent event) {
// Search helper gets first crack, for doing type-to-focus.
if (mSearchHelper.handleKey(doc, keyCode, event)) {
@@ -116,9 +108,7 @@ class FocusManager implements View.OnFocusChangeListener {
}
}
- /**
- * Requests focus on the item that last had focus. Scrolls to that item if necessary.
- */
+ @Override
public void restoreLastFocus() {
if (mAdapter.getItemCount() == 0) {
// Nothing to focus.
@@ -134,9 +124,7 @@ class FocusManager implements View.OnFocusChangeListener {
}
}
- /**
- * @return The adapter position of the last focused item.
- */
+ @Override
public int getFocusPosition() {
return mLastFocusPosition;
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
index 7b0510be644e..5201089b924c 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
@@ -16,7 +16,6 @@
package com.android.documentsui.dirlist;
-import static com.android.documentsui.State.ACTION_BROWSE;
import static com.android.documentsui.State.ACTION_CREATE;
import static com.android.documentsui.State.ACTION_GET_CONTENT;
import static com.android.documentsui.State.ACTION_OPEN;
@@ -25,13 +24,9 @@ import static com.android.documentsui.State.ACTION_PICK_COPY_DESTINATION;
import android.content.Context;
import android.provider.DocumentsContract.Document;
-import android.view.Menu;
-import android.view.MenuItem;
import com.android.documentsui.BaseActivity;
-import com.android.documentsui.Menus;
import com.android.documentsui.MimePredicate;
-import com.android.documentsui.R;
import com.android.documentsui.State;
import com.android.documentsui.dirlist.DirectoryFragment.ResultType;
@@ -49,16 +44,6 @@ public abstract class FragmentTuner {
mState = state;
}
- public static FragmentTuner pick(Context context, State state) {
- switch (state.action) {
- case ACTION_BROWSE:
- return new FilesTuner(context, state);
- default:
- return new DocumentsTuner(context, state);
- }
- }
-
-
// Subtly different from isDocumentEnabled. The reason may be illuminated as follows.
// A folder is enabled such that it may be double clicked, even in settings
// when the folder itself cannot be selected. This may also be true of container types.
@@ -85,13 +70,12 @@ public abstract class FragmentTuner {
return false;
}
- abstract void updateActionMenu(Menu menu, SelectionDetails selection);
abstract void onModelLoaded(Model model, @ResultType int resultType, boolean isSearch);
/**
* Provides support for Platform specific specializations of DirectoryFragment.
*/
- private static final class DocumentsTuner extends FragmentTuner {
+ public static final class DocumentsTuner extends FragmentTuner {
// We use this to keep track of whether a model has been previously loaded or not so we can
// open the drawer on empty directories on first launch
@@ -147,25 +131,6 @@ public abstract class FragmentTuner {
}
@Override
- public void updateActionMenu(Menu menu, SelectionDetails selection) {
-
- MenuItem open = menu.findItem(R.id.menu_open);
- MenuItem share = menu.findItem(R.id.menu_share);
- MenuItem delete = menu.findItem(R.id.menu_delete);
- MenuItem rename = menu.findItem(R.id.menu_rename);
- MenuItem selectAll = menu.findItem(R.id.menu_select_all);
-
- open.setVisible(mState.action == ACTION_GET_CONTENT
- || mState.action == ACTION_OPEN);
- share.setVisible(false);
- delete.setVisible(false);
- rename.setVisible(false);
- selectAll.setVisible(mState.allowMultiple);
-
- Menus.disableHiddenItems(menu);
- }
-
- @Override
void onModelLoaded(Model model, @ResultType int resultType, boolean isSearch) {
boolean showDrawer = false;
@@ -196,7 +161,7 @@ public abstract class FragmentTuner {
/**
* Provides support for Files activity specific specializations of DirectoryFragment.
*/
- private static final class FilesTuner extends FragmentTuner {
+ public static final class FilesTuner extends FragmentTuner {
// We use this to keep track of whether a model has been previously loaded or not so we can
// open the drawer on empty directories on first launch
@@ -206,43 +171,7 @@ public abstract class FragmentTuner {
super(context, state);
}
- @Override
- public void updateActionMenu(Menu menu, SelectionDetails selection) {
-
- menu.findItem(R.id.menu_open).setVisible(false); // "open" is never used in Files.
-
- // Commands accessible only via keyboard...
- MenuItem copy = menu.findItem(R.id.menu_copy_to_clipboard);
- MenuItem paste = menu.findItem(R.id.menu_paste_from_clipboard);
-
- // Commands visible in the UI...
- MenuItem rename = menu.findItem(R.id.menu_rename);
- MenuItem moveTo = menu.findItem(R.id.menu_move_to);
- MenuItem copyTo = menu.findItem(R.id.menu_copy_to);
- MenuItem share = menu.findItem(R.id.menu_share);
- MenuItem delete = menu.findItem(R.id.menu_delete);
- // copy is not visible, keyboard only
- copy.setEnabled(!selection.containsPartialFiles());
-
- // Commands usually on action-bar, so we always manage visibility.
- share.setVisible(!selection.containsDirectories() && !selection.containsPartialFiles());
- delete.setVisible(selection.canDelete());
-
- share.setEnabled(!selection.containsDirectories() && !selection.containsPartialFiles());
- delete.setEnabled(selection.canDelete());
-
- // Commands always in overflow, so we don't bother showing/hiding...
- copyTo.setVisible(true);
- moveTo.setVisible(true);
- rename.setVisible(true);
-
- copyTo.setEnabled(!selection.containsPartialFiles());
- moveTo.setEnabled(!selection.containsPartialFiles() && selection.canDelete());
- rename.setEnabled(!selection.containsPartialFiles() && selection.canRename());
-
- Menus.disableHiddenItems(menu, copy, paste);
- }
@Override
void onModelLoaded(Model model, @ResultType int resultType, boolean isSearch) {
@@ -271,17 +200,4 @@ public abstract class FragmentTuner {
return true;
}
}
-
- /**
- * Access to meta data about the selection.
- */
- interface SelectionDetails {
- boolean containsDirectories();
- boolean containsPartialFiles();
-
- // TODO: Update these to express characteristics instead of answering concrete questions,
- // since the answer to those questions is (or can be) activity specific.
- boolean canDelete();
- boolean canRename();
- }
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/GridDocumentHolder.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/GridDocumentHolder.java
index c4f6f11b31c9..7ba4bddbe1f6 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/GridDocumentHolder.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/GridDocumentHolder.java
@@ -135,8 +135,8 @@ final class GridDocumentHolder extends DocumentHolder {
mIconThumb.setAlpha(0f);
final Uri uri = DocumentsContract.buildDocumentUri(docAuthority, docId);
- mIconHelper.loadThumbnail(uri, docMimeType, docFlags, docIcon, mIconThumb, mIconMimeLg,
- mIconMimeSm);
+ mIconHelper.load(uri, docMimeType, docFlags, docIcon, docLastModified, mIconThumb,
+ mIconMimeLg, mIconMimeSm);
if (mHideTitles) {
mTitle.setVisibility(View.GONE);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/IconHelper.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/IconHelper.java
index ff0f4b10b060..ec723140f5cd 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/IconHelper.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/IconHelper.java
@@ -34,6 +34,7 @@ import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import android.support.annotation.Nullable;
import android.util.Log;
+import android.view.View;
import android.widget.ImageView;
import com.android.documentsui.DocumentsApplication;
@@ -45,21 +46,34 @@ import com.android.documentsui.R;
import com.android.documentsui.State;
import com.android.documentsui.State.ViewMode;
import com.android.documentsui.ThumbnailCache;
+import com.android.documentsui.ThumbnailCache.Result;
+import com.android.documentsui.model.DocumentInfo;
+
+import java.util.function.BiConsumer;
/**
* A class to assist with loading and managing the Images (i.e. thumbnails and icons) associated
* with items in the directory listing.
*/
public class IconHelper {
- private static String TAG = "IconHelper";
+ private static final String TAG = "IconHelper";
+
+ // Two animations applied to image views. The first is used to switch mime icon and thumbnail.
+ // The second is used when we need to update thumbnail.
+ private static final BiConsumer<View, View> ANIM_FADE_IN = (mime, thumb) -> {
+ float alpha = mime.getAlpha();
+ mime.animate().alpha(0f).start();
+ thumb.setAlpha(0f);
+ thumb.animate().alpha(alpha).start();
+ };
+ private static final BiConsumer<View, View> ANIM_NO_OP = (mime, thumb) -> {};
private final Context mContext;
+ private final ThumbnailCache mThumbnailCache;
- // Updated when icon size is set.
- private ThumbnailCache mCache;
- private Point mThumbSize;
// The display mode (MODE_GRID, MODE_LIST, etc).
private int mMode;
+ private Point mCurrentSize;
private boolean mThumbnailsEnabled = true;
/**
@@ -69,7 +83,7 @@ public class IconHelper {
public IconHelper(Context context, int mode) {
mContext = context;
setViewMode(mode);
- mCache = DocumentsApplication.getThumbnailsCache(context, mThumbSize);
+ mThumbnailCache = DocumentsApplication.getThumbnailCache(context);
}
/**
@@ -83,14 +97,14 @@ public class IconHelper {
}
/**
- * Sets the current display mode. This affects the thumbnail sizes that are loaded.
+ * Sets the current display mode. This affects the thumbnail sizes that are loaded.
+ *
* @param mode See {@link State.MODE_LIST} and {@link State.MODE_GRID}.
*/
public void setViewMode(@ViewMode int mode) {
mMode = mode;
int thumbSize = getThumbSize(mode);
- mThumbSize = new Point(thumbSize, thumbSize);
- mCache = DocumentsApplication.getThumbnailsCache(mContext, mThumbSize);
+ mCurrentSize = new Point(thumbSize, thumbSize);
}
private int getThumbSize(int mode) {
@@ -111,6 +125,7 @@ public class IconHelper {
/**
* Cancels any ongoing load operations associated with the given ImageView.
+ *
* @param icon
*/
public void stopLoading(ImageView icon) {
@@ -129,14 +144,21 @@ public class IconHelper {
private final ImageView mIconMime;
private final ImageView mIconThumb;
private final Point mThumbSize;
+ private final long mLastModified;
+
+ // A callback to apply animation to image views after the thumbnail is loaded.
+ private final BiConsumer<View, View> mImageAnimator;
+
private final CancellationSignal mSignal;
public LoaderTask(Uri uri, ImageView iconMime, ImageView iconThumb,
- Point thumbSize) {
+ Point thumbSize, long lastModified, BiConsumer<View, View> animator) {
mUri = uri;
mIconMime = iconMime;
mIconThumb = iconThumb;
mThumbSize = thumbSize;
+ mImageAnimator = animator;
+ mLastModified = lastModified;
mSignal = new CancellationSignal();
if (DEBUG) Log.d(TAG, "Starting icon loader task for " + mUri);
}
@@ -150,8 +172,9 @@ public class IconHelper {
@Override
protected Bitmap doInBackground(Uri... params) {
- if (isCancelled())
+ if (isCancelled()) {
return null;
+ }
final Context context = mIconThumb.getContext();
final ContentResolver resolver = context.getContentResolver();
@@ -163,9 +186,8 @@ public class IconHelper {
resolver, mUri.getAuthority());
result = DocumentsContract.getDocumentThumbnail(client, mUri, mThumbSize, mSignal);
if (result != null) {
- final ThumbnailCache thumbs = DocumentsApplication.getThumbnailsCache(
- context, mThumbSize);
- thumbs.put(mUri, result);
+ final ThumbnailCache cache = DocumentsApplication.getThumbnailCache(context);
+ cache.putThumbnail(mUri, mThumbSize, result, mLastModified);
}
} catch (Exception e) {
if (!(e instanceof OperationCanceledException)) {
@@ -185,28 +207,27 @@ public class IconHelper {
mIconThumb.setTag(null);
mIconThumb.setImageBitmap(result);
- float alpha = mIconMime.getAlpha();
- mIconMime.animate().alpha(0f).start();
- mIconThumb.setAlpha(0f);
- mIconThumb.animate().alpha(alpha).start();
+ mImageAnimator.accept(mIconMime, mIconThumb);
}
}
}
/**
* Load thumbnails for a directory list item.
+ *
* @param uri The URI for the file being represented.
* @param mimeType The mime type of the file being represented.
* @param docFlags Flags for the file being represented.
* @param docIcon Custom icon (if any) for the file being requested.
+ * @param docLastModified the last modified value of the file being requested.
* @param iconThumb The itemview's thumbnail icon.
* @param iconMime The itemview's mime icon. Hidden when iconThumb is shown.
* @param subIconMime The second itemview's mime icon. Always visible.
* @return
*/
- public void loadThumbnail(Uri uri, String mimeType, int docFlags, int docIcon,
+ public void load(Uri uri, String mimeType, int docFlags, int docIcon, long docLastModified,
ImageView iconThumb, ImageView iconMime, @Nullable ImageView subIconMime) {
- boolean cacheHit = false;
+ boolean loadedThumbnail = false;
final String docAuthority = uri.getAuthority();
@@ -215,48 +236,66 @@ public class IconHelper {
|| MimePredicate.mimeMatches(MimePredicate.VISUAL_MIMES, mimeType);
final boolean showThumbnail = supportsThumbnail && allowThumbnail && mThumbnailsEnabled;
if (showThumbnail) {
- final Bitmap cachedResult = mCache.get(uri);
- if (cachedResult != null) {
- iconThumb.setImageBitmap(cachedResult);
- cacheHit = true;
- } else {
- iconThumb.setImageDrawable(null);
- final LoaderTask task = new LoaderTask(uri, iconMime, iconThumb, mThumbSize);
- iconThumb.setTag(task);
- ProviderExecutor.forAuthority(docAuthority).execute(task);
- }
+ loadedThumbnail =
+ loadThumbnail(uri, docAuthority, docLastModified, iconThumb, iconMime);
}
- final Drawable icon = getDocumentIcon(mContext, docAuthority,
+ final Drawable mimeIcon = getDocumentIcon(mContext, docAuthority,
DocumentsContract.getDocumentId(uri), mimeType, docIcon);
if (subIconMime != null) {
- subIconMime.setImageDrawable(icon);
+ setMimeIcon(subIconMime, mimeIcon);
}
- if (cacheHit) {
- iconMime.setImageDrawable(null);
- iconMime.setAlpha(0f);
- iconThumb.setAlpha(1f);
+ if (loadedThumbnail) {
+ hideImageView(iconMime);
} else {
- // Add a mime icon if the thumbnail is being loaded in the background.
- iconThumb.setImageDrawable(null);
- iconMime.setImageDrawable(icon);
- iconMime.setAlpha(1f);
- iconThumb.setAlpha(0f);
+ // Add a mime icon if the thumbnail is not shown.
+ setMimeIcon(iconMime, mimeIcon);
+ hideImageView(iconThumb);
}
}
- /**
- * Gets a mime icon or package icon for a file.
- * @param context
- * @param authority The authority string of the file.
- * @param id The document ID of the file.
- * @param mimeType The mime type of the file.
- * @param icon The custom icon (if any) of the file.
- * @return
- */
- public Drawable getDocumentIcon(Context context, String authority, String id,
- String mimeType, int icon) {
+ private boolean loadThumbnail(Uri uri, String docAuthority, long docLastModified,
+ ImageView iconThumb, ImageView iconMime) {
+ final Result result = mThumbnailCache.getThumbnail(uri, mCurrentSize);
+
+ try {
+ final Bitmap cachedThumbnail = result.getThumbnail();
+ iconThumb.setImageBitmap(cachedThumbnail);
+
+ boolean stale = (docLastModified > result.getLastModified());
+ if (DEBUG) Log.d(TAG,
+ String.format("Load thumbnail for %s, got result %d and stale %b.",
+ uri.toString(), result.getStatus(), stale));
+ if (!result.isExactHit() || stale) {
+ final BiConsumer<View, View> animator =
+ (cachedThumbnail == null ? ANIM_FADE_IN : ANIM_NO_OP);
+ final LoaderTask task = new LoaderTask(uri, iconMime, iconThumb, mCurrentSize,
+ docLastModified, animator);
+
+ iconThumb.setTag(task);
+
+ ProviderExecutor.forAuthority(docAuthority).execute(task);
+ }
+
+ return result.isHit();
+ } finally {
+ result.recycle();
+ }
+ }
+
+ private void setMimeIcon(ImageView view, Drawable icon) {
+ view.setImageDrawable(icon);
+ view.setAlpha(1f);
+ }
+
+ private void hideImageView(ImageView view) {
+ view.setImageDrawable(null);
+ view.setAlpha(0f);
+ }
+
+ private Drawable getDocumentIcon(
+ Context context, String authority, String id, String mimeType, int icon) {
if (icon != 0) {
return IconUtils.loadPackageIcon(context, authority, icon);
} else {
@@ -264,4 +303,11 @@ public class IconHelper {
}
}
+ /**
+ * Returns a mime icon or package icon for a {@link DocumentInfo}.
+ */
+ public Drawable getDocumentIcon(Context context, DocumentInfo doc) {
+ return getDocumentIcon(
+ context, doc.authority, doc.documentId, doc.mimeType, doc.icon);
+ }
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java
index ace53e0b5f4e..e88be0cfe969 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java
@@ -133,7 +133,8 @@ final class ListDocumentHolder extends DocumentHolder {
mIconThumb.setAlpha(0f);
final Uri uri = DocumentsContract.buildDocumentUri(docAuthority, docId);
- mIconHelper.loadThumbnail(uri, docMimeType, docFlags, docIcon, mIconThumb, mIconMime, null);
+ mIconHelper.load(uri, docMimeType, docFlags, docIcon, docLastModified, mIconThumb,
+ mIconMime, null);
mTitle.setText(docDisplayName, TextView.BufferType.SPANNABLE);
mTitle.setVisibility(View.VISIBLE);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListeningGestureDetector.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListeningGestureDetector.java
new file mode 100644
index 000000000000..85ff6ed44119
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListeningGestureDetector.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.dirlist;
+
+import android.content.Context;
+import android.support.v13.view.DragStartHelper;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.OnItemTouchListener;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnTouchListener;
+
+import com.android.documentsui.Events;
+
+// Previously we listened to events with one class, only to bounce them forward
+// to GestureDetector. We're still doing that here, but with a single class
+// that reduces overall complexity in our glue code.
+final class ListeningGestureDetector extends GestureDetector
+ implements OnItemTouchListener, OnTouchListener {
+
+ private DragStartHelper mDragHelper;
+ private UserInputHandler mInputHandler;
+
+ public ListeningGestureDetector(
+ Context context, DragStartHelper dragHelper, UserInputHandler handler) {
+ super(context, handler);
+ mDragHelper = dragHelper;
+ mInputHandler = handler;
+ setOnDoubleTapListener(handler);
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
+ // TODO: If possible, move this into UserInputHandler.
+ if (e.getAction() == MotionEvent.ACTION_DOWN && Events.isMouseEvent(e)) {
+ mInputHandler.setLastButtonState(e.getButtonState());
+ }
+
+ // Detect drag events. When a drag is detected, intercept the rest of the gesture.
+ View itemView = rv.findChildViewUnder(e.getX(), e.getY());
+ if (itemView != null && mDragHelper.onTouch(itemView, e)) {
+ return true;
+ }
+ // Forward unhandled events to the GestureDetector.
+ onTouchEvent(e);
+
+ return false;
+ }
+
+ @Override
+ public void onTouchEvent(RecyclerView rv, MotionEvent e) {
+ View itemView = rv.findChildViewUnder(e.getX(), e.getY());
+ mDragHelper.onTouch(itemView, e);
+ // Note: even though this event is being handled as part of a drag gesture, continue
+ // forwarding to the GestureDetector. The detector needs to see the entire cluster of
+ // events in order to properly interpret gestures.
+ onTouchEvent(e);
+ }
+
+ @Override
+ public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
+
+ // For mEmptyView right-click context menu
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ if (event.getButtonState() == MotionEvent.BUTTON_SECONDARY) {
+ return mInputHandler.onSingleRightClickUp(event);
+ }
+ return false;
+ }
+} \ No newline at end of file
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java
index 0a2960f8ffe0..5c1522811364 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java
@@ -25,6 +25,7 @@ import static com.android.documentsui.model.DocumentInfo.getCursorString;
import android.database.Cursor;
import android.database.MergeCursor;
+import android.net.Uri;
import android.os.Bundle;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
@@ -39,7 +40,6 @@ import com.android.documentsui.dirlist.MultiSelectManager.Selection;
import com.android.documentsui.model.DocumentInfo;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -389,15 +389,15 @@ public class Model {
return mIsLoading;
}
- List<DocumentInfo> getDocuments(Selection items) {
- final int size = (items != null) ? items.size() : 0;
+ List<DocumentInfo> getDocuments(Selection selection) {
+ final int size = (selection != null) ? selection.size() : 0;
final List<DocumentInfo> docs = new ArrayList<>(size);
- for (String modelId: items.getAll()) {
+ // NOTE: That as this now iterates over only final (non-provisional) selection.
+ for (String modelId: selection) {
final Cursor cursor = getItem(modelId);
if (cursor == null) {
- Log.w(TAG,
- "Skipping document. Unabled to obtain cursor for modelId: " + modelId);
+ Log.w(TAG, "Skipping document. Unabled to obtain cursor for modelId: " + modelId);
continue;
}
docs.add(DocumentInfo.fromDirectoryCursor(cursor));
@@ -405,6 +405,11 @@ public class Model {
return docs;
}
+ public Uri getItemUri(String modelId) {
+ final Cursor cursor = getItem(modelId);
+ return DocumentInfo.getUri(cursor);
+ }
+
void addUpdateListener(UpdateListener listener) {
mUpdateListeners.add(listener);
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java
index ca3b2e23648b..2c1a221a4426 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java
@@ -25,11 +25,9 @@ import static com.android.documentsui.model.DocumentInfo.getCursorString;
import android.database.Cursor;
import android.provider.DocumentsContract.Document;
import android.util.Log;
-import android.util.SparseArray;
import android.view.ViewGroup;
import com.android.documentsui.State;
-import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.HashSet;
@@ -166,26 +164,6 @@ final class ModelBackedDocumentsAdapter extends DocumentsAdapter {
}
@Override
- public SparseArray<String> hide(String... ids) {
- if (DEBUG) Log.d(TAG, "Hiding ids: " + ids);
- Set<String> toHide = Sets.newHashSet(ids);
-
- // Proceed backwards through the list of items, because each removal causes the
- // positions of all subsequent items to change.
- SparseArray<String> hiddenItems = new SparseArray<>();
- for (int i = mModelIds.size() - 1; i >= 0; --i) {
- String id = mModelIds.get(i);
- if (toHide.contains(id)) {
- mHiddenIds.add(id);
- hiddenItems.put(i, mModelIds.remove(i));
- notifyItemRemoved(i);
- }
- }
-
- return hiddenItems;
- }
-
- @Override
public List<String> getModelIds() {
return mModelIds;
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java
index 8852985da5d5..9c0b967b7ce4 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java
@@ -17,41 +17,27 @@
package com.android.documentsui.dirlist;
import static com.android.documentsui.Shared.DEBUG;
-import static com.android.documentsui.dirlist.ModelBackedDocumentsAdapter.ITEM_TYPE_DIRECTORY;
-import static com.android.documentsui.dirlist.ModelBackedDocumentsAdapter.ITEM_TYPE_DOCUMENT;
import android.annotation.IntDef;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
-import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
-import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
-import android.util.SparseArray;
-import android.util.SparseBooleanArray;
-import android.util.SparseIntArray;
-import android.view.MotionEvent;
-import android.view.View;
-
-import com.android.documentsui.Events.InputEvent;
-import com.android.documentsui.Events.MotionInputEvent;
-import com.android.documentsui.R;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import javax.annotation.Nullable;
+
/**
* MultiSelectManager provides support traditional multi-item selection support to RecyclerView.
* Additionally it can be configured to restrict selection to a single element, @see
@@ -72,76 +58,19 @@ public final class MultiSelectManager {
private final Selection mSelection = new Selection();
- private final SelectionEnvironment mEnvironment;
private final DocumentsAdapter mAdapter;
private final List<MultiSelectManager.Callback> mCallbacks = new ArrayList<>(1);
- private Range mRanger;
+ private @Nullable Range mRanger;
private boolean mSingleSelect;
- @Nullable private BandController mBandManager;
-
-
- /**
- * @param mode Selection single or multiple selection mode.
- * @param initialSelection selection state probably preserved in external state.
- */
- public MultiSelectManager(
- final RecyclerView recyclerView,
- DocumentsAdapter adapter,
- @SelectionMode int mode,
- @Nullable Selection initialSelection) {
-
- this(new RuntimeSelectionEnvironment(recyclerView), adapter, mode, initialSelection);
-
- if (mode == MODE_MULTIPLE) {
- // TODO: Don't load this on low memory devices.
- mBandManager = new BandController();
- }
-
- recyclerView.addOnItemTouchListener(
- new RecyclerView.OnItemTouchListener() {
- @Override
- public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
- if (mBandManager != null) {
- return mBandManager.handleEvent(new MotionInputEvent(e, recyclerView));
- }
- return false;
- }
-
- @Override
- public void onTouchEvent(RecyclerView rv, MotionEvent e) {
- mBandManager.processInputEvent(
- new MotionInputEvent(e, recyclerView));
- }
- @Override
- public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
- });
- }
+ public MultiSelectManager(DocumentsAdapter adapter, @SelectionMode int mode) {
- /**
- * Constructs a new instance with {@code adapter} and {@code helper}.
- * @param runtimeSelectionEnvironment
- * @hide
- */
- @VisibleForTesting
- MultiSelectManager(
- SelectionEnvironment environment,
- DocumentsAdapter adapter,
- @SelectionMode int mode,
- @Nullable Selection initialSelection) {
-
- assert(environment != null);
assert(adapter != null);
- mEnvironment = environment;
mAdapter = adapter;
mSingleSelect = mode == MODE_SINGLE;
- if (initialSelection != null) {
- mSelection.copyFrom(initialSelection);
- }
-
mAdapter.registerAdapterDataObserver(
new RecyclerView.AdapterDataObserver() {
@@ -154,10 +83,6 @@ public final class MultiSelectManager {
// Update the selection to remove any disappeared IDs.
mSelection.cancelProvisionalSelection();
mSelection.intersect(mModelIds);
-
- if (mBandManager != null && mBandManager.isActive()) {
- mBandManager.endBandSelect();
- }
}
@Override
@@ -188,6 +113,11 @@ public final class MultiSelectManager {
});
}
+ void bindContoller(BandController controller) {
+ // Provides BandController with access to private mSelection state.
+ controller.bindSelection(mSelection);
+ }
+
/**
* Adds {@code callback} such that it will be notified when {@code MultiSelectManager}
* events occur.
@@ -227,11 +157,18 @@ public final class MultiSelectManager {
return dest;
}
+ public void replaceSelection(Iterable<String> ids) {
+ clearSelection();
+ setItemsSelected(ids, true);
+ }
+
/**
- * Updates selection to include items in {@code selection}.
+ * Returns an unordered array of selected positions, including any
+ * provisional selection currently in effect.
*/
- public void updateSelection(Selection selection) {
- setItemsSelected(selection.toList(), true);
+ public void restoreSelection(Selection other) {
+ setItemsSelected(other.mSelection, true);
+ // NOTE: We intentionally don't restore provisional selection. It's provisional.
}
/**
@@ -263,12 +200,6 @@ public final class MultiSelectManager {
notifySelectionChanged();
}
- public void handleLayoutChanged() {
- if (mBandManager != null) {
- mBandManager.handleLayoutChanged();
- }
- }
-
/**
* Clears the selection, without notifying selection listeners. UI elements still need to be
* notified about state changes so that they can update their appearance.
@@ -283,76 +214,21 @@ public final class MultiSelectManager {
Selection oldSelection = getSelection(new Selection());
mSelection.clear();
- for (String id: oldSelection.getAll()) {
+ for (String id: oldSelection.mSelection) {
notifyItemStateChanged(id, false);
}
- }
-
- @VisibleForTesting
- void onLongPress(InputEvent input) {
- if (DEBUG) Log.d(TAG, "Handling long press event.");
-
- if (!input.isOverItem()) {
- if (DEBUG) Log.i(TAG, "Cannot handle tap. No adapter position available.");
- }
-
- handleAdapterEvent(input);
- }
-
- @VisibleForTesting
- boolean onSingleTapUp(InputEvent input) {
- if (DEBUG) Log.d(TAG, "Processing tap event.");
- if (!hasSelection()) {
- // No selection active - do nothing.
- return false;
- }
-
- if (!input.isOverItem()) {
- if (DEBUG) Log.d(TAG, "Activity has no position. Canceling selection.");
- clearSelection();
- return false;
+ for (String id: oldSelection.mProvisionalSelection) {
+ notifyItemStateChanged(id, false);
}
-
- handleAdapterEvent(input);
- return true;
}
- /**
- * Handles a change caused by a click on the item with the given position. If the Shift key is
- * held down, this performs a range select; otherwise, it simply toggles the item's selection
- * state.
- */
- private void handleAdapterEvent(InputEvent input) {
- if (mRanger != null && input.isShiftKeyDown()) {
- mRanger.snapSelection(input.getItemPosition());
-
- // We're being lazy here notifying even when something might not have changed.
- // To make this more correct, we'd need to update the Ranger class to return
- // information about what has changed.
- notifySelectionChanged();
- } else {
- int position = input.getItemPosition();
- toggleSelection(position);
- setSelectionRangeBegin(position);
- }
- }
+ void snapSelection(int position) {
+ mRanger.snapSelection(position);
- /**
- * A convenience method for toggling selection by adapter position.
- *
- * @param position Adapter position to toggle.
- */
- private void toggleSelection(int position) {
- // Position may be special "no position" during certain
- // transitional phases. If so, skip handling of the event.
- if (position == RecyclerView.NO_POSITION) {
- if (DEBUG) Log.d(TAG, "Ignoring toggle for element with no position.");
- return;
- }
- String id = mAdapter.getModelId(position);
- if (id != null) {
- toggleSelection(id);
- }
+ // We're being lazy here notifying even when something might not have changed.
+ // To make this more correct, we'd need to update the Ranger class to return
+ // information about what has changed.
+ notifySelectionChanged();
}
/**
@@ -395,7 +271,9 @@ public final class MultiSelectManager {
* @param pos The new end position for the selection range.
*/
void snapRangeSelection(int pos) {
- assert(mRanger != null);
+ if (!isRangeSelectionActive()) {
+ throw new IllegalStateException("Range start point not set.");
+ }
mRanger.snapSelection(pos);
notifySelectionChanged();
@@ -511,7 +389,7 @@ public final class MultiSelectManager {
return true;
}
- private boolean notifyBeforeItemStateChange(String id, boolean nextState) {
+ boolean notifyBeforeItemStateChange(String id, boolean nextState) {
int lastListener = mCallbacks.size() - 1;
for (int i = lastListener; i > -1; i--) {
if (!mCallbacks.get(i).onBeforeItemStateChange(id, nextState)) {
@@ -525,7 +403,7 @@ public final class MultiSelectManager {
* Notifies registered listeners when the selection status of a single item
* (identified by {@code position}) changes.
*/
- private void notifyItemStateChanged(String id, boolean selected) {
+ void notifyItemStateChanged(String id, boolean selected) {
assert(id != null);
int lastListener = mCallbacks.size() - 1;
for (int i = lastListener; i > -1; i--) {
@@ -540,7 +418,7 @@ public final class MultiSelectManager {
* is complete, e.g. clearingSelection, or updating the single
* selection from one item to another.
*/
- private void notifySelectionChanged() {
+ void notifySelectionChanged() {
int lastListener = mCallbacks.size() - 1;
for (int i = lastListener; i > -1; i--) {
mCallbacks.get(i).onSelectionChanged();
@@ -651,7 +529,7 @@ public final class MultiSelectManager {
* Object representing the current selection. Provides read only access
* public access, and private write access.
*/
- public static final class Selection implements Parcelable {
+ public static final class Selection implements Iterable<String>, Parcelable {
// This class tracks selected items by managing two sets: the saved selection, and the total
// selection. Saved selections are those which have been completed by tapping an item or by
@@ -691,24 +569,18 @@ public final class MultiSelectManager {
}
/**
- * Returns an unordered array of selected positions.
- */
- public String[] getAll() {
- return toList().toArray(new String[0]);
- }
-
- /**
- * Returns an unordered array of selected positions (including any
- * provisional selections current in effect).
+ * Returns an {@link Iterator} that iterators over the selection, *excluding*
+ * any provisional selection.
+ *
+ * {@inheritDoc}
*/
- public List<String> toList() {
- ArrayList<String> selection = new ArrayList<String>(mSelection);
- selection.addAll(mProvisionalSelection);
- return selection;
+ @Override
+ public Iterator<String> iterator() {
+ return mSelection.iterator();
}
/**
- * @return size of the selection.
+ * @return size of the selection including both final and provisional selected items.
*/
public int size() {
return mSelection.size() + mProvisionalSelection.size();
@@ -889,6 +761,7 @@ public final class MultiSelectManager {
return 0;
}
+ @Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mDirectoryKey);
dest.writeStringList(new ArrayList<>(mSelection));
@@ -920,162 +793,6 @@ public final class MultiSelectManager {
};
}
- /**
- * Provides functionality for BandController. Exists primarily to tests that are
- * fully isolated from RecyclerView.
- */
- interface SelectionEnvironment {
- void showBand(Rect rect);
- void hideBand();
- void addOnScrollListener(RecyclerView.OnScrollListener listener);
- void removeOnScrollListener(RecyclerView.OnScrollListener listener);
- void scrollBy(int dy);
- int getHeight();
- void invalidateView();
- void runAtNextFrame(Runnable r);
- void removeCallback(Runnable r);
- Point createAbsolutePoint(Point relativePoint);
- Rect getAbsoluteRectForChildViewAt(int index);
- int getAdapterPositionAt(int index);
- int getColumnCount();
- int getChildCount();
- int getVisibleChildCount();
- /**
- * Layout items are excluded from the GridModel.
- */
- boolean isLayoutItem(int adapterPosition);
- /**
- * Items may be in the adapter, but without an attached view.
- */
- boolean hasView(int adapterPosition);
- }
-
- /** Recycler view facade implementation backed by good ol' RecyclerView. */
- private static final class RuntimeSelectionEnvironment implements SelectionEnvironment {
-
- private final RecyclerView mView;
- private final Drawable mBand;
-
- private boolean mIsOverlayShown = false;
-
- RuntimeSelectionEnvironment(RecyclerView view) {
- mView = view;
- mBand = mView.getContext().getTheme().getDrawable(R.drawable.band_select_overlay);
- }
-
- @Override
- public int getAdapterPositionAt(int index) {
- return mView.getChildAdapterPosition(mView.getChildAt(index));
- }
-
- @Override
- public void addOnScrollListener(RecyclerView.OnScrollListener listener) {
- mView.addOnScrollListener(listener);
- }
-
- @Override
- public void removeOnScrollListener(RecyclerView.OnScrollListener listener) {
- mView.removeOnScrollListener(listener);
- }
-
- @Override
- public Point createAbsolutePoint(Point relativePoint) {
- return new Point(relativePoint.x + mView.computeHorizontalScrollOffset(),
- relativePoint.y + mView.computeVerticalScrollOffset());
- }
-
- @Override
- public Rect getAbsoluteRectForChildViewAt(int index) {
- final View child = mView.getChildAt(index);
- final Rect childRect = new Rect();
- child.getHitRect(childRect);
- childRect.left += mView.computeHorizontalScrollOffset();
- childRect.right += mView.computeHorizontalScrollOffset();
- childRect.top += mView.computeVerticalScrollOffset();
- childRect.bottom += mView.computeVerticalScrollOffset();
- return childRect;
- }
-
- @Override
- public int getChildCount() {
- return mView.getAdapter().getItemCount();
- }
-
- @Override
- public int getVisibleChildCount() {
- return mView.getChildCount();
- }
-
- @Override
- public int getColumnCount() {
- RecyclerView.LayoutManager layoutManager = mView.getLayoutManager();
- if (layoutManager instanceof GridLayoutManager) {
- return ((GridLayoutManager) layoutManager).getSpanCount();
- }
-
- // Otherwise, it is a list with 1 column.
- return 1;
- }
-
- @Override
- public int getHeight() {
- return mView.getHeight();
- }
-
- @Override
- public void invalidateView() {
- mView.invalidate();
- }
-
- @Override
- public void runAtNextFrame(Runnable r) {
- mView.postOnAnimation(r);
- }
-
- @Override
- public void removeCallback(Runnable r) {
- mView.removeCallbacks(r);
- }
-
- @Override
- public void scrollBy(int dy) {
- mView.scrollBy(0, dy);
- }
-
- @Override
- public void showBand(Rect rect) {
- mBand.setBounds(rect);
-
- if (!mIsOverlayShown) {
- mView.getOverlay().add(mBand);
- }
- }
-
- @Override
- public void hideBand() {
- mView.getOverlay().remove(mBand);
- }
-
- @Override
- public boolean isLayoutItem(int pos) {
- // The band selection model only operates on documents and directories. Exclude other
- // types of adapter items (e.g. whitespace items like dividers).
- RecyclerView.ViewHolder vh = mView.findViewHolderForAdapterPosition(pos);
- switch (vh.getItemViewType()) {
- case ITEM_TYPE_DOCUMENT:
- case ITEM_TYPE_DIRECTORY:
- return false;
- default:
- return true;
- }
- }
-
- @Override
- public boolean hasView(int pos) {
- return mView.findViewHolderForAdapterPosition(pos) != null;
- }
- }
-
public interface Callback {
/**
* Called when an item is selected or unselected while in selection mode.
@@ -1101,958 +818,4 @@ public final class MultiSelectManager {
*/
public void onSelectionChanged();
}
-
- /**
- * Provides mouse driven band-select support when used in conjunction with {@link RecyclerView}
- * and {@link MultiSelectManager}. This class is responsible for rendering the band select
- * overlay and selecting overlaid items via MultiSelectManager.
- */
- public class BandController extends RecyclerView.OnScrollListener
- implements GridModel.OnSelectionChangedListener {
-
- private static final int NOT_SET = -1;
-
- private final Runnable mModelBuilder;
-
- @Nullable private Rect mBounds;
- @Nullable private Point mCurrentPosition;
- @Nullable private Point mOrigin;
- @Nullable private GridModel mModel;
-
- // The time at which the current band selection-induced scroll began. If no scroll is in
- // progress, the value is NOT_SET.
- private long mScrollStartTime = NOT_SET;
- private final Runnable mViewScroller = new ViewScroller();
-
- public BandController() {
- mEnvironment.addOnScrollListener(this);
-
- mModelBuilder = new Runnable() {
- @Override
- public void run() {
- mModel = new GridModel(mEnvironment, mAdapter);
- mModel.addOnSelectionChangedListener(BandController.this);
- }
- };
- }
-
- public boolean handleEvent(MotionInputEvent e) {
- // b/23793622 notes the fact that we *never* receive ACTION_DOWN
- // events in onTouchEvent. Where it not for this issue, we'd
- // push start handling down into handleInputEvent.
- if (mBandManager.shouldStart(e)) {
- // endBandSelect is handled in handleInputEvent.
- mBandManager.startBandSelect(e.getOrigin());
- } else if (mBandManager.isActive()
- && e.isMouseEvent()
- && e.isActionUp()) {
- // Same issue here w b/23793622. The ACTION_UP event
- // is only evert dispatched to onTouchEvent when
- // there is some associated motion. If a user taps
- // mouse, but doesn't move, then band select gets
- // started BUT not ended. Causing phantom
- // bands to appear when the user later clicks to start
- // band select.
- mBandManager.processInputEvent(e);
- }
-
- return isActive();
- }
-
- private boolean isActive() {
- return mModel != null;
- }
-
- /**
- * Handle a change in layout by cleaning up and getting rid of the old model and creating
- * a new model which will track the new layout.
- */
- public void handleLayoutChanged() {
- if (mModel != null) {
- mModel.removeOnSelectionChangedListener(this);
- mModel.stopListening();
-
- // build a new model, all fresh and happy.
- mModelBuilder.run();
- }
- }
-
- boolean shouldStart(MotionInputEvent e) {
- return !isActive()
- && e.isMouseEvent() // a mouse
- && e.isActionDown() // the initial button press
- && mAdapter.getItemCount() > 0
- && e.getItemPosition() == RecyclerView.NO_ID; // in empty space
- }
-
- boolean shouldStop(InputEvent input) {
- return isActive()
- && input.isMouseEvent()
- && input.isActionUp();
- }
-
- /**
- * Processes a MotionEvent by starting, ending, or resizing the band select overlay.
- * @param input
- */
- private void processInputEvent(InputEvent input) {
- assert(input.isMouseEvent());
-
- if (shouldStop(input)) {
- endBandSelect();
- return;
- }
-
- // We shouldn't get any events in this method when band select is not active,
- // but it turns some guests show up late to the party.
- if (!isActive()) {
- return;
- }
-
- mCurrentPosition = input.getOrigin();
- mModel.resizeSelection(input.getOrigin());
- scrollViewIfNecessary();
- resizeBandSelectRectangle();
- }
-
- /**
- * Starts band select by adding the drawable to the RecyclerView's overlay.
- */
- private void startBandSelect(Point origin) {
- if (DEBUG) Log.d(TAG, "Starting band select @ " + origin);
-
- mOrigin = origin;
- mModelBuilder.run(); // Creates a new selection model.
- mModel.startSelection(mOrigin);
- }
-
- /**
- * Scrolls the view if necessary.
- */
- private void scrollViewIfNecessary() {
- mEnvironment.removeCallback(mViewScroller);
- mViewScroller.run();
- mEnvironment.invalidateView();
- }
-
- /**
- * Resizes the band select rectangle by using the origin and the current pointer position as
- * two opposite corners of the selection.
- */
- private void resizeBandSelectRectangle() {
- mBounds = new Rect(Math.min(mOrigin.x, mCurrentPosition.x),
- Math.min(mOrigin.y, mCurrentPosition.y),
- Math.max(mOrigin.x, mCurrentPosition.x),
- Math.max(mOrigin.y, mCurrentPosition.y));
- mEnvironment.showBand(mBounds);
- }
-
- /**
- * Ends band select by removing the overlay.
- */
- private void endBandSelect() {
- if (DEBUG) Log.d(TAG, "Ending band select.");
-
- mEnvironment.hideBand();
- mSelection.applyProvisionalSelection();
- mModel.endSelection();
- int firstSelected = mModel.getPositionNearestOrigin();
- if (firstSelected != NOT_SET) {
- if (mSelection.contains(mAdapter.getModelId(firstSelected))) {
- // TODO: firstSelected should really be lastSelected, we want to anchor the item
- // where the mouse-up occurred.
- setSelectionRangeBegin(firstSelected);
- } else {
- // TODO: Check if this is really happening.
- Log.w(TAG, "First selected by band is NOT in selection!");
- }
- }
-
- mModel = null;
- mOrigin = null;
- }
-
- @Override
- public void onSelectionChanged(Set<String> updatedSelection) {
- Map<String, Boolean> delta = mSelection.setProvisionalSelection(updatedSelection);
- for (Map.Entry<String, Boolean> entry: delta.entrySet()) {
- notifyItemStateChanged(entry.getKey(), entry.getValue());
- }
- notifySelectionChanged();
- }
-
- @Override
- public boolean onBeforeItemStateChange(String id, boolean nextState) {
- return notifyBeforeItemStateChange(id, nextState);
- }
-
- private class ViewScroller implements Runnable {
- /**
- * The number of milliseconds of scrolling at which scroll speed continues to increase.
- * At first, the scroll starts slowly; then, the rate of scrolling increases until it
- * reaches its maximum value at after this many milliseconds.
- */
- private static final long SCROLL_ACCELERATION_LIMIT_TIME_MS = 2000;
-
- @Override
- public void run() {
- // Compute the number of pixels the pointer's y-coordinate is past the view.
- // Negative values mean the pointer is at or before the top of the view, and
- // positive values mean that the pointer is at or after the bottom of the view. Note
- // that one additional pixel is added here so that the view still scrolls when the
- // pointer is exactly at the top or bottom.
- int pixelsPastView = 0;
- if (mCurrentPosition.y <= 0) {
- pixelsPastView = mCurrentPosition.y - 1;
- } else if (mCurrentPosition.y >= mEnvironment.getHeight() - 1) {
- pixelsPastView = mCurrentPosition.y - mEnvironment.getHeight() + 1;
- }
-
- if (!isActive() || pixelsPastView == 0) {
- // If band selection is inactive, or if it is active but not at the edge of the
- // view, no scrolling is necessary.
- mScrollStartTime = NOT_SET;
- return;
- }
-
- if (mScrollStartTime == NOT_SET) {
- // If the pointer was previously not at the edge of the view but now is, set the
- // start time for the scroll.
- mScrollStartTime = System.currentTimeMillis();
- }
-
- // Compute the number of pixels to scroll, and scroll that many pixels.
- final int numPixels = computeScrollDistance(
- pixelsPastView, System.currentTimeMillis() - mScrollStartTime);
- mEnvironment.scrollBy(numPixels);
-
- mEnvironment.removeCallback(mViewScroller);
- mEnvironment.runAtNextFrame(this);
- }
-
- /**
- * Computes the number of pixels to scroll based on how far the pointer is past the end
- * of the view and how long it has been there. Roughly based on ItemTouchHelper's
- * algorithm for computing the number of pixels to scroll when an item is dragged to the
- * end of a {@link RecyclerView}.
- * @param pixelsPastView
- * @param scrollDuration
- * @return
- */
- private int computeScrollDistance(int pixelsPastView, long scrollDuration) {
- final int maxScrollStep = mEnvironment.getHeight();
- final int direction = (int) Math.signum(pixelsPastView);
- final int absPastView = Math.abs(pixelsPastView);
-
- // Calculate the ratio of how far out of the view the pointer currently resides to
- // the entire height of the view.
- final float outOfBoundsRatio = Math.min(
- 1.0f, (float) absPastView / mEnvironment.getHeight());
- // Interpolate this ratio and use it to compute the maximum scroll that should be
- // possible for this step.
- final float cappedScrollStep =
- direction * maxScrollStep * smoothOutOfBoundsRatio(outOfBoundsRatio);
-
- // Likewise, calculate the ratio of the time spent in the scroll to the limit.
- final float timeRatio = Math.min(
- 1.0f, (float) scrollDuration / SCROLL_ACCELERATION_LIMIT_TIME_MS);
- // Interpolate this ratio and use it to compute the final number of pixels to
- // scroll.
- final int numPixels = (int) (cappedScrollStep * smoothTimeRatio(timeRatio));
-
- // If the final number of pixels to scroll ends up being 0, the view should still
- // scroll at least one pixel.
- return numPixels != 0 ? numPixels : direction;
- }
-
- /**
- * Interpolates the given out of bounds ratio on a curve which starts at (0,0) and ends
- * at (1,1) and quickly approaches 1 near the start of that interval. This ensures that
- * drags that are at the edge or barely past the edge of the view still cause sufficient
- * scrolling. The equation y=(x-1)^5+1 is used, but this could also be tweaked if
- * needed.
- * @param ratio A ratio which is in the range [0, 1].
- * @return A "smoothed" value, also in the range [0, 1].
- */
- private float smoothOutOfBoundsRatio(float ratio) {
- return (float) Math.pow(ratio - 1.0f, 5) + 1.0f;
- }
-
- /**
- * Interpolates the given time ratio on a curve which starts at (0,0) and ends at (1,1)
- * and stays close to 0 for most input values except those very close to 1. This ensures
- * that scrolls start out very slowly but speed up drastically after the scroll has been
- * in progress close to SCROLL_ACCELERATION_LIMIT_TIME_MS. The equation y=x^5 is used,
- * but this could also be tweaked if needed.
- * @param ratio A ratio which is in the range [0, 1].
- * @return A "smoothed" value, also in the range [0, 1].
- */
- private float smoothTimeRatio(float ratio) {
- return (float) Math.pow(ratio, 5);
- }
- };
-
- @Override
- public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
- if (!isActive()) {
- return;
- }
-
- // Adjust the y-coordinate of the origin the opposite number of pixels so that the
- // origin remains in the same place relative to the view's items.
- mOrigin.y -= dy;
- resizeBandSelectRectangle();
- }
- }
-
- /**
- * Provides a band selection item model for views within a RecyclerView. This class queries the
- * RecyclerView to determine where its items are placed; then, once band selection is underway,
- * it alerts listeners of which items are covered by the selections.
- */
- public static final class GridModel extends RecyclerView.OnScrollListener {
-
- public static final int NOT_SET = -1;
-
- // Enum values used to determine the corner at which the origin is located within the
- private static final int UPPER = 0x00;
- private static final int LOWER = 0x01;
- private static final int LEFT = 0x00;
- private static final int RIGHT = 0x02;
- private static final int UPPER_LEFT = UPPER | LEFT;
- private static final int UPPER_RIGHT = UPPER | RIGHT;
- private static final int LOWER_LEFT = LOWER | LEFT;
- private static final int LOWER_RIGHT = LOWER | RIGHT;
-
- private final SelectionEnvironment mHelper;
- private final DocumentsAdapter mAdapter;
-
- private final List<OnSelectionChangedListener> mOnSelectionChangedListeners =
- new ArrayList<>();
-
- // Map from the x-value of the left side of a SparseBooleanArray of adapter positions, keyed
- // by their y-offset. For example, if the first column of the view starts at an x-value of 5,
- // mColumns.get(5) would return an array of positions in that column. Within that array, the
- // value for key y is the adapter position for the item whose y-offset is y.
- private final SparseArray<SparseIntArray> mColumns = new SparseArray<>();
-
- // List of limits along the x-axis (columns).
- // This list is sorted from furthest left to furthest right.
- private final List<Limits> mColumnBounds = new ArrayList<>();
-
- // List of limits along the y-axis (rows). Note that this list only contains items which
- // have been in the viewport.
- private final List<Limits> mRowBounds = new ArrayList<>();
-
- // The adapter positions which have been recorded so far.
- private final SparseBooleanArray mKnownPositions = new SparseBooleanArray();
-
- // Array passed to registered OnSelectionChangedListeners. One array is created and reused
- // throughout the lifetime of the object.
- private final Set<String> mSelection = new HashSet<>();
-
- // The current pointer (in absolute positioning from the top of the view).
- private Point mPointer = null;
-
- // The bounds of the band selection.
- private RelativePoint mRelativeOrigin;
- private RelativePoint mRelativePointer;
-
- private boolean mIsActive;
-
- // Tracks where the band select originated from. This is used to determine where selections
- // should expand from when Shift+click is used.
- private int mPositionNearestOrigin = NOT_SET;
-
- GridModel(SelectionEnvironment helper, DocumentsAdapter adapter) {
- mHelper = helper;
- mAdapter = adapter;
- mHelper.addOnScrollListener(this);
- }
-
- /**
- * Stops listening to the view's scrolls. Call this function before discarding a
- * BandSelecModel object to prevent memory leaks.
- */
- void stopListening() {
- mHelper.removeOnScrollListener(this);
- }
-
- /**
- * Start a band select operation at the given point.
- * @param relativeOrigin The origin of the band select operation, relative to the viewport.
- * For example, if the view is scrolled to the bottom, the top-left of the viewport
- * would have a relative origin of (0, 0), even though its absolute point has a higher
- * y-value.
- */
- void startSelection(Point relativeOrigin) {
- recordVisibleChildren();
- if (isEmpty()) {
- // The selection band logic works only if there is at least one visible child.
- return;
- }
-
- mIsActive = true;
- mPointer = mHelper.createAbsolutePoint(relativeOrigin);
- mRelativeOrigin = new RelativePoint(mPointer);
- mRelativePointer = new RelativePoint(mPointer);
- computeCurrentSelection();
- notifyListeners();
- }
-
- /**
- * Resizes the selection by adjusting the pointer (i.e., the corner of the selection
- * opposite the origin.
- * @param relativePointer The pointer (opposite of the origin) of the band select operation,
- * relative to the viewport. For example, if the view is scrolled to the bottom, the
- * top-left of the viewport would have a relative origin of (0, 0), even though its
- * absolute point has a higher y-value.
- */
- @VisibleForTesting
- void resizeSelection(Point relativePointer) {
- mPointer = mHelper.createAbsolutePoint(relativePointer);
- updateModel();
- }
-
- /**
- * Ends the band selection.
- */
- void endSelection() {
- mIsActive = false;
- }
-
- /**
- * @return The adapter position for the item nearest the origin corresponding to the latest
- * band select operation, or NOT_SET if the selection did not cover any items.
- */
- int getPositionNearestOrigin() {
- return mPositionNearestOrigin;
- }
-
- @Override
- public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
- if (!mIsActive) {
- return;
- }
-
- mPointer.x += dx;
- mPointer.y += dy;
- recordVisibleChildren();
- updateModel();
- }
-
- /**
- * Queries the view for all children and records their location metadata.
- */
- private void recordVisibleChildren() {
- for (int i = 0; i < mHelper.getVisibleChildCount(); i++) {
- int adapterPosition = mHelper.getAdapterPositionAt(i);
- // Sometimes the view is not attached, as we notify the multi selection manager
- // synchronously, while views are attached asynchronously. As a result items which
- // are in the adapter may not actually have a corresponding view (yet).
- if (mHelper.hasView(adapterPosition) &&
- !mHelper.isLayoutItem(adapterPosition) &&
- !mKnownPositions.get(adapterPosition)) {
- mKnownPositions.put(adapterPosition, true);
- recordItemData(mHelper.getAbsoluteRectForChildViewAt(i), adapterPosition);
- }
- }
- }
-
- /**
- * Checks if there are any recorded children.
- */
- private boolean isEmpty() {
- return mColumnBounds.size() == 0 || mRowBounds.size() == 0;
- }
-
- /**
- * Updates the limits lists and column map with the given item metadata.
- * @param absoluteChildRect The absolute rectangle for the child view being processed.
- * @param adapterPosition The position of the child view being processed.
- */
- private void recordItemData(Rect absoluteChildRect, int adapterPosition) {
- if (mColumnBounds.size() != mHelper.getColumnCount()) {
- // If not all x-limits have been recorded, record this one.
- recordLimits(
- mColumnBounds, new Limits(absoluteChildRect.left, absoluteChildRect.right));
- }
-
- recordLimits(mRowBounds, new Limits(absoluteChildRect.top, absoluteChildRect.bottom));
-
- SparseIntArray columnList = mColumns.get(absoluteChildRect.left);
- if (columnList == null) {
- columnList = new SparseIntArray();
- mColumns.put(absoluteChildRect.left, columnList);
- }
- columnList.put(absoluteChildRect.top, adapterPosition);
- }
-
- /**
- * Ensures limits exists within the sorted list limitsList, and adds it to the list if it
- * does not exist.
- */
- private void recordLimits(List<Limits> limitsList, Limits limits) {
- int index = Collections.binarySearch(limitsList, limits);
- if (index < 0) {
- limitsList.add(~index, limits);
- }
- }
-
- /**
- * Handles a moved pointer; this function determines whether the pointer movement resulted
- * in a selection change and, if it has, notifies listeners of this change.
- */
- private void updateModel() {
- RelativePoint old = mRelativePointer;
- mRelativePointer = new RelativePoint(mPointer);
- if (old != null && mRelativePointer.equals(old)) {
- return;
- }
-
- computeCurrentSelection();
- notifyListeners();
- }
-
- /**
- * Computes the currently-selected items.
- */
- private void computeCurrentSelection() {
- if (areItemsCoveredByBand(mRelativePointer, mRelativeOrigin)) {
- updateSelection(computeBounds());
- } else {
- mSelection.clear();
- mPositionNearestOrigin = NOT_SET;
- }
- }
-
- /**
- * Notifies all listeners of a selection change. Note that this function simply passes
- * mSelection, so computeCurrentSelection() should be called before this
- * function.
- */
- private void notifyListeners() {
- for (OnSelectionChangedListener listener : mOnSelectionChangedListeners) {
- listener.onSelectionChanged(mSelection);
- }
- }
-
- /**
- * @param rect Rectangle including all covered items.
- */
- private void updateSelection(Rect rect) {
- int columnStart =
- Collections.binarySearch(mColumnBounds, new Limits(rect.left, rect.left));
- assert(columnStart >= 0);
- int columnEnd = columnStart;
-
- for (int i = columnStart; i < mColumnBounds.size()
- && mColumnBounds.get(i).lowerLimit <= rect.right; i++) {
- columnEnd = i;
- }
-
- int rowStart = Collections.binarySearch(mRowBounds, new Limits(rect.top, rect.top));
- if (rowStart < 0) {
- mPositionNearestOrigin = NOT_SET;
- return;
- }
-
- int rowEnd = rowStart;
- for (int i = rowStart; i < mRowBounds.size()
- && mRowBounds.get(i).lowerLimit <= rect.bottom; i++) {
- rowEnd = i;
- }
-
- updateSelection(columnStart, columnEnd, rowStart, rowEnd);
- }
-
- /**
- * Computes the selection given the previously-computed start- and end-indices for each
- * row and column.
- */
- private void updateSelection(
- int columnStartIndex, int columnEndIndex, int rowStartIndex, int rowEndIndex) {
- if (DEBUG) Log.d(TAG, String.format("updateSelection: %d, %d, %d, %d",
- columnStartIndex, columnEndIndex, rowStartIndex, rowEndIndex));
-
- mSelection.clear();
- for (int column = columnStartIndex; column <= columnEndIndex; column++) {
- SparseIntArray items = mColumns.get(mColumnBounds.get(column).lowerLimit);
- for (int row = rowStartIndex; row <= rowEndIndex; row++) {
- // The default return value for SparseIntArray.get is 0, which is a valid
- // position. Use a sentry value to prevent erroneously selecting item 0.
- final int rowKey = mRowBounds.get(row).lowerLimit;
- int position = items.get(rowKey, NOT_SET);
- if (position != NOT_SET) {
- String id = mAdapter.getModelId(position);
- if (id != null) {
- // The adapter inserts items for UI layout purposes that aren't associated
- // with files. Those will have a null model ID. Don't select them.
- if (canSelect(id)) {
- mSelection.add(id);
- }
- }
- if (isPossiblePositionNearestOrigin(column, columnStartIndex, columnEndIndex,
- row, rowStartIndex, rowEndIndex)) {
- // If this is the position nearest the origin, record it now so that it
- // can be returned by endSelection() later.
- mPositionNearestOrigin = position;
- }
- }
- }
- }
- }
-
- /**
- * @return True if the item is selectable.
- */
- private boolean canSelect(String id) {
- // TODO: Simplify the logic, so the check whether we can select is done in one place.
- // Consider injecting FragmentTuner, or move the checks from MultiSelectManager to
- // Selection.
- for (OnSelectionChangedListener listener : mOnSelectionChangedListeners) {
- if (!listener.onBeforeItemStateChange(id, true)) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * @return Returns true if the position is the nearest to the origin, or, in the case of the
- * lower-right corner, whether it is possible that the position is the nearest to the
- * origin. See comment below for reasoning for this special case.
- */
- private boolean isPossiblePositionNearestOrigin(int columnIndex, int columnStartIndex,
- int columnEndIndex, int rowIndex, int rowStartIndex, int rowEndIndex) {
- int corner = computeCornerNearestOrigin();
- switch (corner) {
- case UPPER_LEFT:
- return columnIndex == columnStartIndex && rowIndex == rowStartIndex;
- case UPPER_RIGHT:
- return columnIndex == columnEndIndex && rowIndex == rowStartIndex;
- case LOWER_LEFT:
- return columnIndex == columnStartIndex && rowIndex == rowEndIndex;
- case LOWER_RIGHT:
- // Note that in some cases, the last row will not have as many items as there
- // are columns (e.g., if there are 4 items and 3 columns, the second row will
- // only have one item in the first column). This function is invoked for each
- // position from left to right, so return true for any position in the bottom
- // row and only the right-most position in the bottom row will be recorded.
- return rowIndex == rowEndIndex;
- default:
- throw new RuntimeException("Invalid corner type.");
- }
- }
-
- /**
- * Listener for changes in which items have been band selected.
- */
- static interface OnSelectionChangedListener {
- public void onSelectionChanged(Set<String> updatedSelection);
- public boolean onBeforeItemStateChange(String id, boolean nextState);
- }
-
- void addOnSelectionChangedListener(OnSelectionChangedListener listener) {
- mOnSelectionChangedListeners.add(listener);
- }
-
- void removeOnSelectionChangedListener(OnSelectionChangedListener listener) {
- mOnSelectionChangedListeners.remove(listener);
- }
-
- /**
- * Limits of a view item. For example, if an item's left side is at x-value 5 and its right side
- * is at x-value 10, the limits would be from 5 to 10. Used to record the left- and right sides
- * of item columns and the top- and bottom sides of item rows so that it can be determined
- * whether the pointer is located within the bounds of an item.
- */
- private static class Limits implements Comparable<Limits> {
- int lowerLimit;
- int upperLimit;
-
- Limits(int lowerLimit, int upperLimit) {
- this.lowerLimit = lowerLimit;
- this.upperLimit = upperLimit;
- }
-
- @Override
- public int compareTo(Limits other) {
- return lowerLimit - other.lowerLimit;
- }
-
- @Override
- public boolean equals(Object other) {
- if (!(other instanceof Limits)) {
- return false;
- }
-
- return ((Limits) other).lowerLimit == lowerLimit &&
- ((Limits) other).upperLimit == upperLimit;
- }
-
- @Override
- public String toString() {
- return "(" + lowerLimit + ", " + upperLimit + ")";
- }
- }
-
- /**
- * The location of a coordinate relative to items. This class represents a general area of the
- * view as it relates to band selection rather than an explicit point. For example, two
- * different points within an item are considered to have the same "location" because band
- * selection originating within the item would select the same items no matter which point
- * was used. Same goes for points between items as well as those at the very beginning or end
- * of the view.
- *
- * Tracking a coordinate (e.g., an x-value) as a CoordinateLocation instead of as an int has the
- * advantage of tying the value to the Limits of items along that axis. This allows easy
- * selection of items within those Limits as opposed to a search through every item to see if a
- * given coordinate value falls within those Limits.
- */
- private static class RelativeCoordinate
- implements Comparable<RelativeCoordinate> {
- /**
- * Location describing points after the last known item.
- */
- static final int AFTER_LAST_ITEM = 0;
-
- /**
- * Location describing points before the first known item.
- */
- static final int BEFORE_FIRST_ITEM = 1;
-
- /**
- * Location describing points between two items.
- */
- static final int BETWEEN_TWO_ITEMS = 2;
-
- /**
- * Location describing points within the limits of one item.
- */
- static final int WITHIN_LIMITS = 3;
-
- /**
- * The type of this coordinate, which is one of AFTER_LAST_ITEM, BEFORE_FIRST_ITEM,
- * BETWEEN_TWO_ITEMS, or WITHIN_LIMITS.
- */
- final int type;
-
- /**
- * The limits before the coordinate; only populated when type == WITHIN_LIMITS or type ==
- * BETWEEN_TWO_ITEMS.
- */
- Limits limitsBeforeCoordinate;
-
- /**
- * The limits after the coordinate; only populated when type == BETWEEN_TWO_ITEMS.
- */
- Limits limitsAfterCoordinate;
-
- // Limits of the first known item; only populated when type == BEFORE_FIRST_ITEM.
- Limits mFirstKnownItem;
- // Limits of the last known item; only populated when type == AFTER_LAST_ITEM.
- Limits mLastKnownItem;
-
- /**
- * @param limitsList The sorted limits list for the coordinate type. If this
- * CoordinateLocation is an x-value, mXLimitsList should be passed; otherwise,
- * mYLimitsList should be pased.
- * @param value The coordinate value.
- */
- RelativeCoordinate(List<Limits> limitsList, int value) {
- int index = Collections.binarySearch(limitsList, new Limits(value, value));
-
- if (index >= 0) {
- this.type = WITHIN_LIMITS;
- this.limitsBeforeCoordinate = limitsList.get(index);
- } else if (~index == 0) {
- this.type = BEFORE_FIRST_ITEM;
- this.mFirstKnownItem = limitsList.get(0);
- } else if (~index == limitsList.size()) {
- Limits lastLimits = limitsList.get(limitsList.size() - 1);
- if (lastLimits.lowerLimit <= value && value <= lastLimits.upperLimit) {
- this.type = WITHIN_LIMITS;
- this.limitsBeforeCoordinate = lastLimits;
- } else {
- this.type = AFTER_LAST_ITEM;
- this.mLastKnownItem = lastLimits;
- }
- } else {
- Limits limitsBeforeIndex = limitsList.get(~index - 1);
- if (limitsBeforeIndex.lowerLimit <= value && value <= limitsBeforeIndex.upperLimit) {
- this.type = WITHIN_LIMITS;
- this.limitsBeforeCoordinate = limitsList.get(~index - 1);
- } else {
- this.type = BETWEEN_TWO_ITEMS;
- this.limitsBeforeCoordinate = limitsList.get(~index - 1);
- this.limitsAfterCoordinate = limitsList.get(~index);
- }
- }
- }
-
- int toComparisonValue() {
- if (type == BEFORE_FIRST_ITEM) {
- return mFirstKnownItem.lowerLimit - 1;
- } else if (type == AFTER_LAST_ITEM) {
- return mLastKnownItem.upperLimit + 1;
- } else if (type == BETWEEN_TWO_ITEMS) {
- return limitsBeforeCoordinate.upperLimit + 1;
- } else {
- return limitsBeforeCoordinate.lowerLimit;
- }
- }
-
- @Override
- public boolean equals(Object other) {
- if (!(other instanceof RelativeCoordinate)) {
- return false;
- }
-
- RelativeCoordinate otherCoordinate = (RelativeCoordinate) other;
- return toComparisonValue() == otherCoordinate.toComparisonValue();
- }
-
- @Override
- public int compareTo(RelativeCoordinate other) {
- return toComparisonValue() - other.toComparisonValue();
- }
- }
-
- /**
- * The location of a point relative to the Limits of nearby items; consists of both an x- and
- * y-RelativeCoordinateLocation.
- */
- private class RelativePoint {
- final RelativeCoordinate xLocation;
- final RelativeCoordinate yLocation;
-
- RelativePoint(Point point) {
- this.xLocation = new RelativeCoordinate(mColumnBounds, point.x);
- this.yLocation = new RelativeCoordinate(mRowBounds, point.y);
- }
-
- @Override
- public boolean equals(Object other) {
- if (!(other instanceof RelativePoint)) {
- return false;
- }
-
- RelativePoint otherPoint = (RelativePoint) other;
- return xLocation.equals(otherPoint.xLocation) && yLocation.equals(otherPoint.yLocation);
- }
- }
-
- /**
- * Generates a rectangle which contains the items selected by the pointer and origin.
- * @return The rectangle, or null if no items were selected.
- */
- private Rect computeBounds() {
- Rect rect = new Rect();
- rect.left = getCoordinateValue(
- min(mRelativeOrigin.xLocation, mRelativePointer.xLocation),
- mColumnBounds,
- true);
- rect.right = getCoordinateValue(
- max(mRelativeOrigin.xLocation, mRelativePointer.xLocation),
- mColumnBounds,
- false);
- rect.top = getCoordinateValue(
- min(mRelativeOrigin.yLocation, mRelativePointer.yLocation),
- mRowBounds,
- true);
- rect.bottom = getCoordinateValue(
- max(mRelativeOrigin.yLocation, mRelativePointer.yLocation),
- mRowBounds,
- false);
- return rect;
- }
-
- /**
- * Computes the corner of the selection nearest the origin.
- * @return
- */
- private int computeCornerNearestOrigin() {
- int cornerValue = 0;
-
- if (mRelativeOrigin.yLocation ==
- min(mRelativeOrigin.yLocation, mRelativePointer.yLocation)) {
- cornerValue |= UPPER;
- } else {
- cornerValue |= LOWER;
- }
-
- if (mRelativeOrigin.xLocation ==
- min(mRelativeOrigin.xLocation, mRelativePointer.xLocation)) {
- cornerValue |= LEFT;
- } else {
- cornerValue |= RIGHT;
- }
-
- return cornerValue;
- }
-
- private RelativeCoordinate min(RelativeCoordinate first, RelativeCoordinate second) {
- return first.compareTo(second) < 0 ? first : second;
- }
-
- private RelativeCoordinate max(RelativeCoordinate first, RelativeCoordinate second) {
- return first.compareTo(second) > 0 ? first : second;
- }
-
- /**
- * @return The absolute coordinate (i.e., the x- or y-value) of the given relative
- * coordinate.
- */
- private int getCoordinateValue(RelativeCoordinate coordinate,
- List<Limits> limitsList, boolean isStartOfRange) {
- switch (coordinate.type) {
- case RelativeCoordinate.BEFORE_FIRST_ITEM:
- return limitsList.get(0).lowerLimit;
- case RelativeCoordinate.AFTER_LAST_ITEM:
- return limitsList.get(limitsList.size() - 1).upperLimit;
- case RelativeCoordinate.BETWEEN_TWO_ITEMS:
- if (isStartOfRange) {
- return coordinate.limitsAfterCoordinate.lowerLimit;
- } else {
- return coordinate.limitsBeforeCoordinate.upperLimit;
- }
- case RelativeCoordinate.WITHIN_LIMITS:
- return coordinate.limitsBeforeCoordinate.lowerLimit;
- }
-
- throw new RuntimeException("Invalid coordinate value.");
- }
-
- private boolean areItemsCoveredByBand(
- RelativePoint first, RelativePoint second) {
- return doesCoordinateLocationCoverItems(first.xLocation, second.xLocation) &&
- doesCoordinateLocationCoverItems(first.yLocation, second.yLocation);
- }
-
- private boolean doesCoordinateLocationCoverItems(
- RelativeCoordinate pointerCoordinate,
- RelativeCoordinate originCoordinate) {
- if (pointerCoordinate.type == RelativeCoordinate.BEFORE_FIRST_ITEM &&
- originCoordinate.type == RelativeCoordinate.BEFORE_FIRST_ITEM) {
- return false;
- }
-
- if (pointerCoordinate.type == RelativeCoordinate.AFTER_LAST_ITEM &&
- originCoordinate.type == RelativeCoordinate.AFTER_LAST_ITEM) {
- return false;
- }
-
- if (pointerCoordinate.type == RelativeCoordinate.BETWEEN_TWO_ITEMS &&
- originCoordinate.type == RelativeCoordinate.BETWEEN_TWO_ITEMS &&
- pointerCoordinate.limitsBeforeCoordinate.equals(
- originCoordinate.limitsBeforeCoordinate) &&
- pointerCoordinate.limitsAfterCoordinate.equals(
- originCoordinate.limitsAfterCoordinate)) {
- return false;
- }
-
- return true;
- }
- }
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapper.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapper.java
index b6980596908c..55a6de79d6c5 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapper.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapper.java
@@ -20,7 +20,6 @@ import android.content.Context;
import android.database.Cursor;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView.AdapterDataObserver;
-import android.util.SparseArray;
import android.view.ViewGroup;
import android.widget.Space;
@@ -162,13 +161,6 @@ final class SectionBreakDocumentsAdapterWrapper extends DocumentsAdapter {
}
@Override
- public SparseArray<String> hide(String... ids) {
- // NOTE: We hear about these changes and adjust break position
- // in our AdapterDataObserver.
- return mDelegate.hide(ids);
- }
-
- @Override
List<String> getModelIds() {
return mDelegate.getModelIds();
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/TouchSwipeRefreshLayout.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/TouchSwipeRefreshLayout.java
new file mode 100644
index 000000000000..42634ba08854
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/TouchSwipeRefreshLayout.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.dirlist;
+
+import android.content.Context;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+
+import com.android.documentsui.Events;
+
+/**
+ * A {@link SwipeRefreshLayout} that only refresh on touch events.
+ */
+public class TouchSwipeRefreshLayout extends SwipeRefreshLayout {
+
+ public TouchSwipeRefreshLayout(Context context) {
+ this(context, null);
+ }
+
+ public TouchSwipeRefreshLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent e) {
+ return Events.isMouseEvent(e) ? false : super.onInterceptTouchEvent(e);
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/UserInputHandler.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/UserInputHandler.java
new file mode 100644
index 000000000000..07b0cd8f7248
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/UserInputHandler.java
@@ -0,0 +1,423 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.dirlist;
+
+import static com.android.documentsui.Shared.DEBUG;
+
+import android.support.annotation.VisibleForTesting;
+import android.util.Log;
+import android.view.GestureDetector;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import com.android.documentsui.Events;
+import com.android.documentsui.Events.InputEvent;
+import com.android.documentsui.dirlist.DocumentHolder.KeyboardEventListener;
+
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+/**
+ * Grand unified-ish gesture/event listener for items in the directory list.
+ */
+public final class UserInputHandler<T extends InputEvent>
+ extends GestureDetector.SimpleOnGestureListener
+ implements KeyboardEventListener {
+
+ private static final String TAG = "UserInputHandler";
+
+ private final MultiSelectManager mSelectionMgr;
+ private final FocusHandler mFocusHandler;
+ private final Function<MotionEvent, T> mEventConverter;
+ private final Function<T, DocumentDetails> mDocFinder;
+ private final Predicate<DocumentDetails> mSelectable;
+ private final EventHandler mRightClickHandler;
+ private final DocumentHandler mActivateHandler;
+ private final DocumentHandler mDeleteHandler;
+ private final TouchInputDelegate mTouchDelegate;
+ private final MouseInputDelegate mMouseDelegate;
+ private final KeyInputHandler mKeyListener;
+
+ public UserInputHandler(
+ MultiSelectManager selectionMgr,
+ FocusHandler focusHandler,
+ Function<MotionEvent, T> eventConverter,
+ Function<T, DocumentDetails> docFinder,
+ Predicate<DocumentDetails> selectable,
+ EventHandler rightClickHandler,
+ DocumentHandler activateHandler,
+ DocumentHandler deleteHandler) {
+
+ mSelectionMgr = selectionMgr;
+ mFocusHandler = focusHandler;
+ mEventConverter = eventConverter;
+ mDocFinder = docFinder;
+ mSelectable = selectable;
+ mRightClickHandler = rightClickHandler;
+ mActivateHandler = activateHandler;
+ mDeleteHandler = deleteHandler;
+
+ mTouchDelegate = new TouchInputDelegate();
+ mMouseDelegate = new MouseInputDelegate();
+ mKeyListener = new KeyInputHandler();
+ }
+
+ @Override
+ public boolean onSingleTapUp(MotionEvent e) {
+ try (T event = mEventConverter.apply(e)) {
+ return onSingleTapUp(event);
+ }
+ }
+
+ @VisibleForTesting
+ boolean onSingleTapUp(T event) {
+ return event.isMouseEvent()
+ ? mMouseDelegate.onSingleTapUp(event)
+ : mTouchDelegate.onSingleTapUp(event);
+ }
+
+ @Override
+ public boolean onSingleTapConfirmed(MotionEvent e) {
+ try (T event = mEventConverter.apply(e)) {
+ return onSingleTapConfirmed(event);
+ }
+ }
+
+ @VisibleForTesting
+ boolean onSingleTapConfirmed(T event) {
+ return event.isMouseEvent()
+ ? mMouseDelegate.onSingleTapConfirmed(event)
+ : mTouchDelegate.onSingleTapConfirmed(event);
+ }
+
+ @Override
+ public boolean onDoubleTap(MotionEvent e) {
+ try (T event = mEventConverter.apply(e)) {
+ return onDoubleTap(event);
+ }
+ }
+
+ @VisibleForTesting
+ boolean onDoubleTap(T event) {
+ return event.isMouseEvent()
+ ? mMouseDelegate.onDoubleTap(event)
+ : mTouchDelegate.onDoubleTap(event);
+ }
+
+ @Override
+ public void onLongPress(MotionEvent e) {
+ try (T event = mEventConverter.apply(e)) {
+ onLongPress(event);
+ }
+ }
+
+ @VisibleForTesting
+ void onLongPress(T event) {
+ if (event.isMouseEvent()) {
+ mMouseDelegate.onLongPress(event);
+ }
+ mTouchDelegate.onLongPress(event);
+ }
+
+ public boolean onSingleRightClickUp(MotionEvent e) {
+ try (T event = mEventConverter.apply(e)) {
+ return mMouseDelegate.onSingleRightClickUp(event);
+ }
+ }
+
+ @Override
+ public boolean onKey(DocumentHolder doc, int keyCode, KeyEvent event) {
+ return mKeyListener.onKey(doc, keyCode, event);
+ }
+
+ // TODO: Isolate this hack...see if we can't get this solved at the platform level.
+ public void setLastButtonState(int state) {
+ mMouseDelegate.setLastButtonState(state);
+ }
+
+ private boolean activateDocument(DocumentDetails doc) {
+ return mActivateHandler.accept(doc);
+ }
+
+ private boolean selectDocument(DocumentDetails doc) {
+ assert(doc != null);
+ mSelectionMgr.toggleSelection(doc.getModelId());
+ mSelectionMgr.setSelectionRangeBegin(doc.getAdapterPosition());
+ return true;
+ }
+
+ boolean isRangeExtension(T event) {
+ return event.isShiftKeyDown() && mSelectionMgr.isRangeSelectionActive();
+ }
+
+ private void extendSelectionRange(T event) {
+ mSelectionMgr.snapSelection(event.getItemPosition());
+ }
+
+ private final class TouchInputDelegate {
+
+ boolean onSingleTapUp(T event) {
+ if (!event.isOverItem()) {
+ if (DEBUG) Log.d(TAG, "Tap on non-item. Clearing selection.");
+ mSelectionMgr.clearSelection();
+ return false;
+ }
+
+ if (mSelectionMgr.hasSelection()) {
+ if (isRangeExtension(event)) {
+ mSelectionMgr.snapSelection(event.getItemPosition());
+ } else {
+ selectDocument(mDocFinder.apply(event));
+ }
+ return true;
+ }
+
+ // Give the DocumentHolder a crack at the event.
+ DocumentDetails doc = mDocFinder.apply(event);
+ if (doc != null) {
+ // Touch events select if they occur in the selection hotspot,
+ // otherwise they activate.
+ return doc.isInSelectionHotspot(event)
+ ? selectDocument(doc)
+ : activateDocument(doc);
+ }
+
+ return false;
+ }
+
+ boolean onSingleTapConfirmed(T event) {
+ return false;
+ }
+
+ boolean onDoubleTap(T event) {
+ return false;
+ }
+
+ final void onLongPress(T event) {
+ if (!event.isOverItem()) {
+ return;
+ }
+
+ if (isRangeExtension(event)) {
+ extendSelectionRange(event);
+ } else {
+ selectDocument(mDocFinder.apply(event));
+ }
+ }
+ }
+
+ private final class MouseInputDelegate {
+
+ // From the RecyclerView, we get two events sent to
+ // ListeningGestureDetector#onInterceptTouchEvent on a mouse click; we first get an
+ // ACTION_DOWN Event for clicking on the mouse, and then an ACTION_UP event from releasing
+ // the mouse click. ACTION_UP event doesn't have information regarding the button (primary
+ // vs. secondary), so we have to save that somewhere first from ACTION_DOWN, and then reuse
+ // it later. The ACTION_DOWN event doesn't get forwarded to UserInputListener,
+ // so we have open up a public set method to set it.
+ private int mLastButtonState = -1;
+
+ // true when the previous event has consumed a right click motion event
+ private boolean mAteRightClick;
+
+ // The event has been handled in onSingleTapUp
+ private boolean mHandledTapUp;
+
+ boolean onSingleTapUp(T event) {
+ if (eatRightClick()) {
+ return onSingleRightClickUp(event);
+ }
+
+ if (!event.isOverItem()) {
+ mSelectionMgr.clearSelection();
+ return false;
+ }
+
+ if (mSelectionMgr.hasSelection()) {
+ if (isRangeExtension(event)) {
+ extendSelectionRange(event);
+ } else {
+ selectDocument(mDocFinder.apply(event));
+ }
+ mHandledTapUp = true;
+ return true;
+ }
+
+ // We'll toggle selection in onSingleTapConfirmed
+ // This avoids flickering on/off action mode when an item is double clicked.
+ if (!mSelectionMgr.hasSelection()) {
+ return false;
+ }
+
+ DocumentDetails doc = mDocFinder.apply(event);
+ if (doc == null) {
+ return false;
+ }
+
+ mHandledTapUp = true;
+ return selectDocument(doc);
+ }
+
+ boolean onSingleTapConfirmed(T event) {
+ if (mAteRightClick) {
+ mAteRightClick = false;
+ return false;
+ }
+ if (mHandledTapUp) {
+ mHandledTapUp = false;
+ return false;
+ }
+
+ if (mSelectionMgr.hasSelection()) {
+ return false; // should have been handled by onSingleTapUp.
+ }
+
+ DocumentDetails doc = mDocFinder.apply(event);
+ if (doc == null) {
+ return false;
+ }
+
+ return selectDocument(doc);
+ }
+
+ boolean onDoubleTap(T event) {
+ mHandledTapUp = false;
+ DocumentDetails doc = mDocFinder.apply(event);
+ if (doc != null) {
+ return mSelectionMgr.hasSelection()
+ ? selectDocument(doc)
+ : activateDocument(doc);
+ }
+ return false;
+ }
+
+ final void onLongPress(T event) {
+ if (!event.isOverItem()) {
+ return;
+ }
+
+ if (isRangeExtension(event)) {
+ extendSelectionRange(event);
+ } else {
+ selectDocument(mDocFinder.apply(event));
+ }
+ }
+
+ private boolean onSingleRightClickUp(T event) {
+ return mRightClickHandler.apply(event);
+ }
+
+ // hack alert from here through end of class.
+ private void setLastButtonState(int state) {
+ mLastButtonState = state;
+ }
+
+ private boolean eatRightClick() {
+ if (mLastButtonState == MotionEvent.BUTTON_SECONDARY) {
+ mLastButtonState = -1;
+ mAteRightClick = true;
+ return true;
+ }
+ return false;
+ }
+ }
+
+ private final class KeyInputHandler {
+ // TODO: Refactor FocusManager to depend only on DocumentDetails so we can eliminate
+ // difficult to test dependency on DocumentHolder.
+
+ boolean onKey(DocumentHolder doc, int keyCode, KeyEvent event) {
+ // Only handle key-down events. This is simpler, consistent with most other UIs, and
+ // enables the handling of repeated key events from holding down a key.
+ if (event.getAction() != KeyEvent.ACTION_DOWN) {
+ return false;
+ }
+
+ // Ignore tab key events. Those should be handled by the top-level key handler.
+ if (keyCode == KeyEvent.KEYCODE_TAB) {
+ return false;
+ }
+
+ if (mFocusHandler.handleKey(doc, keyCode, event)) {
+ // Handle range selection adjustments. Extending the selection will adjust the
+ // bounds of the in-progress range selection. Each time an unshifted navigation
+ // event is received, the range selection is restarted.
+ if (shouldExtendSelection(doc, event)) {
+ if (!mSelectionMgr.isRangeSelectionActive()) {
+ // Start a range selection if one isn't active
+ mSelectionMgr.startRangeSelection(doc.getAdapterPosition());
+ }
+ mSelectionMgr.snapRangeSelection(mFocusHandler.getFocusPosition());
+ } else {
+ mSelectionMgr.endRangeSelection();
+ }
+ return true;
+ }
+
+ // Handle enter key events
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_ENTER:
+ if (event.isShiftPressed()) {
+ selectDocument(doc);
+ }
+ // For non-shifted enter keypresses, fall through.
+ case KeyEvent.KEYCODE_DPAD_CENTER:
+ case KeyEvent.KEYCODE_BUTTON_A:
+ return activateDocument(doc);
+ case KeyEvent.KEYCODE_FORWARD_DEL:
+ // This has to be handled here instead of in a keyboard shortcut, because
+ // keyboard shortcuts all have to be modified with the 'Ctrl' key.
+ if (mSelectionMgr.hasSelection()) {
+ mDeleteHandler.accept(doc);
+ }
+ // Always handle the key, even if there was nothing to delete. This is a
+ // precaution to prevent other handlers from potentially picking up the event
+ // and triggering extra behaviors.
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean shouldExtendSelection(DocumentDetails doc, KeyEvent event) {
+ if (!Events.isNavigationKeyCode(event.getKeyCode()) || !event.isShiftPressed()) {
+ return false;
+ }
+
+ return mSelectable.test(doc);
+ }
+ }
+
+ /**
+ * Class providing limited access to document view info.
+ */
+ public interface DocumentDetails {
+ String getModelId();
+ int getAdapterPosition();
+ boolean isInSelectionHotspot(InputEvent event);
+ }
+
+ @FunctionalInterface
+ interface EventHandler {
+ boolean apply(InputEvent event);
+ }
+
+ @FunctionalInterface
+ interface DocumentHandler {
+ boolean accept(DocumentDetails doc);
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
index 3a86a51b2d18..b54c9bb98ac7 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
@@ -30,14 +30,16 @@ import android.support.annotation.VisibleForTesting;
import com.android.documentsui.DocumentsApplication;
import com.android.documentsui.RootCursorWrapper;
-import libcore.io.IoUtils;
-
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.ProtocolException;
+import java.util.Arrays;
import java.util.Objects;
+import java.util.Set;
+
+import libcore.io.IoUtils;
/**
* Representation of a {@link Document}.
@@ -263,10 +265,12 @@ public class DocumentInfo implements Durable, Parcelable {
return (flags & Document.FLAG_VIRTUAL_DOCUMENT) != 0;
}
+ @Override
public int hashCode() {
return derivedUri.hashCode() + mimeType.hashCode();
}
+ @Override
public boolean equals(Object o) {
if (o == null) {
return false;
@@ -323,4 +327,21 @@ public class DocumentInfo implements Durable, Parcelable {
fnfe.initCause(t);
throw fnfe;
}
+
+ public static Uri getUri(Cursor cursor) {
+ return DocumentsContract.buildDocumentUri(
+ getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY),
+ getCursorString(cursor, Document.COLUMN_DOCUMENT_ID));
+ }
+
+ public static void addMimeTypes(ContentResolver resolver, Uri uri, Set<String> mimeTypes) {
+ assert(uri != null);
+ if ("content".equals(uri.getScheme())) {
+ mimeTypes.add(resolver.getType(uri));
+ final String[] streamTypes = resolver.getStreamTypes(uri, "*/*");
+ if (streamTypes != null) {
+ mimeTypes.addAll(Arrays.asList(streamTypes));
+ }
+ }
+ }
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentStack.java b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentStack.java
index 34bd6962788c..ae7e8207b77e 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentStack.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentStack.java
@@ -39,6 +39,33 @@ public class DocumentStack extends LinkedList<DocumentInfo> implements Durable,
public RootInfo root;
+ public DocumentStack() {};
+
+ /**
+ * Creates an instance, and pushes all docs to it in the same order as they're passed as
+ * parameters, i.e. the last document will be at the top of the stack.
+ */
+ public DocumentStack(RootInfo root, DocumentInfo... docs) {
+ for (DocumentInfo doc : docs) {
+ push(doc);
+ }
+
+ this.root = root;
+ }
+
+ /**
+ * Makes a new copy, and pushes all docs to the new copy in the same order as they're passed
+ * as parameters, i.e. the last document will be at the top of the stack.
+ */
+ public DocumentStack(DocumentStack src, DocumentInfo... docs) {
+ super(src);
+ for (DocumentInfo doc : docs) {
+ push(doc);
+ }
+
+ root = src.root;
+ }
+
public String getTitle() {
if (size() == 1 && root != null) {
return root.title;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
index 649dde049fc4..e062dfb2f096 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
@@ -23,6 +23,7 @@ import static com.android.documentsui.model.DocumentInfo.getCursorLong;
import static com.android.documentsui.model.DocumentInfo.getCursorString;
import android.annotation.IntDef;
+import android.annotation.Nullable;
import android.content.Context;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
@@ -39,6 +40,7 @@ import com.android.documentsui.R;
import java.io.DataInputStream;
import java.io.DataOutputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -94,6 +96,9 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {
public String[] derivedMimeTypes;
public int derivedIcon;
public @RootType int derivedType;
+ // Currently, we are not persisting this and we should be asking Provider whether a Root
+ // is in the process of eject. Provider does not have this available yet.
+ public transient boolean ejecting;
public RootInfo() {
reset();
@@ -110,6 +115,7 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {
documentId = null;
availableBytes = -1;
mimeTypes = null;
+ ejecting = false;
derivedMimeTypes = null;
derivedIcon = 0;
@@ -298,6 +304,10 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {
return (flags & Root.FLAG_SUPPORTS_SEARCH) != 0;
}
+ public boolean supportsEject() {
+ return (flags & Root.FLAG_SUPPORTS_EJECT) != 0;
+ }
+
public boolean isAdvanced() {
return (flags & Root.FLAG_ADVANCED) != 0;
}
@@ -334,6 +344,23 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {
}
}
+ public Drawable loadEjectIcon(Context context) {
+ return IconUtils.applyTintColor(context, R.drawable.ic_eject, R.color.item_eject_icon);
+ }
+
+ /**
+ * Gets the {@link DocumentInfo} of the root folder of this root.
+ */
+ public @Nullable DocumentInfo getRootDocumentBlocking(Context context) {
+ try {
+ final Uri uri = DocumentsContract.buildDocumentUri(authority, documentId);
+ return DocumentInfo.fromUri(context.getContentResolver(), uri);
+ } catch (FileNotFoundException e) {
+ Log.w(TAG, "Failed to find root", e);
+ return null;
+ }
+ }
+
@Override
public boolean equals(Object o) {
if (o == null) {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java b/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java
index 53fa3cc4abb4..c8f6a64e9a18 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java
@@ -21,12 +21,13 @@ import static android.provider.DocumentsContract.buildChildDocumentsUri;
import static android.provider.DocumentsContract.buildDocumentUri;
import static android.provider.DocumentsContract.getDocumentId;
import static android.provider.DocumentsContract.isChildDocument;
+
import static com.android.documentsui.OperationDialogFragment.DIALOG_TYPE_CONVERTED;
import static com.android.documentsui.Shared.DEBUG;
import static com.android.documentsui.model.DocumentInfo.getCursorLong;
import static com.android.documentsui.model.DocumentInfo.getCursorString;
import static com.android.documentsui.services.FileOperationService.EXTRA_DIALOG_TYPE;
-import static com.android.documentsui.services.FileOperationService.EXTRA_OPERATION;
+import static com.android.documentsui.services.FileOperationService.EXTRA_OPERATION_TYPE;
import static com.android.documentsui.services.FileOperationService.EXTRA_SRC_LIST;
import static com.android.documentsui.services.FileOperationService.OPERATION_COPY;
@@ -35,6 +36,7 @@ import android.app.Notification;
import android.app.Notification.Builder;
import android.app.PendingIntent;
import android.content.ContentProviderClient;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
@@ -45,16 +47,18 @@ import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
-import android.system.ErrnoException;
-import android.system.Os;
import android.text.format.DateUtils;
import android.util.Log;
import android.webkit.MimeTypeMap;
+import com.android.documentsui.DocumentsApplication;
import com.android.documentsui.Metrics;
import com.android.documentsui.R;
+import com.android.documentsui.RootsCache;
+import com.android.documentsui.clipping.UrisSupplier;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.DocumentStack;
+import com.android.documentsui.model.RootInfo;
import com.android.documentsui.services.FileOperationService.OpType;
import libcore.io.IoUtils;
@@ -62,7 +66,6 @@ import libcore.io.IoUtils;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
@@ -70,7 +73,6 @@ import java.util.List;
class CopyJob extends Job {
private static final String TAG = "CopyJob";
- private static final int PROGRESS_INTERVAL_MILLIS = 500;
final List<DocumentInfo> mSrcs;
final ArrayList<DocumentInfo> convertedFiles = new ArrayList<>();
@@ -78,8 +80,7 @@ class CopyJob extends Job {
private long mStartTime = -1;
private long mBatchSize;
- private long mBytesCopied;
- private long mLastNotificationTime;
+ private volatile long mBytesCopied;
// Speed estimation
private long mBytesCopiedSample;
private long mSampleTime;
@@ -87,30 +88,21 @@ class CopyJob extends Job {
private long mRemainingTime;
/**
- * Copies files to a destination identified by {@code destination}.
* @see @link {@link Job} constructor for most param descriptions.
- *
- * @param srcs List of files to be copied.
*/
- CopyJob(Context service, Context appContext, Listener listener,
- String id, DocumentStack stack, List<DocumentInfo> srcs) {
- super(service, appContext, listener, OPERATION_COPY, id, stack);
-
- assert(!srcs.isEmpty());
- this.mSrcs = srcs;
+ CopyJob(Context service, Listener listener, String id, DocumentStack destination,
+ UrisSupplier srcs) {
+ this(service, listener, id, OPERATION_COPY, destination, srcs);
}
- /**
- * @see @link {@link Job} constructor for most param descriptions.
- *
- * @param srcs List of files to be copied.
- */
- CopyJob(Context service, Context appContext, Listener listener,
- @OpType int opType, String id, DocumentStack destination, List<DocumentInfo> srcs) {
- super(service, appContext, listener, opType, id, destination);
+ CopyJob(Context service, Listener listener, String id, @OpType int opType,
+ DocumentStack destination, UrisSupplier srcs) {
+ super(service, listener, id, opType, destination, srcs);
+
+ assert(srcs.getItemCount() > 0);
- assert(!srcs.isEmpty());
- this.mSrcs = srcs;
+ // delay the initialization of it to setUp() because it may be IO extensive.
+ mSrcs = new ArrayList<>(srcs.getItemCount());
}
@Override
@@ -127,16 +119,13 @@ class CopyJob extends Job {
return getSetupNotification(service.getString(R.string.copy_preparing));
}
- public boolean shouldUpdateProgress() {
- // Wait a while between updates :)
- return elapsedRealtime() - mLastNotificationTime > PROGRESS_INTERVAL_MILLIS;
- }
-
Notification getProgressNotification(@StringRes int msgId) {
+ updateRemainingTimeEstimate();
+
if (mBatchSize >= 0) {
double completed = (double) this.mBytesCopied / mBatchSize;
mProgressBuilder.setProgress(100, (int) (completed * 100), false);
- mProgressBuilder.setContentInfo(
+ mProgressBuilder.setSubText(
NumberFormat.getPercentInstance().format(completed));
} else {
// If the total file size failed to compute on some files, then show
@@ -153,12 +142,10 @@ class CopyJob extends Job {
mProgressBuilder.setContentText(null);
}
- // Remember when we last returned progress so we can provide an answer
- // in shouldUpdateProgress.
- mLastNotificationTime = elapsedRealtime();
return mProgressBuilder.build();
}
+ @Override
public Notification getProgressNotification() {
return getProgressNotification(R.string.copy_remaining);
}
@@ -170,11 +157,14 @@ class CopyJob extends Job {
/**
* Generates an estimate of the remaining time in the copy.
*/
- void updateRemainingTimeEstimate() {
+ private void updateRemainingTimeEstimate() {
long elapsedTime = elapsedRealtime() - mStartTime;
- final long sampleDuration = elapsedTime - mSampleTime;
- final long sampleSpeed = ((mBytesCopied - mBytesCopiedSample) * 1000) / sampleDuration;
+ // mBytesCopied is modified in worker thread, but this method is called in monitor thread,
+ // so take a snapshot of mBytesCopied to make sure the updated estimate is consistent.
+ final long bytesCopied = mBytesCopied;
+ final long sampleDuration = Math.max(elapsedTime - mSampleTime, 1L); // avoid dividing 0
+ final long sampleSpeed = ((bytesCopied - mBytesCopiedSample) * 1000) / sampleDuration;
if (mSpeed == 0) {
mSpeed = sampleSpeed;
} else {
@@ -182,13 +172,13 @@ class CopyJob extends Job {
}
if (mSampleTime > 0 && mSpeed > 0) {
- mRemainingTime = ((mBatchSize - mBytesCopied) * 1000) / mSpeed;
+ mRemainingTime = ((mBatchSize - bytesCopied) * 1000) / mSpeed;
} else {
mRemainingTime = 0;
}
mSampleTime = elapsedTime;
- mBytesCopiedSample = mBytesCopied;
+ mBytesCopiedSample = bytesCopied;
}
@Override
@@ -201,7 +191,7 @@ class CopyJob extends Job {
Notification getWarningNotification() {
final Intent navigateIntent = buildNavigateIntent(INTENT_TAG_WARNING);
navigateIntent.putExtra(EXTRA_DIALOG_TYPE, DIALOG_TYPE_CONVERTED);
- navigateIntent.putExtra(EXTRA_OPERATION, operationType);
+ navigateIntent.putExtra(EXTRA_OPERATION_TYPE, operationType);
navigateIntent.putParcelableArrayListExtra(EXTRA_SRC_LIST, convertedFiles);
@@ -221,8 +211,18 @@ class CopyJob extends Job {
}
@Override
- void start() {
- mStartTime = elapsedRealtime();
+ boolean setUp() {
+ try {
+ buildDocumentList();
+ } catch (ResourceException e) {
+ Log.e(TAG, "Failed to get the list of docs.", e);
+ return false;
+ }
+
+ // Check if user has canceled this task.
+ if (isCanceled()) {
+ return false;
+ }
try {
mBatchSize = calculateSize(mSrcs);
@@ -231,6 +231,20 @@ class CopyJob extends Job {
mBatchSize = -1;
}
+ // Check if user has canceled this task. We should check it again here as user cancels
+ // tasks in main thread, but this is running in a worker thread. calculateSize() may
+ // take a long time during which user can cancel this task, and we don't want to waste
+ // resources doing useless large chunk of work.
+ if (isCanceled()) {
+ return false;
+ }
+
+ return checkSpace();
+ }
+
+ @Override
+ void start() {
+ mStartTime = elapsedRealtime();
DocumentInfo srcInfo;
DocumentInfo dstInfo = stack.peek();
for (int i = 0; i < mSrcs.size() && !isCanceled(); ++i) {
@@ -255,6 +269,71 @@ class CopyJob extends Job {
Metrics.logFileOperation(service, operationType, mSrcs, dstInfo);
}
+ private void buildDocumentList() throws ResourceException {
+ try {
+ final ContentResolver resolver = appContext.getContentResolver();
+ final Iterable<Uri> uris = srcs.getUris(appContext);
+ for (Uri uri : uris) {
+ DocumentInfo doc = DocumentInfo.fromUri(resolver, uri);
+ if (canCopy(doc, stack.root)) {
+ mSrcs.add(doc);
+ } else {
+ onFileFailed(doc);
+ }
+
+ if (isCanceled()) {
+ return;
+ }
+ }
+ } catch(IOException e) {
+ failedFileCount += srcs.getItemCount();
+ throw new ResourceException("Failed to open the list of docs to copy.", e);
+ }
+ }
+
+ private static boolean canCopy(DocumentInfo doc, RootInfo root) {
+ // Can't copy folders to downloads, because we don't show folders there.
+ return !root.isDownloads() || !doc.isDirectory();
+ }
+
+ /**
+ * Checks whether the destination folder has enough space to take all source files.
+ * @return true if the root has enough space or doesn't provide free space info; otherwise false
+ */
+ boolean checkSpace() {
+ return checkSpace(mBatchSize);
+ }
+
+ /**
+ * Checks whether the destination folder has enough space to take files of batchSize
+ * @param batchSize the total size of files
+ * @return true if the root has enough space or doesn't provide free space info; otherwise false
+ */
+ final boolean checkSpace(long batchSize) {
+ // Default to be true because if batchSize or available space is invalid, we still let the
+ // copy start anyway.
+ boolean result = true;
+ if (batchSize >= 0) {
+ RootsCache cache = DocumentsApplication.getRootsCache(appContext);
+
+ // Query root info here instead of using stack.root because the number there may be
+ // stale.
+ RootInfo root = cache.getRootOneshot(stack.root.authority, stack.root.rootId, true);
+ if (root.availableBytes >= 0) {
+ result = (batchSize <= root.availableBytes);
+ } else {
+ Log.w(TAG, root.toString() + " doesn't provide available bytes.");
+ }
+ }
+
+ if (!result) {
+ failedFileCount += mSrcs.size();
+ failedFiles.addAll(mSrcs);
+ }
+
+ return result;
+ }
+
@Override
boolean hasWarnings() {
return !convertedFiles.isEmpty();
@@ -267,10 +346,6 @@ class CopyJob extends Job {
*/
private void makeCopyProgress(long bytesCopied) {
onBytesCopied(bytesCopied);
- if (shouldUpdateProgress()) {
- updateRemainingTimeEstimate();
- listener.onProgress(this);
- }
}
/**
@@ -302,6 +377,7 @@ class CopyJob extends Job {
Log.e(TAG, "Provider side copy failed for: " + src.derivedUri
+ " due to an exception.", e);
}
+
// If optimized copy fails, then fallback to byte-by-byte copy.
if (DEBUG) Log.d(TAG, "Fallback to byte-by-byte copy for: " + src.derivedUri);
}
@@ -412,14 +488,16 @@ class CopyJob extends Job {
src = DocumentInfo.fromCursor(cursor, srcDir.authority);
processDocument(src, srcDir, destDir);
} catch (RuntimeException e) {
- Log.e(TAG, "Failed to recursively process a file %s due to an exception."
- .format(srcDir.derivedUri.toString()), e);
+ Log.e(TAG, String.format(
+ "Failed to recursively process a file %s due to an exception.",
+ srcDir.derivedUri.toString()), e);
success = false;
}
}
} catch (RuntimeException e) {
- Log.e(TAG, "Failed to copy a file %s to %s. "
- .format(srcDir.derivedUri.toString(), destDir.derivedUri.toString()), e);
+ Log.e(TAG, String.format(
+ "Failed to copy a file %s to %s. ",
+ srcDir.derivedUri.toString(), destDir.derivedUri.toString()), e);
success = false;
} finally {
IoUtils.closeQuietly(cursor);
@@ -555,11 +633,15 @@ class CopyJob extends Job {
result += calculateFileSizesRecursively(getClient(src), src.derivedUri);
} catch (RemoteException e) {
throw new ResourceException("Failed to obtain the client for %s.",
- src.derivedUri);
+ src.derivedUri, e);
}
} else {
result += src.size;
}
+
+ if (isCanceled()) {
+ return result;
+ }
}
return result;
}
@@ -569,7 +651,7 @@ class CopyJob extends Job {
*
* @throws ResourceException
*/
- private static long calculateFileSizesRecursively(
+ long calculateFileSizesRecursively(
ContentProviderClient client, Uri uri) throws ResourceException {
final String authority = uri.getAuthority();
final Uri queryUri = buildChildDocumentsUri(authority, getDocumentId(uri));
@@ -583,7 +665,7 @@ class CopyJob extends Job {
Cursor cursor = null;
try {
cursor = client.query(queryUri, queryColumns, null, null, null);
- while (cursor.moveToNext()) {
+ while (cursor.moveToNext() && !isCanceled()) {
if (Document.MIME_TYPE_DIR.equals(
getCursorString(cursor, Document.COLUMN_MIME_TYPE))) {
// Recurse into directories.
@@ -630,7 +712,7 @@ class CopyJob extends Job {
.append("CopyJob")
.append("{")
.append("id=" + id)
- .append(", srcs=" + mSrcs)
+ .append(", docs=" + srcs)
.append(", destination=" + stack)
.append("}")
.toString();
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/DeleteJob.java b/packages/DocumentsUI/src/com/android/documentsui/services/DeleteJob.java
index 36a0f3216a63..64bc1a78f2de 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/DeleteJob.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/DeleteJob.java
@@ -21,37 +21,39 @@ import static com.android.documentsui.services.FileOperationService.OPERATION_DE
import android.app.Notification;
import android.app.Notification.Builder;
+import android.content.ContentResolver;
import android.content.Context;
+import android.net.Uri;
import android.util.Log;
+import com.android.documentsui.clipping.UrisSupplier;
import com.android.documentsui.Metrics;
import com.android.documentsui.R;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.DocumentStack;
+import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
final class DeleteJob extends Job {
private static final String TAG = "DeleteJob";
- private List<DocumentInfo> mSrcs;
- final DocumentInfo mSrcParent;
+ private volatile int mDocsProcessed = 0;
+
+ Uri mSrcParent;
/**
* Moves files to a destination identified by {@code destination}.
* Performs most work by delegating to CopyJob, then deleting
* a file after it has been copied.
*
* @see @link {@link Job} constructor for most param descriptions.
- *
- * @param srcs List of files to delete.
- * @param srcParent Parent of all source files.
*/
- DeleteJob(Context service, Context appContext, Listener listener,
- String id, DocumentStack stack, List<DocumentInfo> srcs, DocumentInfo srcParent) {
- super(service, appContext, listener, OPERATION_DELETE, id, stack);
- this.mSrcs = srcs;
- this.mSrcParent = srcParent;
+ DeleteJob(Context service, Listener listener, String id, Uri srcParent, DocumentStack stack,
+ UrisSupplier srcs) {
+ super(service, listener, id, OPERATION_DELETE, stack, srcs);
+ mSrcParent = srcParent;
}
@Override
@@ -69,6 +71,17 @@ final class DeleteJob extends Job {
}
@Override
+ public Notification getProgressNotification() {
+ mProgressBuilder.setProgress(srcs.getItemCount(), mDocsProcessed, false);
+ String format = service.getString(R.string.delete_progress);
+ mProgressBuilder.setSubText(String.format(format, mDocsProcessed, srcs.getItemCount()));
+
+ mProgressBuilder.setContentText(null);
+
+ return mProgressBuilder.build();
+ }
+
+ @Override
Notification getFailureNotification() {
return getFailureNotification(
R.plurals.delete_error_notification_title, R.drawable.ic_menu_delete);
@@ -81,16 +94,37 @@ final class DeleteJob extends Job {
@Override
void start() {
- for (DocumentInfo doc : mSrcs) {
- if (DEBUG) Log.d(TAG, "Deleting document @ " + doc.derivedUri);
- try {
- deleteDocument(doc, mSrcParent);
- } catch (ResourceException e) {
- Log.e(TAG, "Failed to delete document @ " + doc.derivedUri, e);
- onFileFailed(doc);
+ try {
+ final List<DocumentInfo> srcs = new ArrayList<>(this.srcs.getItemCount());
+
+ final Iterable<Uri> uris = this.srcs.getUris(appContext);
+
+ final ContentResolver resolver = appContext.getContentResolver();
+ final DocumentInfo srcParent = DocumentInfo.fromUri(resolver, mSrcParent);
+ for (Uri uri : uris) {
+ DocumentInfo doc = DocumentInfo.fromUri(resolver, uri);
+ srcs.add(doc);
+
+ if (DEBUG) Log.d(TAG, "Deleting document @ " + doc.derivedUri);
+ try {
+ deleteDocument(doc, srcParent);
+
+ if (isCanceled()) {
+ // Canceled, dump the rest of the work. Deleted docs are not recoverable.
+ return;
+ }
+ } catch (ResourceException e) {
+ Log.e(TAG, "Failed to delete document @ " + doc.derivedUri, e);
+ onFileFailed(doc);
+ }
+
+ ++mDocsProcessed;
}
+ Metrics.logFileOperation(service, operationType, srcs, null);
+ } catch(IOException e) {
+ Log.e(TAG, "Failed to get list of docs or parent source.", e);
+ failedFileCount += srcs.getItemCount();
}
- Metrics.logFileOperation(service, operationType, mSrcs, null);
}
@Override
@@ -99,7 +133,7 @@ final class DeleteJob extends Job {
.append("DeleteJob")
.append("{")
.append("id=" + id)
- .append(", srcs=" + mSrcs)
+ .append(", docs=" + srcs)
.append(", srcParent=" + mSrcParent)
.append(", location=" + stack)
.append("}")
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperation.java b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperation.java
new file mode 100644
index 000000000000..43c3bd7e6788
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperation.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.services;
+
+import static com.android.documentsui.services.FileOperationService.OPERATION_COPY;
+import static com.android.documentsui.services.FileOperationService.OPERATION_DELETE;
+import static com.android.documentsui.services.FileOperationService.OPERATION_MOVE;
+import static com.android.documentsui.services.FileOperationService.OPERATION_UNKNOWN;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.support.annotation.VisibleForTesting;
+
+import com.android.documentsui.clipping.UrisSupplier;
+import com.android.documentsui.model.DocumentStack;
+import com.android.documentsui.services.FileOperationService.OpType;
+
+/**
+ * FileOperation describes a file operation, such as move/copy/delete etc.
+ */
+public abstract class FileOperation implements Parcelable {
+ private final @OpType int mOpType;
+
+ private final UrisSupplier mSrcs;
+ private DocumentStack mDestination;
+
+ @VisibleForTesting
+ FileOperation(@OpType int opType, UrisSupplier srcs, DocumentStack destination) {
+ assert(opType != OPERATION_UNKNOWN);
+ assert(srcs.getItemCount() > 0);
+
+ mOpType = opType;
+ mSrcs = srcs;
+ mDestination = destination;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public @OpType int getOpType() {
+ return mOpType;
+ }
+
+ public UrisSupplier getSrc() {
+ return mSrcs;
+ }
+
+ public DocumentStack getDestination() {
+ return mDestination;
+ }
+
+ public void setDestination(DocumentStack destination) {
+ mDestination = destination;
+ }
+
+ public void dispose() {
+ mSrcs.dispose();
+ }
+
+ abstract Job createJob(Context service, Job.Listener listener, String id);
+
+ private void appendInfoTo(StringBuilder builder) {
+ builder.append("opType=").append(mOpType);
+ builder.append(", srcs=").append(mSrcs.toString());
+ builder.append(", destination=").append(mDestination.toString());
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flag) {
+ out.writeInt(mOpType);
+ out.writeParcelable(mSrcs, flag);
+ out.writeParcelable(mDestination, flag);
+ }
+
+ private FileOperation(Parcel in) {
+ mOpType = in.readInt();
+ mSrcs = in.readParcelable(FileOperation.class.getClassLoader());
+ mDestination = in.readParcelable(FileOperation.class.getClassLoader());
+ }
+
+ public static class CopyOperation extends FileOperation {
+ private CopyOperation(UrisSupplier srcs, DocumentStack destination) {
+ super(OPERATION_COPY, srcs, destination);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+
+ builder.append("CopyOperation{");
+ super.appendInfoTo(builder);
+ builder.append("}");
+
+ return builder.toString();
+ }
+
+ CopyJob createJob(Context service, Job.Listener listener, String id) {
+ return new CopyJob(service, listener, id, getDestination(), getSrc());
+ }
+
+ private CopyOperation(Parcel in) {
+ super(in);
+ }
+
+ public static final Parcelable.Creator<CopyOperation> CREATOR =
+ new Parcelable.Creator<CopyOperation>() {
+
+ @Override
+ public CopyOperation createFromParcel(Parcel source) {
+ return new CopyOperation(source);
+ }
+
+ @Override
+ public CopyOperation[] newArray(int size) {
+ return new CopyOperation[size];
+ }
+ };
+ }
+
+ public static class MoveDeleteOperation extends FileOperation {
+ private final Uri mSrcParent;
+
+ private MoveDeleteOperation(
+ @OpType int opType, UrisSupplier srcs, Uri srcParent, DocumentStack destination) {
+ super(opType, srcs, destination);
+
+ assert(srcParent != null);
+ mSrcParent = srcParent;
+ }
+
+ @Override
+ Job createJob(Context service, Job.Listener listener, String id) {
+ switch(getOpType()) {
+ case OPERATION_MOVE:
+ return new MoveJob(
+ service, listener, id, mSrcParent, getDestination(), getSrc());
+ case OPERATION_DELETE:
+ return new DeleteJob(
+ service, listener, id, mSrcParent, getDestination(), getSrc());
+ default:
+ throw new UnsupportedOperationException("Unsupported op type: " + getOpType());
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+
+ builder.append("MoveDeleteOperation{");
+ super.appendInfoTo(builder);
+ builder.append(", srcParent=").append(mSrcParent.toString());
+ builder.append("}");
+
+ return builder.toString();
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flag) {
+ super.writeToParcel(out, flag);
+ out.writeParcelable(mSrcParent, flag);
+ }
+
+ private MoveDeleteOperation(Parcel in) {
+ super(in);
+ mSrcParent = in.readParcelable(null);
+ }
+
+ public static final Parcelable.Creator<MoveDeleteOperation> CREATOR =
+ new Parcelable.Creator<MoveDeleteOperation>() {
+
+
+ @Override
+ public MoveDeleteOperation createFromParcel(Parcel source) {
+ return new MoveDeleteOperation(source);
+ }
+
+ @Override
+ public MoveDeleteOperation[] newArray(int size) {
+ return new MoveDeleteOperation[size];
+ }
+ };
+ }
+
+ public static class Builder {
+ private @OpType int mOpType;
+ private Uri mSrcParent;
+ private UrisSupplier mSrcs;
+ private DocumentStack mDestination;
+
+ public Builder withOpType(@OpType int opType) {
+ mOpType = opType;
+ return this;
+ }
+
+ public Builder withSrcParent(Uri srcParent) {
+ mSrcParent = srcParent;
+ return this;
+ }
+
+ public Builder withSrcs(UrisSupplier srcs) {
+ mSrcs = srcs;
+ return this;
+ }
+
+ public Builder withDestination(DocumentStack destination) {
+ mDestination = destination;
+ return this;
+ }
+
+ public FileOperation build() {
+ switch (mOpType) {
+ case OPERATION_COPY:
+ return new CopyOperation(mSrcs, mDestination);
+ case OPERATION_MOVE:
+ case OPERATION_DELETE:
+ return new MoveDeleteOperation(mOpType, mSrcs, mSrcParent, mDestination);
+ default:
+ throw new UnsupportedOperationException("Unsupported op type: " + mOpType);
+ }
+ }
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java
index 871e1357dd78..b61c1c962b04 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java
@@ -22,33 +22,26 @@ import android.annotation.IntDef;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
+import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManager;
-import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
-import com.android.documentsui.Shared;
-import com.android.documentsui.model.DocumentInfo;
-import com.android.documentsui.model.DocumentStack;
-import com.android.documentsui.services.Job.Factory;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
import javax.annotation.concurrent.GuardedBy;
public class FileOperationService extends Service implements Job.Listener {
- private static final int DEFAULT_DELAY = 0;
- private static final int MAX_DELAY = 10 * 1000; // ten seconds
private static final int POOL_SIZE = 2; // "pool size", not *max* "pool size".
private static final int NOTIFICATION_ID_PROGRESS = 0;
private static final int NOTIFICATION_ID_FAILURE = 1;
@@ -56,17 +49,17 @@ public class FileOperationService extends Service implements Job.Listener {
public static final String TAG = "FileOperationService";
+ // Extra used for OperationDialogFragment, Notifications and picking copy destination.
+ public static final String EXTRA_OPERATION_TYPE = "com.android.documentsui.OPERATION_TYPE";
+
+ // Extras used for OperationDialogFragment...
+ public static final String EXTRA_DIALOG_TYPE = "com.android.documentsui.DIALOG_TYPE";
+ public static final String EXTRA_SRC_LIST = "com.android.documentsui.SRC_LIST";
+
+ // Extras used to start or cancel a file operation...
public static final String EXTRA_JOB_ID = "com.android.documentsui.JOB_ID";
- public static final String EXTRA_DELAY = "com.android.documentsui.DELAY";
public static final String EXTRA_OPERATION = "com.android.documentsui.OPERATION";
public static final String EXTRA_CANCEL = "com.android.documentsui.CANCEL";
- public static final String EXTRA_SRC_LIST = "com.android.documentsui.SRC_LIST";
- public static final String EXTRA_DIALOG_TYPE = "com.android.documentsui.DIALOG_TYPE";
-
- // This extra is used only for moving and deleting. Currently it's not the case,
- // but in the future those files may be from multiple different parents. In
- // such case, this needs to be replaced with pairs of parent and child.
- public static final String EXTRA_SRC_PARENT = "com.android.documentsui.SRC_PARENT";
@IntDef(flag = true, value = {
OPERATION_UNKNOWN,
@@ -87,15 +80,20 @@ public class FileOperationService extends Service implements Job.Listener {
// The executor and job factory are visible for testing and non-final
// so we'll have a way to inject test doubles from the test. It's
// a sub-optimal arrangement.
- @VisibleForTesting ScheduledExecutorService executor;
- @VisibleForTesting Factory jobFactory;
+ @VisibleForTesting ExecutorService executor;
+
+ // Use a separate thread pool to prioritize deletions.
+ @VisibleForTesting ExecutorService deletionExecutor;
+
+ // Use a handler to schedule monitor tasks.
+ @VisibleForTesting Handler handler;
private PowerManager mPowerManager;
private PowerManager.WakeLock mWakeLock; // the wake lock, if held.
private NotificationManager mNotificationManager;
@GuardedBy("mRunning")
- private Map<String, JobRecord> mRunning = new HashMap<>();
+ private final Map<String, JobRecord> mRunning = new HashMap<>();
private int mLastServiceId;
@@ -103,11 +101,16 @@ public class FileOperationService extends Service implements Job.Listener {
public void onCreate() {
// Allow tests to pre-set these with test doubles.
if (executor == null) {
- executor = new ScheduledThreadPoolExecutor(POOL_SIZE);
+ executor = Executors.newFixedThreadPool(POOL_SIZE);
+ }
+
+ if (deletionExecutor == null) {
+ deletionExecutor = Executors.newCachedThreadPool();
}
- if (jobFactory == null) {
- jobFactory = Job.Factory.instance;
+ if (handler == null) {
+ // Monitor tasks are small enough to schedule them on main thread.
+ handler = new Handler();
}
if (DEBUG) Log.d(TAG, "Created.");
@@ -118,11 +121,21 @@ public class FileOperationService extends Service implements Job.Listener {
@Override
public void onDestroy() {
if (DEBUG) Log.d(TAG, "Shutting down executor.");
- List<Runnable> unfinished = executor.shutdownNow();
+
+ List<Runnable> unfinishedCopies = executor.shutdownNow();
+ List<Runnable> unfinishedDeletions = deletionExecutor.shutdownNow();
+ List<Runnable> unfinished =
+ new ArrayList<>(unfinishedCopies.size() + unfinishedDeletions.size());
+ unfinished.addAll(unfinishedCopies);
+ unfinished.addAll(unfinishedDeletions);
if (!unfinished.isEmpty()) {
Log.w(TAG, "Shutting down, but executor reports running jobs: " + unfinished);
}
+
executor = null;
+ deletionExecutor = null;
+ handler = null;
+
if (DEBUG) Log.d(TAG, "Destroyed.");
}
@@ -132,51 +145,48 @@ public class FileOperationService extends Service implements Job.Listener {
// checkArgument(flags == 0); // retry and redeliver are not supported.
String jobId = intent.getStringExtra(EXTRA_JOB_ID);
- @OpType int operationType = intent.getIntExtra(EXTRA_OPERATION, OPERATION_UNKNOWN);
assert(jobId != null);
+ if (DEBUG) Log.d(TAG, "onStartCommand: " + jobId + " with serviceId " + serviceId);
+
if (intent.hasExtra(EXTRA_CANCEL)) {
handleCancel(intent);
} else {
- assert(operationType != OPERATION_UNKNOWN);
- handleOperation(intent, serviceId, jobId, operationType);
+ FileOperation operation = intent.getParcelableExtra(EXTRA_OPERATION);
+ handleOperation(jobId, operation);
}
- return START_NOT_STICKY;
- }
-
- private void handleOperation(Intent intent, int serviceId, String jobId, int operationType) {
- if (DEBUG) Log.d(TAG, "onStartCommand: " + jobId + " with serviceId " + serviceId);
-
// Track the service supplied id so we can stop the service once we're out of work to do.
mLastServiceId = serviceId;
- Job job = null;
+ return START_NOT_STICKY;
+ }
+
+ private void handleOperation(String jobId, FileOperation operation) {
synchronized (mRunning) {
if (mWakeLock == null) {
mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
}
- List<DocumentInfo> srcs = intent.getParcelableArrayListExtra(EXTRA_SRC_LIST);
- DocumentInfo srcParent = intent.getParcelableExtra(EXTRA_SRC_PARENT);
- DocumentStack stack = intent.getParcelableExtra(Shared.EXTRA_STACK);
+ if (mRunning.containsKey(jobId)) {
+ Log.w(TAG, "Duplicate job id: " + jobId
+ + ". Ignoring job request for operation: " + operation + ".");
+ return;
+ }
- job = createJob(operationType, jobId, srcs, srcParent, stack);
+ Job job = operation.createJob(this, this, jobId);
if (job == null) {
return;
}
mWakeLock.acquire();
- }
- assert(job != null);
- int delay = intent.getIntExtra(EXTRA_DELAY, DEFAULT_DELAY);
- assert(delay <= MAX_DELAY);
- if (DEBUG) Log.d(
- TAG, "Scheduling job " + job.id + " to run in " + delay + " milliseconds.");
- ScheduledFuture<?> future = executor.schedule(job, delay, TimeUnit.MILLISECONDS);
- mRunning.put(jobId, new JobRecord(job, future));
+ assert (job != null);
+ if (DEBUG) Log.d(TAG, "Scheduling job " + job.id + ".");
+ Future<?> future = getExecutorService(operation.getOpType()).submit(job);
+ mRunning.put(jobId, new JobRecord(job, future));
+ }
}
/**
@@ -200,14 +210,6 @@ public class FileOperationService extends Service implements Job.Listener {
JobRecord record = mRunning.get(jobId);
if (record != null) {
record.job.cancel();
-
- // If the job hasn't been started, cancel it and explicitly clean up.
- // If it *has* been started, we wait for it to recognize this, then
- // allow it stop working in an orderly fashion.
- if (record.future.getDelay(TimeUnit.MILLISECONDS) > 0) {
- record.future.cancel(false);
- onFinished(record.job);
- }
}
}
@@ -220,38 +222,13 @@ public class FileOperationService extends Service implements Job.Listener {
// TODO: Guarantee the job is being finalized
}
- /**
- * Creates a new job. Returns null if a job with {@code id} already exists.
- * @return
- */
- @GuardedBy("mRunning")
- private @Nullable Job createJob(
- @OpType int operationType, String id, List<DocumentInfo> srcs, DocumentInfo srcParent,
- DocumentStack stack) {
-
- if (srcs.isEmpty()) {
- Log.w(TAG, "Ignoring job request with empty srcs list. Id: " + id);
- return null;
- }
-
- if (mRunning.containsKey(id)) {
- Log.w(TAG, "Duplicate job id: " + id
- + ". Ignoring job request for srcs: " + srcs + ", stack: " + stack + ".");
- return null;
- }
-
+ private ExecutorService getExecutorService(@OpType int operationType) {
switch (operationType) {
case OPERATION_COPY:
- return jobFactory.createCopy(
- this, getApplicationContext(), this, id, stack, srcs);
case OPERATION_MOVE:
- return jobFactory.createMove(
- this, getApplicationContext(), this, id, stack, srcs,
- srcParent);
+ return executor;
case OPERATION_DELETE:
- return jobFactory.createDelete(
- this, getApplicationContext(), this, id, stack, srcs,
- srcParent);
+ return deletionExecutor;
default:
throw new UnsupportedOperationException();
}
@@ -297,50 +274,97 @@ public class FileOperationService extends Service implements Job.Listener {
@Override
public void onStart(Job job) {
if (DEBUG) Log.d(TAG, "onStart: " + job.id);
- mNotificationManager.notify(job.id, NOTIFICATION_ID_PROGRESS, job.getSetupNotification());
+
+ // Show start up notification
+ mNotificationManager.notify(
+ job.id, NOTIFICATION_ID_PROGRESS, job.getSetupNotification());
+
+ // Set up related monitor
+ JobMonitor monitor = new JobMonitor(job, mNotificationManager, handler);
+ monitor.start();
}
@Override
public void onFinished(Job job) {
+ assert(job.isFinished());
if (DEBUG) Log.d(TAG, "onFinished: " + job.id);
- // Dismiss the ongoing copy notification when the copy is done.
- mNotificationManager.cancel(job.id, NOTIFICATION_ID_PROGRESS);
+ // Use the same thread of monitors to tackle notifications to avoid race conditions.
+ // Otherwise we may fail to dismiss progress notification.
+ handler.post(() -> {
+ // Dismiss the ongoing copy notification when the copy is done.
+ mNotificationManager.cancel(job.id, NOTIFICATION_ID_PROGRESS);
- if (job.hasFailures()) {
- Log.e(TAG, "Job failed on files: " + job.failedFiles.size() + ".");
- mNotificationManager.notify(
- job.id, NOTIFICATION_ID_FAILURE, job.getFailureNotification());
- }
+ if (job.hasFailures()) {
+ Log.e(TAG, "Job failed on files: " + job.failedFileCount + ".");
+ mNotificationManager.notify(
+ job.id, NOTIFICATION_ID_FAILURE, job.getFailureNotification());
+ }
- if (job.hasWarnings()) {
- if (DEBUG) Log.d(TAG, "Job finished with warnings.");
- mNotificationManager.notify(
- job.id, NOTIFICATION_ID_WARNING, job.getWarningNotification());
- }
+ if (job.hasWarnings()) {
+ if (DEBUG) Log.d(TAG, "Job finished with warnings.");
+ mNotificationManager.notify(
+ job.id, NOTIFICATION_ID_WARNING, job.getWarningNotification());
+ }
+ });
synchronized (mRunning) {
deleteJob(job);
}
}
- @Override
- public void onProgress(CopyJob job) {
- if (DEBUG) Log.d(TAG, "onProgress: " + job.id);
- mNotificationManager.notify(
- job.id, NOTIFICATION_ID_PROGRESS, job.getProgressNotification());
- }
-
private static final class JobRecord {
private final Job job;
- private final ScheduledFuture<?> future;
+ private final Future<?> future;
- public JobRecord(Job job, ScheduledFuture<?> future) {
+ public JobRecord(Job job, Future<?> future) {
this.job = job;
this.future = future;
}
}
+ /**
+ * A class used to periodically polls state of a job.
+ *
+ * <p>It's possible that jobs hang because underlying document providers stop responding. We
+ * still need to update notifications if jobs hang, so instead of jobs pushing their states,
+ * we poll states of jobs.
+ */
+ private static final class JobMonitor implements Runnable {
+ private static final long PROGRESS_INTERVAL_MILLIS = 500L;
+
+ private final Job mJob;
+ private final NotificationManager mNotificationManager;
+ private final Handler mHandler;
+
+ private JobMonitor(Job job, NotificationManager notificationManager, Handler handler) {
+ mJob = job;
+ mNotificationManager = notificationManager;
+ mHandler = handler;
+ }
+
+ private void start() {
+ mHandler.post(this);
+ }
+
+ @Override
+ public void run() {
+ if (mJob.isFinished()) {
+ // Finish notification is already shown. Progress notification is removed.
+ // Just finish itself.
+ return;
+ }
+
+ // Only job in set up state has progress bar
+ if (mJob.getState() == Job.STATE_SET_UP) {
+ mNotificationManager.notify(
+ mJob.id, NOTIFICATION_ID_PROGRESS, mJob.getProgressNotification());
+ }
+
+ mHandler.postDelayed(this, PROGRESS_INTERVAL_MILLIS);
+ }
+ }
+
@Override
public IBinder onBind(Intent intent) {
return null; // Boilerplate. See super#onBind
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperations.java b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperations.java
index 748da006207f..01956a1b08eb 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperations.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperations.java
@@ -17,35 +17,23 @@
package com.android.documentsui.services;
import static android.os.SystemClock.elapsedRealtime;
+
import static com.android.documentsui.Shared.DEBUG;
-import static com.android.documentsui.Shared.EXTRA_STACK;
-import static com.android.documentsui.Shared.asArrayList;
-import static com.android.documentsui.Shared.getQuantityString;
import static com.android.documentsui.services.FileOperationService.EXTRA_CANCEL;
import static com.android.documentsui.services.FileOperationService.EXTRA_JOB_ID;
import static com.android.documentsui.services.FileOperationService.EXTRA_OPERATION;
-import static com.android.documentsui.services.FileOperationService.EXTRA_SRC_LIST;
-import static com.android.documentsui.services.FileOperationService.EXTRA_SRC_PARENT;
-import static com.android.documentsui.services.FileOperationService.OPERATION_COPY;
-import static com.android.documentsui.services.FileOperationService.OPERATION_DELETE;
-import static com.android.documentsui.services.FileOperationService.OPERATION_MOVE;
+import android.annotation.IntDef;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
-import android.content.res.Resources;
-import android.os.Parcelable;
import android.support.annotation.VisibleForTesting;
-import android.support.design.widget.Snackbar;
import android.util.Log;
-import com.android.documentsui.R;
-import com.android.documentsui.Snackbars;
-import com.android.documentsui.model.DocumentInfo;
-import com.android.documentsui.model.DocumentStack;
import com.android.documentsui.services.FileOperationService.OpType;
-import java.util.List;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
/**
* Helper functions for starting various file operations.
@@ -65,43 +53,19 @@ public final class FileOperations {
/**
* Tries to start the activity. Returns the job id.
*/
- public static String start(
- Activity activity, List<DocumentInfo> srcDocs,
- DocumentStack stack, int operationType) {
+ public static String start(Context context, FileOperation operation, Callback callback) {
if (DEBUG) Log.d(TAG, "Handling generic 'start' call.");
- switch (operationType) {
- case OPERATION_COPY:
- return FileOperations.copy(activity, srcDocs, stack);
- case OPERATION_MOVE:
- throw new IllegalArgumentException("Moving requires providing the source parent.");
- case OPERATION_DELETE:
- throw new UnsupportedOperationException("Delete isn't currently supported.");
- default:
- throw new UnsupportedOperationException("Unknown operation: " + operationType);
- }
- }
+ String jobId = createJobId();
+ Intent intent = createBaseIntent(context, jobId, operation);
- /**
- * Tries to start the activity. Returns the job id.
- */
- public static String start(
- Activity activity, List<DocumentInfo> srcDocs, DocumentInfo srcParent,
- DocumentStack stack, int operationType) {
+ callback.onOperationResult(Callback.STATUS_ACCEPTED, operation.getOpType(),
+ operation.getSrc().getItemCount());
- if (DEBUG) Log.d(TAG, "Handling generic 'start' call.");
+ context.startService(intent);
- switch (operationType) {
- case OPERATION_COPY:
- return FileOperations.copy(activity, srcDocs, stack);
- case OPERATION_MOVE:
- return FileOperations.move(activity, srcDocs, srcParent, stack);
- case OPERATION_DELETE:
- throw new UnsupportedOperationException("Delete isn't currently supported.");
- default:
- throw new UnsupportedOperationException("Unknown operation: " + operationType);
- }
+ return jobId;
}
@VisibleForTesting
@@ -115,122 +79,23 @@ public final class FileOperations {
activity.startService(intent);
}
- @VisibleForTesting
- public static String copy(
- Activity activity, List<DocumentInfo> srcDocs, DocumentStack destination) {
- String jobId = createJobId();
- if (DEBUG) Log.d(TAG, "Initiating 'copy' operation id: " + jobId);
-
- Intent intent = createBaseIntent(OPERATION_COPY, activity, jobId, srcDocs, destination);
-
- createSharedSnackBar(activity, R.plurals.copy_begin, srcDocs.size())
- .show();
-
- activity.startService(intent);
-
- return jobId;
- }
-
- /**
- * Starts the service for a move operation.
- *
- * @param jobId A unique jobid for this job.
- * Use {@link #createJobId} if you don't have one handy.
- * @param srcDocs A list of src files to copy.
- * @param srcParent Parent of all the source documents.
- * @param destination The move destination stack.
- */
- public static String move(
- Activity activity, List<DocumentInfo> srcDocs, DocumentInfo srcParent,
- DocumentStack destination) {
- String jobId = createJobId();
- if (DEBUG) Log.d(TAG, "Initiating 'move' operation id: " + jobId);
-
- Intent intent = createBaseIntent(OPERATION_MOVE, activity, jobId, srcDocs, srcParent,
- destination);
-
- createSharedSnackBar(activity, R.plurals.move_begin, srcDocs.size())
- .show();
-
- activity.startService(intent);
-
- return jobId;
- }
-
- /**
- * Starts the service for a delete operation.
- *
- * @param jobId A unique jobid for this job.
- * Use {@link #createJobId} if you don't have one handy.
- * @param srcDocs A list of src files to delete.
- * @param srcParent Parent of all the source documents.
- * @return Id of the job.
- */
- public static String delete(
- Activity activity, List<DocumentInfo> srcDocs, DocumentInfo srcParent,
- DocumentStack location) {
- String jobId = createJobId();
- if (DEBUG) Log.d(TAG, "Initiating 'delete' operation id " + jobId + ".");
-
- Intent intent = createBaseIntent(OPERATION_DELETE, activity, jobId, srcDocs, srcParent,
- location);
- activity.startService(intent);
-
- return jobId;
- }
-
- /**
- * Starts the service for an operation.
- *
- * @param jobId A unique jobid for this job.
- * Use {@link #createJobId} if you don't have one handy.
- * @param srcDocs A list of src files for an operation.
- * @return Id of the job.
- */
- public static Intent createBaseIntent(
- @OpType int operationType, Context context, String jobId, List<DocumentInfo> srcDocs,
- DocumentStack localeStack) {
-
- Intent intent = new Intent(context, FileOperationService.class);
- intent.putExtra(EXTRA_JOB_ID, jobId);
- intent.putParcelableArrayListExtra(EXTRA_SRC_LIST, asArrayList(srcDocs));
- intent.putExtra(EXTRA_STACK, (Parcelable) localeStack);
- intent.putExtra(EXTRA_OPERATION, operationType);
-
- return intent;
- }
-
/**
* Starts the service for an operation.
*
* @param jobId A unique jobid for this job.
* Use {@link #createJobId} if you don't have one handy.
- * @param srcDocs A list of src files to copy.
- * @param srcParent Parent of all the source documents.
* @return Id of the job.
*/
public static Intent createBaseIntent(
- @OpType int operationType, Context context, String jobId,
- List<DocumentInfo> srcDocs, DocumentInfo srcParent, DocumentStack localeStack) {
+ Context context, String jobId, FileOperation operation) {
Intent intent = new Intent(context, FileOperationService.class);
intent.putExtra(EXTRA_JOB_ID, jobId);
- intent.putParcelableArrayListExtra(EXTRA_SRC_LIST, asArrayList(srcDocs));
- intent.putExtra(EXTRA_SRC_PARENT, srcParent);
- intent.putExtra(EXTRA_STACK, (Parcelable) localeStack);
- intent.putExtra(EXTRA_OPERATION, operationType);
+ intent.putExtra(EXTRA_OPERATION, operation);
return intent;
}
- private static Snackbar createSharedSnackBar(Activity activity, int contentId, int fileCount) {
- Resources res = activity.getResources();
- return Snackbars.makeSnackbar(
- activity,
- getQuantityString(activity, contentId, fileCount),
- Snackbar.LENGTH_SHORT);
- }
-
private static final class IdBuilder {
// Remember last job time so we can guard against collisions.
@@ -250,4 +115,25 @@ public final class FileOperations {
return String.valueOf(mLastJobTime) + "-" + String.valueOf(mSubId);
}
}
+
+ /**
+ * A functional callback called when the file operation starts or fails to start.
+ */
+ @FunctionalInterface
+ public interface Callback {
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({STATUS_ACCEPTED, STATUS_REJECTED})
+ @interface Status {}
+ static final int STATUS_ACCEPTED = 0;
+ static final int STATUS_REJECTED = 1;
+
+ /**
+ * Performs operation when the file operation starts or fails to start.
+ *
+ * @param status {@link Status} of this operation
+ * @param opType file operation type {@link OpType}.
+ * @param docCount number of documents operated.
+ */
+ void onOperationResult(@Status int status, @OpType int opType, int docCount);
+ }
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/Job.java b/packages/DocumentsUI/src/com/android/documentsui/services/Job.java
index b8f8fba72d62..14ae66e6fa36 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/Job.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/Job.java
@@ -20,11 +20,12 @@ import static com.android.documentsui.DocumentsApplication.acquireUnstableProvid
import static com.android.documentsui.services.FileOperationService.EXTRA_CANCEL;
import static com.android.documentsui.services.FileOperationService.EXTRA_DIALOG_TYPE;
import static com.android.documentsui.services.FileOperationService.EXTRA_JOB_ID;
-import static com.android.documentsui.services.FileOperationService.EXTRA_OPERATION;
+import static com.android.documentsui.services.FileOperationService.EXTRA_OPERATION_TYPE;
import static com.android.documentsui.services.FileOperationService.EXTRA_SRC_LIST;
import static com.android.documentsui.services.FileOperationService.OPERATION_UNKNOWN;
import android.annotation.DrawableRes;
+import android.annotation.IntDef;
import android.annotation.PluralsRes;
import android.app.Notification;
import android.app.Notification.Builder;
@@ -39,6 +40,7 @@ import android.os.RemoteException;
import android.provider.DocumentsContract;
import android.util.Log;
+import com.android.documentsui.clipping.UrisSupplier;
import com.android.documentsui.FilesActivity;
import com.android.documentsui.Metrics;
import com.android.documentsui.OperationDialogFragment;
@@ -48,9 +50,10 @@ import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.DocumentStack;
import com.android.documentsui.services.FileOperationService.OpType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
/**
@@ -60,6 +63,19 @@ import java.util.Map;
abstract public class Job implements Runnable {
private static final String TAG = "Job";
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({STATE_CREATED, STATE_STARTED, STATE_SET_UP, STATE_COMPLETED, STATE_CANCELED})
+ @interface State {}
+ static final int STATE_CREATED = 0;
+ static final int STATE_STARTED = 1;
+ static final int STATE_SET_UP = 2;
+ static final int STATE_COMPLETED = 3;
+ /**
+ * A job is in canceled state as long as {@link #cancel()} is called on it, even after it is
+ * completed.
+ */
+ static final int STATE_CANCELED = 4;
+
static final String INTENT_TAG_WARNING = "warning";
static final String INTENT_TAG_FAILURE = "failure";
static final String INTENT_TAG_PROGRESS = "progress";
@@ -72,63 +88,80 @@ abstract public class Job implements Runnable {
final @OpType int operationType;
final String id;
final DocumentStack stack;
+ final UrisSupplier srcs;
+ int failedFileCount = 0;
final ArrayList<DocumentInfo> failedFiles = new ArrayList<>();
final Notification.Builder mProgressBuilder;
private final Map<String, ContentProviderClient> mClients = new HashMap<>();
- private volatile boolean mCanceled;
+ private volatile @State int mState = STATE_CREATED;
/**
* A simple progressable job, much like an AsyncTask, but with support
* for providing various related notification, progress and navigation information.
- * @param operationType
- *
* @param service The service context in which this job is running.
- * @param appContext The context of the invoking application. This is usually
- * just {@code getApplicationContext()}.
* @param listener
* @param id Arbitrary string ID
* @param stack The documents stack context relating to this request. This is the
* destination in the Files app where the user will be take when the
* navigation intent is invoked (presumably from notification).
+ * @param srcs the list of docs to operate on
*/
- Job(Context service, Context appContext, Listener listener,
- @OpType int operationType, String id, DocumentStack stack) {
+ Job(Context service, Listener listener, String id,
+ @OpType int opType, DocumentStack stack, UrisSupplier srcs) {
- assert(operationType != OPERATION_UNKNOWN);
+ assert(opType != OPERATION_UNKNOWN);
this.service = service;
- this.appContext = appContext;
+ this.appContext = service.getApplicationContext();
this.listener = listener;
- this.operationType = operationType;
+ this.operationType = opType;
this.id = id;
this.stack = stack;
+ this.srcs = srcs;
mProgressBuilder = createProgressBuilder();
}
@Override
public final void run() {
+ if (isCanceled()) {
+ // Canceled before running
+ return;
+ }
+
+ mState = STATE_STARTED;
listener.onStart(this);
try {
- start();
+ boolean result = setUp();
+ if (result && !isCanceled()) {
+ mState = STATE_SET_UP;
+ start();
+ }
} catch (RuntimeException e) {
// No exceptions should be thrown here, as all calls to the provider must be
// handled within Job implementations. However, just in case catch them here.
Log.e(TAG, "Operation failed due to an unhandled runtime exception.", e);
Metrics.logFileOperationErrors(service, operationType, failedFiles);
} finally {
+ mState = (mState == STATE_STARTED || mState == STATE_SET_UP) ? STATE_COMPLETED : mState;
listener.onFinished(this);
+
+ // NOTE: If this details is a JumboClipDetails, and it's still referred in primary clip
+ // at this point, user won't be able to paste it to anywhere else because the underlying
+ srcs.dispose();
}
}
+ boolean setUp() {
+ return true;
+ }
abstract void start();
abstract Notification getSetupNotification();
- // TODO: Progress notification for deletes.
- // abstract Notification getProgressNotification(long bytesCopied);
+ abstract Notification getProgressNotification();
abstract Notification getFailureNotification();
abstract Notification getWarningNotification();
@@ -158,13 +191,21 @@ abstract public class Job implements Runnable {
}
}
+ final @State int getState() {
+ return mState;
+ }
+
final void cancel() {
- mCanceled = true;
+ mState = STATE_CANCELED;
Metrics.logFileOperationCancelled(service, operationType);
}
final boolean isCanceled() {
- return mCanceled;
+ return mState == STATE_CANCELED;
+ }
+
+ final boolean isFinished() {
+ return mState == STATE_CANCELED || mState == STATE_COMPLETED;
}
final ContentResolver getContentResolver() {
@@ -172,11 +213,12 @@ abstract public class Job implements Runnable {
}
void onFileFailed(DocumentInfo file) {
+ ++failedFileCount;
failedFiles.add(file);
}
final boolean hasFailures() {
- return !failedFiles.isEmpty();
+ return failedFileCount > 0;
}
boolean hasWarnings() {
@@ -208,12 +250,12 @@ abstract public class Job implements Runnable {
Notification getFailureNotification(@PluralsRes int titleId, @DrawableRes int icon) {
final Intent navigateIntent = buildNavigateIntent(INTENT_TAG_FAILURE);
navigateIntent.putExtra(EXTRA_DIALOG_TYPE, OperationDialogFragment.DIALOG_TYPE_FAILURE);
- navigateIntent.putExtra(EXTRA_OPERATION, operationType);
+ navigateIntent.putExtra(EXTRA_OPERATION_TYPE, operationType);
navigateIntent.putParcelableArrayListExtra(EXTRA_SRC_LIST, failedFiles);
final Notification.Builder errorBuilder = new Notification.Builder(service)
.setContentTitle(service.getResources().getQuantityString(titleId,
- failedFiles.size(), failedFiles.size()))
+ failedFileCount, failedFileCount))
.setContentText(service.getString(R.string.notification_touch_for_details))
.setContentIntent(PendingIntent.getActivity(appContext, 0, navigateIntent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT))
@@ -283,44 +325,10 @@ abstract public class Job implements Runnable {
}
/**
- * Factory class that facilitates our testing FileOperationService.
- */
- static class Factory {
-
- static final Factory instance = new Factory();
-
- Job createCopy(Context service, Context appContext, Listener listener,
- String id, DocumentStack stack, List<DocumentInfo> srcs) {
- assert(!srcs.isEmpty());
- assert(stack.peek().isCreateSupported());
- return new CopyJob(service, appContext, listener, id, stack, srcs);
- }
-
- Job createMove(Context service, Context appContext, Listener listener,
- String id, DocumentStack stack, List<DocumentInfo> srcs,
- DocumentInfo srcParent) {
- assert(!srcs.isEmpty());
- assert(stack.peek().isCreateSupported());
- return new MoveJob(service, appContext, listener, id, stack, srcs, srcParent);
- }
-
- Job createDelete(Context service, Context appContext, Listener listener,
- String id, DocumentStack stack, List<DocumentInfo> srcs,
- DocumentInfo srcParent) {
- assert(!srcs.isEmpty());
- // stack is empty if we delete docs from recent.
- // we can't currently delete from archives.
- assert(stack.isEmpty() || stack.peek().isDirectory());
- return new DeleteJob(service, appContext, listener, id, stack, srcs, srcParent);
- }
- }
-
- /**
* Listener interface employed by the service that owns us as well as tests.
*/
interface Listener {
void onStart(Job job);
void onFinished(Job job);
- void onProgress(CopyJob job);
}
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java b/packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java
index 111817132fa1..ab0fae10ee77 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java
@@ -21,24 +21,28 @@ import static com.android.documentsui.services.FileOperationService.OPERATION_MO
import android.app.Notification;
import android.app.Notification.Builder;
+import android.content.ContentResolver;
import android.content.Context;
+import android.net.Uri;
import android.os.RemoteException;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import android.util.Log;
import com.android.documentsui.R;
+import com.android.documentsui.clipping.UrisSupplier;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.DocumentStack;
-import java.util.List;
+import java.io.FileNotFoundException;
// TODO: Stop extending CopyJob.
final class MoveJob extends CopyJob {
private static final String TAG = "MoveJob";
- final DocumentInfo mSrcParent;
+ Uri mSrcParentUri;
+ DocumentInfo mSrcParent;
/**
* Moves files to a destination identified by {@code destination}.
@@ -46,14 +50,11 @@ final class MoveJob extends CopyJob {
* a file after it has been copied.
*
* @see @link {@link Job} constructor for most param descriptions.
- *
- * @param srcs List of files to be moved.
- * @param srcParent Parent of all source files.
*/
- MoveJob(Context service, Context appContext, Listener listener,
- String id, DocumentStack destination, List<DocumentInfo> srcs, DocumentInfo srcParent) {
- super(service, appContext, listener, OPERATION_MOVE, id, destination, srcs);
- this.mSrcParent = srcParent;
+ MoveJob(Context service, Listener listener,
+ String id, Uri srcParent, DocumentStack destination, UrisSupplier srcs) {
+ super(service, listener, id, OPERATION_MOVE, destination, srcs);
+ mSrcParentUri = srcParent;
}
@Override
@@ -81,6 +82,51 @@ final class MoveJob extends CopyJob {
R.plurals.move_error_notification_title, R.drawable.ic_menu_copy);
}
+ @Override
+ public boolean setUp() {
+ final ContentResolver resolver = appContext.getContentResolver();
+ try {
+ mSrcParent = DocumentInfo.fromUri(resolver, mSrcParentUri);
+ } catch(FileNotFoundException e) {
+ Log.e(TAG, "Failed to create srcParent.", e);
+ failedFileCount += srcs.getItemCount();
+ return false;
+ }
+
+ return super.setUp();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Only check space for moves across authorities. For now we don't know if the doc in
+ * {@link #mSrcs} is in the same root of destination, and if it's optimized move in the same
+ * root it should succeed regardless of free space, but it's for sure a failure if there is no
+ * enough free space if docs are moved from another authority.
+ */
+ @Override
+ boolean checkSpace() {
+ long size = 0;
+ for (DocumentInfo src : mSrcs) {
+ if (!src.authority.equals(stack.root.authority)) {
+ if (src.isDirectory()) {
+ try {
+ size += calculateFileSizesRecursively(getClient(src), src.derivedUri);
+ } catch (RemoteException|ResourceException e) {
+ Log.w(TAG, "Failed to obtain client for %s" + src.derivedUri + ".", e);
+
+ // Failed to calculate size, but move may still succeed.
+ return true;
+ }
+ } else {
+ size += src.size;
+ }
+ }
+ }
+
+ return checkSpace(size);
+ }
+
void processDocument(DocumentInfo src, DocumentInfo srcParent, DocumentInfo dest)
throws ResourceException {
diff --git a/packages/DocumentsUI/tests/Android.mk b/packages/DocumentsUI/tests/Android.mk
index c004315a6d18..febc542096a0 100644
--- a/packages/DocumentsUI/tests/Android.mk
+++ b/packages/DocumentsUI/tests/Android.mk
@@ -7,8 +7,9 @@ LOCAL_MODULE_TAGS := tests
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_JAVA_LIBRARIES := android-support-v4 android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := mockito-target ub-uiautomator android-support-test
+LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_STATIC_JAVA_LIBRARIES := mockito-target ub-uiautomator espresso-core guava
+LOCAL_JARJAR_RULES := $(LOCAL_PATH)/jarjar-rules.txt
LOCAL_PACKAGE_NAME := DocumentsUITests
LOCAL_INSTRUMENTATION_FOR := DocumentsUI
diff --git a/packages/DocumentsUI/tests/jarjar-rules.txt b/packages/DocumentsUI/tests/jarjar-rules.txt
new file mode 100644
index 000000000000..360b69b0c992
--- /dev/null
+++ b/packages/DocumentsUI/tests/jarjar-rules.txt
@@ -0,0 +1,2 @@
+rule com.google.common.** docsui.@0
+rule android.support.annotation.** docsui.@0
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/ActivityTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/ActivityTest.java
index 683fd6c92caf..8ad30d71a811 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/ActivityTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/ActivityTest.java
@@ -20,7 +20,6 @@ import static com.android.documentsui.StubProvider.DEFAULT_AUTHORITY;
import static com.android.documentsui.StubProvider.ROOT_0_ID;
import static com.android.documentsui.StubProvider.ROOT_1_ID;
-import android.annotation.Nullable;
import android.app.Activity;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
@@ -32,17 +31,14 @@ import android.support.test.uiautomator.Configurator;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObjectNotFoundException;
import android.test.ActivityInstrumentationTestCase2;
-import android.util.Log;
import android.view.MotionEvent;
-import com.android.documentsui.BaseActivity;
-import com.android.documentsui.EventListener;
-import com.android.documentsui.bots.DirectoryListBot;
-import com.android.documentsui.bots.KeyboardBot;
-import com.android.documentsui.bots.RootsListBot;
+import com.android.documentsui.bots.Bots;
import com.android.documentsui.bots.UiBot;
import com.android.documentsui.model.RootInfo;
+import javax.annotation.Nullable;
+
/**
* Provides basic test environment for UI tests:
* - Launches activity
@@ -55,6 +51,7 @@ public abstract class ActivityTest<T extends Activity> extends ActivityInstrumen
// Testing files. For custom ones, override initTestFiles().
public static final String dirName1 = "Dir1";
+ public static final String childDir1 = "ChildDir1";
public static final String fileName1 = "file1.log";
public static final String fileName2 = "file12.png";
public static final String fileName3 = "anotherFile0.log";
@@ -81,8 +78,7 @@ public abstract class ActivityTest<T extends Activity> extends ActivityInstrumen
* Override the method if you want to open different root on start.
* @return Root that will be opened. Return null if you want to open activity's default root.
*/
- @Nullable
- protected RootInfo getInitialRoot() {
+ protected @Nullable RootInfo getInitialRoot() {
return rootDir0;
}
@@ -157,29 +153,16 @@ public abstract class ActivityTest<T extends Activity> extends ActivityInstrumen
}
void assertDefaultContentOfTestDir0() throws UiObjectNotFoundException {
+ bots.directory.waitForDocument(fileName1);
+ bots.directory.waitForDocument(fileName2);
+ bots.directory.waitForDocument(dirName1);
+ bots.directory.waitForDocument(fileNameNoRename);
bots.directory.assertDocumentsCount(4);
- bots.directory.assertDocumentsPresent(fileName1, fileName2, dirName1, fileNameNoRename);
}
void assertDefaultContentOfTestDir1() throws UiObjectNotFoundException {
+ bots.directory.waitForDocument(fileName3);
+ bots.directory.waitForDocument(fileName4);
bots.directory.assertDocumentsCount(2);
- bots.directory.assertDocumentsPresent(fileName3, fileName4);
- }
-
- /**
- * Handy collection of bots for working with Files app.
- */
- public static final class Bots {
- public final UiBot main;
- public final RootsListBot roots;
- public final DirectoryListBot directory;
- public final KeyboardBot keyboard;
-
- private Bots(UiDevice device, Context context, int timeout) {
- this.main = new UiBot(device, context, TIMEOUT);
- this.roots = new RootsListBot(device, context, TIMEOUT);
- this.directory = new DirectoryListBot(device, context, TIMEOUT);
- this.keyboard = new KeyboardBot(device, context, TIMEOUT);
- }
}
}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/DocumentsMenuManagerTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/DocumentsMenuManagerTest.java
new file mode 100644
index 000000000000..ec0317360660
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/DocumentsMenuManagerTest.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import static com.android.documentsui.State.ACTION_CREATE;
+import static com.android.documentsui.State.ACTION_OPEN;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.provider.DocumentsContract.Root;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.model.RootInfo;
+import com.android.documentsui.testing.TestDirectoryDetails;
+import com.android.documentsui.testing.TestMenu;
+import com.android.documentsui.testing.TestMenuItem;
+import com.android.documentsui.testing.TestSearchViewManager;
+import com.android.documentsui.testing.TestSelectionDetails;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public final class DocumentsMenuManagerTest {
+
+ private TestMenu testMenu;
+ private TestMenuItem open;
+ private TestMenuItem share;
+ private TestMenuItem delete;
+ private TestMenuItem rename;
+ private TestMenuItem selectAll;
+ private TestMenuItem createDir;
+ private TestMenuItem fileSize;
+ private TestMenuItem grid;
+ private TestMenuItem list;
+ private TestMenuItem cut;
+ private TestMenuItem copy;
+ private TestMenuItem paste;
+ private TestMenuItem sort;
+ private TestMenuItem sortSize;
+ private TestMenuItem advanced;
+ private TestMenuItem settings;
+ private TestMenuItem eject;
+
+ private TestSelectionDetails selectionDetails;
+ private TestDirectoryDetails directoryDetails;
+ private TestSearchViewManager testSearchManager;
+ private State state = new State();
+ private RootInfo testRootInfo;
+
+ @Before
+ public void setUp() {
+ testMenu = TestMenu.create();
+ open = testMenu.findItem(R.id.menu_open);
+ share = testMenu.findItem(R.id.menu_share);
+ delete = testMenu.findItem(R.id.menu_delete);
+ rename = testMenu.findItem(R.id.menu_rename);
+ selectAll = testMenu.findItem(R.id.menu_select_all);
+ createDir = testMenu.findItem(R.id.menu_create_dir);
+ fileSize = testMenu.findItem(R.id.menu_file_size);
+ grid = testMenu.findItem(R.id.menu_grid);
+ list = testMenu.findItem(R.id.menu_list);
+ cut = testMenu.findItem(R.id.menu_cut_to_clipboard);
+ copy = testMenu.findItem(R.id.menu_copy_to_clipboard);
+ paste = testMenu.findItem(R.id.menu_paste_from_clipboard);
+ sort = testMenu.findItem(R.id.menu_sort);
+ sortSize = testMenu.findItem(R.id.menu_sort_size);
+ advanced = testMenu.findItem(R.id.menu_advanced);
+ settings = testMenu.findItem(R.id.menu_settings);
+ eject = testMenu.findItem(R.id.menu_eject_root);
+
+ selectionDetails = new TestSelectionDetails();
+ directoryDetails = new TestDirectoryDetails();
+ testSearchManager = new TestSearchViewManager();
+ testRootInfo = new RootInfo();
+ state.action = ACTION_CREATE;
+ state.allowMultiple = true;
+ }
+
+ @Test
+ public void testActionMenu() {
+ DocumentsMenuManager mgr = new DocumentsMenuManager(testSearchManager, state);
+ mgr.updateActionMenu(testMenu, selectionDetails);
+
+ open.assertInvisible();
+ delete.assertInvisible();
+ share.assertInvisible();
+ rename.assertInvisible();
+ selectAll.assertVisible();
+ }
+
+ @Test
+ public void testActionMenu_openAction() {
+ state.action = ACTION_OPEN;
+ DocumentsMenuManager mgr = new DocumentsMenuManager(testSearchManager, state);
+ mgr.updateActionMenu(testMenu, selectionDetails);
+
+ open.assertVisible();
+ }
+
+
+ @Test
+ public void testActionMenu_notAllowMultiple() {
+ state.allowMultiple = false;
+ DocumentsMenuManager mgr = new DocumentsMenuManager(testSearchManager, state);
+ mgr.updateActionMenu(testMenu, selectionDetails);
+
+ selectAll.assertInvisible();
+ }
+
+ @Test
+ public void testOptionMenu() {
+ DocumentsMenuManager mgr = new DocumentsMenuManager(testSearchManager, state);
+ mgr.updateOptionMenu(testMenu, directoryDetails);
+
+ sort.assertEnabled();
+ sortSize.assertInvisible();
+ advanced.assertInvisible();
+ advanced.assertTitle(R.string.menu_advanced_show);
+ createDir.assertDisabled();
+ fileSize.assertInvisible();
+ assertTrue(testSearchManager.showMenuCalled());
+ }
+
+ @Test
+ public void testOptionMenu_hideSize() {
+ state.showSize = true;
+ DocumentsMenuManager mgr = new DocumentsMenuManager(testSearchManager, state);
+ mgr.updateOptionMenu(testMenu, directoryDetails);
+
+ sortSize.assertVisible();
+ }
+
+ @Test
+ public void testOptionMenu_notPicking() {
+ state.action = ACTION_OPEN;
+ state.derivedMode = State.MODE_LIST;
+ DocumentsMenuManager mgr = new DocumentsMenuManager(testSearchManager, state);
+ mgr.updateOptionMenu(testMenu, directoryDetails);
+
+ createDir.assertInvisible();
+ grid.assertVisible();
+ list.assertInvisible();
+ assertFalse(testSearchManager.showMenuCalled());
+ }
+
+ @Test
+ public void testOptionMenu_canCreateDirectory() {
+ directoryDetails.canCreateDirectory = true;
+ DocumentsMenuManager mgr = new DocumentsMenuManager(testSearchManager, state);
+ mgr.updateOptionMenu(testMenu, directoryDetails);
+
+ createDir.assertEnabled();
+ }
+
+ @Test
+ public void testOptionMenu_showAdvanced() {
+ state.showAdvanced = true;
+ state.showAdvancedOption = true;
+ DocumentsMenuManager mgr = new DocumentsMenuManager(testSearchManager, state);
+ mgr.updateOptionMenu(testMenu, directoryDetails);
+
+ advanced.assertVisible();
+ advanced.assertTitle(R.string.menu_advanced_hide);
+ }
+
+ @Test
+ public void testOptionMenu_inRecents() {
+ directoryDetails.isInRecents = true;
+ DocumentsMenuManager mgr = new DocumentsMenuManager(testSearchManager, state);
+ mgr.updateOptionMenu(testMenu, directoryDetails);
+
+ sort.assertDisabled();
+ grid.assertInvisible();
+ list.assertInvisible();
+ }
+
+ @Test
+ public void testContextMenu_NoSelection() {
+ DocumentsMenuManager mgr = new DocumentsMenuManager(testSearchManager, state);
+ mgr.updateContextMenu(testMenu, null, directoryDetails);
+ cut.assertVisible();
+ copy.assertVisible();
+ cut.assertDisabled();
+ copy.assertDisabled();
+ paste.assertVisible();
+ createDir.assertVisible();
+ delete.assertVisible();
+ }
+
+ @Test
+ public void testContextMenu_Selection() {
+ DocumentsMenuManager mgr = new DocumentsMenuManager(testSearchManager, state);
+ mgr.updateContextMenu(testMenu, selectionDetails, directoryDetails);
+ cut.assertVisible();
+ copy.assertVisible();
+ paste.assertVisible();
+ rename.assertInvisible();
+ createDir.assertVisible();
+ delete.assertVisible();
+ }
+
+ @Test
+ public void testRootContextMenu() {
+ DocumentsMenuManager mgr = new DocumentsMenuManager(testSearchManager, state);
+ mgr.updateRootContextMenu(testMenu, testRootInfo);
+
+ eject.assertInvisible();
+ settings.assertInvisible();
+ }
+
+ @Test
+ public void testRootContextMenu_hasRootSettings() {
+ testRootInfo.flags = Root.FLAG_HAS_SETTINGS;
+ DocumentsMenuManager mgr = new DocumentsMenuManager(testSearchManager, state);
+ mgr.updateRootContextMenu(testMenu, testRootInfo);
+
+ settings.assertInvisible();
+ }
+
+ @Test
+ public void testRootContextMenu_canEject() {
+ testRootInfo.flags = Root.FLAG_SUPPORTS_EJECT;
+ DocumentsMenuManager mgr = new DocumentsMenuManager(testSearchManager, state);
+ mgr.updateRootContextMenu(testMenu, testRootInfo);
+
+ eject.assertInvisible();
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/FileManagementUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/FileManagementUiTest.java
new file mode 100644
index 000000000000..623f68ae794b
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/FileManagementUiTest.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import static com.android.documentsui.StubProvider.ROOT_0_ID;
+import static com.android.documentsui.StubProvider.ROOT_1_ID;
+
+import android.net.Uri;
+import android.os.RemoteException;
+import android.support.test.filters.Suppress;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.view.KeyEvent;
+
+@LargeTest
+public class FileManagementUiTest extends ActivityTest<FilesActivity> {
+
+ public FileManagementUiTest() {
+ super(FilesActivity.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ initTestFiles();
+ }
+
+ @Override
+ public void initTestFiles() throws RemoteException {
+ Uri uri = mDocsHelper.createFolder(rootDir0, dirName1);
+ mDocsHelper.createFolder(uri, childDir1);
+
+ mDocsHelper.createDocument(rootDir0, "text/plain", "file0.log");
+ mDocsHelper.createDocument(rootDir0, "image/png", "file1.png");
+ mDocsHelper.createDocument(rootDir0, "text/csv", "file2.csv");
+
+ mDocsHelper.createDocument(rootDir1, "text/plain", "anotherFile0.log");
+ mDocsHelper.createDocument(rootDir1, "text/plain", "poodles.text");
+ }
+
+ @Suppress
+ public void testCreateDirectory() throws Exception {
+ bots.main.openOverflowMenu();
+ device.waitForIdle();
+
+ bots.main.clickToolbarOverflowItem("New folder");
+ device.waitForIdle();
+
+ bots.main.setDialogText("Kung Fu Panda");
+ device.waitForIdle();
+
+ bots.keyboard.pressEnter();
+
+ bots.directory.waitForDocument("Kung Fu Panda");
+ }
+
+ public void testDeleteDocument() throws Exception {
+ bots.directory.clickDocument("file1.png");
+ device.waitForIdle();
+ bots.main.clickToolbarItem(R.id.menu_delete);
+
+ bots.main.clickDialogOkButton();
+ device.waitForIdle();
+
+ bots.directory.assertDocumentsAbsent("file1.png");
+ }
+
+ public void testKeyboard_CutDocument() throws Exception {
+ bots.directory.clickDocument("file1.png");
+ device.waitForIdle();
+ bots.keyboard.pressKey(KeyEvent.KEYCODE_X, KeyEvent.META_CTRL_ON);
+
+ device.waitForIdle();
+
+ bots.roots.openRoot(ROOT_1_ID);
+ bots.keyboard.pressKey(KeyEvent.KEYCODE_V, KeyEvent.META_CTRL_ON);
+
+ bots.directory.waitForDocument("file1.png");
+ bots.directory.assertDocumentsPresent("file1.png");
+
+ bots.roots.openRoot(ROOT_0_ID);
+ bots.directory.assertDocumentsAbsent("file1.png");
+ }
+
+ public void testKeyboard_CopyDocument() throws Exception {
+ bots.directory.clickDocument("file1.png");
+ device.waitForIdle();
+ bots.keyboard.pressKey(KeyEvent.KEYCODE_C, KeyEvent.META_CTRL_ON);
+
+ device.waitForIdle();
+
+ bots.roots.openRoot(ROOT_1_ID);
+ bots.keyboard.pressKey(KeyEvent.KEYCODE_V, KeyEvent.META_CTRL_ON);
+
+ bots.directory.waitForDocument("file1.png");
+
+ bots.roots.openRoot(ROOT_0_ID);
+ bots.directory.waitForDocument("file1.png");
+ }
+
+ public void testDeleteDocument_Cancel() throws Exception {
+ bots.directory.clickDocument("file1.png");
+ device.waitForIdle();
+ bots.main.clickToolbarItem(R.id.menu_delete);
+
+ bots.main.clickDialogCancelButton();
+
+ bots.directory.waitForDocument("file1.png");
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityDefaultsUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityDefaultsUiTest.java
new file mode 100644
index 000000000000..d0ec9d7164dc
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityDefaultsUiTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import static com.android.documentsui.StubProvider.ROOT_0_ID;
+import static com.android.documentsui.StubProvider.ROOT_1_ID;
+
+import android.content.Intent;
+import android.provider.DocumentsContract;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import com.android.documentsui.model.RootInfo;
+
+@LargeTest
+public class FilesActivityDefaultsUiTest extends ActivityTest<FilesActivity> {
+
+ public FilesActivityDefaultsUiTest() {
+ super(FilesActivity.class);
+ }
+
+ @Override
+ protected RootInfo getInitialRoot() {
+ return null; // test the default, unaffected state of the app.
+ }
+
+ public void testDefaultDirectory() throws Exception {
+ device.waitForIdle();
+
+ // Separate logic for "Documents" root, which presence depends on the config setting
+ if (docsRootEnabled()) {
+ bots.main.assertWindowTitle("Documents");
+ } else {
+ bots.main.assertWindowTitle("Downloads");
+ }
+ }
+
+ public void testDefaultRoots() throws Exception {
+ device.waitForIdle();
+
+ // Should also have Drive, but that requires pre-configuration of devices
+ // We omit for now.
+ bots.roots.assertRootsPresent(
+ "Images",
+ "Videos",
+ "Audio",
+ "Downloads",
+ ROOT_0_ID,
+ ROOT_1_ID);
+
+ // Separate logic for "Documents" root, which presence depends on the config setting
+ if (docsRootEnabled()) {
+ bots.roots.assertRootsPresent("Documents");
+ } else {
+ bots.roots.assertRootsAbsent("Documents");
+ }
+ }
+
+ private boolean docsRootEnabled() {
+ return Shared.shouldShowDocumentsRoot(context, new Intent(DocumentsContract.ACTION_BROWSE));
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java
index 69f0e677eb04..1b47705f48dc 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java
@@ -16,24 +16,9 @@
package com.android.documentsui;
-import static com.android.documentsui.StubProvider.ROOT_0_ID;
-import static com.android.documentsui.StubProvider.ROOT_1_ID;
-
-import android.app.DownloadManager;
-import android.app.DownloadManager.Request;
-import android.content.Context;
-import android.content.Intent;
import android.net.Uri;
import android.os.RemoteException;
-import android.provider.DocumentsContract;
-import android.support.test.uiautomator.Configurator;
-import android.support.test.uiautomator.UiObject;
import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.Suppress;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-
-import com.android.documentsui.model.RootInfo;
@LargeTest
public class FilesActivityUiTest extends ActivityTest<FilesActivity> {
@@ -43,12 +28,16 @@ public class FilesActivityUiTest extends ActivityTest<FilesActivity> {
}
@Override
- protected RootInfo getInitialRoot() {
- return null;
+ public void setUp() throws Exception {
+ super.setUp();
+ initTestFiles();
}
@Override
public void initTestFiles() throws RemoteException {
+ Uri uri = mDocsHelper.createFolder(rootDir0, dirName1);
+ mDocsHelper.createFolder(uri, childDir1);
+
mDocsHelper.createDocument(rootDir0, "text/plain", "file0.log");
mDocsHelper.createDocument(rootDir0, "image/png", "file1.png");
mDocsHelper.createDocument(rootDir0, "text/csv", "file2.csv");
@@ -57,52 +46,16 @@ public class FilesActivityUiTest extends ActivityTest<FilesActivity> {
mDocsHelper.createDocument(rootDir1, "text/plain", "poodles.text");
}
- public void testRootsListed() throws Exception {
- initTestFiles();
-
- // Should also have Drive, but that requires pre-configuration of devices
- // We omit for now.
- bots.roots.assertRootsPresent(
- "Images",
- "Videos",
- "Audio",
- "Downloads",
- ROOT_0_ID,
- ROOT_1_ID);
-
- // Separate logic for "Documents" root, which presence depends on the config setting
- if (Shared.shouldShowDocumentsRoot(context, new Intent(DocumentsContract.ACTION_BROWSE))) {
- bots.roots.assertRootsPresent("Documents");
- } else {
- bots.roots.assertRootsAbsent("Documents");
- }
- }
-
public void testFilesListed() throws Exception {
- initTestFiles();
-
- bots.roots.openRoot(ROOT_0_ID);
bots.directory.assertDocumentsPresent("file0.log", "file1.png", "file2.csv");
}
- public void testLoadsDownloadsDirectoryByDefault() throws Exception {
- initTestFiles();
-
- device.waitForIdle();
- bots.main.assertWindowTitle("Downloads");
- }
-
- public void testRootClickSetsWindowTitle() throws Exception {
- initTestFiles();
-
- bots.roots.openRoot("Downloads");
- bots.main.assertWindowTitle("Downloads");
+ public void testRootClick_SetsWindowTitle() throws Exception {
+ bots.roots.openRoot("Images");
+ bots.main.assertWindowTitle("Images");
}
public void testFilesList_LiveUpdate() throws Exception {
- initTestFiles();
-
- bots.roots.openRoot(ROOT_0_ID);
mDocsHelper.createDocument(rootDir0, "yummers/sandwich", "Ham & Cheese.sandwich");
bots.directory.waitForDocument("Ham & Cheese.sandwich");
@@ -110,115 +63,16 @@ public class FilesActivityUiTest extends ActivityTest<FilesActivity> {
"file0.log", "file1.png", "file2.csv", "Ham & Cheese.sandwich");
}
- public void testCreateDirectory() throws Exception {
- initTestFiles();
+ public void testNavigateByBreadcrumb() throws Exception {
+ bots.directory.openDocument(dirName1);
+ bots.directory.waitForDocument(childDir1); // wait for known content
+ bots.directory.assertDocumentsPresent(childDir1);
- bots.roots.openRoot(ROOT_0_ID);
-
- bots.main.openOverflowMenu();
- bots.main.menuNewFolder().click();
- bots.main.setDialogText("Kung Fu Panda");
-
- bots.keyboard.pressEnter();
-
- bots.directory.assertDocumentsPresent("Kung Fu Panda");
- }
-
- public void testDeleteDocument() throws Exception {
- initTestFiles();
-
- bots.roots.openRoot(ROOT_0_ID);
-
- bots.directory.clickDocument("file1.png");
+ bots.breadcrumb.revealAsNeeded();
device.waitForIdle();
- bots.main.menuDelete().click();
-
- bots.main.findDialogOkButton().click();
-
- bots.directory.assertDocumentsAbsent("file1.png");
- }
-
- public void testDeleteDocument_Cancel() throws Exception {
- initTestFiles();
-
- bots.roots.openRoot(ROOT_0_ID);
-
- bots.directory.clickDocument("file1.png");
- device.waitForIdle();
- bots.main.menuDelete().click();
-
- bots.main.findDialogCancelButton().click();
-
- bots.directory.assertDocumentsPresent("file1.png");
- }
-
- // Tests that pressing tab switches focus between the roots and directory listings.
- @Suppress
- public void testKeyboard_tab() throws Exception {
- bots.main.pressKey(KeyEvent.KEYCODE_TAB);
- bots.roots.assertHasFocus();
- bots.main.pressKey(KeyEvent.KEYCODE_TAB);
- bots.directory.assertHasFocus();
- }
-
- // Tests that arrow keys do not switch focus away from the dir list.
- @Suppress
- public void testKeyboard_arrowsDirList() throws Exception {
- for (int i = 0; i < 10; i++) {
- bots.main.pressKey(KeyEvent.KEYCODE_DPAD_LEFT);
- bots.directory.assertHasFocus();
- }
- for (int i = 0; i < 10; i++) {
- bots.main.pressKey(KeyEvent.KEYCODE_DPAD_RIGHT);
- bots.directory.assertHasFocus();
- }
- }
-
- // Tests that arrow keys do not switch focus away from the roots list.
- public void testKeyboard_arrowsRootsList() throws Exception {
- bots.main.pressKey(KeyEvent.KEYCODE_TAB);
- for (int i = 0; i < 10; i++) {
- bots.main.pressKey(KeyEvent.KEYCODE_DPAD_RIGHT);
- bots.roots.assertHasFocus();
- }
- for (int i = 0; i < 10; i++) {
- bots.main.pressKey(KeyEvent.KEYCODE_DPAD_LEFT);
- bots.roots.assertHasFocus();
- }
- }
-
- // We don't really need to test the entirety of download support
- // since downloads is (almost) just another provider.
- @Suppress
- public void testDownload_Queued() throws Exception {
- DownloadManager dm = (DownloadManager) context.getSystemService(
- Context.DOWNLOAD_SERVICE);
- // This downloads ends up being queued (because DNS can't be resolved).
- // We'll still see an entry in the downloads UI with a "Queued" label.
- dm.enqueue(new Request(Uri.parse("http://hammychamp.toodles")));
-
- bots.roots.openRoot("Downloads");
- bots.directory.assertDocumentsPresent("Queued");
- }
-
- @Suppress
- public void testDownload_RetryUnsuccessful() throws Exception {
- DownloadManager dm = (DownloadManager) context.getSystemService(
- Context.DOWNLOAD_SERVICE);
- // This downloads fails! But it'll still show up.
- dm.enqueue(new Request(Uri.parse("http://www.google.com/hamfancy")));
-
- bots.roots.openRoot("Downloads");
- UiObject doc = bots.directory.findDocument("Unsuccessful");
- doc.waitForExists(TIMEOUT);
-
- int toolType = Configurator.getInstance().getToolType();
- Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_FINGER);
- doc.click();
- Configurator.getInstance().setToolType(toolType);
-
- assertTrue(bots.main.findDownloadRetryDialog().exists());
+ bots.breadcrumb.assertItemsPresent(dirName1, "TEST_ROOT_0");
- device.pressBack(); // to clear the dialog.
+ bots.breadcrumb.clickItem("TEST_ROOT_0");
+ bots.directory.waitForDocument(dirName1);
}
}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/FilesMenuManagerTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/FilesMenuManagerTest.java
new file mode 100644
index 000000000000..3644abcda144
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/FilesMenuManagerTest.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import static org.junit.Assert.assertTrue;
+
+import android.provider.DocumentsContract.Root;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.model.RootInfo;
+import com.android.documentsui.testing.TestDirectoryDetails;
+import com.android.documentsui.testing.TestMenu;
+import com.android.documentsui.testing.TestMenuItem;
+import com.android.documentsui.testing.TestSearchViewManager;
+import com.android.documentsui.testing.TestSelectionDetails;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public final class FilesMenuManagerTest {
+
+ private TestMenu testMenu;
+ private TestMenuItem rename;
+ private TestMenuItem moveTo;
+ private TestMenuItem copyTo;
+ private TestMenuItem share;
+ private TestMenuItem delete;
+ private TestMenuItem createDir;
+ private TestMenuItem fileSize;
+ private TestMenuItem settings;
+ private TestMenuItem newWindow;
+ private TestMenuItem cut;
+ private TestMenuItem copy;
+ private TestMenuItem paste;
+ private TestMenuItem sort;
+ private TestMenuItem sortSize;
+ private TestMenuItem advanced;
+ private TestMenuItem eject;
+ private TestSelectionDetails selectionDetails;
+ private TestDirectoryDetails directoryDetails;
+ private TestSearchViewManager testSearchManager;
+ private RootInfo testRootInfo;
+ private State state = new State();
+
+ @Before
+ public void setUp() {
+ testMenu = TestMenu.create();
+ rename = testMenu.findItem(R.id.menu_rename);
+ moveTo = testMenu.findItem(R.id.menu_move_to);
+ copyTo = testMenu.findItem(R.id.menu_copy_to);
+ share = testMenu.findItem(R.id.menu_share);
+ delete = testMenu.findItem(R.id.menu_delete);
+ createDir = testMenu.findItem(R.id.menu_create_dir);
+ fileSize = testMenu.findItem(R.id.menu_file_size);
+ settings = testMenu.findItem(R.id.menu_settings);
+ newWindow = testMenu.findItem(R.id.menu_new_window);
+ cut = testMenu.findItem(R.id.menu_cut_to_clipboard);
+ copy = testMenu.findItem(R.id.menu_copy_to_clipboard);
+ paste = testMenu.findItem(R.id.menu_paste_from_clipboard);
+ sort = testMenu.findItem(R.id.menu_sort);
+ sortSize = testMenu.findItem(R.id.menu_sort_size);
+ advanced = testMenu.findItem(R.id.menu_advanced);
+ eject = testMenu.findItem(R.id.menu_eject_root);
+
+ // These items by default are visible
+ testMenu.findItem(R.id.menu_select_all).setVisible(true);
+ testMenu.findItem(R.id.menu_list).setVisible(true);
+ testMenu.findItem(R.id.menu_file_size).setVisible(true);
+
+ selectionDetails = new TestSelectionDetails();
+ directoryDetails = new TestDirectoryDetails();
+ testSearchManager = new TestSearchViewManager();
+ testRootInfo = new RootInfo();
+ }
+
+ @Test
+ public void testActionMenu() {
+ selectionDetails.canDelete = true;
+ selectionDetails.canRename = true;
+
+ FilesMenuManager mgr = new FilesMenuManager(testSearchManager, state);
+ mgr.updateActionMenu(testMenu, selectionDetails);
+
+ rename.assertEnabled();
+ delete.assertVisible();
+ share.assertVisible();
+ copyTo.assertEnabled();
+ moveTo.assertEnabled();
+ }
+
+ @Test
+ public void testActionMenu_containsPartial() {
+ selectionDetails.containPartial = true;
+ FilesMenuManager mgr = new FilesMenuManager(testSearchManager, state);
+ mgr.updateActionMenu(testMenu, selectionDetails);
+
+ rename.assertDisabled();
+ share.assertInvisible();
+ copyTo.assertDisabled();
+ moveTo.assertDisabled();
+ }
+
+ @Test
+ public void testActionMenu_cantRename() {
+ selectionDetails.canRename = false;
+ FilesMenuManager mgr = new FilesMenuManager(testSearchManager, state);
+ mgr.updateActionMenu(testMenu, selectionDetails);
+
+ rename.assertDisabled();
+ }
+
+ @Test
+ public void testActionMenu_cantDelete() {
+ selectionDetails.canDelete = false;
+ FilesMenuManager mgr = new FilesMenuManager(testSearchManager, state);
+ mgr.updateActionMenu(testMenu, selectionDetails);
+
+ delete.assertInvisible();
+ // We shouldn't be able to move files if we can't delete them
+ moveTo.assertDisabled();
+ }
+
+ @Test
+ public void testActionMenu_containsDirectory() {
+ selectionDetails.containDirectories = true;
+ FilesMenuManager mgr = new FilesMenuManager(testSearchManager, state);
+ mgr.updateActionMenu(testMenu, selectionDetails);
+
+ // We can't share directories
+ share.assertInvisible();
+ }
+
+ @Test
+ public void testOptionMenu() {
+ FilesMenuManager mgr = new FilesMenuManager(testSearchManager, state);
+ mgr.updateOptionMenu(testMenu, directoryDetails);
+
+ sort.assertEnabled();
+ sortSize.assertInvisible();
+ advanced.assertInvisible();
+ advanced.assertTitle(R.string.menu_advanced_show);
+ createDir.assertDisabled();
+ fileSize.assertVisible();
+ assertTrue(testSearchManager.updateMenuCalled());
+ }
+
+ @Test
+ public void testOptionMenu_hideSize() {
+ state.showSize = true;
+ FilesMenuManager mgr = new FilesMenuManager(testSearchManager, state);
+ mgr.updateOptionMenu(testMenu, directoryDetails);
+
+ sortSize.assertVisible();
+ }
+
+ @Test
+ public void testOptionMenu_showAdvanced() {
+ state.showAdvanced = true;
+ state.showAdvancedOption = true;
+ FilesMenuManager mgr = new FilesMenuManager(testSearchManager, state);
+ mgr.updateOptionMenu(testMenu, directoryDetails);
+
+ advanced.assertVisible();
+ advanced.assertTitle(R.string.menu_advanced_hide);
+ }
+
+ @Test
+ public void testOptionMenu_inRecents() {
+ directoryDetails.isInRecents = true;
+ FilesMenuManager mgr = new FilesMenuManager(testSearchManager, state);
+ mgr.updateOptionMenu(testMenu, directoryDetails);
+
+ sort.assertDisabled();
+ }
+
+ @Test
+ public void testOptionMenu_canCreateDirectory() {
+ directoryDetails.canCreateDirectory = true;
+ FilesMenuManager mgr = new FilesMenuManager(testSearchManager, state);
+ mgr.updateOptionMenu(testMenu, directoryDetails);
+
+ createDir.assertEnabled();
+ }
+
+ @Test
+ public void testOptionMenu_hasRootSettings() {
+ directoryDetails.hasRootSettings = true;
+ FilesMenuManager mgr = new FilesMenuManager(testSearchManager, state);
+ mgr.updateOptionMenu(testMenu, directoryDetails);
+
+ settings.assertVisible();
+ }
+
+ @Test
+ public void testOptionMenu_shouldShowFancyFeatures() {
+ directoryDetails.shouldShowFancyFeatures = true;
+ FilesMenuManager mgr = new FilesMenuManager(testSearchManager, state);
+ mgr.updateOptionMenu(testMenu, directoryDetails);
+
+ newWindow.assertVisible();
+ }
+
+ @Test
+ public void testContextMenu_NoSelection() {
+ FilesMenuManager mgr = new FilesMenuManager(testSearchManager, state);
+ mgr.updateContextMenu(testMenu, null, directoryDetails);
+ cut.assertVisible();
+ copy.assertVisible();
+ cut.assertDisabled();
+ copy.assertDisabled();
+ paste.assertVisible();
+ createDir.assertVisible();
+ delete.assertVisible();
+ }
+
+ @Test
+ public void testContextMenu_Selection() {
+ FilesMenuManager mgr = new FilesMenuManager(testSearchManager, state);
+ mgr.updateContextMenu(testMenu, selectionDetails, directoryDetails);
+ cut.assertVisible();
+ copy.assertVisible();
+ paste.assertVisible();
+ rename.assertVisible();
+ createDir.assertVisible();
+ delete.assertVisible();
+ }
+
+ @Test
+ public void testRootContextMenu() {
+ FilesMenuManager mgr = new FilesMenuManager(testSearchManager, state);
+ mgr.updateRootContextMenu(testMenu, testRootInfo);
+
+ eject.assertVisible();
+ eject.assertDisabled();
+
+ settings.assertVisible();
+ settings.assertDisabled();
+ }
+
+ @Test
+ public void testRootContextMenu_hasRootSettings() {
+ testRootInfo.flags = Root.FLAG_HAS_SETTINGS;
+ FilesMenuManager mgr = new FilesMenuManager(testSearchManager, state);
+ mgr.updateRootContextMenu(testMenu, testRootInfo);
+
+ settings.assertEnabled();
+ }
+
+ @Test
+ public void testRootContextMenu_eject() {
+ testRootInfo.flags = Root.FLAG_SUPPORTS_EJECT;
+ FilesMenuManager mgr = new FilesMenuManager(testSearchManager, state);
+ mgr.updateRootContextMenu(testMenu, testRootInfo);
+
+ eject.assertEnabled();
+ }
+
+ @Test
+ public void testRootContextMenu_ejectInProcess() {
+ testRootInfo.flags = Root.FLAG_SUPPORTS_EJECT;
+ testRootInfo.ejecting = true;
+ FilesMenuManager mgr = new FilesMenuManager(testSearchManager, state);
+ mgr.updateRootContextMenu(testMenu, testRootInfo);
+
+ eject.assertDisabled();
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/IntegratedDownloadsUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/IntegratedDownloadsUiTest.java
new file mode 100644
index 000000000000..ef4a68ddb6a6
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/IntegratedDownloadsUiTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import android.app.DownloadManager;
+import android.app.DownloadManager.Request;
+import android.content.Context;
+import android.net.Uri;
+import android.support.test.uiautomator.Configurator;
+import android.support.test.uiautomator.UiObject;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.Suppress;
+import android.view.MotionEvent;
+
+// TODO: As of this writing all tests in this class are disabled. Please fix.
+@LargeTest
+public class IntegratedDownloadsUiTest extends ActivityTest<FilesActivity> {
+
+ public IntegratedDownloadsUiTest() {
+ super(FilesActivity.class);
+ }
+
+ // We don't really need to test the entirety of download support
+ // since downloads is (almost) just another provider.
+ @Suppress
+ public void testDownload_Queued() throws Exception {
+ DownloadManager dm = (DownloadManager) context.getSystemService(
+ Context.DOWNLOAD_SERVICE);
+ // This downloads ends up being queued (because DNS can't be resolved).
+ // We'll still see an entry in the downloads UI with a "Queued" label.
+ dm.enqueue(new Request(Uri.parse("http://hammychamp.toodles")));
+
+ bots.roots.openRoot("Downloads");
+ bots.directory.assertDocumentsPresent("Queued");
+ }
+
+ @Suppress
+ public void testDownload_RetryUnsuccessful() throws Exception {
+ DownloadManager dm = (DownloadManager) context.getSystemService(
+ Context.DOWNLOAD_SERVICE);
+ // This downloads fails! But it'll still show up.
+ dm.enqueue(new Request(Uri.parse("http://www.google.com/hamfancy")));
+
+ bots.roots.openRoot("Downloads");
+ UiObject doc = bots.directory.findDocument("Unsuccessful");
+ doc.waitForExists(TIMEOUT);
+
+ int toolType = Configurator.getInstance().getToolType();
+ Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_FINGER);
+ doc.click();
+ Configurator.getInstance().setToolType(toolType);
+
+ assertTrue(bots.main.findDownloadRetryDialog().exists());
+
+ device.pressBack(); // to clear the dialog.
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/ItemDragListenerTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/ItemDragListenerTest.java
new file mode 100644
index 000000000000..37f6532c1a9c
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/ItemDragListenerTest.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import android.content.ClipData;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.DragEvent;
+import android.view.View;
+
+import com.android.documentsui.testing.ClipDatas;
+import com.android.documentsui.testing.DragEvents;
+import com.android.documentsui.testing.TestDrawable;
+import com.android.documentsui.testing.TestTimer;
+import com.android.documentsui.testing.Views;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ItemDragListenerTest {
+
+ private static final long DELAY_AFTER_HOVERING = ItemDragListener.SPRING_TIMEOUT + 1;
+
+ private View mTestView;
+ private TestDrawable mTestBackground;
+ private TestDragHost mTestDragHost;
+ private TestTimer mTestTimer;
+
+ private TestDragListener mListener;
+
+ @Before
+ public void setUp() {
+ mTestView = Views.createTestView();
+ mTestBackground = new TestDrawable();
+ mTestTimer = new TestTimer();
+ mTestDragHost = new TestDragHost();
+
+ mListener = new TestDragListener(mTestDragHost, mTestTimer);
+ }
+
+ @Test
+ public void testDragStarted_ReturnsTrue() {
+ assertTrue(triggerDragEvent(DragEvent.ACTION_DRAG_STARTED));
+ }
+
+ @Test
+ public void testDragEntered_HighlightsView() {
+ triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);
+ assertSame(mTestView, mTestDragHost.mHighlightedView);
+ }
+
+ @Test
+ public void testDragExited_UnhighlightsView() {
+ triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);
+
+ triggerDragEvent(DragEvent.ACTION_DRAG_EXITED);
+ assertNull(mTestDragHost.mHighlightedView);
+ }
+
+ @Test
+ public void testDragEnded_UnhighlightsView() {
+ triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);
+
+ triggerDragEvent(DragEvent.ACTION_DRAG_ENDED);
+ assertNull(mTestDragHost.mHighlightedView);
+ }
+
+ @Test
+ public void testDragLocation_notCrashWithoutBackground() {
+ DragEvent locationEvent = DragEvents.createTestLocationEvent(3, 4);
+ mListener.onDrag(mTestView, locationEvent);
+ }
+
+ @Test
+ public void testDragLocation_setHotSpotOnBackground() {
+ Views.setBackground(mTestView, mTestBackground);
+
+ final float x = 2;
+ final float y = 4;
+ DragEvent locationEvent = DragEvents.createTestLocationEvent(x, y);
+ mListener.onDrag(mTestView, locationEvent);
+
+ assertEquals(x, mTestBackground.hotspotX, 0);
+ assertEquals(y, mTestBackground.hotspotY, 0);
+ }
+
+ @Test
+ public void testHover_OpensView() {
+ triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);
+
+ mTestTimer.fastForwardTo(DELAY_AFTER_HOVERING);
+
+ assertSame(mTestView, mTestDragHost.mLastOpenedView);
+ }
+
+ @Test
+ public void testDragExited_CancelsHoverTask() {
+ triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);
+
+ triggerDragEvent(DragEvent.ACTION_DRAG_EXITED);
+
+ mTestTimer.fastForwardTo(DELAY_AFTER_HOVERING);
+
+ assertNull(mTestDragHost.mLastOpenedView);
+ }
+
+ @Test
+ public void testDragEnded_CancelsHoverTask() {
+ triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);
+
+ triggerDragEvent(DragEvent.ACTION_DRAG_ENDED);
+
+ mTestTimer.fastForwardTo(DELAY_AFTER_HOVERING);
+
+ assertNull(mTestDragHost.mLastOpenedView);
+ }
+
+ @Test
+ public void testNoDropWithoutClipData() {
+ triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);
+
+ final DragEvent dropEvent = DragEvents.createTestDropEvent(null);
+ assertFalse(mListener.onDrag(mTestView, dropEvent));
+ }
+
+ @Test
+ public void testDoDropWithClipData() {
+ triggerDragEvent(DragEvent.ACTION_DRAG_ENTERED);
+
+ final ClipData data = ClipDatas.createTestClipData();
+ final DragEvent dropEvent = DragEvents.createTestDropEvent(data);
+ mListener.onDrag(mTestView, dropEvent);
+
+ assertSame(mTestView, mListener.mLastDropOnView);
+ assertSame(dropEvent, mListener.mLastDropEvent);
+ }
+
+ protected boolean triggerDragEvent(int actionId) {
+ final DragEvent testEvent = DragEvents.createTestDragEvent(actionId);
+
+ return mListener.onDrag(mTestView, testEvent);
+ }
+
+ private static class TestDragListener extends ItemDragListener<TestDragHost> {
+
+ private View mLastDropOnView;
+ private DragEvent mLastDropEvent;
+
+ protected TestDragListener(TestDragHost dragHost, Timer timer) {
+ super(dragHost, timer);
+ }
+
+ @Override
+ public TimerTask createOpenTask(View v) {
+ TimerTask task = super.createOpenTask(v);
+ TestTimer.Task testTask = new TestTimer.Task(task);
+
+ return testTask;
+ }
+
+ @Override
+ public boolean handleDropEventChecked(View v, DragEvent event) {
+ mLastDropOnView = v;
+ mLastDropEvent = event;
+ return true;
+ }
+
+ }
+
+ private static class TestDragHost implements ItemDragListener.DragHost {
+ private View mHighlightedView;
+ private View mLastOpenedView;
+
+ @Override
+ public void setDropTargetHighlight(View v, boolean highlight) {
+ mHighlightedView = highlight ? v : null;
+ }
+
+ @Override
+ public void runOnUiThread(Runnable runnable) {
+ runnable.run();
+ }
+
+ @Override
+ public void onViewHovered(View v) {
+ mLastOpenedView = v;
+ }
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/KeyboardNavigationUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/KeyboardNavigationUiTest.java
new file mode 100644
index 000000000000..1657a87a74d8
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/KeyboardNavigationUiTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.Suppress;
+import android.view.KeyEvent;
+
+@LargeTest
+public class KeyboardNavigationUiTest extends ActivityTest<FilesActivity> {
+
+ public KeyboardNavigationUiTest() {
+ super(FilesActivity.class);
+ }
+
+ // Tests that pressing tab switches focus between the roots and directory listings.
+ @Suppress
+ public void testKeyboard_tab() throws Exception {
+ bots.keyboard.pressKey(KeyEvent.KEYCODE_TAB);
+ bots.roots.assertHasFocus();
+ bots.keyboard.pressKey(KeyEvent.KEYCODE_TAB);
+ bots.directory.assertHasFocus();
+ }
+
+ // Tests that arrow keys do not switch focus away from the dir list.
+ @Suppress
+ public void testKeyboard_arrowsDirList() throws Exception {
+ for (int i = 0; i < 10; i++) {
+ bots.keyboard.pressKey(KeyEvent.KEYCODE_DPAD_LEFT);
+ bots.directory.assertHasFocus();
+ }
+ for (int i = 0; i < 10; i++) {
+ bots.keyboard.pressKey(KeyEvent.KEYCODE_DPAD_RIGHT);
+ bots.directory.assertHasFocus();
+ }
+ }
+
+ // Tests that arrow keys do not switch focus away from the roots list.
+ public void testKeyboard_arrowsRootsList() throws Exception {
+ bots.keyboard.pressKey(KeyEvent.KEYCODE_TAB);
+ for (int i = 0; i < 10; i++) {
+ bots.keyboard.pressKey(KeyEvent.KEYCODE_DPAD_RIGHT);
+ bots.roots.assertHasFocus();
+ }
+ for (int i = 0; i < 10; i++) {
+ bots.keyboard.pressKey(KeyEvent.KEYCODE_DPAD_LEFT);
+ bots.roots.assertHasFocus();
+ }
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/RenameDocumentUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/RenameDocumentUiTest.java
index 9a06807f02cc..e7ac2934ced4 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/RenameDocumentUiTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/RenameDocumentUiTest.java
@@ -16,8 +16,8 @@
package com.android.documentsui;
+import android.support.test.uiautomator.UiObjectNotFoundException;
import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.Suppress;
@LargeTest
public class RenameDocumentUiTest extends ActivityTest<FilesActivity> {
@@ -32,8 +32,10 @@ public class RenameDocumentUiTest extends ActivityTest<FilesActivity> {
public void setUp() throws Exception {
super.setUp();
initTestFiles();
+ bots.roots.closeDrawer();
}
+ // TODO: Move this over to the FilesMenuManagerTest.
public void testRenameEnabled_SingleSelection() throws Exception {
bots.directory.selectDocument(fileName1);
bots.main.openOverflowMenu();
@@ -43,6 +45,7 @@ public class RenameDocumentUiTest extends ActivityTest<FilesActivity> {
device.pressBack();
}
+ // TODO: Move this over to the FilesMenuManagerTest.
public void testNoRenameSupport_SingleSelection() throws Exception {
bots.directory.selectDocument(fileNameNoRename);
bots.main.openOverflowMenu();
@@ -52,6 +55,7 @@ public class RenameDocumentUiTest extends ActivityTest<FilesActivity> {
device.pressBack();
}
+ // TODO: Move this over to the FilesMenuManagerTest.
public void testOneHasRenameSupport_MultipleSelection() throws Exception {
bots.directory.selectDocument(fileName1);
bots.directory.selectDocument(fileNameNoRename);
@@ -62,6 +66,7 @@ public class RenameDocumentUiTest extends ActivityTest<FilesActivity> {
device.pressBack();
}
+ // TODO: Move this over to the FilesMenuManagerTest.
public void testRenameDisabled_MultipleSelection() throws Exception {
bots.directory.selectDocument(fileName1);
bots.directory.selectDocument(fileName2);
@@ -72,45 +77,46 @@ public class RenameDocumentUiTest extends ActivityTest<FilesActivity> {
device.pressBack();
}
- @Suppress
public void testRenameFile_OkButton() throws Exception {
bots.directory.selectDocument(fileName1);
- bots.main.openOverflowMenu();
- bots.main.menuRename().click();
+
+ clickRename();
+
+ device.waitForIdle();
bots.main.setDialogText(newName);
- device.waitForIdle(TIMEOUT);
- bots.main.findDialogOkButton().click();
- device.waitForIdle(TIMEOUT);
+ device.waitForIdle();
+ bots.main.clickDialogOkButton();
+ bots.directory.waitForDocument(newName);
bots.directory.assertDocumentsAbsent(fileName1);
- bots.directory.assertDocumentsPresent(newName);
bots.directory.assertDocumentsCount(4);
}
public void testRenameFile_Enter() throws Exception {
bots.directory.selectDocument(fileName1);
- bots.main.openOverflowMenu();
- bots.main.menuRename().click();
+
+ clickRename();
+
+ device.waitForIdle();
bots.main.setDialogText(newName);
+ device.waitForIdle();
bots.keyboard.pressEnter();
+ bots.directory.waitForDocument(newName);
bots.directory.assertDocumentsAbsent(fileName1);
- bots.directory.assertDocumentsPresent(newName);
bots.directory.assertDocumentsCount(4);
}
- @Suppress
public void testRenameFile_Cancel() throws Exception {
bots.directory.selectDocument(fileName1);
- bots.main.openOverflowMenu();
- bots.main.menuRename().click();
+
+ clickRename();
+
bots.main.setDialogText(newName);
- device.waitForIdle(TIMEOUT);
- bots.main.findDialogCancelButton().click();
- device.waitForIdle(TIMEOUT);
+ bots.main.clickDialogCancelButton();
bots.directory.assertDocumentsPresent(fileName1);
bots.directory.assertDocumentsAbsent(newName);
@@ -120,10 +126,10 @@ public class RenameDocumentUiTest extends ActivityTest<FilesActivity> {
public void testRenameDir() throws Exception {
String oldName = "Dir1";
String newName = "Dir123";
-
bots.directory.selectDocument(oldName);
- bots.main.openOverflowMenu();
- bots.main.menuRename().click();
+
+ clickRename();
+
bots.main.setDialogText(newName);
bots.keyboard.pressEnter();
@@ -137,8 +143,9 @@ public class RenameDocumentUiTest extends ActivityTest<FilesActivity> {
// Check that document with the new name exists
bots.directory.assertDocumentsPresent(fileName2);
bots.directory.selectDocument(fileName1);
- bots.main.openOverflowMenu();
- bots.main.menuRename().click();
+
+ clickRename();
+
bots.main.setDialogText(fileName2);
bots.keyboard.pressEnter();
@@ -148,4 +155,9 @@ public class RenameDocumentUiTest extends ActivityTest<FilesActivity> {
bots.directory.assertDocumentsPresent(fileName2);
bots.directory.assertDocumentsCount(4);
}
+
+ private void clickRename() throws UiObjectNotFoundException {
+ bots.main.clickActionbarOverflowItem("Rename");
+ device.waitForIdle();
+ }
}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/RootsUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/RootsUiTest.java
index 621410a44f50..4edfd8a5fe22 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/RootsUiTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/RootsUiTest.java
@@ -39,7 +39,7 @@ public class RootsUiTest extends ActivityTest<FilesActivity> {
public void testRootTapped_GoToRootFromChildDir() throws Exception {
bots.directory.openDocument(dirName1);
- bots.main.assertWindowTitle(dirName1);
+ bots.breadcrumb.assertTitle(dirName1);
bots.roots.openRoot(ROOT_0_ID);
bots.main.assertWindowTitle(ROOT_0_ID);
assertDefaultContentOfTestDir0();
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/SearchViewUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/SearchViewUiTest.java
index a9451a6e3792..01c6e1e53111 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/SearchViewUiTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/SearchViewUiTest.java
@@ -19,8 +19,9 @@ package com.android.documentsui;
import static com.android.documentsui.StubProvider.ROOT_0_ID;
import static com.android.documentsui.StubProvider.ROOT_1_ID;
+import android.support.test.filters.Suppress;
+import android.support.v7.recyclerview.R;
import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.Suppress;
@LargeTest
public class SearchViewUiTest extends ActivityTest<FilesActivity> {
@@ -29,126 +30,136 @@ public class SearchViewUiTest extends ActivityTest<FilesActivity> {
super(FilesActivity.class);
}
- @Suppress
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ initTestFiles();
+ // Drawer interferes with a lot of search action; going to try to close any opened ones
+ bots.roots.closeDrawer();
+
+ // wait for a file to be present in default dir.
+ bots.directory.waitForDocument(fileName1);
+ }
+
+ public void testSearchIconVisible() throws Exception {
+ // The default root (root 0) supports search
+ bots.search.assertInputExists(false);
+ bots.search.assertIconVisible(true);
+ }
+
+ public void testSearchIconHidden() throws Exception {
+ bots.roots.openRoot(ROOT_1_ID); // root 1 doesn't support search
+
+ bots.search.assertIconVisible(false);
+ bots.search.assertInputExists(false);
+ }
+
public void testSearchView_ExpandsOnClick() throws Exception {
- bots.main.openSearchView();
- bots.main.assertSearchTextFiledAndIcon(true, false);
+ bots.search.clickIcon();
+ device.waitForIdle();
+
+ bots.search.assertInputExists(true);
+ bots.search.assertInputFocused(true);
+
+ // FIXME: Matchers fail the not-present check if we've ever clicked this.
+ // bots.search.assertIconVisible(false);
}
public void testSearchView_CollapsesOnBack() throws Exception {
- bots.main.openSearchView();
-
+ bots.search.clickIcon();
device.pressBack();
- bots.main.assertSearchTextFiledAndIcon(false, true);
+ bots.search.assertIconVisible(true);
+ bots.search.assertInputExists(false);
}
- @Suppress
public void testSearchView_ClearsTextOnBack() throws Exception {
- String query = "file2";
- bots.main.openSearchView();
- bots.main.setSearchQuery(query);
+ bots.search.clickIcon();
+ bots.search.setInputText("file2");
device.pressBack();
- bots.main.assertSearchTextFiledAndIcon(false, true);
+ // Wait for a file in the default directory to be listed.
+ bots.directory.waitForDocument(dirName1);
+
+ bots.search.assertIconVisible(true);
+ bots.search.assertInputExists(false);
}
- @Suppress
- public void testSearch_ResultsFound() throws Exception {
- initTestFiles();
- assertDefaultContentOfTestDir0();
+ public void testSearchView_StateAfterSearch() throws Exception {
+ bots.search.clickIcon();
+ bots.search.setInputText("file1");
+ bots.keyboard.pressEnter();
+ device.waitForIdle();
- String query = "file1";
- bots.main.openSearchView();
- bots.main.setSearchQuery(query);
- bots.main.assertSearchTextField(true, query);
+ bots.search.assertInputEquals("file1");
+ bots.search.assertInputFocused(false);
+ }
- device.pressEnter();
+ public void testSearch_ResultsFound() throws Exception {
+ bots.search.clickIcon();
+ bots.search.setInputText("file1");
+ bots.keyboard.pressEnter();
bots.directory.assertDocumentsCountOnList(true, 2);
bots.directory.assertDocumentsPresent(fileName1, fileName2);
-
- bots.main.assertSearchTextField(false, query);
}
- @Suppress
- public void testSearchResultsFound_ClearsOnBack() throws Exception {
- initTestFiles();
- assertDefaultContentOfTestDir0();
-
- String query = fileName1;
- bots.main.openSearchView();
- bots.main.setSearchQuery(query);
+ public void testSearch_NoResults() throws Exception {
+ bots.search.clickIcon();
+ bots.search.setInputText("chocolate");
- device.pressEnter();
- device.pressBack();
+ bots.keyboard.pressEnter();
- assertDefaultContentOfTestDir0();
+ String msg = String.valueOf(context.getString(R.string.no_results));
+ bots.directory.assertMessageTextView(String.format(msg, "TEST_ROOT_0"));
}
@Suppress
- public void testSearch_NoResults() throws Exception {
- initTestFiles();
- assertDefaultContentOfTestDir0();
-
- String query = "chocolate";
- bots.main.openSearchView();
- bots.main.setSearchQuery(query);
-
- device.pressEnter();
-
- bots.directory.assertDocumentsCountOnList(false, 0);
+ public void testSearchResultsFound_ClearsOnBack() throws Exception {
+ bots.search.clickIcon();
+ bots.search.setInputText(fileName1);
+ bots.keyboard.pressEnter();
+ device.pressBack();
device.waitForIdle();
- String msg = String.valueOf(context.getString(R.string.no_results));
- bots.directory.assertMessageTextView(String.format(msg, "TEST_ROOT_0"));
- bots.main.assertSearchTextField(false, query);
+ assertDefaultContentOfTestDir0();
}
@Suppress
public void testSearchNoResults_ClearsOnBack() throws Exception {
- initTestFiles();
- assertDefaultContentOfTestDir0();
-
- String query = "chocolate";
- bots.main.openSearchView();
- bots.main.setSearchQuery(query);
+ bots.search.clickIcon();
+ bots.search.setInputText("chocolate bunny");
- device.pressEnter();
+ bots.keyboard.pressEnter();
device.pressBack();
-
device.waitForIdle();
+
assertDefaultContentOfTestDir0();
}
@Suppress
public void testSearchResultsFound_ClearsOnDirectoryChange() throws Exception {
- initTestFiles();
- assertDefaultContentOfTestDir0();
+ // Skipping this test for phones since currently there's no way to open the drawer on
+ // phones after doing a search (it's a back button instead of a hamburger button)
+ if (!bots.main.inFixedLayout()) {
+ return;
+ }
+
+ bots.search.clickIcon();
- String query = fileName1;
- bots.main.openSearchView();
- bots.main.setSearchQuery(query);
+ bots.search.setInputText(fileName1);
- device.pressEnter();
+ bots.keyboard.pressEnter();
bots.roots.openRoot(ROOT_1_ID);
+ device.waitForIdle();
assertDefaultContentOfTestDir1();
bots.roots.openRoot(ROOT_0_ID);
- assertDefaultContentOfTestDir0();
- }
-
- public void testSearchIconVisible_RootWithSearchSupport() throws Exception {
- bots.roots.openRoot(ROOT_0_ID);
- bots.main.assertSearchTextFiledAndIcon(false, true);
- }
+ device.waitForIdle();
- public void testSearchIconHidden_RootNoSearchSupport() throws Exception {
- bots.roots.openRoot(ROOT_1_ID);
- bots.main.assertSearchTextFiledAndIcon(false, false);
+ assertDefaultContentOfTestDir0();
}
-
}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/TestInputEvent.java b/packages/DocumentsUI/tests/src/com/android/documentsui/TestInputEvent.java
index ec5321a8c940..36e7c1bf7010 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/TestInputEvent.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/TestInputEvent.java
@@ -12,6 +12,7 @@ public class TestInputEvent implements Events.InputEvent {
public boolean actionDown;
public boolean actionUp;
public Point location;
+ public Point rawLocation;
public int position = Integer.MIN_VALUE;
public TestInputEvent() {}
@@ -21,6 +22,11 @@ public class TestInputEvent implements Events.InputEvent {
}
@Override
+ public boolean isTouchEvent() {
+ return !mouseEvent;
+ }
+
+ @Override
public boolean isMouseEvent() {
return mouseEvent;
}
@@ -56,6 +62,26 @@ public class TestInputEvent implements Events.InputEvent {
}
@Override
+ public float getX() {
+ return location.x;
+ }
+
+ @Override
+ public float getY() {
+ return location.y;
+ }
+
+ @Override
+ public float getRawX() {
+ return rawLocation.x;
+ }
+
+ @Override
+ public float getRawY() {
+ return rawLocation.y;
+ }
+
+ @Override
public boolean isOverItem() {
return position != Integer.MIN_VALUE && position != RecyclerView.NO_POSITION;
}
@@ -65,6 +91,9 @@ public class TestInputEvent implements Events.InputEvent {
return position;
}
+ @Override
+ public void close() {}
+
public static TestInputEvent tap(int position) {
return new TestInputEvent(position);
}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/ThumbnailCacheTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/ThumbnailCacheTest.java
new file mode 100644
index 000000000000..dda491847591
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/ThumbnailCacheTest.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import android.content.ComponentCallbacks2;
+import android.graphics.Bitmap;
+import android.graphics.Point;
+import android.net.Uri;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.ThumbnailCache.Result;
+import com.android.documentsui.testing.Bitmaps;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ThumbnailCacheTest {
+
+ private static final Uri URI_0 = Uri.parse("content://authority/document/0");
+ private static final Uri URI_1 = Uri.parse("content://authority/document/1");
+
+ private static final Point SMALL_SIZE = new Point(1, 1);
+ private static final Point MID_SIZE = new Point(2, 2);
+ private static final Point LARGE_SIZE = new Point(3, 3);
+
+ private static final Bitmap SMALL_BITMAP = Bitmaps.createTestBitmap(1, 1);
+ private static final Bitmap MIDSIZE_BITMAP = Bitmaps.createTestBitmap(2, 2);
+ private static final Bitmap LARGE_BITMAP = Bitmaps.createTestBitmap(3, 3);
+
+ private static final long LAST_MODIFIED = 100;
+
+ private static final int CACHE_SIZE_LIMIT =
+ MIDSIZE_BITMAP.getByteCount() + LARGE_BITMAP.getByteCount();
+
+ private ThumbnailCache mCache;
+
+ @Before
+ public void setUp() {
+ mCache = new ThumbnailCache(CACHE_SIZE_LIMIT);
+ }
+
+ @Test
+ public void testMiss() {
+ mCache.putThumbnail(URI_0, MID_SIZE, MIDSIZE_BITMAP, LAST_MODIFIED);
+
+ Result result = mCache.getThumbnail(URI_1, MID_SIZE);
+
+ assertMiss(result);
+ }
+
+ @Test
+ public void testHit_Exact() {
+ mCache.putThumbnail(URI_0, MID_SIZE, MIDSIZE_BITMAP, LAST_MODIFIED);
+
+ Result result = mCache.getThumbnail(URI_0, MID_SIZE);
+
+ assertHitExact(result);
+ assertSame(MIDSIZE_BITMAP, result.getThumbnail());
+ }
+
+ @Test
+ public void testHit_Smaller() {
+ mCache.putThumbnail(URI_0, MID_SIZE, MIDSIZE_BITMAP, LAST_MODIFIED);
+
+ Result result = mCache.getThumbnail(URI_0, LARGE_SIZE);
+
+ assertHitSmaller(result);
+ assertSame(MIDSIZE_BITMAP, result.getThumbnail());
+ }
+
+ @Test
+ public void testHit_Larger() {
+ mCache.putThumbnail(URI_0, MID_SIZE, MIDSIZE_BITMAP, LAST_MODIFIED);
+
+ Result result = mCache.getThumbnail(URI_0, SMALL_SIZE);
+
+ assertHitLarger(result);
+ assertSame(MIDSIZE_BITMAP, result.getThumbnail());
+ }
+
+ @Test
+ public void testHit_Larger_HasBothSize() {
+ mCache.putThumbnail(URI_0, LARGE_SIZE, LARGE_BITMAP, LAST_MODIFIED);
+ mCache.putThumbnail(URI_0, SMALL_SIZE, SMALL_BITMAP, LAST_MODIFIED);
+
+ Result result = mCache.getThumbnail(URI_0, MID_SIZE);
+
+ assertHitLarger(result);
+ assertSame(LARGE_BITMAP, result.getThumbnail());
+ }
+
+ @Test
+ public void testHit_Exact_MultiplePut() {
+ mCache.putThumbnail(URI_0, MID_SIZE, MIDSIZE_BITMAP, LAST_MODIFIED);
+
+ Bitmap localBitmap = Bitmaps.createTestBitmap(MID_SIZE.x, MID_SIZE.y);
+ long localLastModified = LAST_MODIFIED + 100;
+ mCache.putThumbnail(URI_0, MID_SIZE, localBitmap, localLastModified);
+
+ Result result = mCache.getThumbnail(URI_0, MID_SIZE);
+
+ assertHitExact(result);
+ assertSame(localBitmap, result.getThumbnail());
+ }
+
+ @Test
+ public void testHit_EqualLastModified() {
+ mCache.putThumbnail(URI_0, MID_SIZE, MIDSIZE_BITMAP, LAST_MODIFIED);
+
+ Result result = mCache.getThumbnail(URI_0, MID_SIZE);
+
+ assertEquals(LAST_MODIFIED, result.getLastModified());
+ }
+
+ @Test
+ public void testEvictOldest_SizeExceeded() {
+ mCache.putThumbnail(URI_0, MID_SIZE, MIDSIZE_BITMAP, LAST_MODIFIED);
+ mCache.putThumbnail(URI_1, SMALL_SIZE, SMALL_BITMAP, LAST_MODIFIED);
+ mCache.putThumbnail(URI_1, LARGE_SIZE, LARGE_BITMAP, LAST_MODIFIED);
+
+ Result result = mCache.getThumbnail(URI_0, MID_SIZE);
+
+ assertMiss(result);
+ }
+
+ @Test
+ public void testCacheShrink_OnTrimMemory_Moderate() {
+ mCache.putThumbnail(URI_0, MID_SIZE, MIDSIZE_BITMAP, LAST_MODIFIED);
+ mCache.putThumbnail(URI_0, SMALL_SIZE, SMALL_BITMAP, LAST_MODIFIED);
+ mCache.putThumbnail(URI_0, LARGE_SIZE, LARGE_BITMAP, LAST_MODIFIED);
+
+ mCache.onTrimMemory(ComponentCallbacks2.TRIM_MEMORY_MODERATE);
+
+ Result result = mCache.getThumbnail(URI_0, MID_SIZE);
+ assertMiss(result);
+ }
+
+ @Test
+ public void testCacheShrink_OnTrimMemory_Background() {
+ mCache.putThumbnail(URI_0, LARGE_SIZE, LARGE_BITMAP, LAST_MODIFIED);
+ mCache.putThumbnail(URI_0, SMALL_SIZE, SMALL_BITMAP, LAST_MODIFIED);
+
+ mCache.onTrimMemory(ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
+
+ // Math here (size of each pixel omitted):
+ // Limit = midSize + largeSize = 2 * 2 + 3 * 3 = 13, so after all putThumbnail the cache is
+ // full.
+ //
+ // HalfLimit = Limit / 2 = 5. After evicting largeSize bitmap, cache size decreases to 4,
+ // which is smaller than 5. Then smallSize bitmap remains.
+ Result result = mCache.getThumbnail(URI_0, MID_SIZE);
+ assertHitSmaller(result);
+ assertSame(SMALL_BITMAP, result.getThumbnail());
+ }
+
+ private static void assertMiss(Result result) {
+ assertEquals(Result.CACHE_MISS, result.getStatus());
+ assertFalse(result.isExactHit());
+ assertFalse(result.isHit());
+ }
+
+ private static void assertHitExact(Result result) {
+ assertEquals(Result.CACHE_HIT_EXACT, result.getStatus());
+ assertTrue(result.isExactHit());
+ assertTrue(result.isHit());
+ }
+
+ private static void assertHitSmaller(Result result) {
+ assertEquals(Result.CACHE_HIT_SMALLER, result.getStatus());
+ assertFalse(result.isExactHit());
+ assertTrue(result.isHit());
+ }
+
+ private static void assertHitLarger(Result result) {
+ assertEquals(Result.CACHE_HIT_LARGER, result.getStatus());
+ assertFalse(result.isExactHit());
+ assertTrue(result.isHit());
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/bots/BaseBot.java b/packages/DocumentsUI/tests/src/com/android/documentsui/bots/BaseBot.java
deleted file mode 100644
index 1d2b47f2f286..000000000000
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/bots/BaseBot.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.documentsui.bots;
-
-import static junit.framework.Assert.assertNotNull;
-
-import android.content.Context;
-import android.support.test.uiautomator.By;
-import android.support.test.uiautomator.BySelector;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject;
-import android.support.test.uiautomator.UiObject2;
-import android.support.test.uiautomator.UiSelector;
-import android.support.test.uiautomator.Until;
-
-/**
- * A test helper class that provides support for controlling directory list
- * and making assertions against the state of it.
- */
-abstract class BaseBot {
- final UiDevice mDevice;
- final Context mContext;
- final int mTimeout;
-
- BaseBot(UiDevice device, Context context, int timeout) {
- mDevice = device;
- mContext = context;
- mTimeout = timeout;
- }
-
- /**
- * Asserts that the specified view or one of its descendents has focus.
- */
- protected void assertHasFocus(String resourceName) {
- UiObject2 candidate = mDevice.findObject(By.res(resourceName));
- assertNotNull("Expected " + resourceName + " to have focus, but it didn't.",
- candidate.findObject(By.focused(true)));
- }
-
- protected UiObject2 find(BySelector selector) {
- mDevice.wait(Until.findObject(selector), mTimeout);
- return mDevice.findObject(selector);
- }
-
- protected UiObject findObject(String resourceId) {
- final UiSelector object = new UiSelector().resourceId(resourceId);
- return mDevice.findObject(object);
- }
-
- protected UiObject findObject(String parentResourceId, String childResourceId) {
- final UiSelector selector = new UiSelector()
- .resourceId(parentResourceId)
- .childSelector(new UiSelector().resourceId(childResourceId));
- return mDevice.findObject(selector);
- }
-
- protected void waitForIdle() {
- mDevice.waitForIdle(mTimeout);
- }
-}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/bots/Bots.java b/packages/DocumentsUI/tests/src/com/android/documentsui/bots/Bots.java
new file mode 100644
index 000000000000..4bda5319f82e
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/bots/Bots.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.bots;
+
+import static junit.framework.Assert.assertNotNull;
+
+import android.content.Context;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.UiSelector;
+import android.support.test.uiautomator.Until;
+
+/**
+ * Handy collection of bots for working with Files app.
+ */
+public final class Bots {
+
+ private static final int TIMEOUT = 5000;
+
+ public final BreadBot breadcrumb;
+ public final DirectoryListBot directory;
+ public final KeyboardBot keyboard;
+ public final RootsListBot roots;
+ public final SearchBot search;
+ public final UiBot main;
+
+ public Bots(UiDevice device, Context context, int timeout) {
+ main = new UiBot(device, context, TIMEOUT);
+ breadcrumb = new BreadBot(device, context, TIMEOUT, main);
+ roots = new RootsListBot(device, context, TIMEOUT);
+ directory = new DirectoryListBot(device, context, TIMEOUT);
+ keyboard = new KeyboardBot(device, context, TIMEOUT);
+ search = new SearchBot(device, context, TIMEOUT);
+ }
+
+ /**
+ * A test helper class that provides support for controlling directory list
+ * and making assertions against the state of it.
+ */
+ static abstract class BaseBot {
+ final UiDevice mDevice;
+ final Context mContext;
+ final int mTimeout;
+
+ BaseBot(UiDevice device, Context context, int timeout) {
+ mDevice = device;
+ mContext = context;
+ mTimeout = timeout;
+ }
+
+ /**
+ * Asserts that the specified view or one of its descendents has focus.
+ */
+ protected void assertHasFocus(String resourceName) {
+ UiObject2 candidate = mDevice.findObject(By.res(resourceName));
+ assertNotNull("Expected " + resourceName + " to have focus, but it didn't.",
+ candidate.findObject(By.focused(true)));
+ }
+
+ protected UiObject2 find(BySelector selector) {
+ mDevice.wait(Until.findObject(selector), mTimeout);
+ return mDevice.findObject(selector);
+ }
+
+ protected UiObject findObject(String resourceId) {
+ final UiSelector object = new UiSelector().resourceId(resourceId);
+ return mDevice.findObject(object);
+ }
+
+ protected UiObject findObject(String parentResourceId, String childResourceId) {
+ final UiSelector selector = new UiSelector()
+ .resourceId(parentResourceId)
+ .childSelector(new UiSelector().resourceId(childResourceId));
+ return mDevice.findObject(selector);
+ }
+
+ protected void waitForIdle() {
+ mDevice.waitForIdle(mTimeout);
+ }
+ }
+
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/bots/BreadBot.java b/packages/DocumentsUI/tests/src/com/android/documentsui/bots/BreadBot.java
new file mode 100644
index 000000000000..2683e6c3f69e
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/bots/BreadBot.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.bots;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.anyOf;
+import static org.hamcrest.CoreMatchers.is;
+
+import android.content.Context;
+import android.support.test.espresso.ViewInteraction;
+import android.support.test.espresso.matcher.BoundedMatcher;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.view.View;
+
+import com.android.documentsui.DragOverTextView;
+import com.android.documentsui.DropdownBreadcrumb;
+import com.android.documentsui.R;
+import com.android.documentsui.model.DocumentInfo;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Predicate;
+
+import junit.framework.Assert;
+
+/**
+ * A test helper class that provides support for controlling the UI Breadcrumb
+ * programmatically, and making assertions against the state of the UI.
+ * <p>
+ * Support for working directly with Roots and Directory view can be found in the respective bots.
+ */
+public class BreadBot extends Bots.BaseBot {
+
+ public static final String TARGET_PKG = "com.android.documentsui";
+
+ private static final Matcher<View> DROPDOWN_BREADCRUMB = withId(
+ R.id.dropdown_breadcrumb);
+
+ private static final Matcher<View> HORIZONTAL_BREADCRUMB = withId(
+ R.id.horizontal_breadcrumb);
+
+ // When any 'ol breadcrumb will do. Could be dropdown or horizontal.
+ @SuppressWarnings("unchecked")
+ private static final Matcher<View> BREADCRUMB = anyOf(
+ DROPDOWN_BREADCRUMB, HORIZONTAL_BREADCRUMB);
+
+ private UiBot mMain;
+
+ public BreadBot(UiDevice device, Context context, int timeout, UiBot main) {
+ super(device, context, timeout);
+ mMain = main;
+ }
+
+ public void assertTitle(String expected) {
+ // There is no discrete title part on the horizontal breadcrumb...
+ // so we only test on dropdown.
+ if (mMain.inDrawerLayout()) {
+ Matcher<Object> titleMatcher = dropdownTitleMatcher(expected);
+ onView(BREADCRUMB)
+ .check(matches(titleMatcher));
+ }
+ }
+
+ /**
+ * Reveals the bread crumb if it was hidden. This will likely be the case
+ * when the app is in drawer mode.
+ */
+ public void revealAsNeeded() throws Exception {
+ if (mMain.inDrawerLayout()) {
+ onView(DROPDOWN_BREADCRUMB).perform(click());
+ }
+ }
+
+ public void clickItem(String label) throws UiObjectNotFoundException {
+ if (mMain.inFixedLayout()) {
+ findHorizontalEntry(label).perform(click());
+ } else {
+ mMain.findMenuWithName(label).click();
+ }
+ }
+
+ public void assertItemsPresent(String... items) {
+ Predicate<String> checker = mMain.inFixedLayout()
+ ? this::hasHorizontalEntry
+ : mMain::hasMenuWithName;
+
+ assertItemsPresent(items, checker);
+ }
+
+ public void assertItemsPresent(String[] items, Predicate<String> predicate) {
+ List<String> absent = new ArrayList<>();
+ for (String item : items) {
+ if (!predicate.test(item)) {
+ absent.add(item);
+ }
+ }
+ if (!absent.isEmpty()) {
+ Assert.fail("Expected iteams " + Arrays.asList(items)
+ + ", but missing " + absent);
+ }
+ }
+
+ public boolean hasHorizontalEntry(String label) {
+ return Matchers.present(findHorizontalEntry(label), withText(label));
+ }
+
+ @SuppressWarnings("unchecked")
+ public ViewInteraction findHorizontalEntry(String label) {
+ return onView(allOf(isAssignableFrom(DragOverTextView.class), withText(label)));
+ }
+
+ private static Matcher<Object> dropdownTitleMatcher(String expected) {
+ final Matcher<String> textMatcher = is(expected);
+ return new BoundedMatcher<Object, DropdownBreadcrumb>(DropdownBreadcrumb.class) {
+ @Override
+ public boolean matchesSafely(DropdownBreadcrumb breadcrumb) {
+ DocumentInfo selectedDoc = (DocumentInfo) breadcrumb.getSelectedItem();
+ return textMatcher.matches(selectedDoc.displayName);
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("with breadcrumb title: ");
+ textMatcher.describeTo(description);
+ }
+ };
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/bots/DirectoryListBot.java b/packages/DocumentsUI/tests/src/com/android/documentsui/bots/DirectoryListBot.java
index 7c1e2196f6d5..fa1e09c36f17 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/bots/DirectoryListBot.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/bots/DirectoryListBot.java
@@ -21,6 +21,8 @@ import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
import android.content.Context;
+import android.support.test.espresso.Espresso;
+import android.support.test.espresso.matcher.ViewMatchers;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.BySelector;
import android.support.test.uiautomator.Configurator;
@@ -30,8 +32,12 @@ import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.UiObjectNotFoundException;
import android.support.test.uiautomator.UiSelector;
import android.support.test.uiautomator.Until;
+import android.support.v7.widget.RecyclerView;
+import android.view.KeyEvent;
import android.view.MotionEvent;
+import com.android.documentsui.R;
+
import junit.framework.Assert;
import java.util.ArrayList;
@@ -43,7 +49,7 @@ import java.util.regex.Pattern;
* A test helper class that provides support for controlling directory list
* and making assertions against the state of it.
*/
-public class DirectoryListBot extends BaseBot {
+public class DirectoryListBot extends Bots.BaseBot {
private static final String DIR_LIST_ID = "com.android.documentsui:id/dir_list";
private static final BySelector SNACK_DELETE =
@@ -124,11 +130,23 @@ public class DirectoryListBot extends BaseBot {
}
public UiObject selectDocument(String label) throws UiObjectNotFoundException {
+ waitForDocument(label);
UiObject doc = findDocument(label);
doc.longClick();
return doc;
}
+ public void copyFilesToClipboard(String...labels) throws UiObjectNotFoundException {
+ for (String label: labels) {
+ clickDocument(label);
+ }
+ mDevice.pressKeyCode(KeyEvent.KEYCODE_C, KeyEvent.META_CTRL_ON);
+ }
+
+ public void pasteFilesFromClipboard() {
+ mDevice.pressKeyCode(KeyEvent.KEYCODE_V, KeyEvent.META_CTRL_ON);
+ }
+
public UiObject2 getSnackbar(String message) {
return mDevice.wait(Until.findObject(By.text(message)), mTimeout);
}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/bots/KeyboardBot.java b/packages/DocumentsUI/tests/src/com/android/documentsui/bots/KeyboardBot.java
index 4c47cfacac72..2e715777c19f 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/bots/KeyboardBot.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/bots/KeyboardBot.java
@@ -16,14 +16,19 @@
package com.android.documentsui.bots;
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.pressImeActionButton;
+import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
+
import android.content.Context;
import android.support.test.uiautomator.UiDevice;
import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
/**
* A test helper class that provides support for keyboard manipulation.
*/
-public class KeyboardBot extends BaseBot {
+public class KeyboardBot extends Bots.BaseBot {
public KeyboardBot(UiDevice device, Context context, int timeout) {
super(device, context, timeout);
@@ -43,8 +48,17 @@ public class KeyboardBot extends BaseBot {
}
public void pressEnter() {
- waitForIdle();
- mDevice.pressEnter();
- waitForIdle();
+ //TODO: There seems to be a bug on N/Espresso that makes pressing Enter not work
+ // This is a temporary workaround that somehow works
+ // See b/28399576
+ onView(isAssignableFrom(EditText.class)).perform(pressImeActionButton());
+ }
+
+ public void pressKey(int keyCode) {
+ mDevice.pressKeyCode(keyCode);
+ }
+
+ public void pressKey(int keyCode, int metaState) {
+ mDevice.pressKeyCode(keyCode, metaState);
}
}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/bots/Matchers.java b/packages/DocumentsUI/tests/src/com/android/documentsui/bots/Matchers.java
new file mode 100644
index 000000000000..fb3cd0c7216c
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/bots/Matchers.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.bots;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+
+import android.support.test.espresso.ViewInteraction;
+import android.view.View;
+
+import org.hamcrest.Matcher;
+
+/**
+ * Support methods for working with Espresso related matchers 'n stuff.
+ */
+public final class Matchers {
+
+ private Matchers() {}
+
+ public static boolean present(Matcher<View> matcher) {
+ return present(onView(matcher), isDisplayed());
+ }
+
+ public static boolean present(ViewInteraction vi, Matcher<View> matcher) {
+ try {
+ vi.check(matches(matcher));
+ vi.check(matches(isDisplayed()));
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/bots/RootsListBot.java b/packages/DocumentsUI/tests/src/com/android/documentsui/bots/RootsListBot.java
index 096af10bab5f..c73cec2a0433 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/bots/RootsListBot.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/bots/RootsListBot.java
@@ -16,6 +16,11 @@
package com.android.documentsui.bots;
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.swipeLeft;
+import static android.support.test.espresso.action.ViewActions.swipeRight;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+
import android.content.Context;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
@@ -23,18 +28,21 @@ import android.support.test.uiautomator.UiObjectNotFoundException;
import android.support.test.uiautomator.UiScrollable;
import android.support.test.uiautomator.UiSelector;
import android.util.Log;
+import android.view.View;
-import junit.framework.Assert;
+import com.android.documentsui.R;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import junit.framework.Assert;
+
/**
* A test helper class that provides support for controlling and asserting against
* the roots list drawer.
*/
-public class RootsListBot extends BaseBot {
+public class RootsListBot extends Bots.BaseBot {
private static final String ROOTS_LIST_ID = "com.android.documentsui:id/roots_list";
private static final String TAG = "RootsListBot";
@@ -66,7 +74,25 @@ public class RootsListBot extends BaseBot {
public void openRoot(String label) throws UiObjectNotFoundException {
findRoot(label).click();
- mDevice.waitForIdle();
+ // Close the drawer in case we select a pre-selected root already
+ closeDrawer();
+ }
+
+ public void closeDrawer() {
+ // Espresso will try to close the drawer if it's opened
+ // But if no drawer exists (Tablet devices), we will have to catch the exception
+ // and continue on the test
+ // Why can't we do something like .exist() first?
+ // http://stackoverflow.com/questions/20807131/espresso-return-boolean-if-view-exists
+ try {
+ if (mContext.getResources().getConfiguration()
+ .getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
+ onView(withId(R.id.drawer_layout)).perform(swipeRight());
+ } else {
+ onView(withId(R.id.drawer_layout)).perform(swipeLeft());
+ }
+ } catch (Exception e) {
+ }
}
public void assertRootsPresent(String... labels) throws UiObjectNotFoundException {
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/bots/SearchBot.java b/packages/DocumentsUI/tests/src/com/android/documentsui/bots/SearchBot.java
new file mode 100644
index 000000000000..66be677cef89
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/bots/SearchBot.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.bots;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.typeText;
+import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant;
+import static android.support.test.espresso.matcher.ViewMatchers.isClickable;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.anyOf;
+
+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.v7.recyclerview.R;
+import android.view.View;
+
+import org.hamcrest.Matcher;
+
+/**
+ * A test helper class that provides support for controlling the search UI
+ * programmatically, and making assertions against the state of the UI.
+ * <p>
+ * Support for working directly with Roots and Directory view can be found in the respective bots.
+ */
+public class SearchBot extends Bots.BaseBot {
+
+ public static final String TARGET_PKG = "com.android.documentsui";
+
+ // Dumb search layout changes substantially between Ryu and Angler.
+ @SuppressWarnings("unchecked")
+ private static final Matcher<View> SEARCH_WIDGET = allOf(
+ withId(R.id.menu_search),
+ anyOf(isClickable(), hasDescendant(isClickable())));
+
+ // Note that input is visible when the clicky button is not
+ // present. So to clearly qualify the two...we explicitly
+ // require this input be not clickable.
+ @SuppressWarnings("unchecked")
+ private static final Matcher<View> SEARCH_INPUT = allOf(
+ withId(R.id.menu_search),
+ isDisplayed());
+
+ public SearchBot(UiDevice device, Context context, int timeout) {
+ super(device, context, timeout);
+ }
+
+ public void clickIcon() throws UiObjectNotFoundException {
+ UiObject searchView = findSearchView();
+ searchView.click();
+ assertTrue(searchView.exists());
+ }
+
+ public void setInputText(String query) throws UiObjectNotFoundException {
+ onView(SEARCH_INPUT).perform(typeText(query));
+ }
+
+ public void assertIconVisible(boolean visible) {
+ if (visible) {
+ assertTrue(
+ "Search icon should be visible.",
+ Matchers.present(SEARCH_WIDGET));
+ } else {
+ assertFalse(
+ "Search icon should not be visible.",
+ Matchers.present(SEARCH_WIDGET));
+ }
+ }
+
+ public void assertInputEquals(String query)
+ throws UiObjectNotFoundException {
+ UiObject textField = findSearchViewTextField();
+
+ assertTrue(textField.exists());
+ assertEquals(query, textField.getText());
+ }
+
+ public void assertInputFocused(boolean focused)
+ throws UiObjectNotFoundException {
+ UiObject textField = findSearchViewTextField();
+
+ assertTrue(textField.exists());
+ assertEquals(focused, textField.isFocused());
+ }
+
+ public void assertInputExists(boolean exists)
+ throws UiObjectNotFoundException {
+ assertEquals(exists, findSearchViewTextField().exists());
+ }
+
+ private UiObject findSearchView() {
+ return findObject("com.android.documentsui:id/menu_search");
+ }
+
+ private UiObject findSearchViewTextField() {
+ return findObject("com.android.documentsui:id/menu_search", "android:id/search_src_text");
+ }
+
+ private UiObject findSearchViewIcon() {
+ return mContext.getResources().getBoolean(R.bool.full_bar_search_view)
+ ? findObject("com.android.documentsui:id/menu_search")
+ : findObject("com.android.documentsui:id/menu_search", "android:id/search_button");
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/bots/UiBot.java b/packages/DocumentsUI/tests/src/com/android/documentsui/bots/UiBot.java
index 4c8dc00cc0ae..d1b73e2f6bf5 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/bots/UiBot.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/bots/UiBot.java
@@ -16,97 +16,95 @@
package com.android.documentsui.bots;
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
+import static android.support.test.espresso.matcher.ViewMatchers.withClassName;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertTrue;
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.Matchers.endsWith;
import android.content.Context;
+import android.support.test.espresso.Espresso;
+import android.support.test.espresso.action.ViewActions;
+import android.support.test.espresso.matcher.BoundedMatcher;
+import android.support.test.espresso.matcher.ViewMatchers;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.UiObjectNotFoundException;
import android.support.test.uiautomator.UiSelector;
-import android.support.test.uiautomator.Until;
+import android.util.TypedValue;
+import android.view.View;
+import android.widget.Toolbar;
import com.android.documentsui.R;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+
import java.util.Iterator;
import java.util.List;
/**
* A test helper class that provides support for controlling DocumentsUI activities
* programmatically, and making assertions against the state of the UI.
- *
- * <p>Support for working directly with Roots and Directory view can be found
- * in the respective bots.
+ * <p>
+ * Support for working directly with Roots and Directory view can be found in the respective bots.
*/
-public class UiBot extends BaseBot {
+public class UiBot extends Bots.BaseBot {
+
public static final String TARGET_PKG = "com.android.documentsui";
- private static final String LAUNCHER_PKG = "com.android.launcher";
+
+ @SuppressWarnings("unchecked")
+ private static final Matcher<View> TOOLBAR = allOf(
+ isAssignableFrom(Toolbar.class),
+ withId(R.id.toolbar));
+
+ @SuppressWarnings("unchecked")
+ private static final Matcher<View> ACTIONBAR = allOf(
+ withClassName(endsWith("ActionBarContextView")));
+
+ @SuppressWarnings("unchecked")
+ private static final Matcher<View> TEXT_ENTRY = allOf(
+ withClassName(endsWith("EditText")));
+
+ @SuppressWarnings("unchecked")
+ private static final Matcher<View> TOOLBAR_OVERFLOW = allOf(
+ withClassName(endsWith("OverflowMenuButton")),
+ ViewMatchers.isDescendantOfA(TOOLBAR));
+
+ @SuppressWarnings("unchecked")
+ private static final Matcher<View> ACTIONBAR_OVERFLOW = allOf(
+ withClassName(endsWith("OverflowMenuButton")),
+ ViewMatchers.isDescendantOfA(ACTIONBAR));
public UiBot(UiDevice device, Context context, int timeout) {
super(device, context, timeout);
}
public void assertWindowTitle(String expected) {
- // Turns out the title field on a window does not have
- // an id associated with it at runtime (which confuses the hell out of me)
- // In code we address this via "android.R.id.title".
- UiObject2 o = find(By.text(expected));
- // It's a bit of a conceit that we then *assert* that the title
- // is the value that we used to identify the UiObject2.
- // If the preceeding lookup fails, this'll choke with an NPE.
- // But given the issue described in the comment above, we're
- // going to do it anyway. Because we shouldn't be looking up
- // the uiobject by it's expected content :|
- assertEquals(expected, o.getText());
+ onView(TOOLBAR)
+ .check(matches(withToolbarTitle(is(expected))));
}
public void assertMenuEnabled(int id, boolean enabled) {
- UiObject2 menu= findMenuWithName(mContext.getString(id));
+ UiObject2 menu = findMenuWithName(mContext.getString(id));
assertNotNull(menu);
assertEquals(enabled, menu.isEnabled());
}
- public void assertSearchTextField(boolean isFocused, String query)
- throws UiObjectNotFoundException {
- UiObject textField = findSearchViewTextField();
- UiObject searchIcon = findSearchViewIcon();
-
- assertFalse(searchIcon.exists());
- assertTrue(textField.exists());
- assertEquals(isFocused, textField.isFocused());
- if(query != null) {
- assertEquals(query, textField.getText());
- }
- }
-
- public void assertSearchTextFiledAndIcon(boolean searchTextFieldExists, boolean searchIconExists) {
- assertEquals(searchTextFieldExists, findSearchViewTextField().exists());
- assertEquals(searchIconExists, findSearchViewIcon().exists());
- }
-
public void assertInActionMode(boolean inActionMode) {
UiObject actionModeBar = findActionModeBar();
assertEquals(inActionMode, actionModeBar.exists());
}
- public void openSearchView() throws UiObjectNotFoundException {
- UiObject searchView = findSearchView();
- searchView.click();
- assertTrue(searchView.exists());
- }
-
- public void setSearchQuery(String query) throws UiObjectNotFoundException {
- UiObject searchView = findSearchView();
- assertTrue(searchView.exists());
- UiObject searchTextField = findSearchViewTextField();
- searchTextField.setText(query);
- assertSearchTextField(true, query);
- }
-
public UiObject openOverflowMenu() throws UiObjectNotFoundException {
UiObject obj = findMenuMoreOptions();
obj.click();
@@ -115,7 +113,21 @@ public class UiBot extends BaseBot {
}
public void setDialogText(String text) throws UiObjectNotFoundException {
- findDialogEditText().setText(text);
+ onView(TEXT_ENTRY)
+ .perform(ViewActions.replaceText(text));
+ }
+
+ public boolean inFixedLayout() {
+ TypedValue val = new TypedValue();
+ // We alias files_activity to either fixed or drawer layouts based
+ // on screen dimensions. In order to determine which layout
+ // has been selected, we check the resolved value.
+ mContext.getResources().getValue(R.layout.files_activity, val, true);
+ return val.resourceId == R.layout.fixed_layout;
+ }
+
+ public boolean inDrawerLayout() {
+ return !inFixedLayout();
}
void switchViewMode() {
@@ -132,47 +144,38 @@ public class UiBot extends BaseBot {
return find(By.desc("Grid view"));
}
- UiObject2 menuListMode() {
+ UiObject2 menuListMode() {
// Note that we're using By.desc rather than By.res, because of b/25285770
return find(By.desc("List view"));
}
- public UiObject2 menuDelete() {
- return find(By.res("com.android.documentsui:id/menu_delete"));
+ public void clickToolbarItem(int id) {
+ onView(withId(id)).perform(click());
}
- public UiObject2 menuShare() {
- return find(By.res("com.android.documentsui:id/menu_share"));
- }
-
- public UiObject2 menuRename() {
- return findMenuWithName(mContext.getString(R.string.menu_rename));
- }
+ public void clickNewFolder() {
+ onView(ACTIONBAR_OVERFLOW).perform(click());
- public UiObject2 menuNewFolder() {
- return findMenuWithName(mContext.getString(R.string.menu_create_dir));
+ // Click the item by label, since Espresso doesn't support lookup by id on overflow.
+ onView(withText("New folder")).perform(click());
}
- UiObject findSearchView() {
- return findObject("com.android.documentsui:id/menu_search");
+ public void clickActionbarOverflowItem(String label) {
+ onView(ACTIONBAR_OVERFLOW).perform(click());
+ // Click the item by label, since Espresso doesn't support lookup by id on overflow.
+ onView(withText(label)).perform(click());
}
- UiObject findSearchViewTextField() {
- return findObject("com.android.documentsui:id/menu_search", "android:id/search_src_text");
- }
-
- UiObject findSearchViewIcon() {
- return mContext.getResources().getBoolean(R.bool.full_bar_search_view)
- ? findObject("com.android.documentsui:id/menu_search")
- : findObject("com.android.documentsui:id/menu_search", "android:id/search_button");
+ public void clickToolbarOverflowItem(String label) {
+ onView(TOOLBAR_OVERFLOW).perform(click());
+ // Click the item by label, since Espresso doesn't support lookup by id on overflow.
+ onView(withText(label)).perform(click());
}
UiObject findActionModeBar() {
- return findObject("android:id/action_mode_bar");
- }
-
- public UiObject findDialogEditText() {
- return findObject("android:id/content", "android:id/text1");
+ UiObject bar = findObject("android:id/action_mode_bar");
+ bar.waitForExists(mTimeout);
+ return bar;
}
public UiObject findDownloadRetryDialog() {
@@ -182,16 +185,18 @@ public class UiBot extends BaseBot {
return title;
}
- public UiObject findDialogOkButton() {
- UiObject object = findObject("android:id/content", "android:id/button1");
- object.waitForExists(mTimeout);
- return object;
+ public void clickDialogOkButton() {
+ // Espresso has flaky results when keyboard shows up, so hiding it for now
+ // before trying to click on any dialog button
+ Espresso.closeSoftKeyboard();
+ onView(withId(android.R.id.button1)).perform(click());
}
- public UiObject findDialogCancelButton() {
- UiObject object = findObject("android:id/content", "android:id/button2");
- object.waitForExists(mTimeout);
- return object;
+ public void clickDialogCancelButton() throws UiObjectNotFoundException {
+ // Espresso has flaky results when keyboard shows up, so hiding it for now
+ // before trying to click on any dialog button
+ Espresso.closeSoftKeyboard();
+ onView(withId(android.R.id.button2)).perform(click());
}
UiObject findMenuLabelWithName(String label) {
@@ -204,24 +209,40 @@ public class UiBot extends BaseBot {
Iterator<UiObject2> it = menuItems.iterator();
UiObject2 menuItem = null;
- while(it.hasNext()) {
+ while (it.hasNext()) {
menuItem = it.next();
UiObject2 text = menuItem.findObject(By.text(label));
- if(text != null) {
+ if (text != null) {
break;
}
}
return menuItem;
}
+ boolean hasMenuWithName(String label) {
+ return findMenuWithName(label) != null;
+ }
+
UiObject findMenuMoreOptions() {
UiSelector selector = new UiSelector().className("android.widget.ImageButton")
.descriptionContains("More options");
- //TODO: use the system string ? android.R.string.action_menu_overflow_description
+ // TODO: use the system string ? android.R.string.action_menu_overflow_description
return mDevice.findObject(selector);
}
- public void pressKey(int keyCode) {
- mDevice.pressKeyCode(keyCode);
+ private static Matcher<Object> withToolbarTitle(
+ final Matcher<CharSequence> textMatcher) {
+ return new BoundedMatcher<Object, Toolbar>(Toolbar.class) {
+ @Override
+ public boolean matchesSafely(Toolbar toolbar) {
+ return textMatcher.matches(toolbar.getTitle());
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("with toolbar title: ");
+ textMatcher.describeTo(description);
+ }
+ };
}
}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/clipping/ClipStorageTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/clipping/ClipStorageTest.java
new file mode 100644
index 000000000000..73366f871d2c
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/clipping/ClipStorageTest.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.clipping;
+
+import static com.android.documentsui.clipping.ClipStorage.NUM_OF_SLOTS;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.content.SharedPreferences;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.testing.TestScheduledExecutorService;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ClipStorageTest {
+ private static final String PREF_NAME = "pref";
+ private static final List<Uri> TEST_URIS = createList(
+ "content://ham/fancy",
+ "content://poodle/monkey/giraffe");
+
+ @Rule
+ public TemporaryFolder folder = new TemporaryFolder();
+
+ private SharedPreferences mPref;
+ private TestScheduledExecutorService mExecutor;
+ private ClipStorage mStorage;
+
+ private int mTag;
+
+ @Before
+ public void setUp() {
+ mPref = InstrumentationRegistry.getContext().getSharedPreferences(PREF_NAME, 0);
+ File clipDir = ClipStorage.prepareStorage(folder.getRoot());
+ mStorage = new ClipStorage(clipDir, mPref);
+
+ mExecutor = new TestScheduledExecutorService();
+ AsyncTask.setDefaultExecutor(mExecutor);
+
+ mTag = mStorage.claimStorageSlot();
+ }
+
+ @AfterClass
+ public static void tearDownOnce() {
+ AsyncTask.setDefaultExecutor(AsyncTask.SERIAL_EXECUTOR);
+ }
+
+ @Test
+ public void testWrite() throws Exception {
+ writeAll(mTag, TEST_URIS);
+ }
+
+ @Test
+ public void testRead() throws Exception {
+ writeAll(mTag, TEST_URIS);
+ List<Uri> uris = new ArrayList<>();
+
+ File copy = mStorage.getFile(mTag);
+ try(ClipStorageReader provider = mStorage.createReader(copy)) {
+ for (Uri uri : provider) {
+ uris.add(uri);
+ }
+ }
+ assertEquals(TEST_URIS, uris);
+ }
+
+ @Test
+ public void testClaimStorageSlot_NoAvailableSlot() throws Exception {
+ int firstTag = mStorage.claimStorageSlot();
+ writeAll(firstTag, TEST_URIS);
+ mStorage.getFile(firstTag);
+ for (int i = 0; i < NUM_OF_SLOTS - 1; ++i) {
+ int tag = mStorage.claimStorageSlot();
+ writeAll(tag, TEST_URIS);
+ mStorage.getFile(tag);
+ }
+
+ assertEquals(firstTag, mStorage.claimStorageSlot());
+ }
+
+ @Test
+ public void testReadConcurrently() throws Exception {
+ writeAll(mTag, TEST_URIS);
+ List<Uri> uris = new ArrayList<>();
+ List<Uri> uris2 = new ArrayList<>();
+
+ File copy = mStorage.getFile(mTag);
+ File copy2 = mStorage.getFile(mTag);
+ try(ClipStorageReader reader = mStorage.createReader(copy)) {
+ try(ClipStorageReader reader2 = mStorage.createReader(copy2)){
+ Iterator<Uri> iter = reader.iterator();
+ Iterator<Uri> iter2 = reader2.iterator();
+
+ while (iter.hasNext() && iter2.hasNext()) {
+ uris.add(iter.next());
+ uris2.add(iter2.next());
+ }
+
+ assertFalse(iter.hasNext());
+ assertFalse(iter2.hasNext());
+ }
+ }
+ assertEquals(TEST_URIS, uris);
+ assertEquals(TEST_URIS, uris2);
+ }
+
+ @Test
+ public void testPrepareStorage_CreatesDir() throws Exception {
+ File clipDir = ClipStorage.prepareStorage(folder.getRoot());
+ assertTrue(clipDir.exists());
+ assertTrue(clipDir.isDirectory());
+ assertFalse(clipDir.equals(folder.getRoot()));
+ }
+
+ private void writeAll(int tag, List<Uri> uris) {
+ new ClipStorage.PersistTask(mStorage, uris, tag).execute();
+ mExecutor.runAll();
+ }
+
+ private static List<Uri> createList(String... values) {
+ List<Uri> uris = new ArrayList<>(values.length);
+ for (int i = 0; i < values.length; i++) {
+ uris.add(i, Uri.parse(values[i]));
+ }
+ return uris;
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/clipping/UrisSupplierTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/clipping/UrisSupplierTest.java
new file mode 100644
index 000000000000..9815d0e90490
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/clipping/UrisSupplierTest.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.clipping;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import android.content.SharedPreferences;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.provider.DocumentsContract;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.Shared;
+import com.android.documentsui.testing.TestScheduledExecutorService;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class UrisSupplierTest {
+
+ private static final String PREF_NAME = "pref";
+ private static final String AUTHORITY = "foo";
+ private static final List<Uri> SHORT_URI_LIST = createList(3);
+ private static final List<Uri> LONG_URI_LIST = createList(Shared.MAX_DOCS_IN_INTENT + 5);
+
+ @Rule
+ public TemporaryFolder folder = new TemporaryFolder();
+
+ private SharedPreferences mPref;
+ private TestScheduledExecutorService mExecutor;
+ private ClipStorage mStorage;
+
+ @Before
+ public void setUp() {
+ mExecutor = new TestScheduledExecutorService();
+ AsyncTask.setDefaultExecutor(mExecutor);
+
+ mPref = InstrumentationRegistry.getContext().getSharedPreferences(PREF_NAME, 0);
+ mStorage = new ClipStorage(folder.getRoot(), mPref);
+ }
+
+ @AfterClass
+ public static void tearDownOnce() {
+ AsyncTask.setDefaultExecutor(AsyncTask.SERIAL_EXECUTOR);
+ }
+
+ @Test
+ public void testItemCountEquals_shortList() throws Exception {
+ UrisSupplier uris = createWithShortList();
+
+ assertEquals(SHORT_URI_LIST.size(), uris.getItemCount());
+ }
+
+ @Test
+ public void testItemCountEquals_longList() throws Exception {
+ UrisSupplier uris = createWithLongList();
+
+ assertEquals(LONG_URI_LIST.size(), uris.getItemCount());
+ }
+
+ @Test
+ public void testGetDocsEquals_shortList() throws Exception {
+ UrisSupplier uris = createWithShortList();
+
+ assertIterableEquals(SHORT_URI_LIST, uris.getUris(mStorage));
+ }
+
+ @Test
+ public void testGetDocsEquals_longList() throws Exception {
+ UrisSupplier uris = createWithLongList();
+
+ assertIterableEquals(LONG_URI_LIST, uris.getUris(mStorage));
+ }
+
+ @Test
+ public void testDispose_shortList() throws Exception {
+ UrisSupplier uris = createWithShortList();
+
+ uris.dispose();
+ }
+
+ @Test
+ public void testDispose_longList() throws Exception {
+ UrisSupplier uris = createWithLongList();
+
+ uris.dispose();
+ }
+
+ private UrisSupplier createWithShortList() throws Exception {
+ return UrisSupplier.create(SHORT_URI_LIST, mStorage);
+ }
+
+ private UrisSupplier createWithLongList() throws Exception {
+ UrisSupplier uris =
+ UrisSupplier.create(LONG_URI_LIST, mStorage);
+
+ mExecutor.runAll();
+
+ return uris;
+ }
+
+ private void assertIterableEquals(Iterable<Uri> expected, Iterable<Uri> value) {
+ Iterator<Uri> expectedIter = expected.iterator();
+ Iterator<Uri> valueIter = value.iterator();
+
+ while (expectedIter.hasNext() && valueIter.hasNext()) {
+ assertEquals(expectedIter.next(), valueIter.next());
+ }
+
+ assertFalse(expectedIter.hasNext());
+ assertFalse(expectedIter.hasNext());
+ }
+
+ private static List<Uri> createList(int count) {
+ List<Uri> uris = new ArrayList<>(count);
+
+ for (int i = 0; i < count; ++i) {
+ uris.add(DocumentsContract.buildDocumentUri(AUTHORITY, Integer.toString(i)));
+ }
+
+ return uris;
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManager_GridModelTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/BandController_GridModelTest.java
index e401de160708..59547adc08e0 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManager_GridModelTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/BandController_GridModelTest.java
@@ -16,7 +16,7 @@
package com.android.documentsui.dirlist;
-import static com.android.documentsui.dirlist.MultiSelectManager.GridModel.NOT_SET;
+import static com.android.documentsui.dirlist.BandController.GridModel.NOT_SET;
import android.graphics.Point;
import android.graphics.Rect;
@@ -24,14 +24,14 @@ import android.support.v7.widget.RecyclerView.OnScrollListener;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
-import com.android.documentsui.dirlist.MultiSelectManager.GridModel;
+import com.android.documentsui.dirlist.BandController.GridModel;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@SmallTest
-public class MultiSelectManager_GridModelTest extends AndroidTestCase {
+public class BandController_GridModelTest extends AndroidTestCase {
private static final int VIEW_PADDING_PX = 5;
private static final int CHILD_VIEW_EDGE_PX = 100;
@@ -279,7 +279,7 @@ public class MultiSelectManager_GridModelTest extends AndroidTestCase {
model.onScrolled(null, 0, dy);
}
- private static final class TestEnvironment implements MultiSelectManager.SelectionEnvironment {
+ private static final class TestEnvironment implements BandController.SelectionEnvironment {
private final int mNumColumns;
private final int mNumRows;
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/DocumentHolderTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/DocumentHolderTest.java
index 87cd42f08079..949f6b746f47 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/DocumentHolderTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/DocumentHolderTest.java
@@ -20,6 +20,7 @@ import android.content.Context;
import android.database.Cursor;
import android.graphics.Rect;
import android.os.SystemClock;
+import android.support.test.filters.Suppress;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.view.KeyEvent;
@@ -37,6 +38,7 @@ public class DocumentHolderTest extends AndroidTestCase {
DocumentHolder mHolder;
TestListener mListener;
+ @Override
public void setUp() throws Exception {
Context context = getContext();
LayoutInflater inflater = LayoutInflater.from(context);
@@ -46,28 +48,20 @@ public class DocumentHolderTest extends AndroidTestCase {
};
mListener = new TestListener();
- mHolder.addEventListener(mListener);
+ mHolder.addKeyEventListener(mListener);
mHolder.itemView.requestLayout();
mHolder.itemView.invalidate();
}
- public void testClickActivates() {
- click();
- mListener.assertSelected();
+ @Suppress
+ public void testIsInSelectionHotspot() {
+ fail();
}
- public void testTapActivates() {
- tap();
- mListener.assertActivated();
- }
-
- public void click() {
- mHolder.onSingleTapUp(createEvent(MotionEvent.TOOL_TYPE_MOUSE));
- }
-
- public void tap() {
- mHolder.onSingleTapUp(createEvent(MotionEvent.TOOL_TYPE_FINGER));
+ @Suppress
+ public void testDelegatesKeyEvents() {
+ fail();
}
public MotionEvent createEvent(int tooltype) {
@@ -105,32 +99,7 @@ public class DocumentHolderTest extends AndroidTestCase {
);
}
- private class TestListener implements DocumentHolder.EventListener {
- private boolean mActivated = false;
- private boolean mSelected = false;
-
- public void assertActivated() {
- assertTrue(mActivated);
- assertFalse(mSelected);
- }
-
- public void assertSelected() {
- assertTrue(mSelected);
- assertFalse(mActivated);
- }
-
- @Override
- public boolean onActivate(DocumentHolder doc) {
- mActivated = true;
- return true;
- }
-
- @Override
- public boolean onSelect(DocumentHolder doc) {
- mSelected = true;
- return true;
- }
-
+ private class TestListener implements DocumentHolder.KeyboardEventListener {
@Override
public boolean onKey(DocumentHolder doc, int keyCode, KeyEvent event) {
return false;
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java
index 7ab51ba278c1..236621fcee19 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java
@@ -21,13 +21,10 @@ import android.database.Cursor;
import android.support.v7.widget.RecyclerView;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
-import android.util.SparseArray;
import android.view.ViewGroup;
import com.android.documentsui.State;
-import java.util.List;
-
@SmallTest
public class ModelBackedDocumentsAdapterTest extends AndroidTestCase {
@@ -66,13 +63,6 @@ public class ModelBackedDocumentsAdapterTest extends AndroidTestCase {
assertEquals(mModel.getItemCount(), mAdapter.getItemCount());
}
- // Tests that the item count is correct.
- public void testHide_ItemCount() {
- String[] ids = mModel.getModelIds();
- mAdapter.hide(ids[0], ids[1]);
- assertEquals(mModel.getItemCount() - 2, mAdapter.getItemCount());
- }
-
private final class TestEnvironment implements DocumentsAdapter.Environment {
private final Context testContext;
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManagerTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManagerTest.java
index 9447d9c18a83..57b9f926af47 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManagerTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManagerTest.java
@@ -16,16 +16,14 @@
package com.android.documentsui.dirlist;
-import android.support.v7.widget.RecyclerView;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.SparseBooleanArray;
-import com.android.documentsui.TestInputEvent;
import com.android.documentsui.dirlist.MultiSelectManager.Selection;
-import com.google.common.collect.Lists;
+import com.android.documentsui.testing.dirlist.SelectionProbe;
+import com.android.documentsui.testing.dirlist.TestSelectionListener;
-import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -33,187 +31,66 @@ import java.util.Set;
@SmallTest
public class MultiSelectManagerTest extends AndroidTestCase {
- private static final List<String> items;
- static {
- items = new ArrayList<String>();
- for (int i = 0; i < 100; ++i) {
- items.add(Integer.toString(i));
- }
- }
+ private static final List<String> ITEMS = TestData.create(100);
private MultiSelectManager mManager;
- private TestCallback mCallback;
- private TestSelectionEnvironment mEnv;
+ private TestSelectionListener mCallback;
private TestDocumentsAdapter mAdapter;
+ private SelectionProbe mSelection;
+ @Override
public void setUp() throws Exception {
- mCallback = new TestCallback();
- mEnv = new TestSelectionEnvironment(items);
- mAdapter = new TestDocumentsAdapter(items);
- mManager = new MultiSelectManager(mEnv, mAdapter, MultiSelectManager.MODE_MULTIPLE, null);
+ mCallback = new TestSelectionListener();
+ mAdapter = new TestDocumentsAdapter(ITEMS);
+ mManager = new MultiSelectManager(mAdapter, MultiSelectManager.MODE_MULTIPLE);
mManager.addCallback(mCallback);
+
+ mSelection = new SelectionProbe(mManager);
}
public void testSelection() {
// Check selection.
- mManager.toggleSelection(items.get(7));
- assertSelection(items.get(7));
+ mManager.toggleSelection(ITEMS.get(7));
+ mSelection.assertSelection(7);
// Check deselection.
- mManager.toggleSelection(items.get(7));
- assertSelectionSize(0);
+ mManager.toggleSelection(ITEMS.get(7));
+ mSelection.assertNoSelection();
}
public void testSelection_NotifiesSelectionChanged() {
// Selection should notify.
- mManager.toggleSelection(items.get(7));
+ mManager.toggleSelection(ITEMS.get(7));
mCallback.assertSelectionChanged();
// Deselection should notify.
- mManager.toggleSelection(items.get(7));
+ mManager.toggleSelection(ITEMS.get(7));
mCallback.assertSelectionChanged();
}
- public void testMouseClick_ShiftClickExtendsSelection() {
- longPress(7);
- shiftClick(11);
- assertRangeSelection(7, 11);
- }
-
- public void testMouseClick_NoPosition_ClearsSelection() {
- longPress(7);
- click(11);
- click(RecyclerView.NO_POSITION);
- assertSelection();
- }
-
- public void testSetSelectionFocusBegin() {
- mManager.setItemsSelected(Lists.newArrayList(items.get(7)), true);
- mManager.setSelectionRangeBegin(7);
- shiftClick(11);
- assertRangeSelection(7, 11);
- }
-
- public void testLongPress_StartsSelectionMode() {
- longPress(7);
- assertSelection(items.get(7));
- }
-
- public void testLongPress_SecondPressExtendsSelection() {
- longPress(7);
- longPress(99);
- assertSelection(items.get(7), items.get(99));
- }
-
- public void testSingleTapUp_UnselectsSelectedItem() {
- longPress(7);
- tap(7);
- assertSelection();
- }
-
- public void testSingleTapUp_NoPosition_ClearsSelection() {
- longPress(7);
- tap(11);
- tap(RecyclerView.NO_POSITION);
- assertSelection();
- }
-
- public void testSingleTapUp_ExtendsSelection() {
- longPress(99);
- tap(7);
- tap(13);
- assertSelection(items.get(7), items.get(99), items.get(13));
- }
-
- public void testSingleTapUp_ShiftCreatesRangeSelection() {
- longPress(7);
- shiftTap(17);
- assertRangeSelection(7, 17);
- }
-
- public void testSingleTapUp_ShiftCreatesRangeSeletion_Backwards() {
- longPress(17);
- shiftTap(7);
- assertRangeSelection(7, 17);
- }
-
- public void testSingleTapUp_SecondShiftClickExtendsSelection() {
- longPress(7);
- shiftTap(11);
- shiftTap(17);
- assertRangeSelection(7, 17);
- }
-
- public void testSingleTapUp_MultipleContiguousRangesSelected() {
- longPress(7);
- shiftTap(11);
- tap(20);
- shiftTap(25);
- assertRangeSelected(7, 11);
- assertRangeSelected(20, 25);
- assertSelectionSize(11);
- }
-
- public void testSingleTapUp_ShiftReducesSelectionRange_FromPreviousShiftClick() {
- longPress(7);
- shiftTap(17);
- shiftTap(10);
- assertRangeSelection(7, 10);
- }
-
- public void testSingleTapUp_ShiftReducesSelectionRange_FromPreviousShiftClick_Backwards() {
- mManager.onLongPress(TestInputEvent.tap(17));
- shiftTap(7);
- shiftTap(14);
- assertRangeSelection(14, 17);
- }
-
- public void testSingleTapUp_ShiftReversesSelectionDirection() {
- longPress(7);
- shiftTap(17);
- shiftTap(0);
- assertRangeSelection(0, 7);
- }
-
- public void testSingleSelectMode() {
- mManager = new MultiSelectManager(mEnv, mAdapter, MultiSelectManager.MODE_SINGLE, null);
- mManager.addCallback(mCallback);
- longPress(20);
- tap(13);
- assertSelection(items.get(13));
- }
-
- public void testSingleSelectMode_ShiftTap() {
- mManager = new MultiSelectManager(mEnv, mAdapter, MultiSelectManager.MODE_SINGLE, null);
- mManager.addCallback(mCallback);
- longPress(13);
- shiftTap(20);
- assertSelection(items.get(20));
- }
-
public void testRangeSelection() {
mManager.startRangeSelection(15);
mManager.snapRangeSelection(19);
- assertRangeSelection(15, 19);
+ mSelection.assertRangeSelection(15, 19);
}
public void testRangeSelection_snapExpand() {
mManager.startRangeSelection(15);
mManager.snapRangeSelection(19);
mManager.snapRangeSelection(27);
- assertRangeSelection(15, 27);
+ mSelection.assertRangeSelection(15, 27);
}
public void testRangeSelection_snapContract() {
mManager.startRangeSelection(15);
mManager.snapRangeSelection(27);
mManager.snapRangeSelection(19);
- assertRangeSelection(15, 19);
+ mSelection.assertRangeSelection(15, 19);
}
public void testRangeSelection_snapInvert() {
mManager.startRangeSelection(15);
mManager.snapRangeSelection(27);
mManager.snapRangeSelection(3);
- assertRangeSelection(3, 15);
+ mSelection.assertRangeSelection(3, 15);
}
public void testRangeSelection_multiple() {
@@ -222,30 +99,21 @@ public class MultiSelectManagerTest extends AndroidTestCase {
mManager.endRangeSelection();
mManager.startRangeSelection(42);
mManager.snapRangeSelection(57);
- assertSelectionSize(29);
- assertRangeSelected(15, 27);
- assertRangeSelected(42, 57);
-
- }
+ mSelection.assertSelectionSize(29);
+ mSelection.assertRangeSelected(15, 27);
+ mSelection.assertRangeSelected(42, 57);
- public void testRangeSelection_singleSelect() {
- mManager = new MultiSelectManager(mEnv, mAdapter, MultiSelectManager.MODE_SINGLE, null);
- mManager.addCallback(mCallback);
- mManager.startRangeSelection(11);
- mManager.snapRangeSelection(19);
- assertSelectionSize(1);
- assertSelection(items.get(19));
}
public void testProvisionalSelection() {
Selection s = mManager.getSelection();
- assertSelection();
+ mSelection.assertNoSelection();
SparseBooleanArray provisional = new SparseBooleanArray();
provisional.append(1, true);
provisional.append(2, true);
s.setProvisionalSelection(getItemIds(provisional));
- assertSelection(items.get(1), items.get(2));
+ mSelection.assertSelection(1, 2);
}
public void testProvisionalSelection_Replace() {
@@ -260,7 +128,7 @@ public class MultiSelectManagerTest extends AndroidTestCase {
provisional.append(3, true);
provisional.append(4, true);
s.setProvisionalSelection(getItemIds(provisional));
- assertSelection(items.get(3), items.get(4));
+ mSelection.assertSelection(3, 4);
}
public void testProvisionalSelection_IntersectsExistingProvisionalSelection() {
@@ -274,7 +142,7 @@ public class MultiSelectManagerTest extends AndroidTestCase {
provisional.clear();
provisional.append(1, true);
s.setProvisionalSelection(getItemIds(provisional));
- assertSelection(items.get(1));
+ mSelection.assertSelection(1);
}
public void testProvisionalSelection_Apply() {
@@ -285,12 +153,12 @@ public class MultiSelectManagerTest extends AndroidTestCase {
provisional.append(2, true);
s.setProvisionalSelection(getItemIds(provisional));
s.applyProvisionalSelection();
- assertSelection(items.get(1), items.get(2));
+ mSelection.assertSelection(1, 2);
}
public void testProvisionalSelection_Cancel() {
- mManager.toggleSelection(items.get(1));
- mManager.toggleSelection(items.get(2));
+ mManager.toggleSelection(ITEMS.get(1));
+ mManager.toggleSelection(ITEMS.get(2));
Selection s = mManager.getSelection();
SparseBooleanArray provisional = new SparseBooleanArray();
@@ -300,19 +168,19 @@ public class MultiSelectManagerTest extends AndroidTestCase {
s.cancelProvisionalSelection();
// Original selection should remain.
- assertSelection(items.get(1), items.get(2));
+ mSelection.assertSelection(1, 2);
}
public void testProvisionalSelection_IntersectsAppliedSelection() {
- mManager.toggleSelection(items.get(1));
- mManager.toggleSelection(items.get(2));
+ mManager.toggleSelection(ITEMS.get(1));
+ mManager.toggleSelection(ITEMS.get(2));
Selection s = mManager.getSelection();
SparseBooleanArray provisional = new SparseBooleanArray();
provisional.append(2, true);
provisional.append(3, true);
s.setProvisionalSelection(getItemIds(provisional));
- assertSelection(items.get(1), items.get(2), items.get(3));
+ mSelection.assertSelection(1, 2, 3);
}
private static Set<String> getItemIds(SparseBooleanArray selection) {
@@ -320,82 +188,9 @@ public class MultiSelectManagerTest extends AndroidTestCase {
int count = selection.size();
for (int i = 0; i < count; ++i) {
- ids.add(items.get(selection.keyAt(i)));
+ ids.add(ITEMS.get(selection.keyAt(i)));
}
return ids;
}
-
- private void longPress(int position) {
- mManager.onLongPress(TestInputEvent.tap(position));
- }
-
- private void tap(int position) {
- mManager.onSingleTapUp(TestInputEvent.tap(position));
- }
-
- private void shiftTap(int position) {
- mManager.onSingleTapUp(TestInputEvent.shiftTap(position));
- }
-
- private void click(int position) {
- mManager.onSingleTapUp(TestInputEvent.click(position));
- }
-
- private void shiftClick(int position) {
- mManager.onSingleTapUp(TestInputEvent.shiftClick(position));
- }
-
- private void assertSelected(String... expected) {
- for (int i = 0; i < expected.length; i++) {
- Selection selection = mManager.getSelection();
- String err = String.format(
- "Selection %s does not contain %s", selection, expected[i]);
- assertTrue(err, selection.contains(expected[i]));
- }
- }
-
- private void assertSelection(String... expected) {
- assertSelectionSize(expected.length);
- assertSelected(expected);
- }
-
- private void assertRangeSelected(int begin, int end) {
- for (int i = begin; i <= end; i++) {
- assertSelected(items.get(i));
- }
- }
-
- private void assertRangeSelection(int begin, int end) {
- assertSelectionSize(end - begin + 1);
- assertRangeSelected(begin, end);
- }
-
- private void assertSelectionSize(int expected) {
- Selection selection = mManager.getSelection();
- assertEquals(selection.toString(), expected, selection.size());
- }
-
- private static final class TestCallback implements MultiSelectManager.Callback {
-
- Set<String> ignored = new HashSet<>();
- private boolean mSelectionChanged = false;
-
- @Override
- public void onItemStateChanged(String modelId, boolean selected) {}
-
- @Override
- public boolean onBeforeItemStateChange(String modelId, boolean selected) {
- return !ignored.contains(modelId);
- }
-
- @Override
- public void onSelectionChanged() {
- mSelectionChanged = true;
- }
-
- void assertSelectionChanged() {
- assertTrue(mSelectionChanged);
- }
- }
}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManager_SingleSelectTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManager_SingleSelectTest.java
new file mode 100644
index 000000000000..62cb1b05fa55
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManager_SingleSelectTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.dirlist;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.documentsui.testing.dirlist.SelectionProbe;
+import com.android.documentsui.testing.dirlist.TestSelectionListener;
+
+import java.util.List;
+
+@SmallTest
+public class MultiSelectManager_SingleSelectTest extends AndroidTestCase {
+
+ private static final List<String> ITEMS = TestData.create(100);
+
+ private MultiSelectManager mManager;
+ private TestSelectionListener mCallback;
+ private TestDocumentsAdapter mAdapter;
+ private SelectionProbe mSelection;
+
+ @Override
+ public void setUp() throws Exception {
+ mCallback = new TestSelectionListener();
+ mAdapter = new TestDocumentsAdapter(ITEMS);
+ mManager = new MultiSelectManager(mAdapter, MultiSelectManager.MODE_SINGLE);
+ mManager.addCallback(mCallback);
+
+ mSelection = new SelectionProbe(mManager);
+ }
+
+ public void testSimpleSelect() {
+ mManager.toggleSelection(ITEMS.get(3));
+ mManager.toggleSelection(ITEMS.get(4));
+ mCallback.assertSelectionChanged();
+ mSelection.assertSelection(4);
+ }
+
+ public void testRangeSelectionNotEstablished() {
+ mManager.toggleSelection(ITEMS.get(3));
+ mCallback.reset();
+
+ try {
+ mManager.snapRangeSelection(10);
+ fail("Should have thrown.");
+ } catch (Exception expected) {}
+
+ mCallback.assertSelectionUnchanged();
+ mSelection.assertSelection(3);
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestData.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestData.java
new file mode 100644
index 000000000000..5c1d987d45f0
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestData.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.dirlist;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestData {
+ public static List<String> create(int num) {
+ List<String> items = new ArrayList<String>(num);
+ for (int i = 0; i < num; ++i) {
+ items.add(Integer.toString(i));
+ }
+ return items;
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestDocumentsAdapter.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestDocumentsAdapter.java
index e170dbb55181..4df0fa113cd1 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestDocumentsAdapter.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestDocumentsAdapter.java
@@ -16,7 +16,6 @@
package com.android.documentsui.dirlist;
-import android.util.SparseArray;
import android.view.ViewGroup;
import java.util.ArrayList;
@@ -56,11 +55,6 @@ public class TestDocumentsAdapter extends DocumentsAdapter {
}
@Override
- public SparseArray<String> hide(String... ids) {
- throw new UnsupportedOperationException();
- }
-
- @Override
public DocumentHolder onCreateViewHolder(ViewGroup parent, int viewType) {
throw new UnsupportedOperationException();
}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestFocusHandler.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestFocusHandler.java
new file mode 100644
index 000000000000..0585b9fd7afb
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestFocusHandler.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.dirlist;
+
+import android.view.KeyEvent;
+import android.view.View;
+
+/**
+ * A purely dummy instance of FocusHandler.
+ */
+public final class TestFocusHandler implements FocusHandler {
+
+ @Override
+ public boolean handleKey(DocumentHolder doc, int keyCode, KeyEvent event) {
+ return false;
+ }
+
+ @Override
+ public void onFocusChange(View v, boolean hasFocus) {
+ }
+
+ @Override
+ public void restoreLastFocus() {
+ }
+
+ @Override
+ public int getFocusPosition() {
+ return 0;
+ }
+} \ No newline at end of file
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestSelectionEnvironment.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestSelectionEnvironment.java
index f56476978a4e..b69787c697ce 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestSelectionEnvironment.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/TestSelectionEnvironment.java
@@ -20,7 +20,7 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.support.v7.widget.RecyclerView.OnScrollListener;
-import com.android.documentsui.dirlist.MultiSelectManager.SelectionEnvironment;
+import com.android.documentsui.dirlist.BandController.SelectionEnvironment;
import java.util.List;
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/UserInputHandler_MouseTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/UserInputHandler_MouseTest.java
new file mode 100644
index 000000000000..4c34546a82b6
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/UserInputHandler_MouseTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.dirlist;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.v7.widget.RecyclerView;
+import android.view.MotionEvent;
+
+import com.android.documentsui.Events.InputEvent;
+import com.android.documentsui.dirlist.UserInputHandler.DocumentDetails;
+import com.android.documentsui.testing.TestEvent;
+import com.android.documentsui.testing.TestEvent.Builder;
+import com.android.documentsui.testing.TestPredicate;
+import com.android.documentsui.testing.dirlist.SelectionProbe;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public final class UserInputHandler_MouseTest {
+
+ private static final List<String> ITEMS = TestData.create(100);
+
+ private UserInputHandler<TestEvent> mInputHandler;
+
+ private TestDocumentsAdapter mAdapter;
+ private SelectionProbe mSelection;
+ private TestPredicate<DocumentDetails> mCanSelect;
+ private TestPredicate<InputEvent> mRightClickHandler;
+ private TestPredicate<DocumentDetails> mActivateHandler;
+ private TestPredicate<DocumentDetails> mDeleteHandler;
+
+ private Builder mEvent;
+
+ @Before
+ public void setUp() {
+
+ mAdapter = new TestDocumentsAdapter(ITEMS);
+ MultiSelectManager selectionMgr =
+ new MultiSelectManager(mAdapter, MultiSelectManager.MODE_MULTIPLE);
+
+ mSelection = new SelectionProbe(selectionMgr);
+ mCanSelect = new TestPredicate<>();
+ mRightClickHandler = new TestPredicate<>();
+ mActivateHandler = new TestPredicate<>();
+ mDeleteHandler = new TestPredicate<>();
+
+ mInputHandler = new UserInputHandler<>(
+ selectionMgr,
+ new TestFocusHandler(),
+ (MotionEvent event) -> {
+ throw new UnsupportedOperationException("Not exercised in tests.");
+ },
+ (TestEvent event) -> {
+ return event.getDocument();
+ },
+ mCanSelect,
+ mRightClickHandler::test,
+ mActivateHandler::test,
+ mDeleteHandler::test);
+
+ mEvent = TestEvent.builder().mouse();
+ }
+
+ @Test
+ public void testConfirmedClick_StartsSelection() {
+ mInputHandler.onSingleTapConfirmed(mEvent.at(11).build());
+ mSelection.assertSelection(11);
+ }
+
+ @Test
+ public void testUnconfirmedClick_AddsToExistingSelection() {
+ mInputHandler.onSingleTapConfirmed(mEvent.at(7).build());
+
+ mInputHandler.onSingleTapUp(mEvent.at(11).build());
+ mSelection.assertSelection(7, 11);
+ }
+
+ @Test
+ public void testDoubleClick_Activates() {
+ mInputHandler.onDoubleTap(mEvent.at(11).build());
+ mActivateHandler.assertLastArgument(mEvent.build());
+ }
+
+ @Test
+ public void testClickOff_ClearsSelection() {
+ mInputHandler.onSingleTapConfirmed(mEvent.at(11).build());
+ mInputHandler.onSingleTapUp(mEvent.at(RecyclerView.NO_POSITION).build());
+ mSelection.assertNoSelection();
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/UserInputHandler_RangeTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/UserInputHandler_RangeTest.java
new file mode 100644
index 000000000000..1d763f9d9632
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/UserInputHandler_RangeTest.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.dirlist;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.MotionEvent;
+
+import com.android.documentsui.Events.InputEvent;
+import com.android.documentsui.dirlist.UserInputHandler.DocumentDetails;
+import com.android.documentsui.testing.TestEvent;
+import com.android.documentsui.testing.TestEvent.Builder;
+import com.android.documentsui.testing.TestPredicate;
+import com.android.documentsui.testing.dirlist.SelectionProbe;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+/**
+ * UserInputHandler / MultiSelectManager integration test covering the shared
+ * responsibility of range selection.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public final class UserInputHandler_RangeTest {
+
+ private static final List<String> ITEMS = TestData.create(100);
+
+ private UserInputHandler<TestEvent> mInputHandler;
+
+ private TestDocumentsAdapter mAdapter;
+ private SelectionProbe mSelection;
+ private TestPredicate<DocumentDetails> mCanSelect;
+ private TestPredicate<InputEvent> mRightClickHandler;
+ private TestPredicate<DocumentDetails> mActivateHandler;
+ private TestPredicate<DocumentDetails> mDeleteHandler;
+ private Builder mEvent;
+
+ @Before
+ public void setUp() {
+
+ mAdapter = new TestDocumentsAdapter(ITEMS);
+ MultiSelectManager selectionMgr =
+ new MultiSelectManager(mAdapter, MultiSelectManager.MODE_MULTIPLE);
+
+ mSelection = new SelectionProbe(selectionMgr);
+ mCanSelect = new TestPredicate<>();
+ mRightClickHandler = new TestPredicate<>();
+ mActivateHandler = new TestPredicate<>();
+ mDeleteHandler = new TestPredicate<>();
+
+ mInputHandler = new UserInputHandler<>(
+ selectionMgr,
+ new TestFocusHandler(),
+ (MotionEvent event) -> {
+ throw new UnsupportedOperationException("Not exercised in tests.");
+ },
+ (TestEvent event) -> {
+ return event.getDocument();
+ },
+ mCanSelect,
+ mRightClickHandler::test,
+ mActivateHandler::test,
+ mDeleteHandler::test);
+
+ mEvent = TestEvent.builder().mouse();
+ }
+
+ @Test
+ public void testExtendRange() {
+ mInputHandler.onSingleTapConfirmed(mEvent.at(7).build());
+ mInputHandler.onSingleTapUp(mEvent.at(11).shift().build());
+ mSelection.assertRangeSelection(7, 11);
+ }
+
+ @Test
+ public void testExtendRangeContinues() {
+ mInputHandler.onSingleTapConfirmed(mEvent.at(7).build());
+ mInputHandler.onSingleTapUp(mEvent.at(11).shift().build());
+ mInputHandler.onSingleTapUp(mEvent.at(21).shift().build());
+ mSelection.assertRangeSelection(7, 21);
+ }
+
+ @Test
+ public void testMultipleContiguousRanges() {
+ mInputHandler.onSingleTapConfirmed(mEvent.at(7).build());
+ mInputHandler.onSingleTapUp(mEvent.at(11).shift().build());
+
+ // click without shift sets a new range start point.
+ mInputHandler.onSingleTapUp(mEvent.at(20).unshift().build());
+ mInputHandler.onSingleTapUp(mEvent.at(25).shift().build());
+
+ mSelection.assertRangeSelected(7, 11);
+ mSelection.assertRangeSelected(20, 25);
+
+ mSelection.assertRangeNotSelected(12, 19);
+ mSelection.assertSelectionSize(11);
+ }
+
+ @Test
+ public void testReducesSelectionRange() {
+ mInputHandler.onSingleTapConfirmed(mEvent.at(7).build());
+ mInputHandler.onSingleTapUp(mEvent.at(17).shift().build());
+ mInputHandler.onSingleTapUp(mEvent.at(10).shift().build());
+ mSelection.assertRangeSelection(7, 10);
+ }
+
+ @Test
+ public void testReducesSelectionRange_Reverse() {
+ mInputHandler.onSingleTapConfirmed(mEvent.at(17).build());
+ mInputHandler.onSingleTapUp(mEvent.at(7).shift().build());
+ mInputHandler.onSingleTapUp(mEvent.at(14).shift().build());
+ mSelection.assertRangeSelection(14, 17);
+ }
+
+ @Test
+ public void testExtendsRange_Reverse() {
+ mInputHandler.onSingleTapConfirmed(mEvent.at(12).build());
+ mInputHandler.onSingleTapUp(mEvent.at(5).shift().build());
+ mSelection.assertRangeSelection(5, 12);
+ }
+
+ @Test
+ public void testExtendsRange_ReversesAfterForwardClick() {
+ mInputHandler.onSingleTapConfirmed(mEvent.at(7).build());
+ mInputHandler.onSingleTapUp(mEvent.at(11).shift().build());
+ mInputHandler.onSingleTapUp(mEvent.at(0).shift().build());
+ mSelection.assertRangeSelection(0, 7);
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/UserInputHandler_TouchTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/UserInputHandler_TouchTest.java
new file mode 100644
index 000000000000..2d1453eaf0dc
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/UserInputHandler_TouchTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.dirlist;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.v7.widget.RecyclerView;
+import android.view.MotionEvent;
+
+import com.android.documentsui.Events.InputEvent;
+import com.android.documentsui.dirlist.UserInputHandler.DocumentDetails;
+import com.android.documentsui.testing.TestEvent;
+import com.android.documentsui.testing.TestEvent.Builder;
+import com.android.documentsui.testing.TestPredicate;
+import com.android.documentsui.testing.dirlist.SelectionProbe;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public final class UserInputHandler_TouchTest {
+
+ private static final List<String> ITEMS = TestData.create(100);
+
+ private UserInputHandler<TestEvent> mInputHandler;
+
+ private TestDocumentsAdapter mAdapter;
+ private SelectionProbe mSelection;
+ private TestPredicate<DocumentDetails> mCanSelect;
+ private TestPredicate<InputEvent> mRightClickHandler;
+ private TestPredicate<DocumentDetails> mActivateHandler;
+ private TestPredicate<DocumentDetails> mDeleteHandler;
+
+ private Builder mEvent;
+
+ @Before
+ public void setUp() {
+
+ mAdapter = new TestDocumentsAdapter(ITEMS);
+ MultiSelectManager selectionMgr =
+ new MultiSelectManager(mAdapter, MultiSelectManager.MODE_MULTIPLE);
+
+ mSelection = new SelectionProbe(selectionMgr);
+ mCanSelect = new TestPredicate<>();
+ mRightClickHandler = new TestPredicate<>();
+ mActivateHandler = new TestPredicate<>();
+ mDeleteHandler = new TestPredicate<>();
+
+ mInputHandler = new UserInputHandler<>(
+ selectionMgr,
+ new TestFocusHandler(),
+ (MotionEvent event) -> {
+ throw new UnsupportedOperationException("Not exercised in tests.");
+ },
+ (TestEvent event) -> {
+ return event.getDocument();
+ },
+ mCanSelect,
+ mRightClickHandler::test,
+ mActivateHandler::test,
+ mDeleteHandler::test);
+
+ mEvent = TestEvent.builder();
+ }
+
+ @Test
+ public void testTap_ActivatesWhenNoExistingSelection() {
+ mInputHandler.onSingleTapUp(mEvent.at(11).build());
+ mActivateHandler.assertLastArgument(mEvent.build());
+ }
+
+ @Test
+ public void testLongPress_StartsSelectionMode() {
+ mInputHandler.onLongPress(mEvent.at(7).build());
+ mSelection.assertSelection(7);
+ }
+
+ @Test
+ public void testLongPress_SecondPressExtendsSelection() {
+ mInputHandler.onLongPress(mEvent.at(7).build());
+ mInputHandler.onLongPress(mEvent.at(99).build());
+ mInputHandler.onLongPress(mEvent.at(13).build());
+ mSelection.assertSelection(7, 13, 99);
+ }
+
+ @Test
+ public void testTap_UnselectsSelectedItem() {
+ mInputHandler.onLongPress(mEvent.at(7).build());
+ mInputHandler.onSingleTapUp(mEvent.at(7).build());
+ mSelection.assertNoSelection();
+ }
+
+ @Test
+ public void testTapOff_ClearsSelection() {
+ mInputHandler.onLongPress(mEvent.at(7).build());
+ mInputHandler.onSingleTapUp(mEvent.at(11).build());
+ mInputHandler.onSingleTapUp(mEvent.at(RecyclerView.NO_POSITION).build());
+ mSelection.assertNoSelection();
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractCopyJobTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractCopyJobTest.java
index eb8a061833b2..2560f2c9477f 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractCopyJobTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractCopyJobTest.java
@@ -23,13 +23,19 @@ import android.provider.DocumentsContract;
import android.test.suitebuilder.annotation.MediumTest;
import com.android.documentsui.model.DocumentInfo;
-import com.android.documentsui.model.DocumentStack;
+import com.android.documentsui.services.FileOperationService.OpType;
import java.util.List;
@MediumTest
public abstract class AbstractCopyJobTest<T extends CopyJob> extends AbstractJobTest<T> {
+ private final @OpType int mOpType;
+
+ AbstractCopyJobTest(@OpType int opType) {
+ mOpType = opType;
+ }
+
public void runCopyFilesTest() throws Exception {
Uri testFile1 = mDocs.createDocument(mSrcRoot, "text/plain", "test1.txt");
mDocs.writeDocument(testFile1, HAM_BYTES);
@@ -110,7 +116,8 @@ public abstract class AbstractCopyJobTest<T extends CopyJob> extends AbstractJob
public void runNoCopyDirToSelfTest() throws Exception {
Uri testDir = mDocs.createFolder(mSrcRoot, "someDir");
- createJob(newArrayList(testDir),
+ createJob(mOpType,
+ newArrayList(testDir),
DocumentsContract.buildDocumentUri(AUTHORITY, mSrcRoot.documentId),
testDir).run();
@@ -125,7 +132,8 @@ public abstract class AbstractCopyJobTest<T extends CopyJob> extends AbstractJob
Uri testDir = mDocs.createFolder(mSrcRoot, "someDir");
Uri destDir = mDocs.createFolder(testDir, "theDescendent");
- createJob(newArrayList(testDir),
+ createJob(mOpType,
+ newArrayList(testDir),
DocumentsContract.buildDocumentUri(AUTHORITY, mSrcRoot.documentId),
destDir).run();
@@ -160,6 +168,6 @@ public abstract class AbstractCopyJobTest<T extends CopyJob> extends AbstractJob
final T createJob(List<Uri> srcs) throws Exception {
Uri srcParent = DocumentsContract.buildDocumentUri(AUTHORITY, mSrcRoot.documentId);
Uri destination = DocumentsContract.buildDocumentUri(AUTHORITY, mDestRoot.documentId);
- return createJob(srcs, srcParent, destination);
+ return createJob(mOpType, srcs, srcParent, destination);
}
}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractJobTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractJobTest.java
index e559503f8b30..6e4e534e0047 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractJobTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/AbstractJobTest.java
@@ -24,17 +24,17 @@ import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
import android.os.RemoteException;
-import android.provider.DocumentsContract;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
+import com.android.documentsui.clipping.UrisSupplier;
import com.android.documentsui.DocumentsProviderHelper;
import com.android.documentsui.StubProvider;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.DocumentStack;
import com.android.documentsui.model.RootInfo;
-
-import com.google.common.collect.Lists;
+import com.android.documentsui.services.FileOperationService.OpType;
+import com.android.documentsui.testing.DocsProviders;
import java.util.List;
@@ -85,18 +85,19 @@ public abstract class AbstractJobTest<T extends Job> extends AndroidTestCase {
mDestRoot = mDocs.getRoot(ROOT_1_ID);
}
- final T createJob(List<Uri> srcs, Uri srcParent, Uri destination) throws Exception {
+ final T createJob(@OpType int opType, List<Uri> srcs, Uri srcParent, Uri destination)
+ throws Exception {
DocumentStack stack = new DocumentStack();
stack.push(DocumentInfo.fromUri(mResolver, destination));
-
- List<DocumentInfo> srcDocs = Lists.newArrayList();
- for (Uri src : srcs) {
- srcDocs.add(DocumentInfo.fromUri(mResolver, src));
- }
-
- return createJob(srcDocs, DocumentInfo.fromUri(mResolver, srcParent), stack);
+ stack.root = mSrcRoot;
+
+ UrisSupplier urisSupplier = DocsProviders.createDocsProvider(srcs);
+ FileOperation operation = new FileOperation.Builder()
+ .withOpType(opType)
+ .withSrcs(urisSupplier)
+ .withDestination(stack)
+ .withSrcParent(srcParent)
+ .build();
+ return (T) operation.createJob(mContext, mJobListener, FileOperations.createJobId());
}
-
- abstract T createJob(List<DocumentInfo> srcs, DocumentInfo srcParent, DocumentStack destination)
- throws Exception;
}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/CopyJobTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/CopyJobTest.java
index bb7c01afb65e..64211c20e7ca 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/services/CopyJobTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/CopyJobTest.java
@@ -16,20 +16,21 @@
package com.android.documentsui.services;
+import static com.android.documentsui.services.FileOperationService.OPERATION_COPY;
+
import static com.google.common.collect.Lists.newArrayList;
import android.net.Uri;
import android.provider.DocumentsContract.Document;
import android.test.suitebuilder.annotation.MediumTest;
-import com.android.documentsui.model.DocumentInfo;
-import com.android.documentsui.model.DocumentStack;
-
-import java.util.List;
-
@MediumTest
public class CopyJobTest extends AbstractCopyJobTest<CopyJob> {
+ public CopyJobTest() {
+ super(OPERATION_COPY);
+ }
+
public void testCopyFiles() throws Exception {
runCopyFilesTest();
}
@@ -76,12 +77,4 @@ public class CopyJobTest extends AbstractCopyJobTest<CopyJob> {
public void testCopyFileWithReadErrors() throws Exception {
runCopyFileWithReadErrorsTest();
}
-
- @Override
- // TODO: Stop passing srcParent here, as it's not used for copying.
- CopyJob createJob(List<DocumentInfo> srcs, DocumentInfo srcParent, DocumentStack stack)
- throws Exception {
- return new CopyJob(
- mContext, mContext, mJobListener, FileOperations.createJobId(), stack, srcs);
- }
}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/DeleteJobTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/DeleteJobTest.java
index 722df75593bd..9dbe7cee5799 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/services/DeleteJobTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/DeleteJobTest.java
@@ -16,15 +16,14 @@
package com.android.documentsui.services;
+import static com.android.documentsui.services.FileOperationService.OPERATION_DELETE;
+
import static com.google.common.collect.Lists.newArrayList;
import android.net.Uri;
import android.provider.DocumentsContract;
import android.test.suitebuilder.annotation.MediumTest;
-import com.android.documentsui.model.DocumentInfo;
-import com.android.documentsui.model.DocumentStack;
-
import java.util.List;
@MediumTest
@@ -49,15 +48,6 @@ public class DeleteJobTest extends AbstractJobTest<DeleteJob> {
*/
private final DeleteJob createJob(List<Uri> srcs, Uri srcParent) throws Exception {
Uri stack = DocumentsContract.buildDocumentUri(AUTHORITY, mSrcRoot.documentId);
- return createJob(srcs, srcParent, stack);
- }
-
- @Override
- // TODO: Remove inheritance, as stack is not used for deleting, nor srcParent.
- DeleteJob createJob(List<DocumentInfo> srcs, DocumentInfo srcParent, DocumentStack stack)
- throws Exception {
- return new DeleteJob(
- mContext, mContext, mJobListener, FileOperations.createJobId(), stack, srcs,
- srcParent);
+ return createJob(OPERATION_DELETE, srcs, srcParent, stack);
}
}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/FileOperationServiceTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/FileOperationServiceTest.java
index 96d963fb317a..d6bbe5abfcbd 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/services/FileOperationServiceTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/FileOperationServiceTest.java
@@ -17,37 +17,48 @@
package com.android.documentsui.services;
import static com.android.documentsui.services.FileOperationService.OPERATION_COPY;
+import static com.android.documentsui.services.FileOperationService.OPERATION_DELETE;
+import static com.android.documentsui.services.FileOperationService.OpType;
import static com.android.documentsui.services.FileOperations.createBaseIntent;
import static com.android.documentsui.services.FileOperations.createJobId;
+
import static com.google.android.collect.Lists.newArrayList;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.test.ServiceTestCase;
import android.test.suitebuilder.annotation.MediumTest;
+import com.android.documentsui.clipping.UrisSupplier;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.DocumentStack;
-import com.android.documentsui.services.Job.Listener;
+import com.android.documentsui.testing.DocsProviders;
+import com.android.documentsui.testing.TestHandler;
+import com.android.documentsui.testing.TestScheduledExecutorService;
import java.util.ArrayList;
import java.util.List;
-/**
- * TODO: Test progress updates.
- */
@MediumTest
public class FileOperationServiceTest extends ServiceTestCase<FileOperationService> {
+ private static final Uri SRC_PARENT =
+ Uri.parse("content://com.android.documentsui.testing/parent");
private static final DocumentInfo ALPHA_DOC = createDoc("alpha");
private static final DocumentInfo BETA_DOC = createDoc("alpha");
private static final DocumentInfo GAMMA_DOC = createDoc("gamma");
private static final DocumentInfo DELTA_DOC = createDoc("delta");
+ private final List<TestJob> mCopyJobs = new ArrayList<>();
+ private final List<TestJob> mDeleteJobs = new ArrayList<>();
+
private FileOperationService mService;
private TestScheduledExecutorService mExecutor;
- private TestJobFactory mJobFactory;
+ private TestScheduledExecutorService mDeletionExecutor;
+ private TestHandler mHandler;
public FileOperationServiceTest() {
super(FileOperationService.class);
@@ -59,7 +70,11 @@ public class FileOperationServiceTest extends ServiceTestCase<FileOperationServi
setupService(); // must be called first for our test setup to work correctly.
mExecutor = new TestScheduledExecutorService();
- mJobFactory = new TestJobFactory();
+ mDeletionExecutor = new TestScheduledExecutorService();
+ mHandler = new TestHandler();
+
+ mCopyJobs.clear();
+ mDeleteJobs.clear();
// Install test doubles.
mService = getService();
@@ -67,36 +82,96 @@ public class FileOperationServiceTest extends ServiceTestCase<FileOperationServi
assertNull(mService.executor);
mService.executor = mExecutor;
- assertNull(mService.jobFactory);
- mService.jobFactory = mJobFactory;
+ assertNull(mService.deletionExecutor);
+ mService.deletionExecutor = mDeletionExecutor;
+
+ assertNull(mService.handler);
+ mService.handler = mHandler;
}
- public void testRunsJobs() throws Exception {
+ @Override
+ protected void tearDown() {
+ // There are lots of progress notifications generated in this test case.
+ // Dismiss all of them here.
+ mHandler.dispatchAllMessages();
+ }
+
+ public void testRunsCopyJobs() throws Exception {
startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC));
mExecutor.runAll();
- mJobFactory.assertAllJobsStarted();
+ assertAllCopyJobsStarted();
}
- public void testRunsJobs_AfterExceptionInJobCreation() throws Exception {
- startService(createCopyIntent(new ArrayList<DocumentInfo>(), BETA_DOC));
+ public void testRunsCopyJobs_AfterExceptionInJobCreation() throws Exception {
+ try {
+ startService(createCopyIntent(new ArrayList<>(), BETA_DOC));
+ } catch(AssertionError e) {
+ // Expected AssertionError
+ }
startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC));
- mJobFactory.assertJobsCreated(1);
+ assertJobsCreated(1);
mExecutor.runAll();
- mJobFactory.assertAllJobsStarted();
+ assertAllCopyJobsStarted();
}
- public void testRunsJobs_AfterFailure() throws Exception {
+ public void testRunsCopyJobs_AfterFailure() throws Exception {
startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC));
- mJobFactory.jobs.get(0).fail(ALPHA_DOC);
+ mCopyJobs.get(0).fail(ALPHA_DOC);
+
+ mExecutor.runAll();
+ assertAllCopyJobsStarted();
+ }
+
+ public void testRunsCopyJobs_notRunsDeleteJobs() throws Exception {
+ startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
+ startService(createDeleteIntent(newArrayList(GAMMA_DOC)));
+
+ mExecutor.runAll();
+ assertNoDeleteJobsStarted();
+ }
+
+ public void testRunsDeleteJobs() throws Exception {
+ startService(createDeleteIntent(newArrayList(ALPHA_DOC)));
+ mDeletionExecutor.runAll();
+ assertAllDeleteJobsStarted();
+ }
+
+ public void testRunsDeleteJobs_NotRunsCopyJobs() throws Exception {
+ startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
+ startService(createDeleteIntent(newArrayList(GAMMA_DOC)));
+
+ mDeletionExecutor.runAll();
+ assertNoCopyJobsStarted();
+ }
+
+ public void testUpdatesNotification() throws Exception {
+ startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
+ mExecutor.runAll();
+
+ // Assert monitoring continues until job is done
+ assertTrue(mHandler.hasScheduledMessage());
+ // Two notifications -- one for setup; one for progress
+ assertEquals(2, mCopyJobs.get(0).getNumOfNotifications());
+ }
+
+ public void testStopsUpdatingNotificationAfterFinished() throws Exception {
+ startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
mExecutor.runAll();
- mJobFactory.assertAllJobsStarted();
+
+ mHandler.dispatchNextMessage();
+ // Assert monitoring stops once job is completed.
+ assertFalse(mHandler.hasScheduledMessage());
+
+ // Assert no more notification is generated after finish.
+ assertEquals(2, mCopyJobs.get(0).getNumOfNotifications());
+
}
public void testHoldsWakeLockWhileWorking() throws Exception {
@@ -125,36 +200,37 @@ public class FileOperationServiceTest extends ServiceTestCase<FileOperationServi
startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
mExecutor.assertAlive();
+ mDeletionExecutor.assertAlive();
mExecutor.runAll();
shutdownService();
- mExecutor.assertShutdown();
+ assertExecutorsShutdown();
}
public void testShutdownStopsExecutor_AfterMixedFailures() throws Exception {
startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC));
- mJobFactory.jobs.get(0).fail(ALPHA_DOC);
+ mCopyJobs.get(0).fail(ALPHA_DOC);
mExecutor.runAll();
shutdownService();
- mExecutor.assertShutdown();
+ assertExecutorsShutdown();
}
public void testShutdownStopsExecutor_AfterTotalFailure() throws Exception {
startService(createCopyIntent(newArrayList(ALPHA_DOC), BETA_DOC));
startService(createCopyIntent(newArrayList(GAMMA_DOC), DELTA_DOC));
- mJobFactory.jobs.get(0).fail(ALPHA_DOC);
- mJobFactory.jobs.get(1).fail(GAMMA_DOC);
+ mCopyJobs.get(0).fail(ALPHA_DOC);
+ mCopyJobs.get(1).fail(GAMMA_DOC);
mExecutor.runAll();
shutdownService();
- mExecutor.assertShutdown();
+ assertExecutorsShutdown();
}
private Intent createCopyIntent(ArrayList<DocumentInfo> files, DocumentInfo dest)
@@ -162,7 +238,29 @@ public class FileOperationServiceTest extends ServiceTestCase<FileOperationServi
DocumentStack stack = new DocumentStack();
stack.push(dest);
- return createBaseIntent(OPERATION_COPY, getContext(), createJobId(), files, stack);
+ List<Uri> uris = new ArrayList<>(files.size());
+ for (DocumentInfo file: files) {
+ uris.add(file.derivedUri);
+ }
+
+ UrisSupplier urisSupplier = DocsProviders.createDocsProvider(uris);
+ TestFileOperation operation = new TestFileOperation(OPERATION_COPY, urisSupplier, stack);
+
+ return createBaseIntent(getContext(), createJobId(), operation);
+ }
+
+ private Intent createDeleteIntent(ArrayList<DocumentInfo> files) {
+ DocumentStack stack = new DocumentStack();
+
+ List<Uri> uris = new ArrayList<>(files.size());
+ for (DocumentInfo file: files) {
+ uris.add(file.derivedUri);
+ }
+
+ UrisSupplier urisSupplier = DocsProviders.createDocsProvider(uris);
+ TestFileOperation operation = new TestFileOperation(OPERATION_DELETE, urisSupplier, stack);
+
+ return createBaseIntent(getContext(), createJobId(), operation);
}
private static DocumentInfo createDoc(String name) {
@@ -176,37 +274,94 @@ public class FileOperationServiceTest extends ServiceTestCase<FileOperationServi
return createDoc(uri);
}
+ void assertAllCopyJobsStarted() {
+ for (TestJob job : mCopyJobs) {
+ job.assertStarted();
+ }
+ }
+
+ void assertAllDeleteJobsStarted() {
+ for (TestJob job : mDeleteJobs) {
+ job.assertStarted();
+ }
+ }
+
+ void assertNoCopyJobsStarted() {
+ for (TestJob job : mCopyJobs) {
+ job.assertNotStarted();
+ }
+ }
+
+ void assertNoDeleteJobsStarted() {
+ for (TestJob job : mDeleteJobs) {
+ job.assertNotStarted();
+ }
+ }
+
+ void assertJobsCreated(int expected) {
+ assertEquals(expected, mCopyJobs.size() + mDeleteJobs.size());
+ }
private static DocumentInfo createDoc(Uri destination) {
DocumentInfo destDoc = new DocumentInfo();
destDoc.derivedUri = destination;
return destDoc;
}
- private final class TestJobFactory extends Job.Factory {
-
- final List<TestJob> jobs = new ArrayList<>();
-
- void assertAllJobsStarted() {
- for (TestJob job : jobs) {
- job.assertStarted();
- }
- }
+ private void assertExecutorsShutdown() {
+ mExecutor.assertShutdown();
+ mDeletionExecutor.assertShutdown();
+ }
- void assertJobsCreated(int expected) {
- assertEquals(expected, jobs.size());
+ private final class TestFileOperation extends FileOperation {
+
+ private final Runnable mJobRunnable = () -> {
+ // The following statement is executed concurrently to Job.start() in real situation.
+ // Call it in TestJob.start() to mimic this behavior.
+ mHandler.dispatchNextMessage();
+ };
+ private final @OpType int mOpType;
+ private final UrisSupplier mSrcs;
+ private final DocumentStack mDestination;
+
+ private TestFileOperation(
+ @OpType int opType, UrisSupplier srcs, DocumentStack destination) {
+ super(opType, srcs, destination);
+ mOpType = opType;
+ mSrcs = srcs;
+ mDestination = destination;
}
@Override
- Job createCopy(Context service, Context appContext, Listener listener, String id,
- DocumentStack stack, List<DocumentInfo> srcs) {
+ public Job createJob(Context service, Job.Listener listener, String id) {
+ TestJob job =
+ new TestJob(service, listener, id, mOpType, mDestination, mSrcs, mJobRunnable);
- if (srcs.isEmpty()) {
- throw new RuntimeException("Empty srcs not supported!");
+ if (mOpType == OPERATION_COPY) {
+ mCopyJobs.add(job);
+ }
+
+ if (mOpType == OPERATION_DELETE) {
+ mDeleteJobs.add(job);
}
- TestJob job = new TestJob(service, appContext, listener, OPERATION_COPY, id, stack);
- jobs.add(job);
return job;
}
+
+ /**
+ * CREATOR is required for Parcelables, but we never pass this class via parcel.
+ */
+ public Parcelable.Creator<TestFileOperation> CREATOR =
+ new Parcelable.Creator<TestFileOperation>() {
+
+ @Override
+ public TestFileOperation createFromParcel(Parcel source) {
+ throw new UnsupportedOperationException("Can't create from a parcel.");
+ }
+
+ @Override
+ public TestFileOperation[] newArray(int size) {
+ throw new UnsupportedOperationException("Can't create a new array.");
+ }
+ };
}
}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/MoveJobTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/MoveJobTest.java
index 24181d62e208..56d96ccaee1d 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/services/MoveJobTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/MoveJobTest.java
@@ -16,21 +16,21 @@
package com.android.documentsui.services;
+import static com.android.documentsui.services.FileOperationService.OPERATION_MOVE;
+
import static com.google.common.collect.Lists.newArrayList;
import android.net.Uri;
import android.provider.DocumentsContract.Document;
-import android.provider.DocumentsContract;
import android.test.suitebuilder.annotation.MediumTest;
-import com.android.documentsui.model.DocumentInfo;
-import com.android.documentsui.model.DocumentStack;
-
-import java.util.List;
-
@MediumTest
public class MoveJobTest extends AbstractCopyJobTest<MoveJob> {
+ public MoveJobTest() {
+ super(OPERATION_MOVE);
+ }
+
public void testMoveFiles() throws Exception {
runCopyFilesTest();
@@ -108,12 +108,4 @@ public class MoveJobTest extends AbstractCopyJobTest<MoveJob> {
}
// TODO: Add test cases for moving when multi-parented.
-
- @Override
- MoveJob createJob(List<DocumentInfo> srcs, DocumentInfo srcParent, DocumentStack stack)
- throws Exception {
- return new MoveJob(
- mContext, mContext, mJobListener, FileOperations.createJobId(), stack, srcs,
- srcParent);
- }
}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestJob.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestJob.java
index 9147a578f8e1..1fbcf377fa69 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestJob.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestJob.java
@@ -16,45 +16,76 @@
package com.android.documentsui.services;
+import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import android.app.Notification;
import android.app.Notification.Builder;
import android.content.Context;
+import com.android.documentsui.clipping.UrisSupplier;
import com.android.documentsui.R;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.DocumentStack;
+import com.android.documentsui.services.FileOperationService.OpType;
+
+import java.text.NumberFormat;
public class TestJob extends Job {
private boolean mStarted;
+ private Runnable mStartRunnable;
+
+ private int mNumOfNotifications = 0;
TestJob(
- Context service, Context appContext, Listener listener,
- int operationType, String id, DocumentStack stack) {
- super(service, appContext, listener, operationType, id, stack);
+ Context service, Listener listener, String id,
+ @OpType int opType, DocumentStack stack, UrisSupplier srcs, Runnable startRunnable) {
+ super(service, listener, id, opType, stack, srcs);
+
+ mStartRunnable = startRunnable;
}
@Override
void start() {
mStarted = true;
+
+ mStartRunnable.run();
}
void assertStarted() {
assertTrue(mStarted);
}
+ void assertNotStarted() {
+ assertFalse(mStarted);
+ }
+
void fail(DocumentInfo doc) {
onFileFailed(doc);
}
+ int getNumOfNotifications() {
+ return mNumOfNotifications;
+ }
+
@Override
Notification getSetupNotification() {
+ ++mNumOfNotifications;
return getSetupNotification(service.getString(R.string.copy_preparing));
}
@Override
+ Notification getProgressNotification() {
+ ++mNumOfNotifications;
+ double completed = mStarted ? 1F : 0F;
+ return mProgressBuilder
+ .setProgress(1, (int) completed, true)
+ .setSubText(NumberFormat.getPercentInstance().format(completed))
+ .build();
+ }
+
+ @Override
Notification getFailureNotification() {
// the "copy" stuff was just convenient and available :)
return getFailureNotification(
@@ -68,6 +99,7 @@ public class TestJob extends Job {
@Override
Builder createProgressBuilder() {
+ ++mNumOfNotifications;
// the "copy" stuff was just convenient and available :)
return super.createProgressBuilder(
service.getString(R.string.copy_notification_title),
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestJobListener.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestJobListener.java
index 46b093d4f24a..e9c68c6abe71 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestJobListener.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestJobListener.java
@@ -46,11 +46,6 @@ public class TestJobListener implements Job.Listener {
latch.countDown();
}
- @Override
- public void onProgress(CopyJob job) {
- progress.add(job);
- }
-
public void assertStarted() {
if (started == null) {
fail("Job didn't start. onStart never called.");
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/testing/Bitmaps.java b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/Bitmaps.java
new file mode 100644
index 000000000000..1b94b15eb3bf
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/Bitmaps.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.testing;
+
+import android.graphics.Bitmap;
+
+public final class Bitmaps {
+
+ private Bitmaps() {}
+
+ public static Bitmap createTestBitmap(int width, int height) {
+ final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+
+ return bitmap;
+ }
+
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/testing/ClipDatas.java b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/ClipDatas.java
new file mode 100644
index 000000000000..525a02e4f496
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/ClipDatas.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.testing;
+
+import android.content.ClipData;
+
+import org.mockito.Mockito;
+
+public final class ClipDatas {
+
+ private ClipDatas() {}
+
+ public static ClipData createTestClipData() {
+ final ClipData data = Mockito.mock(ClipData.class);
+
+ return data;
+ }
+
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/testing/DocsProviders.java b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/DocsProviders.java
new file mode 100644
index 000000000000..c08157fb371b
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/DocsProviders.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.testing;
+
+import android.net.Uri;
+
+import com.android.documentsui.clipping.UrisSupplier;
+
+import java.util.List;
+
+public final class DocsProviders {
+ private DocsProviders() {}
+
+ public static UrisSupplier createDocsProvider(List<Uri> docs) {
+ return new UrisSupplier.StandardUrisSupplier(docs);
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/testing/DragEvents.java b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/DragEvents.java
new file mode 100644
index 000000000000..4ad9ec0701c2
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/DragEvents.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.testing;
+
+import android.content.ClipData;
+import android.view.DragEvent;
+
+import org.mockito.Mockito;
+
+public final class DragEvents {
+
+ private DragEvents() {}
+
+ public static DragEvent createTestDragEvent(int actionId) {
+ final DragEvent mockEvent = Mockito.mock(DragEvent.class);
+ Mockito.when(mockEvent.getAction()).thenReturn(actionId);
+
+ return mockEvent;
+ }
+
+ public static DragEvent createTestLocationEvent(float x, float y) {
+ final DragEvent locationEvent = createTestDragEvent(DragEvent.ACTION_DRAG_LOCATION);
+ Mockito.when(locationEvent.getX()).thenReturn(x);
+ Mockito.when(locationEvent.getY()).thenReturn(y);
+
+ return locationEvent;
+ }
+
+ public static DragEvent createTestDropEvent(ClipData clipData) {
+ final DragEvent dropEvent = createTestDragEvent(DragEvent.ACTION_DROP);
+ Mockito.when(dropEvent.getClipData()).thenReturn(clipData);
+
+ return dropEvent;
+ }
+
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestDirectoryDetails.java b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestDirectoryDetails.java
new file mode 100644
index 000000000000..e2891bfc5bd6
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestDirectoryDetails.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.testing;
+
+import com.android.documentsui.MenuManager.DirectoryDetails;
+
+/**
+ * Test copy of DirectoryDetails, everything default to false
+ */
+public class TestDirectoryDetails extends DirectoryDetails {
+
+ public boolean shouldShowFancyFeatures;
+ public boolean isInRecents;
+ public boolean hasRootSettings;
+ public boolean hasItemsToPaste;
+ public boolean canCreateDirectory;
+ public boolean getDisplayFileSize;
+
+ public TestDirectoryDetails() {
+ super(null);
+ }
+
+ @Override
+ public boolean shouldShowFancyFeatures() {
+ return shouldShowFancyFeatures;
+ }
+
+ @Override
+ public boolean hasRootSettings() {
+ return hasRootSettings;
+ }
+
+ @Override
+ public boolean hasItemsToPaste() {
+ return hasItemsToPaste;
+ }
+
+ @Override
+ public boolean isInRecents() {
+ return isInRecents;
+ }
+
+ @Override
+ public boolean canCreateDirectory() {
+ return canCreateDirectory;
+ }
+
+ @Override
+ public boolean getDisplayFileSize() {
+ return getDisplayFileSize;
+ }
+} \ No newline at end of file
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestDrawable.java b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestDrawable.java
new file mode 100644
index 000000000000..bc3831ec5089
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestDrawable.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.testing;
+
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.drawable.Drawable;
+
+public class TestDrawable extends Drawable {
+
+ public float hotspotX;
+ public float hotspotY;
+
+ @Override
+ public void setHotspot(float x, float y) {
+ hotspotX = x;
+ hotspotY = y;
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter colorFilter) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int getOpacity() {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestEvent.java b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestEvent.java
new file mode 100644
index 000000000000..98fa2de9a508
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestEvent.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.testing;
+
+import com.android.documentsui.Events.InputEvent;
+import com.android.documentsui.TestInputEvent;
+import com.android.documentsui.dirlist.UserInputHandler.DocumentDetails;
+
+/**
+ * Events and DocDetails are closely related. For the pursposes of this test
+ * we coalesce the two in a single, handy-dandy test class.
+ */
+public class TestEvent extends TestInputEvent implements DocumentDetails {
+
+ private String modelId;
+ private boolean inHotspot;
+
+ @Override
+ public String getModelId() {
+ return modelId;
+ }
+
+ @Override
+ public int getAdapterPosition() {
+ return getItemPosition();
+ }
+
+ @Override
+ public boolean isInSelectionHotspot(InputEvent event) {
+ return inHotspot;
+ }
+
+ public TestEvent at(int position) {
+ this.position = position; // this is both "adapter position" and "item position".
+ modelId = String.valueOf(position);
+ return this;
+ }
+
+ public TestEvent shift() {
+ this.shiftKeyDow = true;
+ return this;
+ }
+
+ public TestEvent inHotspot() {
+ this.inHotspot = true;
+ return this;
+ }
+
+ public DocumentDetails getDocument() {
+ return this;
+ }
+
+ @Override
+ public int hashCode() {
+ return modelId != null ? modelId.hashCode() : -1;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (!(o instanceof TestEvent)) {
+ return false;
+ }
+
+ TestEvent other = (TestEvent) o;
+ return position == other.position
+ && modelId == other.modelId
+ && shiftKeyDow == other.shiftKeyDow
+ && mouseEvent == other.mouseEvent;
+ }
+
+ public static final Builder builder() {
+ return new Builder();
+ }
+
+ public static final class Builder {
+
+ private TestEvent mState = new TestEvent();
+
+ public Builder reset() {
+ mState = new TestEvent();
+ return this;
+ }
+
+ public Builder at(int position) {
+ mState.position = position; // this is both "adapter position" and "item position".
+ mState.modelId = String.valueOf(position);
+ return this;
+ }
+
+ public Builder shift() {
+ mState.shiftKeyDow = true;
+ return this;
+ }
+
+ public Builder unshift() {
+ mState.shiftKeyDow = false;
+ return this;
+ }
+
+ public Builder inHotspot() {
+ mState.inHotspot = true;
+ return this;
+ }
+
+ public Builder mouse() {
+ mState.mouseEvent = true;
+ return this;
+ }
+
+ public TestEvent build() {
+ // Return a copy, so nobody can mess w/ our internal state.
+ TestEvent e = new TestEvent();
+ e.position = mState.position;
+ e.modelId = mState.modelId;
+ e.shiftKeyDow = mState.shiftKeyDow;
+ e.mouseEvent = mState.mouseEvent;
+ return e;
+ }
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestHandler.java b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestHandler.java
new file mode 100644
index 000000000000..143ec71b3e3e
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestHandler.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.testing;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+
+import java.util.TimerTask;
+
+/**
+ * A test double of {@link Handler}, backed by {@link TestTimer}.
+ */
+public class TestHandler extends Handler {
+ private TestTimer mTimer = new TestTimer();
+
+ public TestHandler() {
+ // Use main looper to trick underlying handler, we're not using it at all.
+ super(Looper.getMainLooper());
+ }
+
+ public boolean hasScheduledMessage() {
+ return mTimer.hasScheduledTask();
+ }
+
+ public void dispatchNextMessage() {
+ mTimer.fastForwardToNextTask();
+ }
+
+ public void dispatchAllMessages() {
+ while (hasScheduledMessage()) {
+ dispatchNextMessage();
+ }
+ }
+
+ @Override
+ public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
+ msg.setTarget(this);
+ TimerTask task = new MessageTimerTask(msg);
+ mTimer.scheduleAtTime(new TestTimer.Task(task), uptimeMillis);
+ return true;
+ }
+
+ private static class MessageTimerTask extends TimerTask {
+ private Message mMessage;
+
+ private MessageTimerTask(Message message) {
+ mMessage = message;
+ }
+
+ @Override
+ public void run() {
+ mMessage.getTarget().dispatchMessage(mMessage);
+ }
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestMenu.java b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestMenu.java
new file mode 100644
index 000000000000..a8699b9040b4
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestMenu.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.testing;
+
+import android.util.SparseArray;
+import android.view.Menu;
+
+import com.android.documentsui.R;
+
+import org.mockito.Mockito;
+
+/**
+ *
+ * Test copy of {@link android.view.Menu}.
+ *
+ * We use abstract so we don't have to implement all the necessary methods from the interface,
+ * and we use Mockito to just mock out the methods we need.
+ * To get an instance, use {@link #create(int...)}.
+ */
+public abstract class TestMenu implements Menu {
+
+ private SparseArray<TestMenuItem> items = new SparseArray<>();
+
+ public static TestMenu create() {
+ return create(R.id.menu_open,
+ R.id.menu_rename,
+ R.id.menu_move_to,
+ R.id.menu_copy_to,
+ R.id.menu_cut_to_clipboard,
+ R.id.menu_copy_to_clipboard,
+ R.id.menu_paste_from_clipboard,
+ R.id.menu_share,
+ R.id.menu_delete,
+ R.id.menu_create_dir,
+ R.id.menu_settings,
+ R.id.menu_new_window,
+ R.id.menu_select_all,
+ R.id.menu_file_size,
+ R.id.menu_grid,
+ R.id.menu_list,
+ R.id.menu_sort,
+ R.id.menu_sort_size,
+ R.id.menu_advanced,
+ R.id.menu_eject_root);
+ }
+
+ public static TestMenu create(int... ids) {
+ final TestMenu menu = Mockito.mock(TestMenu.class,
+ Mockito.withSettings().defaultAnswer(Mockito.CALLS_REAL_METHODS));
+ menu.items = new SparseArray<>();
+ for (int id : ids) {
+ TestMenuItem item = TestMenuItem.create(id);
+ menu.addMenuItem(id, item);
+ }
+ return menu;
+ }
+
+ public void addMenuItem(int id, TestMenuItem item) {
+ items.put(id, item);
+ }
+
+ @Override
+ public TestMenuItem findItem(int id) {
+ return items.get(id);
+ }
+
+ @Override
+ public int size() {
+ return items.size();
+ }
+
+ @Override
+ public TestMenuItem getItem(int index) {
+ return items.valueAt(index);
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestMenuItem.java b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestMenuItem.java
new file mode 100644
index 000000000000..6314b7bb102b
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestMenuItem.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.testing;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.annotation.StringRes;
+import android.view.MenuItem;
+
+import org.mockito.Mockito;
+
+/**
+*
+* Test copy of {@link android.view.MenuItem}.
+*
+* We use abstract so we don't have to implement all the necessary methods from the interface,
+* and we use Mockito to just mock out the methods we need.
+* To get an instance, use {@link #create(int)}.
+*/
+
+public abstract class TestMenuItem implements MenuItem {
+
+ boolean enabled;
+ boolean visible;
+ @StringRes int title;
+
+ public static TestMenuItem create(int id) {
+ final TestMenuItem mockMenuItem = Mockito.mock(TestMenuItem.class,
+ Mockito.withSettings().defaultAnswer(Mockito.CALLS_REAL_METHODS));
+
+ return mockMenuItem;
+ }
+
+ @Override
+ public TestMenuItem setTitle(@StringRes int title) {
+ this.title = title;
+ return this;
+ }
+
+ @Override
+ public MenuItem setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ return this;
+ }
+
+ @Override
+ public MenuItem setVisible(boolean visible) {
+ this.visible = visible;
+ return this;
+ }
+
+ @Override
+ public boolean isVisible() {
+ return this.visible;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return this.enabled;
+ }
+
+ public void assertEnabled() {
+ assertTrue(this.enabled);
+ }
+
+ public void assertDisabled() {
+ assertFalse(this.enabled);
+ }
+
+ public void assertVisible() {
+ assertTrue(this.visible);
+ }
+
+ public void assertInvisible() {
+ assertFalse(this.visible);
+ }
+
+ public void assertTitle(@StringRes int title) {
+ assertTrue(this.title == title);
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestPredicate.java b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestPredicate.java
new file mode 100644
index 000000000000..f8ee21e30413
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestPredicate.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.testing;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.function.Predicate;
+
+import javax.annotation.Nullable;
+
+/**
+ * Test predicate that can be used to spy control responses and make
+ * assertions against values tested.
+ */
+public class TestPredicate<T> implements Predicate<T> {
+
+ private @Nullable T lastValue;
+ private boolean nextReturnValue;
+
+ @Override
+ public boolean test(T t) {
+ lastValue = t;
+ return nextReturnValue;
+ }
+
+ public void assertLastArgument(@Nullable T expected) {
+ assertEquals(expected, lastValue);
+ }
+
+ public void nextReturn(boolean value) {
+ nextReturnValue = value;
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestScheduledExecutorService.java b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestScheduledExecutorService.java
index 4d417cfc095c..f5001ee41d64 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/services/TestScheduledExecutorService.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestScheduledExecutorService.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.documentsui.services;
+package com.android.documentsui.testing;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.fail;
@@ -47,7 +47,7 @@ public class TestScheduledExecutorService implements ScheduledExecutorService {
return new ArrayList<>();
}
- void assertShutdown() {
+ public void assertShutdown() {
if (!shutdown) {
fail("Executor wasn't shut down.");
}
@@ -80,7 +80,7 @@ public class TestScheduledExecutorService implements ScheduledExecutorService {
@Override
public Future<?> submit(Runnable task) {
- throw new UnsupportedOperationException();
+ return schedule(task, 0, TimeUnit.MILLISECONDS);
}
@Override
@@ -109,7 +109,7 @@ public class TestScheduledExecutorService implements ScheduledExecutorService {
@Override
public void execute(Runnable command) {
- throw new UnsupportedOperationException();
+ schedule(command, 0, TimeUnit.MILLISECONDS);
}
@Override
@@ -136,13 +136,13 @@ public class TestScheduledExecutorService implements ScheduledExecutorService {
throw new UnsupportedOperationException();
}
- void runAll() {
+ public void runAll() {
for (TestFuture future : scheduled) {
future.runnable.run();
}
}
- void run(int taskIndex) {
+ public void run(int taskIndex) {
scheduled.get(taskIndex).runnable.run();
}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestSearchViewManager.java b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestSearchViewManager.java
new file mode 100644
index 000000000000..29ae3bd39e0b
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestSearchViewManager.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.testing;
+
+import android.os.Bundle;
+
+import com.android.documentsui.SearchViewManager;
+
+/**
+ * Test copy of {@link com.android.documentsui.SearchViewManager}
+ *
+ * Specficially used to test whether {@link #showMenu(boolean)}
+ * and {@link #updateMenu()} are called.
+ */
+public class TestSearchViewManager extends SearchViewManager {
+
+ boolean updateMenuCalled;
+ boolean showMenuCalled;
+
+ public TestSearchViewManager(SearchManagerListener listener, Bundle savedState) {
+ super(listener, savedState);
+ }
+
+ public TestSearchViewManager() {
+ super(null, null);
+ }
+
+ @Override
+ protected void showMenu(boolean visible) {
+ showMenuCalled = true;
+ }
+
+ @Override
+ public void updateMenu() {
+ updateMenuCalled = true;
+ }
+
+ public boolean showMenuCalled() {
+ return showMenuCalled;
+ }
+
+ public boolean updateMenuCalled() {
+ return updateMenuCalled;
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestSelectionDetails.java b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestSelectionDetails.java
new file mode 100644
index 000000000000..20796ca0060b
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestSelectionDetails.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.testing;
+
+import com.android.documentsui.MenuManager.SelectionDetails;
+
+/**
+ * Test copy of SelectionDetails, everything default to false
+ */
+public class TestSelectionDetails implements SelectionDetails {
+
+ public boolean canRename;
+ public boolean canDelete;
+ public boolean containPartial;
+ public boolean containDirectories;
+
+ @Override
+ public boolean containsPartialFiles() {
+ return containPartial;
+ }
+
+ @Override
+ public boolean containsDirectories() {
+ return containDirectories;
+ }
+
+ @Override
+ public boolean canRename() {
+ return canRename;
+ }
+
+ @Override
+ public boolean canDelete() {
+ return canDelete;
+ }
+ } \ No newline at end of file
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestTimer.java b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestTimer.java
new file mode 100644
index 000000000000..04af28366f04
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/TestTimer.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.testing;
+
+import java.util.Date;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.ListIterator;
+import java.util.Timer;
+import java.util.TimerTask;
+
+/**
+ * A {@link Timer} for testing that can dial its clock hands to any future time.
+ */
+public class TestTimer extends Timer {
+
+ private long mNow = 0;
+
+ private final LinkedList<Task> mTaskList = new LinkedList<>();
+
+ public void fastForwardTo(long time) {
+ if (time < mNow) {
+ throw new IllegalArgumentException("Can't fast forward to past.");
+ }
+
+ mNow = time;
+ while (!mTaskList.isEmpty() && mTaskList.getFirst().mExecuteTime <= mNow) {
+ Task task = mTaskList.getFirst();
+ if (!task.isCancelled()) {
+ task.run();
+ }
+ mTaskList.removeFirst();
+ }
+ }
+
+ public boolean hasScheduledTask() {
+ return !mTaskList.isEmpty();
+ }
+
+ public void fastForwardToNextTask() {
+ if (!hasScheduledTask()) {
+ throw new IllegalStateException("There is no scheduled task!");
+ }
+ fastForwardTo(mTaskList.getFirst().mExecuteTime);
+ }
+
+ @Override
+ public void cancel() {
+ mTaskList.clear();
+ }
+
+ @Override
+ public int purge() {
+ int count = 0;
+ Iterator<Task> iter = mTaskList.iterator();
+ while (iter.hasNext()) {
+ Task task = iter.next();
+ if (task.isCancelled()) {
+ iter.remove();
+ ++count;
+ }
+ }
+ return count;
+ }
+
+ @Override
+ public void schedule(TimerTask task, Date time) {
+ long executeTime = time.getTime();
+ scheduleAtTime(task, executeTime);
+ }
+
+ @Override
+ public void schedule(TimerTask task, Date firstTime, long period) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void schedule(TimerTask task, long delay) {
+ long executeTime = mNow + delay;
+ scheduleAtTime(task, executeTime);
+ }
+
+ @Override
+ public void schedule(TimerTask task, long delay, long period) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void scheduleAtTime(TimerTask task, long executeTime) {
+ Task testTimerTask = (Task) task;
+ testTimerTask.mExecuteTime = executeTime;
+
+ ListIterator<Task> iter = mTaskList.listIterator(0);
+ while (iter.hasNext()) {
+ if (iter.next().mExecuteTime >= executeTime) {
+ break;
+ }
+ }
+ iter.add(testTimerTask);
+ }
+
+ public static class Task extends TimerTask {
+ private boolean mIsCancelled;
+ private long mExecuteTime;
+
+ private TimerTask mDelegate;
+
+ public Task(TimerTask delegate) {
+ mDelegate = delegate;
+ }
+
+ @Override
+ public boolean cancel() {
+ mIsCancelled = true;
+ return mDelegate.cancel();
+ }
+
+ @Override
+ public void run() {
+ mDelegate.run();
+ }
+
+ boolean isCancelled() {
+ return mIsCancelled;
+ }
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/testing/Views.java b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/Views.java
new file mode 100644
index 000000000000..52a9cbc19d13
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/Views.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.testing;
+
+import android.graphics.drawable.Drawable;
+import android.view.View;
+
+import org.mockito.Mockito;
+
+public final class Views {
+
+ private Views() {}
+
+ public static View createTestView() {
+ final View view = Mockito.mock(View.class);
+ Mockito.doCallRealMethod().when(view).setTag(Mockito.anyInt(), Mockito.any());
+ Mockito.doCallRealMethod().when(view).getTag(Mockito.anyInt());
+
+ return view;
+ }
+
+ public static void setBackground(View testView, Drawable background) {
+ Mockito.when(testView.getBackground()).thenReturn(background);
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/testing/dirlist/SelectionProbe.java b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/dirlist/SelectionProbe.java
new file mode 100644
index 000000000000..12f4642110e2
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/dirlist/SelectionProbe.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.testing.dirlist;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import com.android.documentsui.dirlist.MultiSelectManager;
+import com.android.documentsui.dirlist.MultiSelectManager.Selection;
+
+/**
+ * Helper class for making assertions against the state of a MultiSelectManager instance.
+ */
+public final class SelectionProbe {
+
+ private final MultiSelectManager mMgr;
+
+ public SelectionProbe(MultiSelectManager mgr) {
+ mMgr = mgr;
+ }
+
+ public void assertRangeSelected(int begin, int end) {
+ for (int i = begin; i <= end; i++) {
+ assertSelected(i);
+ }
+ }
+
+ public void assertRangeNotSelected(int begin, int end) {
+ for (int i = begin; i <= end; i++) {
+ assertNotSelected(i);
+ }
+ }
+
+ public void assertRangeSelection(int begin, int end) {
+ assertSelectionSize(end - begin + 1);
+ assertRangeSelected(begin, end);
+ }
+
+ public void assertSelectionSize(int expected) {
+ Selection selection = mMgr.getSelection();
+ assertEquals(selection.toString(), expected, selection.size());
+ }
+
+ public void assertNoSelection() {
+ assertSelectionSize(0);
+ }
+
+ public void assertSelection(int... ids) {
+ assertSelected(ids);
+ assertEquals(ids.length, mMgr.getSelection().size());
+ }
+
+ public void assertSelected(int... ids) {
+ Selection sel = mMgr.getSelection();
+ for (int id : ids) {
+ String sid = String.valueOf(id);
+ assertTrue(sid + " is not in selection " + sel, sel.contains(sid));
+ }
+ }
+
+ public void assertNotSelected(int... ids) {
+ Selection sel = mMgr.getSelection();
+ for (int id : ids) {
+ String sid = String.valueOf(id);
+ assertFalse(sid + " is in selection " + sel, sel.contains(sid));
+ }
+ }
+
+ public void select(int...positions) {
+ for (int position : positions) {
+ mMgr.toggleSelection(String.valueOf(position));
+ }
+ }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/testing/dirlist/TestSelectionListener.java b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/dirlist/TestSelectionListener.java
new file mode 100644
index 000000000000..08f29f0132af
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/testing/dirlist/TestSelectionListener.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.testing.dirlist;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import com.android.documentsui.dirlist.MultiSelectManager;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public final class TestSelectionListener implements MultiSelectManager.Callback {
+
+ Set<String> ignored = new HashSet<>();
+ private boolean mSelectionChanged = false;
+
+ @Override
+ public void onItemStateChanged(String modelId, boolean selected) {}
+
+ @Override
+ public boolean onBeforeItemStateChange(String modelId, boolean selected) {
+ return !ignored.contains(modelId);
+ }
+
+ @Override
+ public void onSelectionChanged() {
+ mSelectionChanged = true;
+ }
+
+ public void reset() {
+ mSelectionChanged = false;
+ }
+
+ public void assertSelectionChanged() {
+ assertTrue(mSelectionChanged);
+ }
+
+ public void assertSelectionUnchanged() {
+ assertFalse(mSelectionChanged);
+ }
+} \ No newline at end of file