diff options
116 files changed, 1164 insertions, 114 deletions
diff --git a/flags.aconfig b/flags.aconfig index 54403563a..5af4a2656 100644 --- a/flags.aconfig +++ b/flags.aconfig @@ -30,3 +30,10 @@ flag { description: "Enables desktop file handling." bug: "381778967" } + +flag { + name: "visual_signals" + namespace: "documentsui" + description: "Enables in-app progress display of file operations" + bug: "378011512" +} diff --git a/proguard.flags b/proguard.flags index a0f96ae09..e71b073c8 100644 --- a/proguard.flags +++ b/proguard.flags @@ -23,7 +23,10 @@ } # To prevent class not found exception in org.brotli.dec.Dictionary --keep final class org.brotli.dec.DictionaryData +# TODO(b/373579455): Evaluate if <init> needs to be kept. +-keep final class org.brotli.dec.DictionaryData { + void <init>(); +} # keep rule generated after running trace references on the test app against DocumentsUIGoogle.jar # TODO(b/339312616): Remove after a more permanent fix is available @@ -103,6 +106,7 @@ int inspector_details_view; int option_menu_create_dir; int option_menu_debug; + int option_menu_extract_all; int option_menu_inspect; int option_menu_launcher; int option_menu_new_window; diff --git a/res/flag(!com.android.documentsui.flags.use_material3)/menu/activity.xml b/res/flag(!com.android.documentsui.flags.use_material3)/menu/activity.xml index 39be106ca..9c3516aeb 100644 --- a/res/flag(!com.android.documentsui.flags.use_material3)/menu/activity.xml +++ b/res/flag(!com.android.documentsui.flags.use_material3)/menu/activity.xml @@ -67,6 +67,13 @@ android:visible="false" app:showAsAction="never"/> <item + android:id="@+id/option_menu_extract_all" + android:title="@string/menu_extract_all" + android:icon="@drawable/ic_menu_extract" + android:enabled="false" + android:visible="false" + app:showAsAction="always"/> + <item android:id="@+id/option_menu_settings" android:title="@string/menu_settings" android:visible="false" diff --git a/res/flag(com.android.documentsui.flags.use_material3)/layout-w900dp/column_headers.xml b/res/flag(com.android.documentsui.flags.use_material3)/layout-w900dp/column_headers.xml index f24a28241..c21f39c72 100644 --- a/res/flag(com.android.documentsui.flags.use_material3)/layout-w900dp/column_headers.xml +++ b/res/flag(com.android.documentsui.flags.use_material3)/layout-w900dp/column_headers.xml @@ -30,8 +30,8 @@ android:baselineAligned="false" android:gravity="center_vertical" android:minHeight="@dimen/list_item_height" - android:paddingStart="@dimen/list_item_padding" - android:paddingEnd="@dimen/list_item_width" + android:paddingStart="@dimen/list_item_padding_start" + android:paddingEnd="@dimen/list_item_padding_end" android:orientation="horizontal"> <!-- Placeholder for icon --> <View diff --git a/res/flag(com.android.documentsui.flags.use_material3)/layout-w900dp/item_doc_list.xml b/res/flag(com.android.documentsui.flags.use_material3)/layout-w900dp/item_doc_list.xml index b0db7ec38..5e1ca3438 100644 --- a/res/flag(com.android.documentsui.flags.use_material3)/layout-w900dp/item_doc_list.xml +++ b/res/flag(com.android.documentsui.flags.use_material3)/layout-w900dp/item_doc_list.xml @@ -119,6 +119,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="0.2" + android:textAlignment="viewStart" style="@style/FileItemLabelStyle"/> <TextView @@ -126,6 +127,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="0.2" + android:textAlignment="viewEnd" style="@style/FileItemLabelStyle"/> <TextView @@ -133,6 +135,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="0.2" + android:textAlignment="viewEnd" style="@style/FileItemLabelStyle"/> </LinearLayout> diff --git a/res/flag(com.android.documentsui.flags.use_material3)/menu/action_mode_menu.xml b/res/flag(com.android.documentsui.flags.use_material3)/menu/action_mode_menu.xml index a87bee4ff..db4d581c1 100644 --- a/res/flag(com.android.documentsui.flags.use_material3)/menu/action_mode_menu.xml +++ b/res/flag(com.android.documentsui.flags.use_material3)/menu/action_mode_menu.xml @@ -54,7 +54,8 @@ <item android:id="@+id/action_menu_extract_to" android:title="@string/menu_extract" - android:showAsAction="never" + android:icon="@drawable/ic_menu_extract" + android:showAsAction="always" android:visible="false" /> <item android:id="@+id/action_menu_move_to" diff --git a/res/flag(com.android.documentsui.flags.use_material3)/menu/activity.xml b/res/flag(com.android.documentsui.flags.use_material3)/menu/activity.xml index 16b0f82af..0e636a18c 100644 --- a/res/flag(com.android.documentsui.flags.use_material3)/menu/activity.xml +++ b/res/flag(com.android.documentsui.flags.use_material3)/menu/activity.xml @@ -77,6 +77,13 @@ android:visible="false" app:showAsAction="never"/> <item + android:id="@+id/option_menu_extract_all" + android:title="@string/menu_extract_all" + android:icon="@drawable/ic_menu_extract" + android:enabled="false" + android:visible="false" + app:showAsAction="always"/> + <item android:id="@+id/option_menu_settings" android:title="@string/menu_settings" android:visible="false" diff --git a/res/flag(com.android.documentsui.flags.use_material3)/values/styles.xml b/res/flag(com.android.documentsui.flags.use_material3)/values/styles.xml index 5fde94ab8..ce554c427 100644 --- a/res/flag(com.android.documentsui.flags.use_material3)/values/styles.xml +++ b/res/flag(com.android.documentsui.flags.use_material3)/values/styles.xml @@ -163,7 +163,6 @@ <item name="android:ellipsize">end</item> <item name="android:minWidth">70dp</item> <item name="android:singleLine">true</item> - <item name="android:textAlignment">viewStart</item> <item name="android:textAppearance">@style/FileItemLabelText</item> </style> diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml index 74f2c90eb..7ecedcd5d 100644 --- a/res/values-af/strings.xml +++ b/res/values-af/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Skuif na …"</string> <string name="menu_compress" msgid="37539111904724188">"Pers saam"</string> <string name="menu_extract" msgid="8171946945982532262">"Onttrek na …"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Uittreksel van alles …"</string> <string name="menu_rename" msgid="1883113442688817554">"Hernoem"</string> <string name="menu_inspect" msgid="7279855349299446224">"Kry inligting"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Wys versteekte lêers"</string> diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml index 428783c41..40cda4a01 100644 --- a/res/values-am/strings.xml +++ b/res/values-am/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"ውሰድ ወደ…"</string> <string name="menu_compress" msgid="37539111904724188">"ጭመቅ"</string> <string name="menu_extract" msgid="8171946945982532262">"አውጣ ወደ…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"ሁሉንም አውጣ…"</string> <string name="menu_rename" msgid="1883113442688817554">"ዳግም ሰይም"</string> <string name="menu_inspect" msgid="7279855349299446224">"መረጃ አግኝ"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"የተደበቁ ፋይሎችን አሳይ"</string> diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index 84917168f..329b59df4 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"نقل إلى..."</string> <string name="menu_compress" msgid="37539111904724188">"ضغط"</string> <string name="menu_extract" msgid="8171946945982532262">"الاستخراج إلى…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"استخراج الكل…"</string> <string name="menu_rename" msgid="1883113442688817554">"إعادة تسمية"</string> <string name="menu_inspect" msgid="7279855349299446224">"الحصول على المعلومات"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"إظهار الملفات المخفية"</string> diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml index 285cd0bfe..72d34172e 100644 --- a/res/values-as/strings.xml +++ b/res/values-as/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"ইয়ালৈ স্থানান্তৰ কৰক…"</string> <string name="menu_compress" msgid="37539111904724188">"সংকুচিত কৰক"</string> <string name="menu_extract" msgid="8171946945982532262">"ইয়ালৈ আহৰণ কৰক…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"আটাইবোৰ আহৰণ কৰক…"</string> <string name="menu_rename" msgid="1883113442688817554">"নতুন নাম দিয়ক"</string> <string name="menu_inspect" msgid="7279855349299446224">"তথ্য পাওক"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"লুকুৱাই থোৱা ফাইল দেখুৱাওক"</string> diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml index dfba630de..4f26eb52e 100644 --- a/res/values-az/strings.xml +++ b/res/values-az/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Daşıyın..."</string> <string name="menu_compress" msgid="37539111904724188">"Sıxışdırın"</string> <string name="menu_extract" msgid="8171946945982532262">"Çıxarın…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Hamısını çıxarın…"</string> <string name="menu_rename" msgid="1883113442688817554">"Adını dəyişdirin"</string> <string name="menu_inspect" msgid="7279855349299446224">"Məlumat əldə edin"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Gizli faylları göstərin"</string> diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml index fca11a776..4399d8353 100644 --- a/res/values-b+sr+Latn/strings.xml +++ b/res/values-b+sr+Latn/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Premesti u…"</string> <string name="menu_compress" msgid="37539111904724188">"Komprimuj"</string> <string name="menu_extract" msgid="8171946945982532262">"Izdvoj u…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Izdvoji sve…"</string> <string name="menu_rename" msgid="1883113442688817554">"Preimenuj"</string> <string name="menu_inspect" msgid="7279855349299446224">"Prikaži informacije"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Prikazuj skrivene datoteke"</string> diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml index 4c2a98cec..723a8fbd6 100644 --- a/res/values-be/strings.xml +++ b/res/values-be/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Перамясціць у…"</string> <string name="menu_compress" msgid="37539111904724188">"Сціснуць"</string> <string name="menu_extract" msgid="8171946945982532262">"Выняць у…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Выняць усе…"</string> <string name="menu_rename" msgid="1883113442688817554">"Перайменаваць"</string> <string name="menu_inspect" msgid="7279855349299446224">"Атрымаць інфармацыю"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Паказваць схаваныя файлы"</string> diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml index e1444b40b..7a00de0fb 100644 --- a/res/values-bg/strings.xml +++ b/res/values-bg/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Преместване във…"</string> <string name="menu_compress" msgid="37539111904724188">"Компресиране"</string> <string name="menu_extract" msgid="8171946945982532262">"Извличане в/ъв…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Извличане на всички…"</string> <string name="menu_rename" msgid="1883113442688817554">"Преименуване"</string> <string name="menu_inspect" msgid="7279855349299446224">"Получаване на информация"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Показване на скрити файлове"</string> diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml index f51afc50f..4b25ce368 100644 --- a/res/values-bn/strings.xml +++ b/res/values-bn/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"এতে সরান…"</string> <string name="menu_compress" msgid="37539111904724188">"সঙ্কুচিত করুন"</string> <string name="menu_extract" msgid="8171946945982532262">"এখানে রাখুন…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"সব এক্সট্র্যাক্ট করুন…"</string> <string name="menu_rename" msgid="1883113442688817554">"পুনঃনামকরণ"</string> <string name="menu_inspect" msgid="7279855349299446224">"তথ্য পান"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"লুকানো ফাইল দেখুন"</string> diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml index bb5627dbe..2564464ff 100644 --- a/res/values-bs/strings.xml +++ b/res/values-bs/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Premjesti u…"</string> <string name="menu_compress" msgid="37539111904724188">"Kompresiraj"</string> <string name="menu_extract" msgid="8171946945982532262">"Izdvoji u…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Izdvajanje svega…"</string> <string name="menu_rename" msgid="1883113442688817554">"Promijeni naziv"</string> <string name="menu_inspect" msgid="7279855349299446224">"Prikaži informacije"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Prikaži skrivene fajlove"</string> diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 76d717243..3367fc94b 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Mou a…"</string> <string name="menu_compress" msgid="37539111904724188">"Comprimeix"</string> <string name="menu_extract" msgid="8171946945982532262">"Extreu a…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Extreu-ho tot…"</string> <string name="menu_rename" msgid="1883113442688817554">"Canvia el nom"</string> <string name="menu_inspect" msgid="7279855349299446224">"Obtén informació"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Mostra els fitxers amagats"</string> diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index 44ee41907..d58addbf9 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Přesunout do…"</string> <string name="menu_compress" msgid="37539111904724188">"Zkomprimovat"</string> <string name="menu_extract" msgid="8171946945982532262">"Rozbalit do…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Extrahovat vše…"</string> <string name="menu_rename" msgid="1883113442688817554">"Přejmenovat"</string> <string name="menu_inspect" msgid="7279855349299446224">"Zobrazit informace"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Zobrazit skryté soubory"</string> diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index c0d5cf0c8..facc58ba5 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Flyt til…"</string> <string name="menu_compress" msgid="37539111904724188">"Komprimer"</string> <string name="menu_extract" msgid="8171946945982532262">"Pak ud i…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Pak alle ud…"</string> <string name="menu_rename" msgid="1883113442688817554">"Omdøb"</string> <string name="menu_inspect" msgid="7279855349299446224">"Få oplysninger"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Vis skjulte filer"</string> diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 381f3b696..0b7943238 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Verschieben nach…"</string> <string name="menu_compress" msgid="37539111904724188">"Komprimieren"</string> <string name="menu_extract" msgid="8171946945982532262">"Extrahieren nach…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Alle extrahieren…"</string> <string name="menu_rename" msgid="1883113442688817554">"Umbenennen"</string> <string name="menu_inspect" msgid="7279855349299446224">"Weitere Informationen"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Ausgeblendete Dateien anzeigen"</string> diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index 9233d5d20..706630dda 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Μετακίνηση σε…"</string> <string name="menu_compress" msgid="37539111904724188">"Συμπίεση"</string> <string name="menu_extract" msgid="8171946945982532262">"Εξαγωγή σε…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Εξαγωγή όλων…"</string> <string name="menu_rename" msgid="1883113442688817554">"Μετονομασία"</string> <string name="menu_inspect" msgid="7279855349299446224">"Λήψη πληροφοριών"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Εμφάνιση κρυφών αρχείων"</string> diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml index 5523ed3f1..ad4cbfeea 100644 --- a/res/values-en-rAU/strings.xml +++ b/res/values-en-rAU/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Move to…"</string> <string name="menu_compress" msgid="37539111904724188">"Compress"</string> <string name="menu_extract" msgid="8171946945982532262">"Extract to…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Extract all…"</string> <string name="menu_rename" msgid="1883113442688817554">"Rename"</string> <string name="menu_inspect" msgid="7279855349299446224">"Get info"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Show hidden files"</string> diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml index 0dcc1f5c1..df51b525d 100644 --- a/res/values-en-rCA/strings.xml +++ b/res/values-en-rCA/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Move to…"</string> <string name="menu_compress" msgid="37539111904724188">"Compress"</string> <string name="menu_extract" msgid="8171946945982532262">"Extract to…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Extract all…"</string> <string name="menu_rename" msgid="1883113442688817554">"Rename"</string> <string name="menu_inspect" msgid="7279855349299446224">"Get info"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Show hidden files"</string> diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index 5523ed3f1..ad4cbfeea 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Move to…"</string> <string name="menu_compress" msgid="37539111904724188">"Compress"</string> <string name="menu_extract" msgid="8171946945982532262">"Extract to…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Extract all…"</string> <string name="menu_rename" msgid="1883113442688817554">"Rename"</string> <string name="menu_inspect" msgid="7279855349299446224">"Get info"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Show hidden files"</string> diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml index 5523ed3f1..ad4cbfeea 100644 --- a/res/values-en-rIN/strings.xml +++ b/res/values-en-rIN/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Move to…"</string> <string name="menu_compress" msgid="37539111904724188">"Compress"</string> <string name="menu_extract" msgid="8171946945982532262">"Extract to…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Extract all…"</string> <string name="menu_rename" msgid="1883113442688817554">"Rename"</string> <string name="menu_inspect" msgid="7279855349299446224">"Get info"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Show hidden files"</string> diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml index c7f1e717e..c5ce3eb95 100644 --- a/res/values-es-rUS/strings.xml +++ b/res/values-es-rUS/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Mover a…"</string> <string name="menu_compress" msgid="37539111904724188">"Comprimir"</string> <string name="menu_extract" msgid="8171946945982532262">"Extraer en…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Extraer todo…"</string> <string name="menu_rename" msgid="1883113442688817554">"Cambiar nombre"</string> <string name="menu_inspect" msgid="7279855349299446224">"Obtener información"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Mostrar archivos ocultos"</string> diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 573a6768b..8850843c4 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Mover a…"</string> <string name="menu_compress" msgid="37539111904724188">"Comprimir"</string> <string name="menu_extract" msgid="8171946945982532262">"Extraer a…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Extraer todo…"</string> <string name="menu_rename" msgid="1883113442688817554">"Cambiar nombre"</string> <string name="menu_inspect" msgid="7279855349299446224">"Obtener información"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Mostrar archivos ocultos"</string> diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml index e7dbe750b..21a9aaabc 100644 --- a/res/values-et/strings.xml +++ b/res/values-et/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Teisalda asukohta …"</string> <string name="menu_compress" msgid="37539111904724188">"Tihenda"</string> <string name="menu_extract" msgid="8171946945982532262">"Ekstrakti …"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Ekstrakti kõik …"</string> <string name="menu_rename" msgid="1883113442688817554">"Nimeta ümber"</string> <string name="menu_inspect" msgid="7279855349299446224">"Hangi teavet"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Kuva peidetud failid"</string> diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index c8dbc0577..46a1e2bfb 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Eraman hona…"</string> <string name="menu_compress" msgid="37539111904724188">"Konprimatu"</string> <string name="menu_extract" msgid="8171946945982532262">"Atera hona…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Atera guztia…"</string> <string name="menu_rename" msgid="1883113442688817554">"Aldatu izena"</string> <string name="menu_inspect" msgid="7279855349299446224">"Lortu informazioa"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Erakutsi fitxategi ezkutuak"</string> diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index f5a469861..1c9e0c1e5 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"انتقال به…"</string> <string name="menu_compress" msgid="37539111904724188">"فشرده کردن"</string> <string name="menu_extract" msgid="8171946945982532262">"استخراج در…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"استخراج همه…"</string> <string name="menu_rename" msgid="1883113442688817554">"تغییر نام"</string> <string name="menu_inspect" msgid="7279855349299446224">"دریافت اطلاعات"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"فایلهای پنهان نشان داده شود"</string> diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml index 6fa10bf1a..6a8cb5633 100644 --- a/res/values-fi/strings.xml +++ b/res/values-fi/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Siirrä kohteeseen…"</string> <string name="menu_compress" msgid="37539111904724188">"Pakkaa"</string> <string name="menu_extract" msgid="8171946945982532262">"Pura kohteeseen…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Pura kaikki…"</string> <string name="menu_rename" msgid="1883113442688817554">"Nimeä uudelleen"</string> <string name="menu_inspect" msgid="7279855349299446224">"Näytä tiedot"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Näytä piilotetut tiedostot"</string> diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml index c61478375..ede583abb 100644 --- a/res/values-fr-rCA/strings.xml +++ b/res/values-fr-rCA/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Déplacer dans…"</string> <string name="menu_compress" msgid="37539111904724188">"Compresser"</string> <string name="menu_extract" msgid="8171946945982532262">"Extraire vers…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Tout extraire…"</string> <string name="menu_rename" msgid="1883113442688817554">"Renommer"</string> <string name="menu_inspect" msgid="7279855349299446224">"En savoir plus"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Afficher les fichiers masqués"</string> diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 85bdeb0fd..01935a805 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Déplacer vers…"</string> <string name="menu_compress" msgid="37539111904724188">"Compresser"</string> <string name="menu_extract" msgid="8171946945982532262">"Extraire sur…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Tout extraire…"</string> <string name="menu_rename" msgid="1883113442688817554">"Renommer"</string> <string name="menu_inspect" msgid="7279855349299446224">"Obtenir les informations"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Afficher les fichiers masqués"</string> diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index 1b9fe1d2f..db1aeccf5 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Mover a…"</string> <string name="menu_compress" msgid="37539111904724188">"Comprimir"</string> <string name="menu_extract" msgid="8171946945982532262">"Extraer en..."</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Extraer todo…"</string> <string name="menu_rename" msgid="1883113442688817554">"Cambiar nome"</string> <string name="menu_inspect" msgid="7279855349299446224">"Obter información"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Amosar ficheiros ocultos"</string> diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml index 766540c51..e161c1656 100644 --- a/res/values-gu/strings.xml +++ b/res/values-gu/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"આમાં ખસેડો…"</string> <string name="menu_compress" msgid="37539111904724188">"સંકુચિત કરો"</string> <string name="menu_extract" msgid="8171946945982532262">"આમાં એક્સટ્રેક્ટ કરો…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"બધું એક્સટ્રેક્ટ કરો…"</string> <string name="menu_rename" msgid="1883113442688817554">"નામ બદલો"</string> <string name="menu_inspect" msgid="7279855349299446224">"માહિતી મેળવો"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"છુપાવેલી ફાઇલો બતાવો"</string> diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml index 3183bd297..96c4dcfc2 100644 --- a/res/values-hi/strings.xml +++ b/res/values-hi/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"यहां ले जाएं…"</string> <string name="menu_compress" msgid="37539111904724188">"कंप्रेस करें"</string> <string name="menu_extract" msgid="8171946945982532262">"यहां निकालें…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"सभी को एक्सट्रैक्ट करें…"</string> <string name="menu_rename" msgid="1883113442688817554">"नाम बदलें"</string> <string name="menu_inspect" msgid="7279855349299446224">"जानकारी पाएं"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"छिपी हुई फ़ाइलें दिखाएं"</string> diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml index e6cfbf934..f9536bc31 100644 --- a/res/values-hr/strings.xml +++ b/res/values-hr/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Premjesti u…"</string> <string name="menu_compress" msgid="37539111904724188">"Sažmi"</string> <string name="menu_extract" msgid="8171946945982532262">"Izdvoji u…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Izdvoji sve…"</string> <string name="menu_rename" msgid="1883113442688817554">"Promijeni naziv"</string> <string name="menu_inspect" msgid="7279855349299446224">"Informacije"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Prikaži skrivene datoteke"</string> diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml index 9d7a2a675..8c40453d5 100644 --- a/res/values-hu/strings.xml +++ b/res/values-hu/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Áthelyezés…"</string> <string name="menu_compress" msgid="37539111904724188">"Tömörítés"</string> <string name="menu_extract" msgid="8171946945982532262">"Kicsomagolás ide…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Összes kibontása"</string> <string name="menu_rename" msgid="1883113442688817554">"Átnevezés"</string> <string name="menu_inspect" msgid="7279855349299446224">"Információ megjelenítése"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Rejtett fájlok megjelenítése"</string> diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml index fb55c8bee..e848e0429 100644 --- a/res/values-hy/strings.xml +++ b/res/values-hy/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Տեղափոխել…"</string> <string name="menu_compress" msgid="37539111904724188">"Սեղմել"</string> <string name="menu_extract" msgid="8171946945982532262">"Արտահանել…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Դուրս բերել բոլորը…"</string> <string name="menu_rename" msgid="1883113442688817554">"Վերանվանել"</string> <string name="menu_inspect" msgid="7279855349299446224">"Տեղեկություններ"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Ցուցադրել թաքցված ֆայլերը"</string> diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index f89f539c3..5d79af348 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Pindahkan ke..."</string> <string name="menu_compress" msgid="37539111904724188">"Kompresi"</string> <string name="menu_extract" msgid="8171946945982532262">"Ekstrak ke…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Ekstrak semua…"</string> <string name="menu_rename" msgid="1883113442688817554">"Ganti nama"</string> <string name="menu_inspect" msgid="7279855349299446224">"Dapatkan info"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Tampilkan file tersembunyi"</string> diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml index 676c483d4..1601f65a5 100644 --- a/res/values-is/strings.xml +++ b/res/values-is/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Færa í…"</string> <string name="menu_compress" msgid="37539111904724188">"Þjappa"</string> <string name="menu_extract" msgid="8171946945982532262">"Flytja út í…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Draga allt út …"</string> <string name="menu_rename" msgid="1883113442688817554">"Endurnefna"</string> <string name="menu_inspect" msgid="7279855349299446224">"Sækja upplýsingar"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Sýna faldar skrár"</string> diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 905815c87..f83c11d46 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Sposta in…"</string> <string name="menu_compress" msgid="37539111904724188">"Comprimi"</string> <string name="menu_extract" msgid="8171946945982532262">"Estrai in…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Estrai tutto…"</string> <string name="menu_rename" msgid="1883113442688817554">"Rinomina"</string> <string name="menu_inspect" msgid="7279855349299446224">"Informazioni"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Mostra file nascosti"</string> diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml index 822177a1e..df5d6de4c 100644 --- a/res/values-iw/strings.xml +++ b/res/values-iw/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"העברה אל…"</string> <string name="menu_compress" msgid="37539111904724188">"דחיסה"</string> <string name="menu_extract" msgid="8171946945982532262">"חילוץ לתיקייה…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"חילוץ הכול…"</string> <string name="menu_rename" msgid="1883113442688817554">"שינוי שם"</string> <string name="menu_inspect" msgid="7279855349299446224">"מידע על המסמך"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"הצגת קבצים מוסתרים"</string> diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index 35685ca9a..e545ab1fa 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"移動…"</string> <string name="menu_compress" msgid="37539111904724188">"圧縮"</string> <string name="menu_extract" msgid="8171946945982532262">"次の場所に解凍…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"すべて抽出…"</string> <string name="menu_rename" msgid="1883113442688817554">"名前を変更"</string> <string name="menu_inspect" msgid="7279855349299446224">"詳細情報"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"非表示のファイルを表示"</string> diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml index 1a698668f..77c7cb2b1 100644 --- a/res/values-ka/strings.xml +++ b/res/values-ka/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"გადაადგილება..."</string> <string name="menu_compress" msgid="37539111904724188">"შეკუმშვა"</string> <string name="menu_extract" msgid="8171946945982532262">"ამოღება…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"ყველას ამოღება…"</string> <string name="menu_rename" msgid="1883113442688817554">"გადარქმევა"</string> <string name="menu_inspect" msgid="7279855349299446224">"ინფორმაციის მიღება"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"გამოჩნდეს დამალული ფაილები"</string> diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml index 7d1f402e1..9bc4c9a51 100644 --- a/res/values-kk/strings.xml +++ b/res/values-kk/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Тасымалдау…"</string> <string name="menu_compress" msgid="37539111904724188">"Сығу"</string> <string name="menu_extract" msgid="8171946945982532262">"Алынуда…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Барлығын шығарып алу…"</string> <string name="menu_rename" msgid="1883113442688817554">"Атын өзгерту"</string> <string name="menu_inspect" msgid="7279855349299446224">"Ақпарат алу"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Жасырын файлдарды көрсету"</string> diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml index 365efd1fe..87ac1cf9d 100644 --- a/res/values-km/strings.xml +++ b/res/values-km/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"ផ្លាស់ទីទៅ…"</string> <string name="menu_compress" msgid="37539111904724188">"បង្ហាប់"</string> <string name="menu_extract" msgid="8171946945982532262">"ស្រង់ទៅ…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"ស្រង់ចេញទាំងអស់…"</string> <string name="menu_rename" msgid="1883113442688817554">"ប្ដូរឈ្មោះ"</string> <string name="menu_inspect" msgid="7279855349299446224">"ទទួលព័ត៌មាន"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"បង្ហាញឯកសារដែលបានលាក់"</string> diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index 1cf89f41f..bc89a9f08 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"ಇದಕ್ಕೆ ಸರಿಸಿ…"</string> <string name="menu_compress" msgid="37539111904724188">"ಕುಗ್ಗಿಸಿ"</string> <string name="menu_extract" msgid="8171946945982532262">"ಇದಕ್ಕೆ ಬೇರ್ಪಡಿಸಲಾಗಿದೆ…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"ಎಲ್ಲವನ್ನೂ ಎಕ್ಸ್ಟ್ರ್ಯಾಕ್ಟ್ ಮಾಡಿ…"</string> <string name="menu_rename" msgid="1883113442688817554">"ಮರುಹೆಸರಿಸು"</string> <string name="menu_inspect" msgid="7279855349299446224">"ಮಾಹಿತಿಯನ್ನು ಪಡೆಯಿರಿ"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"ಮರೆಮಾಡಿದ ಫೈಲ್ಗಳನ್ನು ತೋರಿಸಿ"</string> @@ -221,19 +222,19 @@ <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="8338069763240613258">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ಅಳಿಸುವುದೇ?"</string> - <string name="delete_foldername_confirmation_message" msgid="9084085260877704140">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ಫೋಲ್ಡರ್ ಮತ್ತು ಅದರ ವಿಷಯಗಳನ್ನು ಅಳಿಸುವುದೇ?"</string> + <string name="delete_filename_confirmation_message" msgid="8338069763240613258">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ಅಳಿಸಬೇಕೆ?"</string> + <string name="delete_foldername_confirmation_message" msgid="9084085260877704140">"\"<xliff:g id="NAME">%1$s</xliff:g>\" ಫೋಲ್ಡರ್ ಮತ್ತು ಅದರ ವಿಷಯಗಳನ್ನು ಅಳಿಸಬೇಕೆ?"</string> <plurals name="delete_files_confirmation_message" formatted="false" msgid="4866664063250034142"> - <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="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="1028946402799686388"> - <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="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="7285090426511028179"> - <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="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="images_shortcut_label" msgid="2545168016070493574">"ಚಿತ್ರಗಳು"</string> <string name="archive_loading_failed" msgid="7243436722828766996">"ಬ್ರೌಸಿಂಗ್ಗಾಗಿ ಆರ್ಕೈವ್ ಅನ್ನು ತೆರೆಯಲು ಸಾಧ್ಯವಿಲ್ಲ. ಫೈಲ್ ದೋಷಪೂರಿತವಾಗಿದೆ ಅಥವಾ ಬೆಂಬಲಿಸದ ಸ್ವರೂಪದಲ್ಲಿರಬಹುದು."</string> diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index bb313e892..374b95d93 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"다음으로 이동:"</string> <string name="menu_compress" msgid="37539111904724188">"압축"</string> <string name="menu_extract" msgid="8171946945982532262">"다음 위치에 추출..."</string> + <string name="menu_extract_all" msgid="7335680068521252718">"모두 추출…"</string> <string name="menu_rename" msgid="1883113442688817554">"이름 바꾸기"</string> <string name="menu_inspect" msgid="7279855349299446224">"정보 확인"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"숨겨진 파일 표시"</string> diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml index 83ac3fead..49ea76f6c 100644 --- a/res/values-ky/strings.xml +++ b/res/values-ky/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Төмөнкүгө жылдыруу..."</string> <string name="menu_compress" msgid="37539111904724188">"Кысуу"</string> <string name="menu_extract" msgid="8171946945982532262">"Төмөнкүгө чыгаруу…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Баарын чыгаруу…"</string> <string name="menu_rename" msgid="1883113442688817554">"Аталышын өзгөртүү"</string> <string name="menu_inspect" msgid="7279855349299446224">"Маалымат алуу"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Жашырылган файлдар көрүнсүн"</string> diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml index 8794da0e8..32f741faa 100644 --- a/res/values-lo/strings.xml +++ b/res/values-lo/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"ຍ້າຍໄປໃສ່..."</string> <string name="menu_compress" msgid="37539111904724188">"ບີບອັດ"</string> <string name="menu_extract" msgid="8171946945982532262">"ແຕກໄຟລ໌ໄປ…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"ດຶງຂໍ້ມູນຈາກເອກະສານທັງໝົດ…"</string> <string name="menu_rename" msgid="1883113442688817554">"ປ່ຽນຊື່"</string> <string name="menu_inspect" msgid="7279855349299446224">"ຂໍຂໍ້ມູນ"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"ສະແດງໄຟລ໌ທີ່ເຊື່ອງໄວ້"</string> diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml index 88420bf91..9c3142dc4 100644 --- a/res/values-lt/strings.xml +++ b/res/values-lt/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Perkelti į…"</string> <string name="menu_compress" msgid="37539111904724188">"Suglaudinti"</string> <string name="menu_extract" msgid="8171946945982532262">"Išskleisti į..."</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Išskleisti viską…"</string> <string name="menu_rename" msgid="1883113442688817554">"Pervardyti"</string> <string name="menu_inspect" msgid="7279855349299446224">"Gauti informacijos"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Rodyti paslėptus failus"</string> diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml index 384395b89..8afe403b6 100644 --- a/res/values-lv/strings.xml +++ b/res/values-lv/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Pārvietot uz…"</string> <string name="menu_compress" msgid="37539111904724188">"Saspiest"</string> <string name="menu_extract" msgid="8171946945982532262">"Izvilkt..."</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Izgūt visu…"</string> <string name="menu_rename" msgid="1883113442688817554">"Pārdēvēt"</string> <string name="menu_inspect" msgid="7279855349299446224">"Iegūt informāciju"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Rādīt paslēptos failus"</string> diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml index 92d58f55a..94f840c94 100644 --- a/res/values-mk/strings.xml +++ b/res/values-mk/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Премести во…"</string> <string name="menu_compress" msgid="37539111904724188">"Компримирај"</string> <string name="menu_extract" msgid="8171946945982532262">"Отпакувај во…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Извлечи сѐ…"</string> <string name="menu_rename" msgid="1883113442688817554">"Преименувај"</string> <string name="menu_inspect" msgid="7279855349299446224">"Добијте информации"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Прикажи скриени датотеки"</string> diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml index 5de00993a..cb43ab59a 100644 --- a/res/values-ml/strings.xml +++ b/res/values-ml/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"ഇതിലേക്ക് നീക്കുക..."</string> <string name="menu_compress" msgid="37539111904724188">"കംപ്രസ് ചെയ്യുക"</string> <string name="menu_extract" msgid="8171946945982532262">"എക്സ്ട്രാക്റ്റുചെയ്യുക…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"എക്സ്ട്രാക്റ്റ് ചെയ്യൂ…"</string> <string name="menu_rename" msgid="1883113442688817554">"പേര് മാറ്റുക"</string> <string name="menu_inspect" msgid="7279855349299446224">"വിവരങ്ങൾ നേടുക"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"മറച്ചിരിക്കുന്ന ഫയൽ കാണിക്കൂ"</string> diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml index cfbd53e1e..3172a07f4 100644 --- a/res/values-mn/strings.xml +++ b/res/values-mn/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Дараахад зөөх"</string> <string name="menu_compress" msgid="37539111904724188">"Шахах"</string> <string name="menu_extract" msgid="8171946945982532262">"Дараахад задлах…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Бүгдийг задлах…"</string> <string name="menu_rename" msgid="1883113442688817554">"Нэр өөрчлөх"</string> <string name="menu_inspect" msgid="7279855349299446224">"Мэдээлэл авах"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Нуусан файлудыг харуул"</string> diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml index a98a5c279..4229508e2 100644 --- a/res/values-mr/strings.xml +++ b/res/values-mr/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"यामध्ये हलवा…"</string> <string name="menu_compress" msgid="37539111904724188">"कॉंप्रेस करा"</string> <string name="menu_extract" msgid="8171946945982532262">"मध्ये काढा..."</string> + <string name="menu_extract_all" msgid="7335680068521252718">"सर्व काढा…"</string> <string name="menu_rename" msgid="1883113442688817554">"नाव बदला"</string> <string name="menu_inspect" msgid="7279855349299446224">"माहिती मिळवा"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"लपवलेल्या फाइल दाखवा"</string> diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml index f72d99f10..7394358ca 100644 --- a/res/values-ms/strings.xml +++ b/res/values-ms/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Alihkan ke…"</string> <string name="menu_compress" msgid="37539111904724188">"Mampatkan"</string> <string name="menu_extract" msgid="8171946945982532262">"Ekstrak ke…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Ekstrak semua…"</string> <string name="menu_rename" msgid="1883113442688817554">"Namakan semula"</string> <string name="menu_inspect" msgid="7279855349299446224">"Dapatkan maklumat"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Tunjukkan fail tersembunyi"</string> diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml index e9c9f40ba..49d1278e6 100644 --- a/res/values-my/strings.xml +++ b/res/values-my/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"အောက်ပါနေရာသို့ ရွှေ့ပါ…"</string> <string name="menu_compress" msgid="37539111904724188">"ချုံ့ရန်"</string> <string name="menu_extract" msgid="8171946945982532262">"ရွှေးချယ်ထည့်သွင်းရန်…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"အားလုံးထုတ်ယူရန်…"</string> <string name="menu_rename" msgid="1883113442688817554">"အမည်ပြောင်းပါ"</string> <string name="menu_inspect" msgid="7279855349299446224">"အချက်အလက် ရယူရန်"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"ဝှက်ထားသည့်ဖိုင်များ ပြရန်"</string> diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index 4fb2e0e36..4090122dd 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Flytt til"</string> <string name="menu_compress" msgid="37539111904724188">"Komprimer"</string> <string name="menu_extract" msgid="8171946945982532262">"Pakk ut til …"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Pakk ut alt …"</string> <string name="menu_rename" msgid="1883113442688817554">"Gi nytt navn"</string> <string name="menu_inspect" msgid="7279855349299446224">"Hent informasjon"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Vis skjulte filer"</string> diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml index 550ae21e0..1e8dc9b36 100644 --- a/res/values-ne/strings.xml +++ b/res/values-ne/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"निम्नमा सार्नुहोस्…"</string> <string name="menu_compress" msgid="37539111904724188">"कम्प्रेस गर्नुहोस्"</string> <string name="menu_extract" msgid="8171946945982532262">"यसमा एकस्ट्र्याक्ट गर्नुहोस्…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"सबै एक्स्ट्रयाक्ट गर्नुहोस्…"</string> <string name="menu_rename" msgid="1883113442688817554">"पुनःनामाकरण गर्नुहोस्"</string> <string name="menu_inspect" msgid="7279855349299446224">"जानकारी प्राप्त गर्नुहोस्"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"लुकाइएका फाइलहरू देखाउनुहोस्"</string> diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index fc266ef30..fe37feb5b 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Verplaatsen naar…"</string> <string name="menu_compress" msgid="37539111904724188">"Comprimeren"</string> <string name="menu_extract" msgid="8171946945982532262">"Uitpakken naar…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Alles uitpakken…"</string> <string name="menu_rename" msgid="1883113442688817554">"Naam wijzigen"</string> <string name="menu_inspect" msgid="7279855349299446224">"Informatie bekijken"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Verborgen bestanden tonen"</string> diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml index 4d3d59831..645c74bf8 100644 --- a/res/values-or/strings.xml +++ b/res/values-or/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"ଏଠାକୁ ନିଅନ୍ତୁ…"</string> <string name="menu_compress" msgid="37539111904724188">"କମ୍ପ୍ରେସ୍ କରନ୍ତୁ"</string> <string name="menu_extract" msgid="8171946945982532262">"ଏଠାକୁ ଏକ୍ସଟ୍ରାକ୍ଟ କରନ୍ତୁ…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"ସବୁ ଏକ୍ସଟ୍ରାକ୍ଟ କରନ୍ତୁ…"</string> <string name="menu_rename" msgid="1883113442688817554">"ରିନେମ କରନ୍ତୁ"</string> <string name="menu_inspect" msgid="7279855349299446224">"ସୂଚନା ପାଆନ୍ତୁ"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"ଲୁକ୍କାୟିତ ଫାଇଲ ଦେଖାନ୍ତୁ"</string> diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml index f1390ce6e..4169a9e5c 100644 --- a/res/values-pa/strings.xml +++ b/res/values-pa/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"ਇਸ ਵਿੱਚ ਲਿਜਾਓ…"</string> <string name="menu_compress" msgid="37539111904724188">"ਨਪੀੜੋ"</string> <string name="menu_extract" msgid="8171946945982532262">"ਇਸ ਵਿੱਚ ਐਕਸਟ੍ਰੈਕਟ ਕਰੋ…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"ਸਭ ਐਕਸਟਰੈਕਟ ਕਰੋ…"</string> <string name="menu_rename" msgid="1883113442688817554">"ਨਾਮ ਬਦਲੋ"</string> <string name="menu_inspect" msgid="7279855349299446224">"ਜਾਣਕਾਰੀ ਪ੍ਰਾਪਤ ਕਰੋ"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"ਲੁਕਾਈਆਂ ਗਈਆਂ ਫ਼ਾਈਲਾਂ ਦਿਖਾਓ"</string> diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index 4a76fafb5..5c1360039 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Przenieś do…"</string> <string name="menu_compress" msgid="37539111904724188">"Skompresuj"</string> <string name="menu_extract" msgid="8171946945982532262">"Rozpakuj do…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Wyodrębnij wszystko…"</string> <string name="menu_rename" msgid="1883113442688817554">"Zmień nazwę"</string> <string name="menu_inspect" msgid="7279855349299446224">"Zobacz informacje"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Pokaż ukryte pliki"</string> diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml index 8dd6249e8..3e492209d 100644 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Mover para…"</string> <string name="menu_compress" msgid="37539111904724188">"Compactar"</string> <string name="menu_extract" msgid="8171946945982532262">"Extrair para…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Extrair tudo…"</string> <string name="menu_rename" msgid="1883113442688817554">"Renomear"</string> <string name="menu_inspect" msgid="7279855349299446224">"Ver informações"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Mostrar arquivos ocultos"</string> diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index 03a36e95c..972ef954d 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Mover para..."</string> <string name="menu_compress" msgid="37539111904724188">"Comprimir"</string> <string name="menu_extract" msgid="8171946945982532262">"Extrair para…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Extrair tudo…"</string> <string name="menu_rename" msgid="1883113442688817554">"Mudar o nome"</string> <string name="menu_inspect" msgid="7279855349299446224">"Obter informações"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Mostrar ficheiros ocultos"</string> diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index 8dd6249e8..3e492209d 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Mover para…"</string> <string name="menu_compress" msgid="37539111904724188">"Compactar"</string> <string name="menu_extract" msgid="8171946945982532262">"Extrair para…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Extrair tudo…"</string> <string name="menu_rename" msgid="1883113442688817554">"Renomear"</string> <string name="menu_inspect" msgid="7279855349299446224">"Ver informações"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Mostrar arquivos ocultos"</string> diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index b3bb84146..d0a89f345 100644 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Mută în…"</string> <string name="menu_compress" msgid="37539111904724188">"Comprimă"</string> <string name="menu_extract" msgid="8171946945982532262">"Extrage în…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Extrage tot…"</string> <string name="menu_rename" msgid="1883113442688817554">"Redenumește"</string> <string name="menu_inspect" msgid="7279855349299446224">"Vezi informațiile"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Afișează fișierele ascunse"</string> diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index cedb653d5..f345cef8d 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Переместить в..."</string> <string name="menu_compress" msgid="37539111904724188">"Сжать"</string> <string name="menu_extract" msgid="8171946945982532262">"Извлечь"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Извлечь все…"</string> <string name="menu_rename" msgid="1883113442688817554">"Переименовать"</string> <string name="menu_inspect" msgid="7279855349299446224">"Сведения о файле"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Показывать скрытые файлы"</string> diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml index 3c2b2429e..48d8f5f75 100644 --- a/res/values-si/strings.xml +++ b/res/values-si/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"වෙත ගෙනයන්න..."</string> <string name="menu_compress" msgid="37539111904724188">"සම්පීඩනය කරන්න"</string> <string name="menu_extract" msgid="8171946945982532262">"උපුටා ගන්න…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"සියල්ල උපුටා ගන්න…"</string> <string name="menu_rename" msgid="1883113442688817554">"යළි නම් කරන්න"</string> <string name="menu_inspect" msgid="7279855349299446224">"තොරතුරු ලබා ගන්න"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"සැඟවුණු ගොනු පෙන්වන්න"</string> diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index 8b5e87fbb..db6a892e8 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Presunúť do…"</string> <string name="menu_compress" msgid="37539111904724188">"Komprimovať"</string> <string name="menu_extract" msgid="8171946945982532262">"Rozbaliť do…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Extrahovať všetko…"</string> <string name="menu_rename" msgid="1883113442688817554">"Premenovať"</string> <string name="menu_inspect" msgid="7279855349299446224">"Zobraziť informácie"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Zobraziť skryté súbory"</string> diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml index e2faad032..d14c32517 100644 --- a/res/values-sl/strings.xml +++ b/res/values-sl/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Premakni v ..."</string> <string name="menu_compress" msgid="37539111904724188">"Stisni"</string> <string name="menu_extract" msgid="8171946945982532262">"Razširi v …"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Razširi vse …"</string> <string name="menu_rename" msgid="1883113442688817554">"Preimenuj"</string> <string name="menu_inspect" msgid="7279855349299446224">"Prikaži informacije"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Prikaži skrite datoteke"</string> diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml index 5de2e9d3b..7f2ddfdd7 100644 --- a/res/values-sq/strings.xml +++ b/res/values-sq/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Zhvendos te..."</string> <string name="menu_compress" msgid="37539111904724188">"Ngjish"</string> <string name="menu_extract" msgid="8171946945982532262">"Nxirre te…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Nxirri të gjitha…"</string> <string name="menu_rename" msgid="1883113442688817554">"Riemërto"</string> <string name="menu_inspect" msgid="7279855349299446224">"Merr informacione"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Shfaq skedarët e fshehur"</string> diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index 2dcc91983..343e77050 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Премести у…"</string> <string name="menu_compress" msgid="37539111904724188">"Компримуј"</string> <string name="menu_extract" msgid="8171946945982532262">"Издвој у…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Издвоји све…"</string> <string name="menu_rename" msgid="1883113442688817554">"Преименуј"</string> <string name="menu_inspect" msgid="7279855349299446224">"Прикажи информације"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Приказуј скривене датотеке"</string> diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index 281612761..1c6be4153 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Flytta till ..."</string> <string name="menu_compress" msgid="37539111904724188">"Komprimera"</string> <string name="menu_extract" msgid="8171946945982532262">"Extrahera till …"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Extrahera alla …"</string> <string name="menu_rename" msgid="1883113442688817554">"Byt namn"</string> <string name="menu_inspect" msgid="7279855349299446224">"Hämta information"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Visa dolda filer"</string> diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml index c09e09ff5..e030a1029 100644 --- a/res/values-sw/strings.xml +++ b/res/values-sw/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Hamishia kwenye..."</string> <string name="menu_compress" msgid="37539111904724188">"Bana"</string> <string name="menu_extract" msgid="8171946945982532262">"Weka kwenye…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Dondoa zote…"</string> <string name="menu_rename" msgid="1883113442688817554">"Badilisha jina"</string> <string name="menu_inspect" msgid="7279855349299446224">"Pata maelezo zaidi"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Onyesha faili zilizofichwa"</string> diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml index 1e8b754d7..b8392fe0b 100644 --- a/res/values-ta/strings.xml +++ b/res/values-ta/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"இங்கு நகர்த்து…"</string> <string name="menu_compress" msgid="37539111904724188">"அளவைக் குறை"</string> <string name="menu_extract" msgid="8171946945982532262">"இங்கு பிரி…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"அனைத்தையும் பிரித்தெடு…"</string> <string name="menu_rename" msgid="1883113442688817554">"பெயர் மாற்று"</string> <string name="menu_inspect" msgid="7279855349299446224">"தகவலைப் பெறு"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"மறைக்கப்பட்ட ஃபைல்களைக் காட்டு"</string> diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml index aff5a7337..2c4d3d3d0 100644 --- a/res/values-te/strings.xml +++ b/res/values-te/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"ఇక్కడికి తరలించు..."</string> <string name="menu_compress" msgid="37539111904724188">"కుదించు"</string> <string name="menu_extract" msgid="8171946945982532262">"దీనిలోకి సంగ్రహించు…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"అన్నీ ఎక్స్ట్రాక్ట్ చేయండి…"</string> <string name="menu_rename" msgid="1883113442688817554">"పేరు మార్చు"</string> <string name="menu_inspect" msgid="7279855349299446224">"సమాచారాన్ని పొందండి"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"దాచబడిన ఫైళ్లను చూపించు"</string> diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml index b33809db7..7c917a2b0 100644 --- a/res/values-th/strings.xml +++ b/res/values-th/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"ย้ายไปที่…"</string> <string name="menu_compress" msgid="37539111904724188">"บีบอัด"</string> <string name="menu_extract" msgid="8171946945982532262">"แตกข้อมูลไปยัง…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"แตกเอกสารทั้งหมด…"</string> <string name="menu_rename" msgid="1883113442688817554">"เปลี่ยนชื่อ"</string> <string name="menu_inspect" msgid="7279855349299446224">"รับข้อมูล"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"แสดงไฟล์ที่ซ่อนไว้"</string> diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml index dc7719470..f4c397dda 100644 --- a/res/values-tl/strings.xml +++ b/res/values-tl/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Ilipat sa…"</string> <string name="menu_compress" msgid="37539111904724188">"I-compress"</string> <string name="menu_extract" msgid="8171946945982532262">"I-extract sa…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"I-extract lahat…"</string> <string name="menu_rename" msgid="1883113442688817554">"Palitan ang pangalan"</string> <string name="menu_inspect" msgid="7279855349299446224">"Kumuha ng impormasyon"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Ipakita ang hidden files"</string> diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index f8bbc893b..ea91bfdee 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Klasöre taşı..."</string> <string name="menu_compress" msgid="37539111904724188">"Sıkıştır"</string> <string name="menu_extract" msgid="8171946945982532262">"Şuraya çıkar:"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Tümünü çıkar…"</string> <string name="menu_rename" msgid="1883113442688817554">"Yeniden adlandır"</string> <string name="menu_inspect" msgid="7279855349299446224">"Bilgi al"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Gizli dosyaları göster"</string> diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index 170e4fc11..f36363d34 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Перемістити в…"</string> <string name="menu_compress" msgid="37539111904724188">"Стиснути"</string> <string name="menu_extract" msgid="8171946945982532262">"Розпакувати…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Розархівувати все…"</string> <string name="menu_rename" msgid="1883113442688817554">"Перейменувати"</string> <string name="menu_inspect" msgid="7279855349299446224">"Переглянути інформацію"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Показувати приховані файли"</string> diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml index b0ee0558b..6ef8b2787 100644 --- a/res/values-ur/strings.xml +++ b/res/values-ur/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"اس میں منتقل کریں…"</string> <string name="menu_compress" msgid="37539111904724188">"کمپریس کریں"</string> <string name="menu_extract" msgid="8171946945982532262">"اس میں کھولیں۔۔۔"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"سبھی نکالیں…"</string> <string name="menu_rename" msgid="1883113442688817554">"نام تبدیل کریں"</string> <string name="menu_inspect" msgid="7279855349299446224">"معلومات حاصل کریں"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"پوشیدہ فائلز دکھائیں"</string> diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml index 02bdfb3a2..703119c70 100644 --- a/res/values-uz/strings.xml +++ b/res/values-uz/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Boshqa joyga olish…"</string> <string name="menu_compress" msgid="37539111904724188">"Arxivlash"</string> <string name="menu_extract" msgid="8171946945982532262">"Arxivdan chiqarish"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Barchasini ajratish…"</string> <string name="menu_rename" msgid="1883113442688817554">"Qayta nomlash"</string> <string name="menu_inspect" msgid="7279855349299446224">"Axborot olish"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Yashirin fayllarni chiqarish"</string> diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index 7f922d0fc..f063ad569 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Chuyển tới..."</string> <string name="menu_compress" msgid="37539111904724188">"Nén"</string> <string name="menu_extract" msgid="8171946945982532262">"Trích xuất sang…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Trích xuất tất cả…"</string> <string name="menu_rename" msgid="1883113442688817554">"Đổi tên"</string> <string name="menu_inspect" msgid="7279855349299446224">"Xem thông tin"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Hiện các tệp bị ẩn"</string> diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index 992c57151..402cb66f8 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"移至…"</string> <string name="menu_compress" msgid="37539111904724188">"压缩"</string> <string name="menu_extract" msgid="8171946945982532262">"解压到…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"提取全部…"</string> <string name="menu_rename" msgid="1883113442688817554">"重命名"</string> <string name="menu_inspect" msgid="7279855349299446224">"获取信息"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"显示隐藏的文件"</string> diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml index eec2956d0..d69e372fd 100644 --- a/res/values-zh-rHK/strings.xml +++ b/res/values-zh-rHK/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"移至…"</string> <string name="menu_compress" msgid="37539111904724188">"壓縮"</string> <string name="menu_extract" msgid="8171946945982532262">"壓縮至…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"擷取全部…"</string> <string name="menu_rename" msgid="1883113442688817554">"重新命名"</string> <string name="menu_inspect" msgid="7279855349299446224">"顯示資訊"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"顯示已隱藏的檔案"</string> diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 16d0a7305..28318cc89 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"移至…"</string> <string name="menu_compress" msgid="37539111904724188">"壓縮"</string> <string name="menu_extract" msgid="8171946945982532262">"解壓縮到…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"全部解壓縮…"</string> <string name="menu_rename" msgid="1883113442688817554">"重新命名"</string> <string name="menu_inspect" msgid="7279855349299446224">"取得資訊"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"顯示隱藏的檔案"</string> diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml index 83a654282..1b85d7f00 100644 --- a/res/values-zu/strings.xml +++ b/res/values-zu/strings.xml @@ -45,6 +45,7 @@ <string name="menu_move" msgid="2310760789561129882">"Hambisa ku…"</string> <string name="menu_compress" msgid="37539111904724188">"Cindezela"</string> <string name="menu_extract" msgid="8171946945982532262">"Khiphela ku…"</string> + <string name="menu_extract_all" msgid="7335680068521252718">"Khipha konke…"</string> <string name="menu_rename" msgid="1883113442688817554">"Qamba kabusha"</string> <string name="menu_inspect" msgid="7279855349299446224">"Thola ulwazi"</string> <string name="menu_show_hidden_files" msgid="5140676344684492769">"Bonisa amafayela afihliwe"</string> diff --git a/res/values/strings.xml b/res/values/strings.xml index 89e40ac4c..5f78c93e7 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -78,6 +78,8 @@ <string name="menu_compress">Compress</string> <!-- Menu item title that extracts the selected documents [CHAR LIMIT=28] --> <string name="menu_extract">Extract to\u2026</string> + <!-- Menu item title that extracts all the documents in the current directory [CHAR LIMIT=28] --> + <string name="menu_extract_all">Extract all\u2026</string> <!-- Menu item that renames the selected document [CHAR LIMIT=28] --> <string name="menu_rename">Rename</string> <!-- Menu item that displays properties about the selected document [CHAR LIMIT=28] --> diff --git a/src/com/android/documentsui/AbstractActionHandler.java b/src/com/android/documentsui/AbstractActionHandler.java index da599d47f..8e1a51301 100644 --- a/src/com/android/documentsui/AbstractActionHandler.java +++ b/src/com/android/documentsui/AbstractActionHandler.java @@ -20,6 +20,7 @@ import static com.android.documentsui.base.DocumentInfo.getCursorInt; import static com.android.documentsui.base.DocumentInfo.getCursorString; import static com.android.documentsui.base.SharedMinimal.DEBUG; import static com.android.documentsui.flags.Flags.desktopFileHandling; +import static com.android.documentsui.flags.Flags.useSearchV2; import android.app.PendingIntent; import android.content.ActivityNotFoundException; @@ -38,6 +39,7 @@ import android.util.Log; import android.util.Pair; import android.view.DragEvent; +import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import androidx.fragment.app.FragmentActivity; import androidx.loader.app.LoaderManager.LoaderCallbacks; @@ -63,6 +65,9 @@ import com.android.documentsui.dirlist.AnimationView.AnimationType; import com.android.documentsui.dirlist.FocusHandler; import com.android.documentsui.files.LauncherActivity; import com.android.documentsui.files.QuickViewIntentBuilder; +import com.android.documentsui.loaders.FolderLoader; +import com.android.documentsui.loaders.QueryOptions; +import com.android.documentsui.loaders.SearchLoader; import com.android.documentsui.queries.SearchViewManager; import com.android.documentsui.roots.GetRootDocumentTask; import com.android.documentsui.roots.LoadFirstRootTask; @@ -73,10 +78,14 @@ import com.android.documentsui.sorting.SortListFragment; import com.android.documentsui.ui.DialogController; import com.android.documentsui.ui.Snackbars; +import java.time.Duration; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Objects; import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; import java.util.function.Consumer; @@ -894,16 +903,28 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA private final class LoaderBindings implements LoaderCallbacks<DirectoryResult> { + private ExecutorService mExecutorService = null; + private static final long MAX_SEARCH_TIME_MS = 3000; + private static final int MAX_RESULTS = 500; + + @NonNull @Override public Loader<DirectoryResult> onCreateLoader(int id, Bundle args) { - Context context = mActivity; - // If document stack is not initialized, i.e. if the root is null, create "Recents" root // with the selected user. if (!mState.stack.isInitialized()) { mState.stack.changeRoot(mActivity.getCurrentRoot()); } + if (useSearchV2()) { + return onCreateLoaderV2(id, args); + } + return onCreateLoaderV1(id, args); + } + + private Loader<DirectoryResult> onCreateLoaderV1(int id, Bundle args) { + Context context = mActivity; + if (mState.stack.isRecents()) { final LockingContentObserver observer = new LockingContentObserver( mContentLock, AbstractActionHandler.this::loadDocumentsForCurrentStack); @@ -980,6 +1001,69 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA } } + private Loader<DirectoryResult> onCreateLoaderV2(int id, Bundle args) { + if (mExecutorService == null) { + // TODO(b:388130971): Fine tune the size of the thread pool. + mExecutorService = Executors.newFixedThreadPool( + GlobalSearchLoader.MAX_OUTSTANDING_TASK); + } + DocumentStack stack = mState.stack; + RootInfo root = stack.getRoot(); + List<UserId> userIdList = DocumentsApplication.getUserIdManager(mActivity).getUserIds(); + + Duration lastModifiedDelta = stack.isRecents() + ? Duration.ofMillis(RecentsLoader.REJECT_OLDER_THAN) + : null; + int maxResults = (root == null || root.isRecents()) + ? RecentsLoader.MAX_DOCS_FROM_ROOT : MAX_RESULTS; + QueryOptions options = new QueryOptions( + maxResults, lastModifiedDelta, Duration.ofMillis(MAX_SEARCH_TIME_MS), + mState.showHiddenFiles, mState.acceptMimes); + + if (stack.isRecents() || mSearchMgr.isSearching()) { + Log.d(TAG, "Creating search loader V2"); + // For search and recent we create an observer that restart the loader every time + // one of the searched content providers reports a change. + final LockingContentObserver observer = new LockingContentObserver( + mContentLock, AbstractActionHandler.this::loadDocumentsForCurrentStack); + Collection<RootInfo> rootList = new ArrayList<>(); + if (root == null || root.isRecents()) { + // TODO(b:381346575): Pass roots based on user selection. + rootList.addAll(mProviders.getMatchingRootsBlocking(mState).stream().filter( + r -> r.supportsSearch() && r.authority != null + && r.rootId != null).toList()); + } else { + rootList.add(root); + } + return new SearchLoader( + mActivity, + userIdList, + mInjector.fileTypeLookup, + observer, + rootList, + mSearchMgr.getCurrentSearch(), + options, + mState.sortModel, + mExecutorService + ); + } + Log.d(TAG, "Creating folder loader V2"); + // For folder scan we pass the content lock to the loader so that it can register + // an a callback to its internal method that forces a reload of the folder, every + // time the content provider reports a change. + return new FolderLoader( + mActivity, + userIdList, + mInjector.fileTypeLookup, + mContentLock, + root, + stack.peek(), + options, + mState.sortModel + ); + + } + @Override public void onLoadFinished(Loader<DirectoryResult> loader, DirectoryResult result) { if (DEBUG) { diff --git a/src/com/android/documentsui/MenuManager.java b/src/com/android/documentsui/MenuManager.java index 2d1e2a59a..126a777da 100644 --- a/src/com/android/documentsui/MenuManager.java +++ b/src/com/android/documentsui/MenuManager.java @@ -27,11 +27,13 @@ import android.view.View; import androidx.annotation.VisibleForTesting; import androidx.fragment.app.Fragment; +import com.android.documentsui.archives.ArchivesProvider; import com.android.documentsui.base.DocumentInfo; import com.android.documentsui.base.Menus; import com.android.documentsui.base.RootInfo; import com.android.documentsui.base.State; import com.android.documentsui.dirlist.DirectoryFragment; +import com.android.documentsui.flags.Flags; import com.android.documentsui.queries.SearchViewManager; import com.android.documentsui.sidebar.RootsFragment; @@ -91,6 +93,9 @@ public abstract class MenuManager { return; } updateCreateDir(mOptionMenu.findItem(R.id.option_menu_create_dir)); + if (Flags.zipNg()) { + updateExtractAll(mOptionMenu.findItem(R.id.option_menu_extract_all)); + } updateSettings(mOptionMenu.findItem(R.id.option_menu_settings)); updateSelectAll(mOptionMenu.findItem(R.id.option_menu_select_all)); updateNewWindow(mOptionMenu.findItem(R.id.option_menu_new_window)); @@ -229,10 +234,7 @@ public abstract class MenuManager { Menus.setEnabledAndVisible(inspect, selectionDetails.size() == 1); - final MenuItem compress = menu.findItem(R.id.dir_menu_compress); - if (compress != null) { - updateCompress(compress, selectionDetails); - } + updateCompress(menu.findItem(R.id.dir_menu_compress), selectionDetails); } /** @@ -397,6 +399,10 @@ public abstract class MenuManager { Menus.setEnabledAndVisible(launcher, false); } + protected void updateExtractAll(MenuItem it) { + Menus.setEnabledAndVisible(it, false); + } + protected abstract void updateSelectAll(MenuItem selectAll); protected abstract void updateSelectAll(MenuItem selectAll, SelectionDetails selectionDetails); protected abstract void updateDeselectAll( @@ -455,6 +461,12 @@ public abstract class MenuManager { return mActivity.isInRecents(); } + /** Is the current directory showing the contents of an archive? */ + public boolean isInArchive() { + final DocumentInfo dir = mActivity.getCurrentDirectory(); + return dir != null && ArchivesProvider.AUTHORITY.equals(dir.authority); + } + public boolean canCreateDirectory() { return mActivity.canCreateDirectory(); } diff --git a/src/com/android/documentsui/MultiRootDocumentsLoader.java b/src/com/android/documentsui/MultiRootDocumentsLoader.java index db78daa48..1213a6711 100644 --- a/src/com/android/documentsui/MultiRootDocumentsLoader.java +++ b/src/com/android/documentsui/MultiRootDocumentsLoader.java @@ -71,7 +71,7 @@ public abstract class MultiRootDocumentsLoader extends AsyncTaskLoader<Directory // previously returned cursors for filtering/sorting; this currently races // with the UI thread. - private static final int MAX_OUTSTANDING_TASK = 4; + public static final int MAX_OUTSTANDING_TASK = 4; private static final int MAX_OUTSTANDING_TASK_SVELTE = 2; /** diff --git a/src/com/android/documentsui/RecentsLoader.java b/src/com/android/documentsui/RecentsLoader.java index b3cfa0180..9a3e06fba 100644 --- a/src/com/android/documentsui/RecentsLoader.java +++ b/src/com/android/documentsui/RecentsLoader.java @@ -37,13 +37,13 @@ public class RecentsLoader extends MultiRootDocumentsLoader { private static final String TAG = "RecentsLoader"; /** Ignore documents older than this age. */ - private static final long REJECT_OLDER_THAN = 45 * DateUtils.DAY_IN_MILLIS; + public static final long REJECT_OLDER_THAN = 45 * DateUtils.DAY_IN_MILLIS; - /** MIME types that should always be excluded from recents. */ + /** MIME types that should always be excluded from the Recents view. */ private static final String[] REJECT_MIMES = new String[]{Document.MIME_TYPE_DIR}; /** Maximum documents from a single root. */ - private static final int MAX_DOCS_FROM_ROOT = 64; + public static final int MAX_DOCS_FROM_ROOT = 64; private final UserId mUserId; diff --git a/src/com/android/documentsui/base/Menus.java b/src/com/android/documentsui/base/Menus.java index eba240c83..6ceea3269 100644 --- a/src/com/android/documentsui/base/Menus.java +++ b/src/com/android/documentsui/base/Menus.java @@ -19,6 +19,8 @@ package com.android.documentsui.base; import android.view.Menu; import android.view.MenuItem; +import androidx.annotation.NonNull; + public final class Menus { private Menus() {} @@ -41,7 +43,7 @@ public final class Menus { } /** Set enabled/disabled state of a menuItem, and updates its visibility. */ - public static void setEnabledAndVisible(MenuItem item, boolean enabled) { + public static void setEnabledAndVisible(@NonNull MenuItem item, boolean enabled) { item.setEnabled(enabled); item.setVisible(enabled); } diff --git a/src/com/android/documentsui/dirlist/DirectoryFragment.java b/src/com/android/documentsui/dirlist/DirectoryFragment.java index 43fc91e3a..b4b08ce1b 100644 --- a/src/com/android/documentsui/dirlist/DirectoryFragment.java +++ b/src/com/android/documentsui/dirlist/DirectoryFragment.java @@ -968,7 +968,7 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On return true; // TODO: Implement extract (to the current directory). - } else if (id == R.id.action_menu_extract_to) { + } else if (id == R.id.action_menu_extract_to || id == R.id.option_menu_extract_all) { transferDocuments(selection, null, FileOperationService.OPERATION_EXTRACT); // TODO: Only finish selection mode if compress-to is not canceled. // Need to plum down into handling the way we do with deleteDocuments. @@ -1198,7 +1198,7 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On intent.putExtra(FileOperationService.EXTRA_OPERATION_TYPE, mode); // This just identifies the type of request...we'll check it - // when we reveive a response. + // when we receive a response. startActivityForResult(intent, REQUEST_COPY_DESTINATION); } diff --git a/src/com/android/documentsui/files/FilesActivity.java b/src/com/android/documentsui/files/FilesActivity.java index 1da0d8f2b..cd744476e 100644 --- a/src/com/android/documentsui/files/FilesActivity.java +++ b/src/com/android/documentsui/files/FilesActivity.java @@ -17,6 +17,7 @@ package com.android.documentsui.files; import static com.android.documentsui.OperationDialogFragment.DIALOG_TYPE_UNKNOWN; +import static com.android.documentsui.base.SharedMinimal.DEBUG; import static com.android.documentsui.flags.Flags.useMaterial3; import android.app.ActivityManager.TaskDescription; @@ -24,6 +25,7 @@ import android.content.Intent; import android.graphics.Color; import android.net.Uri; import android.os.Bundle; +import android.util.Log; import android.view.KeyEvent; import android.view.KeyboardShortcutGroup; import android.view.Menu; @@ -58,6 +60,7 @@ import com.android.documentsui.clipping.DocumentClipper; import com.android.documentsui.dirlist.AnimationView.AnimationType; import com.android.documentsui.dirlist.AppsRowManager; import com.android.documentsui.dirlist.DirectoryFragment; +import com.android.documentsui.flags.Flags; import com.android.documentsui.services.FileOperationService; import com.android.documentsui.sidebar.RootsFragment; import com.android.documentsui.ui.DialogController; @@ -338,12 +341,22 @@ public class FilesActivity extends BaseActivity implements AbstractActionHandler mInjector.actions.openInNewWindow(mState.stack); } else if (id == R.id.option_menu_settings) { mInjector.actions.openSettings(getCurrentRoot()); + } else if (id == R.id.option_menu_extract_all) { + if (!Flags.zipNg()) return false; + final DirectoryFragment dir = getDirectoryFragment(); + if (dir == null) return false; + mInjector.actions.selectAllFiles(); + return dir.onContextItemSelected(item); } else if (id == R.id.option_menu_select_all) { mInjector.actions.selectAllFiles(); } else if (id == R.id.option_menu_inspect) { mInjector.actions.showInspector(getCurrentDirectory()); } else { - return super.onOptionsItemSelected(item); + final boolean ok = super.onOptionsItemSelected(item); + if (DEBUG && !ok) { + Log.d(TAG, "Unhandled option item " + id); + } + return ok; } return true; } diff --git a/src/com/android/documentsui/files/MenuManager.java b/src/com/android/documentsui/files/MenuManager.java index 3e2e00feb..0fb7c4fa1 100644 --- a/src/com/android/documentsui/files/MenuManager.java +++ b/src/com/android/documentsui/files/MenuManager.java @@ -225,6 +225,11 @@ public final class MenuManager extends com.android.documentsui.MenuManager { } @Override + protected void updateExtractAll(MenuItem it) { + Menus.setEnabledAndVisible(it, mDirDetails.isInArchive()); + } + + @Override protected void updateSelectAll(MenuItem selectAll) { Menus.setEnabledAndVisible(selectAll, true); } diff --git a/src/com/android/documentsui/loaders/BaseFileLoader.kt b/src/com/android/documentsui/loaders/BaseFileLoader.kt new file mode 100644 index 000000000..dd76217ac --- /dev/null +++ b/src/com/android/documentsui/loaders/BaseFileLoader.kt @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2024 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.loaders + +import android.content.Context +import android.database.Cursor +import android.database.MatrixCursor +import android.database.MergeCursor +import android.net.Uri +import android.os.Bundle +import android.os.CancellationSignal +import android.os.RemoteException +import android.provider.DocumentsContract.Document +import android.util.Log +import androidx.loader.content.AsyncTaskLoader +import com.android.documentsui.DirectoryResult +import com.android.documentsui.base.Lookup +import com.android.documentsui.base.UserId +import com.android.documentsui.roots.RootCursorWrapper + +const val TAG = "SearchV2" + +val FILE_ENTRY_COLUMNS = arrayOf( + Document.COLUMN_DOCUMENT_ID, + Document.COLUMN_MIME_TYPE, + Document.COLUMN_DISPLAY_NAME, + Document.COLUMN_LAST_MODIFIED, + Document.COLUMN_FLAGS, + Document.COLUMN_SUMMARY, + Document.COLUMN_SIZE, + Document.COLUMN_ICON, +) + +fun emptyCursor(): Cursor { + return MatrixCursor(FILE_ENTRY_COLUMNS) +} + +/** + * Helper function that returns a single, non-null cursor constructed from the given list of + * cursors. + */ +fun toSingleCursor(cursorList: List<Cursor>): Cursor { + if (cursorList.isEmpty()) { + return emptyCursor() + } + if (cursorList.size == 1) { + return cursorList[0] + } + return MergeCursor(cursorList.toTypedArray()) +} + +/** + * The base class for search and directory loaders. This class implements common functionality + * shared by these loaders. The extending classes should implement loadInBackground, which + * should call the queryLocation method. + */ +abstract class BaseFileLoader( + context: Context, + private val mUserIdList: List<UserId>, + protected val mMimeTypeLookup: Lookup<String, String>, +) : AsyncTaskLoader<DirectoryResult>(context) { + + private var mSignal: CancellationSignal? = null + private var mResult: DirectoryResult? = null + + override fun cancelLoadInBackground() { + Log.d(TAG, "BasedFileLoader.cancelLoadInBackground") + super.cancelLoadInBackground() + + synchronized(this) { + mSignal?.cancel() + } + } + + override fun deliverResult(result: DirectoryResult?) { + Log.d(TAG, "BasedFileLoader.deliverResult") + if (isReset) { + closeResult(result) + return + } + val oldResult: DirectoryResult? = mResult + mResult = result + + if (isStarted) { + super.deliverResult(result) + } + + if (oldResult != null && oldResult !== result) { + closeResult(oldResult) + } + } + + override fun onStartLoading() { + Log.d(TAG, "BasedFileLoader.onStartLoading") + val isCursorStale: Boolean = checkIfCursorStale(mResult) + if (mResult != null && !isCursorStale) { + deliverResult(mResult) + } + if (takeContentChanged() || mResult == null || isCursorStale) { + forceLoad() + } + } + + override fun onStopLoading() { + Log.d(TAG, "BasedFileLoader.onStopLoading") + cancelLoad() + } + + override fun onCanceled(result: DirectoryResult?) { + Log.d(TAG, "BasedFileLoader.onCanceled") + closeResult(result) + } + + override fun onReset() { + Log.d(TAG, "BasedFileLoader.onReset") + super.onReset() + + // Ensure the loader is stopped + onStopLoading() + + closeResult(mResult) + mResult = null + } + + /** + * Quietly closes the result cursor, if results are still available. + */ + fun closeResult(result: DirectoryResult?) { + try { + result?.close() + } catch (e: Exception) { + Log.d(TAG, "Failed to close result", e) + } + } + + private fun checkIfCursorStale(result: DirectoryResult?): Boolean { + if (result == null) { + return true + } + val cursor = result.cursor ?: return true + if (cursor.isClosed) { + return true + } + Log.d(TAG, "Long check of cursor staleness") + val count = cursor.count + if (!cursor.moveToPosition(-1)) { + return true + } + for (i in 1..count) { + if (!cursor.moveToNext()) { + return true + } + } + return false + } + + /** + * A function that, for the specified location rooted in the root with the given rootId + * attempts to obtain a non-null cursor from the content provider client obtained for the + * given locationUri. It returns the first non-null cursor, if one can be found, or null, + * if it fails to query the given location for all known users. + */ + fun queryLocation( + rootId: String, + locationUri: Uri, + queryArgs: Bundle?, + maxResults: Int, + ): Cursor? { + val authority = locationUri.authority ?: return null + for (userId in mUserIdList) { + Log.d(TAG, "BaseFileLoader.queryLocation for $userId at $locationUri") + val resolver = userId.getContentResolver(context) + try { + resolver.acquireUnstableContentProviderClient( + authority + ).use { client -> + if (client == null) { + return null + } + try { + val cursor = + client.query(locationUri, null, queryArgs, mSignal) ?: return null + return RootCursorWrapper(userId, authority, rootId, cursor, maxResults) + } catch (e: RemoteException) { + Log.d(TAG, "Failed to get cursor for $locationUri", e) + } + } + } catch (e: Exception) { + Log.d(TAG, "Failed to get a content provider client for $locationUri", e) + } + } + + return null + } +} diff --git a/src/com/android/documentsui/loaders/FolderLoader.kt b/src/com/android/documentsui/loaders/FolderLoader.kt new file mode 100644 index 000000000..2bfcd895d --- /dev/null +++ b/src/com/android/documentsui/loaders/FolderLoader.kt @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2024 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.loaders + +import android.content.Context +import android.provider.DocumentsContract +import com.android.documentsui.ContentLock +import com.android.documentsui.DirectoryResult +import com.android.documentsui.LockingContentObserver +import com.android.documentsui.base.DocumentInfo +import com.android.documentsui.base.FilteringCursorWrapper +import com.android.documentsui.base.Lookup +import com.android.documentsui.base.RootInfo +import com.android.documentsui.base.UserId +import com.android.documentsui.sorting.SortModel + +/** + * A specialization of the BaseFileLoader that loads the children of a single folder. To list + * a directory you need to provide: + * + * - The current application context + * - A content lock for which a locking content observer is built + * - A list of user IDs on behalf of which the search is conducted + * - The root info of the listed directory + * - The document info of the listed directory + * - a lookup from file extension to file type + * - The model capable of sorting results + */ +class FolderLoader( + context: Context, + userIdList: List<UserId>, + mimeTypeLookup: Lookup<String, String>, + contentLock: ContentLock, + private val mRoot: RootInfo, + private val mListedDir: DocumentInfo, + private val mOptions: QueryOptions, + private val mSortModel: SortModel, +) : BaseFileLoader(context, userIdList, mimeTypeLookup) { + + // An observer registered on the cursor to force a reload if the cursor reports a change. + private val mObserver = LockingContentObserver(contentLock, this::onContentChanged) + + // Creates a directory result object corresponding to the current parameters of the loader. + override fun loadInBackground(): DirectoryResult? { + val rejectBeforeTimestamp = mOptions.getRejectBeforeTimestamp() + val folderChildrenUri = DocumentsContract.buildChildDocumentsUri( + mListedDir.authority, + mListedDir.documentId + ) + var cursor = + queryLocation(mRoot.rootId, folderChildrenUri, null, ALL_RESULTS) ?: emptyCursor() + val filteredCursor = FilteringCursorWrapper(cursor) + filteredCursor.filterHiddenFiles(mOptions.showHidden) + if (rejectBeforeTimestamp > 0L) { + filteredCursor.filterLastModified(rejectBeforeTimestamp) + } + // TODO(b:380945065): Add filtering by category, such as images, audio, video. + val sortedCursor = mSortModel.sortCursor(filteredCursor, mMimeTypeLookup) + sortedCursor.registerContentObserver(mObserver) + + val result = DirectoryResult() + result.doc = mListedDir + result.cursor = sortedCursor + return result + } +} diff --git a/src/com/android/documentsui/loaders/QueryOptions.kt b/src/com/android/documentsui/loaders/QueryOptions.kt new file mode 100644 index 000000000..1e098b288 --- /dev/null +++ b/src/com/android/documentsui/loaders/QueryOptions.kt @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2024 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.loaders + +import java.time.Duration + +/** + * The constant to be used for the maxResults parameter, if we wish to get all (unlimited) results. + */ +const val ALL_RESULTS: Int = -1 + +/** + * Common query options. These are: + * - maximum number to return; pass ALL_RESULTS to impose no limits. + * - maximum lastModified delta in milliseconds: the delta from now used to reject files that were + * not modified in the specified milliseconds; pass null for no limits. + * - maximum time the query should return, including empty, results; pass null for no limits. + * - whether or not to show hidden files. + * - A list of MIME types used to filter returned files. + */ +data class QueryOptions( + val maxResults: Int, + val maxLastModifiedDelta: Duration?, + val maxQueryTime: Duration?, + val showHidden: Boolean, + val acceptableMimeTypes: Array<String>, +) { + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as QueryOptions + + return maxResults == other.maxResults && + maxLastModifiedDelta == other.maxLastModifiedDelta && + maxQueryTime == other.maxQueryTime && + showHidden == other.showHidden && + acceptableMimeTypes.contentEquals(other.acceptableMimeTypes) + } + + /** + * Helper method that computes the earliest valid last modified timestamp. Converts last + * modified duration to milliseconds past now. If the maxLastModifiedDelta is negative + * this method returns 0L. + */ + fun getRejectBeforeTimestamp() = + if (maxLastModifiedDelta == null) { + 0L + } else { + System.currentTimeMillis() - maxLastModifiedDelta.toMillis() + } + + /** + * Helper function that indicates if query time is unlimited. Due to internal reliance on + * Java's Duration class it assumes anything larger than 60 seconds has unlimited waiting + * time. + */ + fun isQueryTimeUnlimited() = maxQueryTime == null + + override fun hashCode(): Int { + var result = maxResults + result = 31 * result + maxLastModifiedDelta.hashCode() + result = 31 * result + maxQueryTime.hashCode() + result = 31 * result + showHidden.hashCode() + result = 31 * result + acceptableMimeTypes.contentHashCode() + return result + } +} diff --git a/src/com/android/documentsui/loaders/SearchLoader.kt b/src/com/android/documentsui/loaders/SearchLoader.kt new file mode 100644 index 000000000..b394c009e --- /dev/null +++ b/src/com/android/documentsui/loaders/SearchLoader.kt @@ -0,0 +1,246 @@ +/* + * Copyright (C) 2024 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.loaders + +import android.content.Context +import android.database.Cursor +import android.net.Uri +import android.os.Bundle +import android.provider.DocumentsContract +import android.provider.DocumentsContract.Document +import android.util.Log +import com.android.documentsui.DirectoryResult +import com.android.documentsui.LockingContentObserver +import com.android.documentsui.base.DocumentInfo +import com.android.documentsui.base.FilteringCursorWrapper +import com.android.documentsui.base.Lookup +import com.android.documentsui.base.RootInfo +import com.android.documentsui.base.UserId +import com.android.documentsui.sorting.SortModel +import com.google.common.util.concurrent.AbstractFuture +import java.io.Closeable +import java.util.concurrent.CountDownLatch +import java.util.concurrent.ExecutorService +import java.util.concurrent.TimeUnit +import kotlin.time.measureTime + +/** + * A specialization of the BaseFileLoader that searches the set of specified roots. To search + * the roots you must provider: + * + * - The current application context + * - A content lock for which a locking content observer is built + * - A list of user IDs, on whose behalf we query content provider clients. + * - A list of RootInfo objects representing searched roots + * - A query used to search for matching files. + * - Query options such as maximum number of results, last modified time delta, etc. + * - a lookup from file extension to file type + * - The model capable of sorting results + * - An acceptable mime types + */ +class SearchLoader( + context: Context, + userIdList: List<UserId>, + mimeTypeLookup: Lookup<String, String>, + private val mObserver: LockingContentObserver, + private val mRootList: Collection<RootInfo>, + private val mQuery: String?, + private val mOptions: QueryOptions, + private val mSortModel: SortModel, + private val mExecutorService: ExecutorService, +) : BaseFileLoader(context, userIdList, mimeTypeLookup) { + + /** + * Helper class that runs query on a single user for the given parameter. This class implements + * an abstract future so that if the task is completed, we can retrieve the cursor via the get + * method. + */ + inner class SearchTask( + private val mRootId: String, + private val mSearchUri: Uri, + private val mQueryArgs: Bundle, + private val mLatch: CountDownLatch, + ) : Closeable, Runnable, AbstractFuture<Cursor>() { + private var mCursor: Cursor? = null + val cursor: Cursor? get() = mCursor + val taskId: String get() = mSearchUri.toString() + + override fun close() { + mCursor = null + } + + override fun run() { + val queryDuration = measureTime { + try { + mCursor = queryLocation(mRootId, mSearchUri, mQueryArgs, mOptions.maxResults) + set(mCursor) + } finally { + mLatch.countDown() + } + } + Log.d(TAG, "Query on $mSearchUri took $queryDuration") + } + } + + @Volatile + private lateinit var mSearchTaskList: List<SearchTask> + + // Creates a directory result object corresponding to the current parameters of the loader. + override fun loadInBackground(): DirectoryResult? { + val result = DirectoryResult() + // TODO(b:378590632): If root list has one root use it to construct result.doc + result.doc = DocumentInfo() + result.cursor = emptyCursor() + + val searchedRoots = mRootList + val countDownLatch = CountDownLatch(searchedRoots.size) + val rejectBeforeTimestamp = mOptions.getRejectBeforeTimestamp() + + // Step 1: Build a list of search tasks. + val searchTaskList = + createSearchTaskList(rejectBeforeTimestamp, countDownLatch, mRootList) + Log.d(TAG, "${searchTaskList.size} tasks have been created") + + // Check if we are cancelled; if not copy the task list. + if (isLoadInBackgroundCanceled) { + return result + } + mSearchTaskList = searchTaskList + + // Step 2: Enqueue tasks and wait for them to complete or time out. + for (task in mSearchTaskList) { + mExecutorService.execute(task) + } + Log.d(TAG, "${mSearchTaskList.size} tasks have been enqueued") + + // Step 3: Wait for the results. + try { + if (mOptions.isQueryTimeUnlimited()) { + Log.d(TAG, "Waiting for results with no time limit") + countDownLatch.await() + } else { + Log.d(TAG, "Waiting ${mOptions.maxQueryTime!!.toMillis()}ms for results") + countDownLatch.await( + mOptions.maxQueryTime.toMillis(), + TimeUnit.MILLISECONDS + ) + } + Log.d(TAG, "Waiting for results is done") + } catch (e: InterruptedException) { + Log.d(TAG, "Failed to complete all searches within ${mOptions.maxQueryTime}") + // TODO(b:388336095): Record a metrics indicating incomplete search. + throw RuntimeException(e) + } + + // Step 4: Collect cursors from done tasks. + val cursorList = mutableListOf<Cursor>() + for (task in mSearchTaskList) { + Log.d(TAG, "Processing task ${task.taskId}") + if (isLoadInBackgroundCanceled) { + break + } + // TODO(b:388336095): Record a metric for each done and not done task. + val cursor = task.cursor + if (task.isDone && cursor != null) { + // TODO(b:388336095): Record a metric for null and not null cursor. + Log.d(TAG, "Task ${task.taskId} has ${cursor.count} results") + cursorList.add(cursor) + } + } + Log.d(TAG, "Search complete with ${cursorList.size} cursors collected") + + // Step 5: Assign the cursor, after adding filtering and sorting, to the results. + val filteringCursor = FilteringCursorWrapper(toSingleCursor(cursorList)) + filteringCursor.filterHiddenFiles(mOptions.showHidden) + if (rejectBeforeTimestamp > 0L) { + filteringCursor.filterLastModified(rejectBeforeTimestamp) + } + filteringCursor.filterMimes(mOptions.acceptableMimeTypes, arrayOf(Document.MIME_TYPE_DIR)) + val sortingCursor = mSortModel.sortCursor(filteringCursor, mMimeTypeLookup) + sortingCursor.registerContentObserver(mObserver) + result.cursor = sortingCursor + + // TODO(b:388336095): Record the total time it took to complete search. + return result + } + + private fun createContentProviderQuery(root: RootInfo) = + if (mQuery == null || mQuery.isBlank()) { + DocumentsContract.buildRecentDocumentsUri( + root.authority, + root.rootId + ) + } else { + // NOTE: We pass empty query, as the name matching query is placed in queryArgs. + DocumentsContract.buildSearchDocumentsUri( + root.authority, + root.rootId, + "" + ) + } + + private fun createQueryArgs(rejectBeforeTimestamp: Long): Bundle { + val queryArgs = Bundle() + mSortModel.addQuerySortArgs(queryArgs) + if (rejectBeforeTimestamp > 0L) { + queryArgs.putLong( + DocumentsContract.QUERY_ARG_LAST_MODIFIED_AFTER, + rejectBeforeTimestamp + ) + } + if (mQuery != null && !mQuery.isBlank()) { + queryArgs.putString(DocumentsContract.QUERY_ARG_DISPLAY_NAME, mQuery) + } + return queryArgs + } + + /** + * Helper function that creates a list of search tasks for the given countdown latch. + */ + private fun createSearchTaskList( + rejectBeforeTimestamp: Long, + countDownLatch: CountDownLatch, + rootList: Collection<RootInfo> + ): List<SearchTask> { + val searchTaskList = mutableListOf<SearchTask>() + for (root in rootList) { + if (isLoadInBackgroundCanceled) { + break + } + val rootSearchUri = createContentProviderQuery(root) + // TODO(b:385789236): Correctly pass sort order information. + val queryArgs = createQueryArgs(rejectBeforeTimestamp) + mSortModel.addQuerySortArgs(queryArgs) + Log.d(TAG, "Query $rootSearchUri and queryArgs $queryArgs") + val task = SearchTask( + root.rootId, + rootSearchUri, + queryArgs, + countDownLatch + ) + searchTaskList.add(task) + } + return searchTaskList + } + + override fun onReset() { + for (task in mSearchTaskList) { + task.close() + } + Log.d(TAG, "Resetting search loader; search task list emptied.") + super.onReset() + } +} diff --git a/src/com/android/documentsui/sorting/HeaderCell.java b/src/com/android/documentsui/sorting/HeaderCell.java index 43e254e39..b0e79e93c 100644 --- a/src/com/android/documentsui/sorting/HeaderCell.java +++ b/src/com/android/documentsui/sorting/HeaderCell.java @@ -19,8 +19,6 @@ package com.android.documentsui.sorting; import android.animation.AnimatorInflater; import android.animation.LayoutTransition; import android.animation.ObjectAnimator; -import androidx.annotation.AnimatorRes; -import androidx.annotation.StringRes; import android.content.Context; import android.util.AttributeSet; import android.view.Gravity; @@ -29,14 +27,14 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; +import androidx.annotation.AnimatorRes; +import androidx.annotation.StringRes; + import com.android.documentsui.R; -import com.android.documentsui.sorting.SortDimension; /** - * A clickable, sortable table header cell layout. - * - * It updates its display when it binds to {@link SortDimension} and changes the status of sorting - * when it's clicked. + * A clickable, sortable table header cell layout. It updates its display when it binds to {@link + * SortDimension} and changes the status of sorting when it's clicked. */ public class HeaderCell extends LinearLayout { @@ -62,7 +60,7 @@ public class HeaderCell extends LinearLayout { setVisibility(dimension.getVisibility()); if (dimension.getVisibility() == View.VISIBLE) { - TextView label = (TextView) findViewById(R.id.label); + TextView label = findViewById(R.id.label); label.setText(dimension.getLabelId()); switch (dimension.getDataType()) { case SortDimension.DATA_TYPE_NUMBER: @@ -77,17 +75,21 @@ public class HeaderCell extends LinearLayout { } if (mCurDirection != dimension.getSortDirection()) { - ImageView arrow = (ImageView) findViewById(R.id.sort_arrow); + ImageView arrow = findViewById(R.id.sort_arrow); switch (dimension.getSortDirection()) { case SortDimension.SORT_DIRECTION_NONE: arrow.setVisibility(View.GONE); break; case SortDimension.SORT_DIRECTION_ASCENDING: - showArrow(arrow, R.animator.arrow_rotate_up, + showArrow( + arrow, + R.animator.arrow_rotate_up, R.string.sort_direction_ascending); break; case SortDimension.SORT_DIRECTION_DESCENDING: - showArrow(arrow, R.animator.arrow_rotate_down, + showArrow( + arrow, + R.animator.arrow_rotate_down, R.string.sort_direction_descending); break; default: diff --git a/src/com/android/documentsui/sorting/TableHeaderController.java b/src/com/android/documentsui/sorting/TableHeaderController.java index 549478cfc..17fe29c55 100644 --- a/src/com/android/documentsui/sorting/TableHeaderController.java +++ b/src/com/android/documentsui/sorting/TableHeaderController.java @@ -22,43 +22,44 @@ import com.android.documentsui.R; import javax.annotation.Nullable; -/** - * View controller for table header that associates header cells in table header and columns. - */ +/** View controller for table header that associates header cells in table header and columns. */ public final class TableHeaderController implements SortController.WidgetController { - private View mTableHeader; - private final HeaderCell mTitleCell; private final HeaderCell mSummaryCell; private final HeaderCell mSizeCell; private final HeaderCell mFileTypeCell; private final HeaderCell mDateCell; - + private final SortModel mModel; // We assign this here porque each method reference creates a new object // instance (which is wasteful). private final View.OnClickListener mOnCellClickListener = this::onCellClicked; private final SortModel.UpdateListener mModelListener = this::onModelUpdate; - - private final SortModel mModel; + private final View mTableHeader; private TableHeaderController(SortModel sortModel, View tableHeader) { - assert(sortModel != null); - assert(tableHeader != null); + assert (sortModel != null); + assert (tableHeader != null); mModel = sortModel; mTableHeader = tableHeader; - mTitleCell = (HeaderCell) tableHeader.findViewById(android.R.id.title); - mSummaryCell = (HeaderCell) tableHeader.findViewById(android.R.id.summary); - mSizeCell = (HeaderCell) tableHeader.findViewById(R.id.size); - mFileTypeCell = (HeaderCell) tableHeader.findViewById(R.id.file_type); - mDateCell = (HeaderCell) tableHeader.findViewById(R.id.date); + mTitleCell = tableHeader.findViewById(android.R.id.title); + mSummaryCell = tableHeader.findViewById(android.R.id.summary); + mSizeCell = tableHeader.findViewById(R.id.size); + mFileTypeCell = tableHeader.findViewById(R.id.file_type); + mDateCell = tableHeader.findViewById(R.id.date); onModelUpdate(mModel, SortModel.UPDATE_TYPE_UNSPECIFIED); mModel.addListener(mModelListener); } + /** Creates a TableHeaderController. */ + public static @Nullable TableHeaderController create( + SortModel sortModel, @Nullable View tableHeader) { + return (tableHeader == null) ? null : new TableHeaderController(sortModel, tableHeader); + } + private void onModelUpdate(SortModel model, int updateTypeUnspecified) { bindCell(mTitleCell, SortModel.SORT_DIMENSION_ID_TITLE); bindCell(mSummaryCell, SortModel.SORT_DIMENSION_ID_SUMMARY); @@ -78,7 +79,7 @@ public final class TableHeaderController implements SortController.WidgetControl } private void bindCell(HeaderCell cell, int id) { - assert(cell != null); + assert (cell != null); SortDimension dimension = mModel.getDimensionById(id); cell.setTag(dimension); @@ -97,9 +98,4 @@ public final class TableHeaderController implements SortController.WidgetControl mModel.sortByUser(dimension.getId(), dimension.getNextDirection()); } - - public static @Nullable TableHeaderController create( - SortModel sortModel, @Nullable View tableHeader) { - return (tableHeader == null) ? null : new TableHeaderController(sortModel, tableHeader); - } } diff --git a/tests/common/com/android/documentsui/bots/SortBot.java b/tests/common/com/android/documentsui/bots/SortBot.java index 0a77de4ee..a2990d7d9 100644 --- a/tests/common/com/android/documentsui/bots/SortBot.java +++ b/tests/common/com/android/documentsui/bots/SortBot.java @@ -49,10 +49,11 @@ import com.android.documentsui.sorting.SortModel; import org.hamcrest.Matcher; /** - * 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. + * 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 SortBot extends Bots.BaseBot { @@ -67,7 +68,7 @@ public class SortBot extends Bots.BaseBot { } public void sortBy(int id, @SortDirection int direction) { - assert(direction != SortDimension.SORT_DIRECTION_NONE); + assert (direction != SortDimension.SORT_DIRECTION_NONE); final @StringRes int labelId = mSortModel.getDimensionById(id).getLabelId(); final String label = mContext.getString(labelId); @@ -78,16 +79,15 @@ public class SortBot extends Bots.BaseBot { result = sortByMenu(id, direction); } - assertTrue("Sorting by id: " + id + " in direction: " + direction + " failed.", - result); + assertTrue("Sorting by id: " + id + " in direction: " + direction + " failed.", result); } public boolean isHeaderShow() { - return Matchers.present(mColumnBot.MATCHER); + return Matchers.present(ColumnSortBot.MATCHER); } public void assertHeaderHide() { - assertFalse(Matchers.present(mColumnBot.MATCHER)); + assertFalse(Matchers.present(ColumnSortBot.MATCHER)); } public void assertHeaderShow() { @@ -98,11 +98,11 @@ public class SortBot extends Bots.BaseBot { // or with espresso. It's sad that I'm leaving you // with this little gremlin, but we all have to // move on and get stuff done :) - assertTrue(Matchers.present(mColumnBot.MATCHER)); + assertTrue(Matchers.present(ColumnSortBot.MATCHER)); } private boolean sortByMenu(int id, @SortDirection int direction) { - assert(direction != SortDimension.SORT_DIRECTION_NONE); + assert (direction != SortDimension.SORT_DIRECTION_NONE); clickMenuSort(); mDevice.waitForIdle(); @@ -131,9 +131,8 @@ public class SortBot extends Bots.BaseBot { private static final Matcher<View> MATCHER = withId(R.id.table_header); private boolean sortBy(String label, @SortDirection int direction) { - final Matcher<View> cellMatcher = allOf( - withChild(withText(label)), - isDescendantOfA(MATCHER)); + final Matcher<View> cellMatcher = + allOf(withChild(withText(label)), isDescendantOfA(MATCHER)); onView(cellMatcher).perform(click()); final @SortDirection int viewDirection = getDirection(cellMatcher); diff --git a/tests/common/com/android/documentsui/testing/TestDirectoryDetails.java b/tests/common/com/android/documentsui/testing/TestDirectoryDetails.java index 28416775a..fb1a7b6db 100644 --- a/tests/common/com/android/documentsui/testing/TestDirectoryDetails.java +++ b/tests/common/com/android/documentsui/testing/TestDirectoryDetails.java @@ -24,6 +24,7 @@ import com.android.documentsui.MenuManager.DirectoryDetails; public class TestDirectoryDetails extends DirectoryDetails { public boolean isInRecents; + public boolean isInArchive; public boolean hasRootSettings; public boolean hasItemsToPaste; public boolean canCreateDoc; @@ -50,6 +51,11 @@ public class TestDirectoryDetails extends DirectoryDetails { } @Override + public boolean isInArchive() { + return isInArchive; + } + + @Override public boolean canCreateDoc() { return canCreateDoc; } diff --git a/tests/common/com/android/documentsui/testing/TestMenu.java b/tests/common/com/android/documentsui/testing/TestMenu.java index 10e0ea493..9795fd373 100644 --- a/tests/common/com/android/documentsui/testing/TestMenu.java +++ b/tests/common/com/android/documentsui/testing/TestMenu.java @@ -77,6 +77,7 @@ public abstract class TestMenu implements Menu { R.id.option_menu_debug, R.id.option_menu_new_window, R.id.option_menu_create_dir, + R.id.option_menu_extract_all, R.id.option_menu_select_all, R.id.option_menu_settings, R.id.option_menu_inspect, @@ -101,6 +102,11 @@ public abstract class TestMenu implements Menu { if (id == R.id.option_menu_search) { item.setActionView(Mockito.mock(SearchView.class)); } + + if (id == R.id.option_menu_extract_all) { + item.setEnabled(false); + item.setVisible(false); + } } return menu; } diff --git a/tests/functional/com/android/documentsui/SortDocumentUiTest.java b/tests/functional/com/android/documentsui/SortDocumentUiTest.java index 05878bbe7..a6907d680 100644 --- a/tests/functional/com/android/documentsui/SortDocumentUiTest.java +++ b/tests/functional/com/android/documentsui/SortDocumentUiTest.java @@ -38,28 +38,34 @@ public class SortDocumentUiTest extends ActivityTest<FilesActivity> { private static final String MIME_2 = "text/html"; // HTML document private static final String MIME_3 = "image/jpeg"; // JPG image - private static final String[] FILES = { FILE_1, FILE_3, FILE_2 }; - private static final String[] MIMES = { MIME_1, MIME_3, MIME_2 }; - private static final String[] DIRS = { DIR_1, DIR_2 }; - - private static final String[] DIRS_IN_NAME_ASC = { DIR_2, DIR_1 }; + private static final String[] FILES = {FILE_1, FILE_3, FILE_2}; + private static final String[] FILES_IN_MODIFIED_DESC = reverse(FILES); + private static final String[] MIMES = {MIME_1, MIME_3, MIME_2}; + private static final String[] DIRS = {DIR_1, DIR_2}; + private static final String[] DIRS_IN_MODIFIED_DESC = reverse(DIRS); + private static final String[] DIRS_IN_NAME_ASC = {DIR_2, DIR_1}; private static final String[] DIRS_IN_NAME_DESC = reverse(DIRS_IN_NAME_ASC); - private static final String[] FILES_IN_NAME_ASC = { FILE_2, FILE_1, FILE_3 }; + private static final String[] FILES_IN_NAME_ASC = {FILE_2, FILE_1, FILE_3}; private static final String[] FILES_IN_NAME_DESC = reverse(FILES_IN_NAME_ASC); - - private static final String[] FILES_IN_SIZE_ASC = { FILE_2, FILE_1, FILE_3 }; + private static final String[] FILES_IN_SIZE_ASC = {FILE_2, FILE_1, FILE_3}; private static final String[] FILES_IN_SIZE_DESC = reverse(FILES_IN_SIZE_ASC); - - private static final String[] DIRS_IN_MODIFIED_DESC = reverse(DIRS); - private static final String[] FILES_IN_MODIFIED_DESC = reverse(FILES); - - private static final String[] FILES_IN_TYPE_ASC = { FILE_2, FILE_3, FILE_1 }; + private static final String[] FILES_IN_TYPE_ASC = {FILE_2, FILE_3, FILE_1}; private static final String[] FILES_IN_TYPE_DESC = reverse(FILES_IN_TYPE_ASC); public SortDocumentUiTest() { super(FilesActivity.class); } + private static String[] reverse(String[] array) { + String[] ret = new String[array.length]; + + for (int i = 0; i < array.length; ++i) { + ret[ret.length - i - 1] = array[i]; + } + + return ret; + } + @Override public void setUp() throws Exception { super.setUp(); @@ -71,8 +77,9 @@ public class SortDocumentUiTest extends ActivityTest<FilesActivity> { } /** - * Initiate test files. It allows waiting between creations of files, so that we can assure - * the modified date of each document is different. + * Initiate test files. It allows waiting between creations of files, so that we can assure the + * modified date of each document is different. + * * @param sleep time to sleep in ms */ private void initFiles(long sleep) throws Exception { @@ -110,8 +117,7 @@ public class SortDocumentUiTest extends ActivityTest<FilesActivity> { bots.main.switchToListMode(); - bots.sort.sortBy( - SortModel.SORT_DIMENSION_ID_SIZE, SortDimension.SORT_DIRECTION_ASCENDING); + bots.sort.sortBy(SortModel.SORT_DIMENSION_ID_SIZE, SortDimension.SORT_DIRECTION_ASCENDING); bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_SIZE_ASC); } @@ -120,8 +126,7 @@ public class SortDocumentUiTest extends ActivityTest<FilesActivity> { bots.main.switchToListMode(); - bots.sort.sortBy( - SortModel.SORT_DIMENSION_ID_SIZE, SortDimension.SORT_DIRECTION_DESCENDING); + bots.sort.sortBy(SortModel.SORT_DIMENSION_ID_SIZE, SortDimension.SORT_DIRECTION_DESCENDING); bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_SIZE_DESC); } @@ -130,8 +135,7 @@ public class SortDocumentUiTest extends ActivityTest<FilesActivity> { bots.main.switchToListMode(); - bots.sort.sortBy( - SortModel.SORT_DIMENSION_ID_DATE, SortDimension.SORT_DIRECTION_ASCENDING); + bots.sort.sortBy(SortModel.SORT_DIMENSION_ID_DATE, SortDimension.SORT_DIRECTION_ASCENDING); bots.directory.assertOrder(DIRS, FILES); } @@ -140,8 +144,7 @@ public class SortDocumentUiTest extends ActivityTest<FilesActivity> { bots.main.switchToListMode(); - bots.sort.sortBy( - SortModel.SORT_DIMENSION_ID_DATE, SortDimension.SORT_DIRECTION_DESCENDING); + bots.sort.sortBy(SortModel.SORT_DIMENSION_ID_DATE, SortDimension.SORT_DIRECTION_DESCENDING); bots.directory.assertOrder(DIRS_IN_MODIFIED_DESC, FILES_IN_MODIFIED_DESC); } @@ -180,8 +183,7 @@ public class SortDocumentUiTest extends ActivityTest<FilesActivity> { bots.main.switchToGridMode(); - bots.sort.sortBy( - SortModel.SORT_DIMENSION_ID_SIZE, SortDimension.SORT_DIRECTION_ASCENDING); + bots.sort.sortBy(SortModel.SORT_DIMENSION_ID_SIZE, SortDimension.SORT_DIRECTION_ASCENDING); bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_SIZE_ASC); } @@ -190,8 +192,7 @@ public class SortDocumentUiTest extends ActivityTest<FilesActivity> { bots.main.switchToGridMode(); - bots.sort.sortBy( - SortModel.SORT_DIMENSION_ID_SIZE, SortDimension.SORT_DIRECTION_DESCENDING); + bots.sort.sortBy(SortModel.SORT_DIMENSION_ID_SIZE, SortDimension.SORT_DIRECTION_DESCENDING); bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_SIZE_DESC); } @@ -200,8 +201,7 @@ public class SortDocumentUiTest extends ActivityTest<FilesActivity> { bots.main.switchToGridMode(); - bots.sort.sortBy( - SortModel.SORT_DIMENSION_ID_DATE, SortDimension.SORT_DIRECTION_ASCENDING); + bots.sort.sortBy(SortModel.SORT_DIMENSION_ID_DATE, SortDimension.SORT_DIRECTION_ASCENDING); bots.directory.assertOrder(DIRS, FILES); } @@ -210,8 +210,7 @@ public class SortDocumentUiTest extends ActivityTest<FilesActivity> { bots.main.switchToGridMode(); - bots.sort.sortBy( - SortModel.SORT_DIMENSION_ID_DATE, SortDimension.SORT_DIRECTION_DESCENDING); + bots.sort.sortBy(SortModel.SORT_DIMENSION_ID_DATE, SortDimension.SORT_DIRECTION_DESCENDING); bots.directory.assertOrder(DIRS_IN_MODIFIED_DESC, FILES_IN_MODIFIED_DESC); } @@ -234,14 +233,4 @@ public class SortDocumentUiTest extends ActivityTest<FilesActivity> { SortModel.SORT_DIMENSION_ID_FILE_TYPE, SortDimension.SORT_DIRECTION_DESCENDING); bots.directory.assertOrder(DIRS_IN_NAME_ASC, FILES_IN_TYPE_DESC); } - - private static String[] reverse(String[] array) { - String[] ret = new String[array.length]; - - for (int i = 0; i < array.length; ++i) { - ret[ret.length - i - 1] = array[i]; - } - - return ret; - } } diff --git a/tests/unit/com/android/documentsui/files/MenuManagerTest.java b/tests/unit/com/android/documentsui/files/MenuManagerTest.java index 6f97de814..f3b7078e8 100644 --- a/tests/unit/com/android/documentsui/files/MenuManagerTest.java +++ b/tests/unit/com/android/documentsui/files/MenuManagerTest.java @@ -111,6 +111,7 @@ public final class MenuManagerTest { private TestMenuItem optionSort; private TestMenuItem mOptionLauncher; private TestMenuItem mOptionShowHiddenFiles; + private TestMenuItem mOptionExtractAll; /* Sub Option Menu items */ private TestMenuItem subOptionGrid; @@ -185,6 +186,7 @@ public final class MenuManagerTest { optionSort = testMenu.findItem(R.id.option_menu_sort); mOptionLauncher = testMenu.findItem(R.id.option_menu_launcher); mOptionShowHiddenFiles = testMenu.findItem(R.id.option_menu_show_hidden_files); + mOptionExtractAll = testMenu.findItem(R.id.option_menu_extract_all); // Menu actions on root title row. subOptionGrid = testMenu.findItem(R.id.sub_menu_grid); @@ -253,6 +255,7 @@ public final class MenuManagerTest { actionModeSort.assertEnabledAndVisible(); actionModeSelectAll.assertEnabledAndVisible(); mActionModeDeselectAll.assertDisabledAndInvisible(); + mOptionExtractAll.assertDisabledAndInvisible(); } @Test @@ -268,6 +271,7 @@ public final class MenuManagerTest { actionModeExtractTo.assertDisabledAndInvisible(); actionModeMoveTo.assertDisabledAndInvisible(); actionModeViewInOwner.assertDisabledAndInvisible(); + mOptionExtractAll.assertDisabledAndInvisible(); } @Test diff --git a/tests/unit/com/android/documentsui/loaders/BaseLoaderTest.kt b/tests/unit/com/android/documentsui/loaders/BaseLoaderTest.kt new file mode 100644 index 000000000..71512e9a1 --- /dev/null +++ b/tests/unit/com/android/documentsui/loaders/BaseLoaderTest.kt @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2024 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.loaders + +import android.os.Parcel +import com.android.documentsui.DirectoryResult +import com.android.documentsui.TestActivity +import com.android.documentsui.TestConfigStore +import com.android.documentsui.base.DocumentInfo +import com.android.documentsui.sorting.SortModel +import com.android.documentsui.testing.ActivityManagers +import com.android.documentsui.testing.TestEnv +import com.android.documentsui.testing.UserManagers +import java.util.Locale +import org.junit.Before + +/** + * Returns the number of matched files, or -1. + */ +fun getFileCount(result: DirectoryResult?) = result?.cursor?.count ?: -1 + +/** + * Common base class for search and folder loaders. + */ +open class BaseLoaderTest { + lateinit var mEnv: TestEnv + lateinit var mActivity: TestActivity + lateinit var mTestConfigStore: TestConfigStore + + @Before + open fun setUp() { + mEnv = TestEnv.create() + mTestConfigStore = TestConfigStore() + mEnv.state.configStore = mTestConfigStore + mEnv.state.showHiddenFiles = false + val parcel = Parcel.obtain() + mEnv.state.sortModel = SortModel.CREATOR.createFromParcel(parcel) + + mActivity = TestActivity.create(mEnv) + mActivity.activityManager = ActivityManagers.create(false) + mActivity.userManager = UserManagers.create() + } + + fun createDocuments(count: Int): Array<DocumentInfo> { + val extensionList = arrayOf("txt", "png", "mp4", "mpg") + return Array<DocumentInfo>(count) { i -> + val id = String.format(Locale.US, "%05d", i) + mEnv.model.createFile("sample-$id.${extensionList[i % extensionList.size]}") + } + } +} diff --git a/tests/unit/com/android/documentsui/loaders/FolderLoaderTest.kt b/tests/unit/com/android/documentsui/loaders/FolderLoaderTest.kt new file mode 100644 index 000000000..92aaaa041 --- /dev/null +++ b/tests/unit/com/android/documentsui/loaders/FolderLoaderTest.kt @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2024 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.loaders + +import androidx.test.filters.SmallTest +import com.android.documentsui.ContentLock +import com.android.documentsui.base.DocumentInfo +import com.android.documentsui.testing.TestFileTypeLookup +import com.android.documentsui.testing.TestProvidersAccess +import junit.framework.Assert.assertEquals +import org.junit.Test + +@SmallTest +class FolderLoaderTest : BaseLoaderTest() { + @Test + fun testLoadInBackground() { + val mockProvider = mEnv.mockProviders[TestProvidersAccess.DOWNLOADS.authority] + val docs = createDocuments(5) + mockProvider!!.setNextChildDocumentsReturns(*docs) + val userIds = listOf(TestProvidersAccess.DOWNLOADS.userId) + val queryOptions = QueryOptions(10, null, null, true, arrayOf<String>("*/*")) + val contentLock = ContentLock() + // TODO(majewski): Is there a better way to create Downloads root folder DocumentInfo? + val rootFolderInfo = DocumentInfo() + rootFolderInfo.authority = TestProvidersAccess.DOWNLOADS.authority + rootFolderInfo.userId = userIds[0] + + val loader = + FolderLoader( + mActivity, + userIds, + TestFileTypeLookup(), + contentLock, + TestProvidersAccess.DOWNLOADS, + rootFolderInfo, + queryOptions, + mEnv.state.sortModel + ) + val directoryResult = loader.loadInBackground() + assertEquals(docs.size, getFileCount(directoryResult)) + } +} diff --git a/tests/unit/com/android/documentsui/loaders/SearchLoaderTest.kt b/tests/unit/com/android/documentsui/loaders/SearchLoaderTest.kt new file mode 100644 index 000000000..6d78ffdd9 --- /dev/null +++ b/tests/unit/com/android/documentsui/loaders/SearchLoaderTest.kt @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2024 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.loaders + +import com.android.documentsui.ContentLock +import com.android.documentsui.LockingContentObserver +import com.android.documentsui.base.DocumentInfo +import com.android.documentsui.testing.TestFileTypeLookup +import com.android.documentsui.testing.TestProvidersAccess +import java.util.concurrent.ExecutorService +import java.util.concurrent.Executors +import junit.framework.Assert.assertEquals +import org.junit.Before +import org.junit.Test + +class SearchLoaderTest : BaseLoaderTest() { + lateinit var mExecutor: ExecutorService + + @Before + override fun setUp() { + super.setUp() + mExecutor = Executors.newSingleThreadExecutor() + } + + @Test + fun testLoadInBackground() { + val mockProvider = mEnv.mockProviders[TestProvidersAccess.DOWNLOADS.authority] + val docs = createDocuments(8) + mockProvider!!.setNextChildDocumentsReturns(*docs) + val userIds = listOf(TestProvidersAccess.DOWNLOADS.userId) + val queryOptions = QueryOptions(10, null, null, true, arrayOf("*/*")) + val contentLock = ContentLock() + val rootIds = listOf(TestProvidersAccess.DOWNLOADS) + val observer = LockingContentObserver(contentLock) { + } + + // TODO(majewski): Is there a better way to create Downloads root folder DocumentInfo? + val rootFolderInfo = DocumentInfo() + rootFolderInfo.authority = TestProvidersAccess.DOWNLOADS.authority + rootFolderInfo.userId = userIds[0] + + val loader = + SearchLoader( + mActivity, + userIds, + TestFileTypeLookup(), + observer, + rootIds, + "txt", + queryOptions, + mEnv.state.sortModel, + mExecutor, + ) + val directoryResult = loader.loadInBackground() + // Expect only 2 text files to match txt. + assertEquals(2, getFileCount(directoryResult)) + } +} diff --git a/tests/unit/com/android/documentsui/picker/MenuManagerTest.java b/tests/unit/com/android/documentsui/picker/MenuManagerTest.java index cf9699a3b..7ebf1e6a3 100644 --- a/tests/unit/com/android/documentsui/picker/MenuManagerTest.java +++ b/tests/unit/com/android/documentsui/picker/MenuManagerTest.java @@ -61,6 +61,7 @@ public final class MenuManagerTest { private TestMenuItem dirCutToClipboard; private TestMenuItem dirCopyToClipboard; private TestMenuItem dirPasteFromClipboard; + private TestMenuItem mDirCompress; private TestMenuItem dirCreateDir; private TestMenuItem dirSelectAll; private TestMenuItem mDirDeselectAll; @@ -102,6 +103,7 @@ public final class MenuManagerTest { private TestMenuItem optionSort; private TestMenuItem mOptionLauncher; private TestMenuItem mOptionShowHiddenFiles; + private TestMenuItem mOptionExtractAll; private TestMenuItem subOptionGrid; private TestMenuItem subOptionList; @@ -124,6 +126,7 @@ public final class MenuManagerTest { dirOpenWith = testMenu.findItem(R.id.dir_menu_open_with); dirCutToClipboard = testMenu.findItem(R.id.dir_menu_cut_to_clipboard); dirCopyToClipboard = testMenu.findItem(R.id.dir_menu_copy_to_clipboard); + mDirCompress = testMenu.findItem(R.id.dir_menu_compress); dirPasteFromClipboard = testMenu.findItem(R.id.dir_menu_paste_from_clipboard); dirCreateDir = testMenu.findItem(R.id.dir_menu_create_dir); dirSelectAll = testMenu.findItem(R.id.dir_menu_select_all); @@ -162,6 +165,7 @@ public final class MenuManagerTest { optionSort = testMenu.findItem(R.id.option_menu_sort); mOptionLauncher = testMenu.findItem(R.id.option_menu_launcher); mOptionShowHiddenFiles = testMenu.findItem(R.id.option_menu_show_hidden_files); + mOptionExtractAll = testMenu.findItem(R.id.option_menu_extract_all); // Menu actions on root title row. subOptionGrid = testMenu.findItem(R.id.sub_menu_grid); @@ -195,6 +199,7 @@ public final class MenuManagerTest { mActionModeDeselectAll.assertDisabledAndInvisible(); actionModeViewInOwner.assertDisabledAndInvisible(); actionModeSort.assertEnabledAndVisible(); + mOptionExtractAll.assertDisabledAndInvisible(); } @Test @@ -268,6 +273,7 @@ public final class MenuManagerTest { optionSort.assertEnabledAndVisible(); mOptionLauncher.assertDisabledAndInvisible(); mOptionShowHiddenFiles.assertEnabledAndVisible(); + mOptionExtractAll.assertDisabledAndInvisible(); assertTrue(testSearchManager.showMenuCalled()); } @@ -281,6 +287,7 @@ public final class MenuManagerTest { optionCreateDir.assertDisabledAndInvisible(); subOptionGrid.assertEnabledAndVisible(); subOptionList.assertDisabledAndInvisible(); + mOptionExtractAll.assertDisabledAndInvisible(); assertFalse(testSearchManager.showMenuCalled()); } @@ -300,6 +307,7 @@ public final class MenuManagerTest { subOptionGrid.assertDisabledAndInvisible(); subOptionList.assertDisabledAndInvisible(); + mOptionExtractAll.assertDisabledAndInvisible(); } @@ -402,6 +410,7 @@ public final class MenuManagerTest { dirOpenWith.assertDisabledAndInvisible(); dirCutToClipboard.assertDisabledAndInvisible(); dirCopyToClipboard.assertEnabledAndVisible(); + mDirCompress.assertDisabledAndInvisible(); dirRename.assertDisabledAndInvisible(); dirDelete.assertDisabledAndInvisible(); } @@ -414,6 +423,7 @@ public final class MenuManagerTest { dirOpenInNewWindow.assertDisabledAndInvisible(); dirCutToClipboard.assertDisabledAndInvisible(); dirCopyToClipboard.assertEnabledAndVisible(); + mDirCompress.assertDisabledAndInvisible(); // Doesn't matter if directory is selected, we don't want pasteInto for PickerActivity dirPasteIntoFolder.assertDisabledAndInvisible(); dirRename.assertDisabledAndInvisible(); @@ -429,6 +439,7 @@ public final class MenuManagerTest { mgr.updateContextMenu(testMenu, selectionDetails); dirCutToClipboard.assertEnabledAndVisible(); dirCopyToClipboard.assertEnabledAndVisible(); + mDirCompress.assertDisabledAndInvisible(); dirDelete.assertEnabledAndVisible(); } @@ -442,6 +453,7 @@ public final class MenuManagerTest { mgr.updateContextMenu(testMenu, selectionDetails); dirCutToClipboard.assertDisabledAndInvisible(); dirCopyToClipboard.assertDisabledAndInvisible(); + mDirCompress.assertDisabledAndInvisible(); dirDelete.assertEnabledAndVisible(); } @@ -454,6 +466,7 @@ public final class MenuManagerTest { mgr.updateContextMenu(testMenu, selectionDetails); dirCutToClipboard.assertDisabledAndInvisible(); dirCopyToClipboard.assertEnabledAndVisible(); + mDirCompress.assertDisabledAndInvisible(); dirDelete.assertDisabledAndInvisible(); } |