summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml14
-rw-r--r--res/values-af/strings.xml5
-rw-r--r--res/values-am/strings.xml5
-rw-r--r--res/values-ar/strings.xml25
-rw-r--r--res/values-az-rAZ/strings.xml63
-rw-r--r--res/values-az/strings.xml62
-rw-r--r--res/values-be/strings.xml58
-rw-r--r--res/values-bg/strings.xml5
-rw-r--r--res/values-ca/strings.xml5
-rw-r--r--res/values-cs/strings.xml5
-rw-r--r--res/values-da/strings.xml9
-rw-r--r--res/values-de/strings.xml5
-rw-r--r--res/values-el/strings.xml5
-rw-r--r--res/values-en-rGB/strings.xml5
-rw-r--r--res/values-en-rIN/strings.xml63
-rw-r--r--res/values-es-rUS/strings.xml5
-rw-r--r--res/values-es/strings.xml5
-rw-r--r--res/values-et-rEE/strings.xml (renamed from res/values-et/strings.xml)5
-rw-r--r--res/values-fa/strings.xml31
-rw-r--r--res/values-fi/strings.xml5
-rw-r--r--res/values-fr-rCA/strings.xml63
-rw-r--r--res/values-fr/strings.xml5
-rw-r--r--res/values-hi/strings.xml19
-rw-r--r--res/values-hr/strings.xml5
-rw-r--r--res/values-hu/strings.xml5
-rw-r--r--res/values-hy-rAM/strings.xml63
-rw-r--r--res/values-in/strings.xml5
-rw-r--r--res/values-it/strings.xml11
-rw-r--r--res/values-iw/strings.xml31
-rw-r--r--res/values-ja/strings.xml5
-rw-r--r--res/values-ka-rGE/strings.xml63
-rw-r--r--res/values-km-rKH/strings.xml63
-rw-r--r--res/values-ko/strings.xml5
-rw-r--r--res/values-lo-rLA/strings.xml63
-rw-r--r--res/values-lt/strings.xml5
-rw-r--r--res/values-lv/strings.xml5
-rw-r--r--res/values-mn-rMN/strings.xml63
-rw-r--r--res/values-ms-rMY/strings.xml (renamed from res/values-ms/strings.xml)5
-rw-r--r--res/values-nb/strings.xml9
-rw-r--r--res/values-ne-rNP/strings.xml63
-rw-r--r--res/values-ne/strings.xml62
-rw-r--r--res/values-nl/strings.xml5
-rw-r--r--res/values-pl/strings.xml7
-rw-r--r--res/values-pt-rPT/strings.xml5
-rw-r--r--res/values-pt/strings.xml5
-rw-r--r--res/values-ro/strings.xml5
-rw-r--r--res/values-ru/strings.xml5
-rw-r--r--res/values-si-rLK/strings.xml63
-rw-r--r--res/values-si/strings.xml62
-rw-r--r--res/values-sk/strings.xml49
-rw-r--r--res/values-sl/strings.xml5
-rw-r--r--res/values-sr/strings.xml5
-rw-r--r--res/values-sv/strings.xml5
-rw-r--r--res/values-sw/strings.xml23
-rw-r--r--res/values-th/strings.xml5
-rw-r--r--res/values-tl/strings.xml5
-rw-r--r--res/values-tr/strings.xml5
-rw-r--r--res/values-uk/strings.xml5
-rw-r--r--res/values-vi/strings.xml5
-rw-r--r--res/values-zh-rCN/strings.xml5
-rw-r--r--res/values-zh-rHK/strings.xml63
-rw-r--r--res/values-zh-rTW/strings.xml5
-rw-r--r--res/values-zu/strings.xml11
-rw-r--r--src/com/android/providers/downloads/Constants.java17
-rw-r--r--src/com/android/providers/downloads/DownloadIdleService.java143
-rw-r--r--src/com/android/providers/downloads/DownloadInfo.java82
-rw-r--r--src/com/android/providers/downloads/DownloadProvider.java21
-rw-r--r--src/com/android/providers/downloads/DownloadReceiver.java57
-rw-r--r--src/com/android/providers/downloads/DownloadService.java73
-rw-r--r--src/com/android/providers/downloads/DownloadThread.java886
-rw-r--r--src/com/android/providers/downloads/Helpers.java219
-rw-r--r--src/com/android/providers/downloads/StopRequestException.java8
-rw-r--r--src/com/android/providers/downloads/StorageManager.java472
-rw-r--r--src/com/android/providers/downloads/StorageUtils.java271
-rw-r--r--tests/AndroidManifest.xml2
-rw-r--r--tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java36
-rw-r--r--tests/src/com/android/providers/downloads/AbstractPublicApiTest.java15
-rw-r--r--tests/src/com/android/providers/downloads/FakeSystemFacade.java4
-rw-r--r--tests/src/com/android/providers/downloads/HelpersTest.java68
-rw-r--r--tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java14
-rw-r--r--tests/src/com/android/providers/downloads/StorageTest.java247
-rw-r--r--tests/src/com/android/providers/downloads/ThreadingTest.java11
-rw-r--r--ui/res/values-ar/strings.xml2
-rw-r--r--ui/res/values-az-rAZ/strings.xml50
-rw-r--r--ui/res/values-az/strings.xml50
-rw-r--r--ui/res/values-be/strings.xml50
-rw-r--r--ui/res/values-ca/strings.xml2
-rw-r--r--ui/res/values-en-rIN/strings.xml50
-rw-r--r--ui/res/values-et-rEE/strings.xml (renamed from ui/res/values-et/strings.xml)0
-rw-r--r--ui/res/values-fa/strings.xml2
-rw-r--r--ui/res/values-fr-rCA/strings.xml50
-rw-r--r--ui/res/values-hy-rAM/strings.xml50
-rw-r--r--ui/res/values-in/strings.xml4
-rw-r--r--ui/res/values-iw/strings.xml2
-rw-r--r--ui/res/values-ka-rGE/strings.xml50
-rw-r--r--ui/res/values-km-rKH/strings.xml50
-rw-r--r--ui/res/values-lo-rLA/strings.xml50
-rw-r--r--ui/res/values-mn-rMN/strings.xml50
-rw-r--r--ui/res/values-ms-rMY/strings.xml (renamed from ui/res/values-ms/strings.xml)0
-rw-r--r--ui/res/values-ne-rNP/strings.xml50
-rw-r--r--ui/res/values-ne/strings.xml50
-rw-r--r--ui/res/values-si-rLK/strings.xml50
-rw-r--r--ui/res/values-si/strings.xml50
-rw-r--r--ui/res/values-sk/strings.xml26
-rw-r--r--ui/res/values-th/strings.xml2
-rw-r--r--ui/res/values-zh-rHK/strings.xml50
106 files changed, 3402 insertions, 1390 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index cee7cbc..579f8dd 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -54,6 +54,7 @@
<!-- TODO: replace with READ_NETWORK_POLICY permission when it exists -->
<uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
<uses-permission android:name="android.permission.MODIFY_NETWORK_ACCOUNTING" />
+ <uses-permission android:name="android.permission.CLEAR_APP_CACHE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application android:process="android.process.media"
@@ -92,12 +93,21 @@
</intent-filter>
</provider>
- <service android:name=".DownloadService"
- android:permission="android.permission.ACCESS_DOWNLOAD_MANAGER" />
+ <service
+ android:name=".DownloadService"
+ android:permission="android.permission.ACCESS_DOWNLOAD_MANAGER" />
+
+ <service
+ android:name="com.android.providers.downloads.DownloadIdleService"
+ android:exported="true"
+ android:permission="android.permission.BIND_JOB_SERVICE">
+ </service>
+
<receiver android:name=".DownloadReceiver" android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
+ <action android:name="android.intent.action.UID_REMOVED" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MEDIA_MOUNTED" />
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index baf0e46..a8984e3 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> oor"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Kan nie lêer oopmaak nie"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Aflaaisels"</string>
+ <string name="download_queued" msgid="3302638231377947451">"In waglys"</string>
+ <string name="download_running" msgid="3925050393361158266">"Besig"</string>
+ <string name="download_error" msgid="5144180777324573236">"Onsuksesvol"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Tans aan die gang, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 049ef77..fd5a94f 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> ቀርቷል"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"ፋይል መክፈት አይቻልም"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"የወረዱ"</string>
+ <string name="download_queued" msgid="3302638231377947451">"ወረፋ ይዟል"</string>
+ <string name="download_running" msgid="3925050393361158266">"በሂደት ላይ"</string>
+ <string name="download_error" msgid="5144180777324573236">"ስኬታማ ያልሆነ"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"በሂደት ላይ፣ <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 119671d..229ba23 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -21,26 +21,26 @@
<string name="permdesc_downloadManager" msgid="4237406545998908947">"للسماح للتطبيق بالدخول إلى إدارة التنزيل واستخدامها لتنزيل الملفات. يمكن للتطبيقات الضارة استخدام هذا لتعطيل التنزيلات والدخول إلى المعلومات الخاصة."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"وظائف إدارة التنزيل المتقدمة."</string>
<string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"للسماح للتطبيق بالدخول إلى وظائف إدارة التنزيل المتقدمة. يمكن للتطبيقات الضارة استخدام هذا لتعطيل التنزيلات والدخول إلى المعلومات الخاصة."</string>
- <string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"إرسال تنبيهات بالتنزيل."</string>
- <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"للسماح للتطبيق بإرسال تنبيهات عن التنزيلات المكتملة. يمكن للتطبيقات الضارة استخدام هذا لإرباك التطبيقات الأخرى التي تنزل الملفات."</string>
- <string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"عرض جميع التنزيلات إلى وحدة تخزين USB"</string>
- <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"مشاهدة جميع التنزيلات على بطاقة SD"</string>
- <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"للسماح للتطبيق بمشاهدة جميع التنزيلات على بطاقة SD، بغض النظر عن التطبيق الذي نزلها."</string>
+ <string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"إرسال اشعارات بالتنزيل."</string>
+ <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"للسماح للتطبيق بإرسال اشعارات عن التنزيلات المكتملة. يمكن للتطبيقات الضارة استخدام هذا لإرباك التطبيقات الأخرى التي تنزل الملفات."</string>
+ <string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"‏عرض جميع التنزيلات إلى وحدة تخزين USB"</string>
+ <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"‏مشاهدة جميع التنزيلات على بطاقة SD"</string>
+ <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"‏للسماح للتطبيق بمشاهدة جميع التنزيلات على بطاقة SD، بغض النظر عن التطبيق الذي نزلها."</string>
<string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"الاحتفاظ بمساحة في ذاكرة التخزين المؤقت للتنزيل"</string>
<string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"للسماح للتطبيق بتنزيل الملفات إلى ذاكرة التخزين المؤقت للتنزيل والتي لا يمكن حذفها تلقائيًا عندما تكون إدارة التنزيل في حاجة إلى مساحة أكبر."</string>
<string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"تنزيل الملفات بدون تنبيه"</string>
- <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"للسماح للتطبيق بتنزيل ملفات من خلال إدارة التنزيل بدون عرض أية تنبيهات للمستخدم."</string>
+ <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"للسماح للتطبيق بتنزيل ملفات من خلال إدارة التنزيل بدون عرض أية اشعارات للمستخدم."</string>
<string name="permlab_accessAllDownloads" msgid="2436240495424393717">"الدخول إلى جميع تنزيلات النظام"</string>
<string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"للسماح للتطبيق بعرض وتعديل جميع التنزيلات التي بدأت من خلال أي تطبيق على النظام."</string>
- <string name="download_unknown_title" msgid="7015124071247271585">"&lt;بلا عنوان&gt;"</string>
+ <string name="download_unknown_title" msgid="7015124071247271585">"‏&lt;بلا عنوان&gt;"</string>
<string name="notification_download_complete" msgid="5443563299253103667">"اكتمل التنزيل."</string>
<string name="notification_download_failed" msgid="8612136111952014978">"أخفق التنزيل."</string>
- <string name="notification_need_wifi_for_size" msgid="2556172885154833575">"يتطلب حجم التنزيل شبكة Wi-Fi."</string>
+ <string name="notification_need_wifi_for_size" msgid="2556172885154833575">"‏يتطلب حجم التنزيل شبكة Wi-Fi."</string>
<string name="notification_paused_in_background" msgid="4328508073283591772">"متوقف مؤقتًا في الخلفية."</string>
<string name="wifi_required_title" msgid="1995971416871498179">"حجم التنزيل كبير جدًا بالنسبة إلى مشغّل الشبكة"</string>
- <string name="wifi_required_body" msgid="3067694630143784449">"يجب استخدام Wi-Fi لإكمال هذا التنزيل البالغ حجمه <xliff:g id="SIZE">%s </xliff:g> . \n\nالمس <xliff:g id="QUEUE_TEXT">%s </xliff:g> لبدء هذا التنزيل في المرة القادمة التي تتصل فيها بشبكة Wi-Fi."</string>
+ <string name="wifi_required_body" msgid="3067694630143784449">"‏يجب استخدام Wi-Fi لإكمال هذا التنزيل البالغ حجمه <xliff:g id="SIZE">%s </xliff:g> . \n\nالمس <xliff:g id="QUEUE_TEXT">%s </xliff:g> لبدء هذا التنزيل في المرة القادمة التي تتصل فيها بشبكة Wi-Fi."</string>
<string name="wifi_recommended_title" msgid="7441589306734687400">"هل تريد وضعه في قائمة الانتظار للتنزيل لاحقًا؟"</string>
- <string name="wifi_recommended_body" msgid="1314735166699936073">"قد يؤدي بدء هذا التنزيل البالغ حجمه <xliff:g id="SIZE">%s </xliff:g> الآن إلى إنقاص عمر البطارية و/أو ينتج عنه استخدام زائد لاتصال بيانات الجوال، وهو ما يمكنه أن يؤدي إلى تحصيل مشغّل شبكة الجوال بعض الرسوم بناء على خطة البيانات الخاصة بك.\n\n المس <xliff:g id="QUEUE_TEXT">%s</xliff:g> لبدء هذا التنزيل في المرة القادمة التي تتصل فيها بشبكة Wi-Fi."</string>
+ <string name="wifi_recommended_body" msgid="1314735166699936073">"‏قد يؤدي بدء هذا التنزيل البالغ حجمه <xliff:g id="SIZE">%s </xliff:g> الآن إلى إنقاص عمر البطارية و/أو ينتج عنه استخدام زائد لاتصال بيانات الجوال، وهو ما يمكنه أن يؤدي إلى تحصيل مشغّل شبكة الجوال بعض الرسوم بناء على خطة البيانات الخاصة بك.\n\n المس <xliff:g id="QUEUE_TEXT">%s</xliff:g> لبدء هذا التنزيل في المرة القادمة التي تتصل فيها بشبكة Wi-Fi."</string>
<string name="button_queue_for_wifi" msgid="422576726189179221">"قائمة انتظار"</string>
<string name="button_cancel_download" msgid="2430166148737975604">"إلغاء"</string>
<string name="button_start_now" msgid="792123674007840864">"البدء الآن"</string>
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"المدة المتبقية: <xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"لا يمكن فتح الملف"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"التنزيلات"</string>
+ <string name="download_queued" msgid="3302638231377947451">"في قائمة الانتظار"</string>
+ <string name="download_running" msgid="3925050393361158266">"قيد التقدم"</string>
+ <string name="download_error" msgid="5144180777324573236">"أخفق الاتصال بالشبكة"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"قيد التقدم، <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-az-rAZ/strings.xml b/res/values-az-rAZ/strings.xml
new file mode 100644
index 0000000..28af64d
--- /dev/null
+++ b/res/values-az-rAZ/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3658948994665187911">"Endirmə İdarəçisi"</string>
+ <string name="permlab_downloadManager" msgid="7779544811202855500">"Endirmə idarəçisinə daxil ol."</string>
+ <string name="permdesc_downloadManager" msgid="4237406545998908947">"Tətbiqə faylları endirmək üçün endirmə idarçisinə daxil olmağa imkan verir. Zərərli tətbiqlər bundan endirmələri pozmaq və özəl məlumatlara daxil olmaq üçün istifadə edə bilər."</string>
+ <string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Ətraflı endirmə idarəçisi funksiyaları."</string>
+ <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"Tətbiqə endirmə idarəçisinin inkişaf etmiş funksiyalarına daxil olmaq üçün imkan verir. Zərərli tətbiqlər bunu endirmələri pozmaq və özəl məlumatlara daxil olmaq üçün istifadə edə bilər."</string>
+ <string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Endirmə məlumatı göndər."</string>
+ <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"Tətbiqə tamamlanmış endirmələr haqqında məlumat göndərməyə imkan verir. Zərərli tətbiqlər bunu faylları endirən tətbiqləri çaşdırmaq üçün istifadə edə bilər."</string>
+ <string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"USB yaddaşına bütün endirmələrə baxın"</string>
+ <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"SD karta endirmələrə baxın"</string>
+ <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"Tətbiqə hansı tətbiqin endirdiyindən asılı olmayaraq yaddaş kartındakı endirilən faylları görmə imkanı verir."</string>
+ <string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"Endirmə keşində ehtiyat yer mühafizə et"</string>
+ <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"Tətbiqə endirmə idarəçisinə daha çox yer lazım olanda başqa faylları endirmə vasitəsi ilə avtomatik olarak silinməyən keşlər endirməsinə imkan verir."</string>
+ <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"xəbərdarlıq etmədən faylları endir"</string>
+ <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"Bu tətbiq istifadəçiyə hər hansı bir məlumat göstərmədən faylları endirmə idarəçisi vasitəsi ilə endirmək imkanı verir."</string>
+ <string name="permlab_accessAllDownloads" msgid="2436240495424393717">"Sistemdəki bütün endirilənlərə gir"</string>
+ <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"Tətbiqə başqa bir tətbiq vasitəsi ilə başladılan endirmələri göstərmək və dəyişdirmək imkanı verir."</string>
+ <string name="download_unknown_title" msgid="7015124071247271585">"&lt;Başlıqsız&gt;"</string>
+ <string name="notification_download_complete" msgid="5443563299253103667">"Endirmə tamamlandı."</string>
+ <string name="notification_download_failed" msgid="8612136111952014978">"Endirmə uğursuz oldu."</string>
+ <string name="notification_need_wifi_for_size" msgid="2556172885154833575">"Endirmə həcmi Wi-Fi tələb edir."</string>
+ <string name="notification_paused_in_background" msgid="4328508073283591772">"Arxa fonda dayandırıldı."</string>
+ <string name="wifi_required_title" msgid="1995971416871498179">"Endirmə operator şəbəkə üçün çox böyükdür"</string>
+ <string name="wifi_required_body" msgid="3067694630143784449">"Bu <xliff:g id="SIZE">%s </xliff:g> endirməni başa çatdırmaq üçün Wi-Fi istifadə etməlisiniz. \n \n Növbəti dəfə WiFi şəbəkəsinə qoşulanda bu endirməni başlatmaq üçün <xliff:g id="QUEUE_TEXT">%s </xliff:g> toxunun."</string>
+ <string name="wifi_recommended_title" msgid="7441589306734687400">"Daha sonra endirmək üçün növbəyə salmaq istəyirsiniz?"</string>
+ <string name="wifi_recommended_body" msgid="1314735166699936073">"Bu <xliff:g id="SIZE">%s </xliff:g> böyüklükdəki faylı endirməyə başlamaq batareyanızı azalda bilər/və ya mobil data əlaqənizin böyük bir hissəsinin işlədilməsinə gətirib çixara bilər, bu da sizin data planınınızdan asılı olaraq mobil operatorunuz tərəfindən xərcə səbəb ola bilər. \n \n Növbəti dəfə WiFi şəbəkəsinə qoşulanda bu endirməyə başlamaq üçün <xliff:g id="QUEUE_TEXT">%s</xliff:g> toxunun."</string>
+ <string name="button_queue_for_wifi" msgid="422576726189179221">"Növbəyə sal"</string>
+ <string name="button_cancel_download" msgid="2430166148737975604">"Ləğv et"</string>
+ <string name="button_start_now" msgid="792123674007840864">"İndi başlat"</string>
+ <string name="download_percent" msgid="6889426633242976698">"<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <plurals name="notif_summary_active">
+ <item quantity="one" msgid="8475775855911967027">"1 fayl endirilir"</item>
+ <item quantity="other" msgid="9087228371320573153">"<xliff:g id="NUMBER">%d</xliff:g> fayl endirilir"</item>
+ </plurals>
+ <plurals name="notif_summary_waiting">
+ <item quantity="one" msgid="5537481763963544278">"1 fayl gözləyir"</item>
+ <item quantity="other" msgid="549229034166062887">"<xliff:g id="NUMBER">%d</xliff:g> fayl gözləyir"</item>
+ </plurals>
+ <string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> qalır"</string>
+ <string name="download_no_application_title" msgid="7935659741162801699">"Fayl açılmır"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Endirmələr"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Növbəyə salınıb"</string>
+ <string name="download_running" msgid="3925050393361158266">"Davam edir"</string>
+ <string name="download_error" msgid="5144180777324573236">"Uğursuz"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"İrəliləyir, <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
+</resources>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
new file mode 100644
index 0000000..cb1bb74
--- /dev/null
+++ b/res/values-az/strings.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3658948994665187911">"Endirmə İdarəçisi"</string>
+ <string name="permlab_downloadManager" msgid="7779544811202855500">"Endirmə idarəçisinə daxil ol."</string>
+ <string name="permdesc_downloadManager" msgid="4237406545998908947">"Tətbiqə faylları endirmək üçün endirmə idarçisinə daxil olmağa imkan verir. Zərərli tətbiqlər bundan endirmələri pozmaq və özəl məlumatlara daxil olmaq üçün istifadə edə bilər."</string>
+ <string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Ətraflı endirmə idarəçisi funksiyaları."</string>
+ <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"Tətbiqə endirmə idarəçisinin inkişaf etmiş funksiyalarına daxil olmaq üçün imkan verir. Zərərli tətbiqlər bunu endirmələri pozmaq və özəl məlumatlara daxil olmaq üçün istifadə edə bilər."</string>
+ <string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Endirmə məlumatı göndər."</string>
+ <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"Tətbiqə tamamlanmış endirmələr haqqında məlumat göndərməyə imkan verir. Zərərli tətbiqlər bunu faylları endirən tətbiqləri çaşdırmaq üçün istifadə edə bilər."</string>
+ <string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"USB yaddaşına bütün endirmələrə baxın"</string>
+ <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"SD karta endirmələrə baxın"</string>
+ <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"Tətbiqə hansı tətbiqin endirdiyindən asılı olmayaraq yaddaş kartındakı endirilən faylları görmə imkanı verir."</string>
+ <string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"Endirmə keşində ehtiyat yer mühafizə et"</string>
+ <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"Tətbiqə endirmə idarəçisinə daha çox yer lazım olanda başqa faylları endirmə vasitəsi ilə avtomatik olarak silinməyən keşlər endirməsinə imkan verir."</string>
+ <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"xəbərdarlıq etmədən faylları endir"</string>
+ <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"Bu tətbiq istifadəçiyə hər hansı bir məlumat göstərmədən faylları endirmə idarəçisi vasitəsi ilə endirmək imkanı verir."</string>
+ <string name="permlab_accessAllDownloads" msgid="2436240495424393717">"Sistemdəki bütün endirilənlərə gir"</string>
+ <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"Tətbiqə başqa bir tətbiq vasitəsi ilə başladılan endirmələri göstərmək və dəyişdirmək imkanı verir."</string>
+ <string name="download_unknown_title" msgid="7015124071247271585">"&lt;Başlıqsız&gt;"</string>
+ <string name="notification_download_complete" msgid="5443563299253103667">"Endirmə tamamlandı."</string>
+ <string name="notification_download_failed" msgid="8612136111952014978">"Endirmə uğursuz oldu."</string>
+ <string name="notification_need_wifi_for_size" msgid="2556172885154833575">"Endirmə həcmi Wi-Fi tələb edir."</string>
+ <string name="notification_paused_in_background" msgid="4328508073283591772">"Arxa fonda dayandırıldı."</string>
+ <string name="wifi_required_title" msgid="1995971416871498179">"Endirmə operator şəbəkə üçün çox böyükdür"</string>
+ <string name="wifi_required_body" msgid="3067694630143784449">"Bu <xliff:g id="SIZE">%s </xliff:g> endirməni başa çatdırmaq üçün Wi-Fi istifadə etməlisiniz. \n \n Növbəti dəfə WiFi şəbəkəsinə qoşulanda bu endirməni başlatmaq üçün <xliff:g id="QUEUE_TEXT">%s </xliff:g> toxunun."</string>
+ <string name="wifi_recommended_title" msgid="7441589306734687400">"Daha sonra endirmək üçün növbəyə salmaq istəyirsiniz?"</string>
+ <string name="wifi_recommended_body" msgid="1314735166699936073">"Bu <xliff:g id="SIZE">%s </xliff:g> böyüklükdəki faylı endirməyə başlamaq batareyanızı azalda bilər/və ya mobil data əlaqənizin böyük bir hissəsinin işlədilməsinə gətirib çixara bilər, bu da sizin data planınınızdan asılı olaraq mobil operatorunuz tərəfindən xərcə səbəb ola bilər. \n \n Növbəti dəfə WiFi şəbəkəsinə qoşulanda bu endirməyə başlamaq üçün <xliff:g id="QUEUE_TEXT">%s</xliff:g> toxunun."</string>
+ <string name="button_queue_for_wifi" msgid="422576726189179221">"Növbəyə sal"</string>
+ <string name="button_cancel_download" msgid="2430166148737975604">"Ləğv et"</string>
+ <string name="button_start_now" msgid="792123674007840864">"İndi başlat"</string>
+ <string name="download_percent" msgid="6889426633242976698">"<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <plurals name="notif_summary_active">
+ <item quantity="one" msgid="8475775855911967027">"1 fayl endirilir"</item>
+ <item quantity="other" msgid="9087228371320573153">"<xliff:g id="NUMBER">%d</xliff:g> fayl endirilir"</item>
+ </plurals>
+ <plurals name="notif_summary_waiting">
+ <item quantity="one" msgid="5537481763963544278">"1 fayl gözləyir"</item>
+ <item quantity="other" msgid="549229034166062887">"<xliff:g id="NUMBER">%d</xliff:g> fayl gözləyir"</item>
+ </plurals>
+ <string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> qalır"</string>
+ <string name="download_no_application_title" msgid="7935659741162801699">"Fayl açılmır"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Endirmələr"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Növbəyə salınıb"</string>
+ <string name="download_running" msgid="3925050393361158266">"Davam edir"</string>
+ <string name="download_error" msgid="5144180777324573236">"Uğursuz"</string>
+</resources>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
deleted file mode 100644
index f4b59a8..0000000
--- a/res/values-be/strings.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="3658948994665187911">"Менеджэр спампоўвання"</string>
- <string name="permlab_downloadManager" msgid="7779544811202855500">"Доступ да менеджэра спампоўванняў."</string>
- <string name="permdesc_downloadManager" msgid="4237406545998908947">"Дазваляе прыкладанню атрымлiваць доступ да менеджэра спампавання i выкарыстоўваць яго для спампавання файлаў. Шкоднасныя прыкладаннi могуць выкарыстоўваць гэта, каб сарваць загрузку і закрыць доступ да прыватнай інфармацыі."</string>
- <string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Пашыраныя функцыі менеджэра спампоўванняў."</string>
- <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"Дазваляе прыкладанню атрымлiваць доступ да пашыраных функцый менеджэра спампавання. Шкоднасныя прыкладаннi могуць выкарыстоўваць гэта, каб сарваць загрузку і закрыць доступ да прыватнай інфармацыі."</string>
- <string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Адпраўляць апавяшчэнні аб спампоўцы."</string>
- <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"Дазваляе прыкладанню адпраўляць апавяшчэннi аб завершаных спампаваннях. Шкоднасныя прыкладаннi могуць выкарыстоўваць гэта, каб негатыўна паўсплываць на іншыя прыкладаннi для спампавання файлаў."</string>
- <string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"Прагледзець усе спампоўкі на USB-назапашвальнiк"</string>
- <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"Прагледзець усе спампоўкі на SD-карце"</string>
- <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"Дазваляе прыкладанюе бачыць усе спампоўкі на SD-карце, незалежна ад таго, праз якое прыкладанне яны былi спампаваны."</string>
- <string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"Зарэзерваваць месца ў кэшы спампоўкі"</string>
- <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"Дазваляе прыкладанню спампоўваць файлы ў кэш-памяць, якую нельга ачысцiць аўтаматычна, калі менеджэру спампавання спатрэбіцца больш месца на дыске."</string>
- <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"спампоўваць файлы без апавяшчэння"</string>
- <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"Дазваляе прыкладанню спампоўваць файлы праз менеджэр спампавання, не кажучы пра гэта карыстальнiку."</string>
- <string name="permlab_accessAllDownloads" msgid="2436240495424393717">"Доступ да ўсіх сістэмных спамповак"</string>
- <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"Дазваляе прыкладанню праглядаць і змяняць усе спампоўкi, пачатыя любым сiстэмным прыкладаннем."</string>
- <string name="download_unknown_title" msgid="7015124071247271585">"&lt;Без назвы&gt;"</string>
- <string name="notification_download_complete" msgid="5443563299253103667">"Спампаванне завершана"</string>
- <string name="notification_download_failed" msgid="8612136111952014978">"Не атрымалася спампаваць."</string>
- <string name="notification_need_wifi_for_size" msgid="2556172885154833575">"Для спампавання патрабуецца сетка Wi-Fi"</string>
- <string name="notification_paused_in_background" msgid="4328508073283591772">"Прыпынена ў фон. рэжыме"</string>
- <string name="wifi_required_title" msgid="1995971416871498179">"Спампоўка занадта вялікая для сеткі аператара"</string>
- <string name="wifi_required_body" msgid="3067694630143784449">"Каб завяршыць спампаванне файла памерам <xliff:g id="SIZE">%s </xliff:g>, патрабуецца падлучэнне да сеткi Wi-Fi. \n\nДакранiцеся да надпiсу <xliff:g id="QUEUE_TEXT">%s </xliff:g>, каб пачаць спампаванне, калi будзе даступна сетка Wi-Fi."</string>
- <string name="wifi_recommended_title" msgid="7441589306734687400">"Стаць у чаргу, каб спампаваць пазней?"</string>
- <string name="wifi_recommended_body" msgid="1314735166699936073">"Спампаванне файла памерам <xliff:g id="SIZE">%s </xliff:g> можа скараціць тэрмін службы акумулятара або прывесці да празмернага выкарыстання мабільнага падлучэння дадзеных, за што вашым мабiльным аператарам можа спаганяцца дадатковая плата.\n\nДакранiцеся да надпiсу <xliff:g id="QUEUE_TEXT">%s</xliff:g>, каб пачаць спампаванне, калi з\'явiцца падлучэнне да сеткi Wi-Fi."</string>
- <string name="button_queue_for_wifi" msgid="422576726189179221">"Чарга"</string>
- <string name="button_cancel_download" msgid="2430166148737975604">"Адмена"</string>
- <string name="button_start_now" msgid="792123674007840864">"Пачаць прама цяпер"</string>
- <string name="download_percent" msgid="6889426633242976698">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
- <plurals name="notif_summary_active">
- <item quantity="one" msgid="8475775855911967027">"Спампоўваецца 1 файл"</item>
- <item quantity="other" msgid="9087228371320573153">"Спампоўваюцца файлы: <xliff:g id="NUMBER">%d</xliff:g>"</item>
- </plurals>
- <plurals name="notif_summary_waiting">
- <item quantity="one" msgid="5537481763963544278">"1 файл чакае"</item>
- <item quantity="other" msgid="549229034166062887">"Файлы чакаюць: <xliff:g id="NUMBER">%d</xliff:g>"</item>
- </plurals>
- <string name="download_remaining" msgid="3139295890887972718">"Засталося <xliff:g id="DURATION">%s</xliff:g>"</string>
- <string name="download_no_application_title" msgid="7935659741162801699">"Не атрымлiваецца адкрыць файл"</string>
-</resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 79df065..0341681 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"Оставащо време: <xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Файлът не може да се отвори"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Изтегляния"</string>
+ <string name="download_queued" msgid="3302638231377947451">"На опашка"</string>
+ <string name="download_running" msgid="3925050393361158266">"В ход"</string>
+ <string name="download_error" msgid="5144180777324573236">"Неуспешно"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"В ход – <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index f1f3618..4d95aa8 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"Temps restant: <xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"No es pot obrir el fitxer"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Baixades"</string>
+ <string name="download_queued" msgid="3302638231377947451">"En cua"</string>
+ <string name="download_running" msgid="3925050393361158266">"En curs"</string>
+ <string name="download_error" msgid="5144180777324573236">"Incorrecte"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"En curs, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index a800fca..b8c3757 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> do stažení"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Soubor nelze otevřít"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Ke stažení"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Ve frontě"</string>
+ <string name="download_running" msgid="3925050393361158266">"Probíhá"</string>
+ <string name="download_error" msgid="5144180777324573236">"Neúspěšné"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Probíhá (<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>)"</string>
</resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 7802892..5928073 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -21,14 +21,14 @@
<string name="permdesc_downloadManager" msgid="4237406545998908947">"Tillader, at appen kan få adgang til downloadadministratoren og til at bruge den til at downloade filer. Ondsindede apps kan bruge dette til at afbryde downloads og få adgang til personlige oplysninger."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Avancerede funktioner for downloadadministrator."</string>
<string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"Tillader, at appen kan få adgang til downloadadministrators avancerede funktioner. Ondsindede apps kan bruge dette til at afbryde downloads og få adgang til personlige oplysninger."</string>
- <string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Send downloadmeddelelser."</string>
+ <string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Send underretninger om downloads."</string>
<string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"Tillader, at appen kan sende meddelelser om fuldførte downloads. Ondsindede apps kan bruge dette til at forvirre andre apps, der downloader filer."</string>
<string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"Se alle downloads til USB-lagr."</string>
<string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"Se alle downloads til SD-kort"</string>
<string name="permdesc_seeAllExternal" msgid="1672759909065511233">"Tillader, at appen kan se alle downloads på SD-kortet, uanset hvilken app der har downloadet dem."</string>
<string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"Reserver plads i downloadcache"</string>
<string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"Tillader, at appen kan downloade filer til downloadcachen, som ikke automatisk kan slettes, når downloadadministratoren har brug for mere plads."</string>
- <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"download filer uden meddelelse"</string>
+ <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"downloade filer uden underretning"</string>
<string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"Tillader, at appen kan downloade filer via downloadadministratoren, uden at brugeren får besked."</string>
<string name="permlab_accessAllDownloads" msgid="2436240495424393717">"Adgang til alle systemdownloads"</string>
<string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"Tillader, at appen kan se og ændre alle downloads, der igangsættes af en app i systemet."</string>
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> tilbage"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Filen kan ikke åbnes"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Downloads"</string>
+ <string name="download_queued" msgid="3302638231377947451">"I kø"</string>
+ <string name="download_running" msgid="3925050393361158266">"I gang"</string>
+ <string name="download_error" msgid="5144180777324573236">"Mislykkedes"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"I gang, <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 4345170..5fa35c1 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"Noch <xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Datei kann nicht geöffnet werden."</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Downloads"</string>
+ <string name="download_queued" msgid="3302638231377947451">"In der Warteschlange"</string>
+ <string name="download_running" msgid="3925050393361158266">"In Bearbeitung"</string>
+ <string name="download_error" msgid="5144180777324573236">"Nicht erfolgreich"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Läuft, <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 1f749e7..ba74568 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"Απομένουν <xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Δεν είναι δυνατό το άνοιγμα του αρχείου"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Λήψεις"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Σε ουρά"</string>
+ <string name="download_running" msgid="3925050393361158266">"Σε εξέλιξη"</string>
+ <string name="download_error" msgid="5144180777324573236">"Ανεπιτυχής"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Σε εξέλιξη, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 8cea9ac..26fede3 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> left"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Can\'t open file"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Downloads"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Queued"</string>
+ <string name="download_running" msgid="3925050393361158266">"In progress"</string>
+ <string name="download_error" msgid="5144180777324573236">"Unsuccessful"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"In progress, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..26fede3
--- /dev/null
+++ b/res/values-en-rIN/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3658948994665187911">"Download Manager"</string>
+ <string name="permlab_downloadManager" msgid="7779544811202855500">"Access download manager."</string>
+ <string name="permdesc_downloadManager" msgid="4237406545998908947">"Allows the app to access the download manager and to use it to download files. Malicious apps can use this to disrupt downloads and access private information."</string>
+ <string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Advanced download manager functions."</string>
+ <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"Allows the app to access the download manager\'s advanced functions. Malicious apps can use this to disrupt downloads and access private information."</string>
+ <string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Send download notifications."</string>
+ <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"Allows the app to send notifications about completed downloads. Malicious apps can use this to confuse other apps that download files."</string>
+ <string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"See all downloads to USB storage"</string>
+ <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"See all downloads to SD card"</string>
+ <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"Allows the app to see all downloads to the SD card, regardless of which app downloaded them."</string>
+ <string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"Reserve space in the download cache"</string>
+ <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"Allows the app to download files to the download cache, which can\'t be deleted automatically when the download manager needs more space."</string>
+ <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"download files without notification"</string>
+ <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"Allows the application to download files through the download manager without any notification being shown to the user."</string>
+ <string name="permlab_accessAllDownloads" msgid="2436240495424393717">"Access all system downloads"</string>
+ <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"Allows the app to view and modify all downloads initiated by any app on the system."</string>
+ <string name="download_unknown_title" msgid="7015124071247271585">"&lt;Untitled&gt;"</string>
+ <string name="notification_download_complete" msgid="5443563299253103667">"Download complete."</string>
+ <string name="notification_download_failed" msgid="8612136111952014978">"Download unsuccessful."</string>
+ <string name="notification_need_wifi_for_size" msgid="2556172885154833575">"Download size requires Wi-Fi"</string>
+ <string name="notification_paused_in_background" msgid="4328508073283591772">"Paused in background"</string>
+ <string name="wifi_required_title" msgid="1995971416871498179">"Download too large for operator network"</string>
+ <string name="wifi_required_body" msgid="3067694630143784449">"You must use Wi-Fi to complete this <xliff:g id="SIZE">%s </xliff:g> download. \n\nTouch <xliff:g id="QUEUE_TEXT">%s </xliff:g> to start this download the next time that you\'re connected to a Wi-Fi network."</string>
+ <string name="wifi_recommended_title" msgid="7441589306734687400">"Queue for download later?"</string>
+ <string name="wifi_recommended_body" msgid="1314735166699936073">"Starting this <xliff:g id="SIZE">%s </xliff:g> download now may shorten your battery life and/or result in excessive usage of your mobile data connection, which can lead to charges by your mobile operator depending on your data plan.\n\n Touch <xliff:g id="QUEUE_TEXT">%s</xliff:g> to start this download the next time that you\'re connected to a Wi-Fi network."</string>
+ <string name="button_queue_for_wifi" msgid="422576726189179221">"Queue"</string>
+ <string name="button_cancel_download" msgid="2430166148737975604">"Cancel"</string>
+ <string name="button_start_now" msgid="792123674007840864">"Start now"</string>
+ <string name="download_percent" msgid="6889426633242976698">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <plurals name="notif_summary_active">
+ <item quantity="one" msgid="8475775855911967027">"1 file downloading"</item>
+ <item quantity="other" msgid="9087228371320573153">"<xliff:g id="NUMBER">%d</xliff:g> files downloading"</item>
+ </plurals>
+ <plurals name="notif_summary_waiting">
+ <item quantity="one" msgid="5537481763963544278">"1 file waiting"</item>
+ <item quantity="other" msgid="549229034166062887">"<xliff:g id="NUMBER">%d</xliff:g> files waiting"</item>
+ </plurals>
+ <string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> left"</string>
+ <string name="download_no_application_title" msgid="7935659741162801699">"Can\'t open file"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Downloads"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Queued"</string>
+ <string name="download_running" msgid="3925050393361158266">"In progress"</string>
+ <string name="download_error" msgid="5144180777324573236">"Unsuccessful"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"In progress, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+</resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 0fbb309..9abcb6d 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> restantes"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"No se puede abrir el archivo."</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Descargas"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Pendiente"</string>
+ <string name="download_running" msgid="3925050393361158266">"En curso"</string>
+ <string name="download_error" msgid="5144180777324573236">"Error"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"En curso, <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 3735acc..8ab2eeb 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"Tiempo restante: <xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Error al abrir el archivo"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Descargas"</string>
+ <string name="download_queued" msgid="3302638231377947451">"En cola"</string>
+ <string name="download_running" msgid="3925050393361158266">"En curso"</string>
+ <string name="download_error" msgid="5144180777324573236">"No se ha completado"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"En curso (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
</resources>
diff --git a/res/values-et/strings.xml b/res/values-et-rEE/strings.xml
index a3503c2..16b97b6 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et-rEE/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"Jäänud: <xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Faili ei saa avada"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Allalaadimised"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Järjekorras"</string>
+ <string name="download_running" msgid="3925050393361158266">"Töötlemisel"</string>
+ <string name="download_error" msgid="5144180777324573236">"Ebaõnnestus"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Edenemine: <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 336d6f9..2586832 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -17,30 +17,30 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="3658948994665187911">"Download Manager"</string>
- <string name="permlab_downloadManager" msgid="7779544811202855500">"دسترسی به Download Manager."</string>
- <string name="permdesc_downloadManager" msgid="4237406545998908947">"به برنامهٔ کاربردی اجازه می‌دهد تا به download manager دسترسی داشته باشد و از آن برای دانلود فایل‌ها استفاده کند. برنامه‌های مضر می‌توانند از این امکان استفاده کرده و برای دانلودها مشکل ایجاد کنند و به اطلاعات خصوصی دسترسی داشته باشند."</string>
- <string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"عملکرد Download Manager پیشرفته."</string>
- <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"به برنامهٔ کاربردی اجازه می‌دهد تا به عملکردهای پیشرفته download manager دسترسی داشته باشد. برنامه‌های مضر می‌توانند از این امکان استفاده کرده و برای دانلودها مشکل ایجاد کنند و به اطلاعات خصوصی دسترسی داشته باشند."</string>
+ <string name="permlab_downloadManager" msgid="7779544811202855500">"‏دسترسی به Download Manager."</string>
+ <string name="permdesc_downloadManager" msgid="4237406545998908947">"‏به برنامهٔ کاربردی اجازه می‌دهد تا به download manager دسترسی داشته باشد و از آن برای دانلود فایل‌ها استفاده کند. برنامه‌های مضر می‌توانند از این امکان استفاده کرده و برای دانلودها مشکل ایجاد کنند و به اطلاعات خصوصی دسترسی داشته باشند."</string>
+ <string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"‏عملکرد Download Manager پیشرفته."</string>
+ <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"‏به برنامهٔ کاربردی اجازه می‌دهد تا به عملکردهای پیشرفته download manager دسترسی داشته باشد. برنامه‌های مضر می‌توانند از این امکان استفاده کرده و برای دانلودها مشکل ایجاد کنند و به اطلاعات خصوصی دسترسی داشته باشند."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"اعلان‌های دانلود ارسال شود."</string>
<string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"به برنامهٔ کاربردی اجازه می‌دهد اعلان‌های مربوط به دانلودهای کامل شده را ارسال کند. برنامه‌های مضر می‌توانند از این امکان استفاده کرده و برای سایر برنامه‌هایی که فایل‌ها را دانلود می‌کنند، مشکلاتی را ایجاد کنند."</string>
- <string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"مشاهدهٔ همه دانلودها در حافظهٔ USB"</string>
- <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"مشاهدهٔ همه دانلودها در کارت SD"</string>
- <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"به برنامهٔ کاربردی اجازه می‌دهد بدون در نظر گرفتن اینکه کدام برنامه دانلود را انجام داده است، تمام دانلودهای موجود در کارت SD را مشاهده کند."</string>
+ <string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"‏مشاهدهٔ همه دانلودها در حافظهٔ USB"</string>
+ <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"‏مشاهدهٔ همه دانلودها در کارت SD"</string>
+ <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"‏به برنامهٔ کاربردی اجازه می‌دهد بدون در نظر گرفتن اینکه کدام برنامه دانلود را انجام داده است، تمام دانلودهای موجود در کارت SD را مشاهده کند."</string>
<string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"رزرو فضا در حافظه موقت دانلود"</string>
- <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"به برنامهٔ کاربردی اجازه می‌دهد فایل‌ها را در حافظهٔ پنهان دانلود کند، تا هنگامی که Download Manager به فضای بیشتری احتیاج دارد، بطور خودکار حذف نشوند.+"</string>
+ <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"‏به برنامهٔ کاربردی اجازه می‌دهد فایل‌ها را در حافظهٔ پنهان دانلود کند، تا هنگامی که Download Manager به فضای بیشتری احتیاج دارد، بطور خودکار حذف نشوند.+"</string>
<string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"دانلود فایل‌ها بدون اطلاع"</string>
- <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"به برنامهٔ کاربردی اجازه می‌دهد فایل‌ها را از طریق Download Manager، بدون نمایش اعلان به کاربر دانلود کند."</string>
+ <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"‏به برنامهٔ کاربردی اجازه می‌دهد فایل‌ها را از طریق Download Manager، بدون نمایش اعلان به کاربر دانلود کند."</string>
<string name="permlab_accessAllDownloads" msgid="2436240495424393717">"دسترسی به همه دانلودهای سیستم"</string>
<string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"به برنامهٔ کاربردی اجازه می‌دهد تمام دانلودهای شروع شده توسط هر برنامه‌ای را در سیستم مشاهده کرده و تغییر دهد."</string>
- <string name="download_unknown_title" msgid="7015124071247271585">"&lt;بدون عنوان&gt;"</string>
+ <string name="download_unknown_title" msgid="7015124071247271585">"‏&lt;بدون عنوان&gt;"</string>
<string name="notification_download_complete" msgid="5443563299253103667">"دانلود کامل شد."</string>
<string name="notification_download_failed" msgid="8612136111952014978">"دانلود ناموفق بود."</string>
- <string name="notification_need_wifi_for_size" msgid="2556172885154833575">"برای این حجم از دانلود به Wi-Fi نیاز است."</string>
+ <string name="notification_need_wifi_for_size" msgid="2556172885154833575">"‏برای این حجم از دانلود به Wi-Fi نیاز است."</string>
<string name="notification_paused_in_background" msgid="4328508073283591772">"در پس‌زمینه موقتاً متوقف شد."</string>
<string name="wifi_required_title" msgid="1995971416871498179">"دانلود برای شبکه اپراتور بسیار بزرگ است"</string>
- <string name="wifi_required_body" msgid="3067694630143784449">"برای تکمیل این دانلود <xliff:g id="SIZE">%s </xliff:g> باید از Wi-Fi استفاده کنید. در اتصال بعدی به شبکه Wi-Fi و برای شروع دانلود، \n\nلمس<xliff:g id="QUEUE_TEXT">%s </xliff:g> کنید."</string>
+ <string name="wifi_required_body" msgid="3067694630143784449">"‏برای تکمیل این دانلود <xliff:g id="SIZE">%s </xliff:g> باید از Wi-Fi استفاده کنید. در اتصال بعدی به شبکه Wi-Fi و برای شروع دانلود، \n\nلمس<xliff:g id="QUEUE_TEXT">%s </xliff:g> کنید."</string>
<string name="wifi_recommended_title" msgid="7441589306734687400">"برای دانلود در فرصتی دیگر در صف گذاشته شود؟"</string>
- <string name="wifi_recommended_body" msgid="1314735166699936073">"شروع دانلود <xliff:g id="SIZE">%s </xliff:g> سبب کم شدن طول عمر باتری و/یا استفاده بیش از حد از اتصال داده تلفن همراه می‌شود که بسته به قرارداد ارائه داده شما ممکن است از طرف اپراتور تلفن هزینه‌هایی برای شما در نظر گرفته شود. \n\n<xliff:g id="QUEUE_TEXT">%s</xliff:g> را لمس کنید تا در اتصال بعدی به شبکه Wi-Fi، این دانلود شروع شود."</string>
+ <string name="wifi_recommended_body" msgid="1314735166699936073">"‏شروع دانلود <xliff:g id="SIZE">%s </xliff:g> سبب کم شدن طول عمر باتری و/یا استفاده بیش از حد از اتصال داده تلفن همراه می‌شود که بسته به قرارداد ارائه داده شما ممکن است از طرف اپراتور تلفن هزینه‌هایی برای شما در نظر گرفته شود. \n\n<xliff:g id="QUEUE_TEXT">%s</xliff:g> را لمس کنید تا در اتصال بعدی به شبکه Wi-Fi، این دانلود شروع شود."</string>
<string name="button_queue_for_wifi" msgid="422576726189179221">"صف"</string>
<string name="button_cancel_download" msgid="2430166148737975604">"لغو"</string>
<string name="button_start_now" msgid="792123674007840864">"اکنون شروع"</string>
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> باقیمانده"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"فایل باز نمی‌شود"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"دانلودها"</string>
+ <string name="download_queued" msgid="3302638231377947451">"در صف"</string>
+ <string name="download_running" msgid="3925050393361158266">"در حال انجام"</string>
+ <string name="download_error" msgid="5144180777324573236">"ناموفق"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"در حال انجام، <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 679d66d..6bc8807 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> jäljellä"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Tiedostoa ei voi avata"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Lataukset"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Jonossa"</string>
+ <string name="download_running" msgid="3925050393361158266">"Kesken"</string>
+ <string name="download_error" msgid="5144180777324573236">"Epäonnistui"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Käynnissä, <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..3ccab1a
--- /dev/null
+++ b/res/values-fr-rCA/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3658948994665187911">"Gestionnaire de téléchargement"</string>
+ <string name="permlab_downloadManager" msgid="7779544811202855500">"Accéder au gestionnaire de téléchargement."</string>
+ <string name="permdesc_downloadManager" msgid="4237406545998908947">"Permet à l\'application d\'accéder au gestionnaire de téléchargement et de l\'utiliser pour télécharger des fichiers. Des applications malveillantes peuvent utiliser cette fonctionnalité pour perturber les téléchargements et accéder à des données confidentielles."</string>
+ <string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Fonctions avancées du gestionnaire de téléchargement."</string>
+ <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"Permet à l\'application d\'accéder aux fonctionnalités avancées du gestionnaire de téléchargement. Les applications malveillantes peuvent utiliser cette fonctionnalité pour perturber les téléchargements et accéder à des données confidentielles."</string>
+ <string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Envoyer des notifications de téléchargement."</string>
+ <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"Permet à l\'application d\'envoyer des notifications relatives aux téléchargements terminés. Des applications malveillantes peuvent utiliser cette fonctionnalité pour induire en erreur d\'autres applications pouvant télécharger des fichiers."</string>
+ <string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"Voir tous les téléchargements sur la mémoire de stockage USB"</string>
+ <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"Voir tous les téléchargements effectués sur la carte SD"</string>
+ <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"Permet à l\'application de voir tous les téléchargements sur la carte SD, quelle que soit l\'application utilisée pour les télécharger."</string>
+ <string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"Réserver de l\'espace dans le cache de téléchargement"</string>
+ <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"Permet à l\'application de télécharger des fichiers dans le cache de téléchargement, et empêche ainsi leur suppression automatique par le gestionnaire de téléchargement."</string>
+ <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"télécharger des fichiers sans envoyer de notification"</string>
+ <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"Permet à l\'application de télécharger des fichiers dans le gestionnaire de téléchargement sans afficher de notification à l\'attention de l\'utilisateur."</string>
+ <string name="permlab_accessAllDownloads" msgid="2436240495424393717">"Accéder à tous les téléchargements système"</string>
+ <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"Permet à l\'application d\'afficher et de modifier tous les téléchargements lancés par n\'importe quelle application du système."</string>
+ <string name="download_unknown_title" msgid="7015124071247271585">"&lt;Sans_titre&gt;"</string>
+ <string name="notification_download_complete" msgid="5443563299253103667">"Téléchargement terminé."</string>
+ <string name="notification_download_failed" msgid="8612136111952014978">"Échec du téléchargement"</string>
+ <string name="notification_need_wifi_for_size" msgid="2556172885154833575">"Taille du fichier requiert Wi-Fi."</string>
+ <string name="notification_paused_in_background" msgid="4328508073283591772">"Interrompu en arr.-plan."</string>
+ <string name="wifi_required_title" msgid="1995971416871498179">"Téléchargement trop volumineux pour l\'opérateur"</string>
+ <string name="wifi_required_body" msgid="3067694630143784449">"Vous devez utiliser le Wi-Fi pour finaliser ce téléchargement de <xliff:g id="SIZE">%s </xliff:g>. \n\nAppuyez sur <xliff:g id="QUEUE_TEXT">%s </xliff:g> pour le lancer lors de votre prochaine connexion à un réseau Wi-Fi."</string>
+ <string name="wifi_recommended_title" msgid="7441589306734687400">"Ajouter à la file d\'attente des téléchargements?"</string>
+ <string name="wifi_recommended_body" msgid="1314735166699936073">"Ce téléchargement (<xliff:g id="SIZE">%s </xliff:g>) risque de décharger votre batterie et/ou d\'entraîner une consommation excessive de votre connexion Internet mobile. Des frais supplémentaires peuvent être facturés par votre opérateur en fonction de votre forfait.\n\nAppuyez sur <xliff:g id="QUEUE_TEXT">%s</xliff:g> pour le lancer lors de votre prochaine connexion au Wi-Fi."</string>
+ <string name="button_queue_for_wifi" msgid="422576726189179221">"File d\'attente"</string>
+ <string name="button_cancel_download" msgid="2430166148737975604">"Annuler"</string>
+ <string name="button_start_now" msgid="792123674007840864">"Commencer maintenant"</string>
+ <string name="download_percent" msgid="6889426633242976698">"<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <plurals name="notif_summary_active">
+ <item quantity="one" msgid="8475775855911967027">"Téléchargement d\'un fichier"</item>
+ <item quantity="other" msgid="9087228371320573153">"Téléchargement de <xliff:g id="NUMBER">%d</xliff:g> fichiers"</item>
+ </plurals>
+ <plurals name="notif_summary_waiting">
+ <item quantity="one" msgid="5537481763963544278">"1 fichier en attente"</item>
+ <item quantity="other" msgid="549229034166062887">"<xliff:g id="NUMBER">%d</xliff:g> fichiers en attente"</item>
+ </plurals>
+ <string name="download_remaining" msgid="3139295890887972718">"Temps restant : <xliff:g id="DURATION">%s</xliff:g>"</string>
+ <string name="download_no_application_title" msgid="7935659741162801699">"Impossible d\'ouvrir le fichier."</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Téléchargements"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Placé en file d\'attente"</string>
+ <string name="download_running" msgid="3925050393361158266">"En cours de traitement"</string>
+ <string name="download_error" msgid="5144180777324573236">"Échec"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"En cours : <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
+</resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index cedf5de..3a1dfb3 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"Temps restant : <xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Impossible d\'ouvrir le fichier."</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Téléchargements"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Placé en file d\'attente"</string>
+ <string name="download_running" msgid="3925050393361158266">"En cours"</string>
+ <string name="download_error" msgid="5144180777324573236">"Échec"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"En cours (<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>)"</string>
</resources>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index b440379..37c8ce8 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -18,20 +18,20 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="3658948994665187911">"डाउनलोड प्रबंधक"</string>
<string name="permlab_downloadManager" msgid="7779544811202855500">"डाउनलोड प्रबंधक में पहुंच प्राप्त करें."</string>
- <string name="permdesc_downloadManager" msgid="4237406545998908947">"एप्लिकेशन को डाउनलोड प्रबंधक तक पहुंचने देता और फ़ाइलें डाउनलोड करने के लिए इसका उपयोग करने देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग डाउनलोड को बाधित करने और निजी जानकारी तक पहुंचने के लिए कर सकते हैं."</string>
+ <string name="permdesc_downloadManager" msgid="4237406545998908947">"ऐप्स को डाउनलोड प्रबंधक तक पहुंचने देता और फ़ाइलें डाउनलोड करने के लिए इसका उपयोग करने देता है. दुर्भावनापूर्ण ऐप्स इसका उपयोग डाउनलोड को बाधित करने और निजी जानकारी तक पहुंचने के लिए कर सकते हैं."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"उन्‍नत डाउनलोड प्रबंधक प्रकार्य."</string>
- <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"एप्लिकेशन को डाउनलोड प्रबंधक के उन्नत फ़ंक्शन तक पहुंचने देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग डाउनलोड को बाधित करने और निजी जानकारी तक पहुंचने के लिए कर सकते हैं."</string>
+ <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"ऐप्स को डाउनलोड प्रबंधक के उन्नत फ़ंक्शन तक पहुंचने देता है. दुर्भावनापूर्ण ऐप्स इसका उपयोग डाउनलोड को बाधित करने और निजी जानकारी तक पहुंचने के लिए कर सकते हैं."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"डाउनलोड सूचनाएं भेजें."</string>
- <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"पूर्ण किए गए डाउनलोड के बारे में एप्लिकेशन को सूचना भेजने देता है. दुर्भावनापूर्ण एप्लिकेशन इसका उपयोग फ़ाइलों को डाउनलोड करने वाले अन्य एप्लिकेशन को भ्रमित करने के लिए कर सकते हैं."</string>
+ <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"पूर्ण किए गए डाउनलोड के बारे में ऐप्स को सूचना भेजने देता है. दुर्भावनापूर्ण ऐप्स इसका उपयोग फ़ाइलों को डाउनलोड करने वाले अन्य ऐप्स को भ्रमित करने के लिए कर सकते हैं."</string>
<string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"USB संग्रहण के सभी डाउनलोड देखें"</string>
<string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"SD कार्ड के लिए सभी डाउनलोड देखें"</string>
- <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"इस बात पर ध्यान दिए बिना कि किस एप्लिकेशन ने उन्हें डाउनलोड किया है, एप्लिकेशन को SD कार्ड पर किए गए सभी डाउनलोड देखने देता है."</string>
+ <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"इस बात पर ध्यान दिए बिना कि किस ऐप्स ने उन्हें डाउनलोड किया है, ऐप्स को SD कार्ड पर किए गए सभी डाउनलोड देखने देता है."</string>
<string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"डाउनलोड कैश में स्थान सुरक्षित रखें"</string>
- <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"एप्लिकेशन को डाउनलोड संचय पर फ़ाइलें डाउनलोड करने देता है, जिन्हें अपने आप तब हटाया नहीं जा सकता, जब डाउनलोड प्रबंधक को अधिक स्थान की आवश्‍यकता होती है."</string>
+ <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"ऐप्स को डाउनलोड संचय पर फ़ाइलें डाउनलोड करने देता है, जिन्हें अपने आप तब हटाया नहीं जा सकता, जब डाउनलोड प्रबंधक को अधिक स्थान की आवश्‍यकता होती है."</string>
<string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"बिना सूचना के फ़ाइलें डाउनलोड करें"</string>
- <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"उपयोगकर्ता को कोई भी सूचना दिखाए बिना एप्‍लिकेशन को डाउनलोड प्रबंधक द्वारा फ़ाइलें डाउनलोड करने देता है."</string>
+ <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"उपयोगकर्ता को कोई भी सूचना दिखाए बिना ऐप्स को डाउनलोड प्रबंधक द्वारा फ़ाइलें डाउनलोड करने देता है."</string>
<string name="permlab_accessAllDownloads" msgid="2436240495424393717">"सभी सिस्‍टम डाउनलोड में पहुंच प्राप्त करें"</string>
- <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"एप्लिकेशन को सिस्टम पर किसी भी एप्लिकेशन द्वारा शुरू किए गए सभी डाउनलोड देखने और संशोधित करने देता है."</string>
+ <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"ऐप्स को सिस्टम पर किसी भी ऐप्स द्वारा शुरू किए गए सभी डाउनलोड देखने और संशोधित करने देता है."</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;शीर्षक-रहित&gt;"</string>
<string name="notification_download_complete" msgid="5443563299253103667">"डाउनलोड पूर्ण."</string>
<string name="notification_download_failed" msgid="8612136111952014978">"डाउनलोड विफल."</string>
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> शेष"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"फ़ाइल नहीं खोली जा सकती"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"डाउनलोड"</string>
+ <string name="download_queued" msgid="3302638231377947451">"कतारबद्ध"</string>
+ <string name="download_running" msgid="3925050393361158266">"जारी है"</string>
+ <string name="download_error" msgid="5144180777324573236">"असफल"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"प्रगति में, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 70f0cff..48bec50 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"Još <xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Datoteka se ne može otvoriti"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Preuzimanja"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Na čekanju"</string>
+ <string name="download_running" msgid="3925050393361158266">"U tijeku"</string>
+ <string name="download_error" msgid="5144180777324573236">"Neuspješno"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"U tijeku, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 58965d3..a627faa 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> van hátra"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"A fájlt nem lehet megnyitni."</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Letöltések"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Várólistán"</string>
+ <string name="download_running" msgid="3925050393361158266">"Folyamatban"</string>
+ <string name="download_error" msgid="5144180777324573236">"Sikertelen"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Folyamatban: <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000..05a5001
--- /dev/null
+++ b/res/values-hy-rAM/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3658948994665187911">"Ներբեռնման կառավարիչ"</string>
+ <string name="permlab_downloadManager" msgid="7779544811202855500">"Գործարկել ներբեռնման կառավարիչը:"</string>
+ <string name="permdesc_downloadManager" msgid="4237406545998908947">"Թույլատրում է հավելվածին օգտագործել ներբեռնման կառավարիչը և կիրառել ֆայլերի ներբեռնման համար: Վնասակար ծրագրերը կարող են օգտագործել սա՝ ներբեռնումները վնասելու և անձնական տեղեկություններն օգտագործելու համար:"</string>
+ <string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Ընդլայնված ներբեռնման կառավարչի գործառույթներ:"</string>
+ <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"Թույլատրում է հավելվածին օգտագործել ներբեռնման կառավարչի ընդլայնված գործառույթները: Վնասակար ծրագրերը կարող են օգտագործել սա՝ ներբեռնումները վնասելու և անձնական տեղեկություններն օգտագործելու համար:"</string>
+ <string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Ուղարկել ներբեռնման ծանուցումներ:"</string>
+ <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"Թույլատրում է հավելվածին ուղարկել ավարտված ներբեռնումների մասին ծանուցումներ: Վնասակար ծրագրերը կարող են օգտագործել սա՝ այլ ֆայլեր ներբեռնող ծրագրերը վնասելու համար:"</string>
+ <string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"Տեսնել USB կրիչի բոլոր ներբեռնումները"</string>
+ <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"Տեսնել SD քարտի բոլոր ներբեռնումները"</string>
+ <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"Թույլատրում է հավելվածին տեսնել SD քարտի բոլոր ներբեռնումները` անտեսելով, թե որ հավելվածն է ներբեռնել դրանք:"</string>
+ <string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"Խնայել ներբեռնման շտեմի տարածությունը"</string>
+ <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"Թույլատրում է հավելվածին ներբեռնել ֆայլերը ներբեռնման շտեմ, որոնք հնարավոր չէ ավտոմատ ջնջել, երբ ներբեռնման կառավարիչը հավելյալ ծավալի կարիք ունի:"</string>
+ <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"ներբեռնել ֆայլերը՝ առանց ծանուցման"</string>
+ <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"Թույլատրում է հավելվածին ներբեռնել ֆայլեր ներբեռնման կառավարչի միջոցով՝ առանց օգտագործողին որևէ ծանուցում ցուցադրելու:"</string>
+ <string name="permlab_accessAllDownloads" msgid="2436240495424393717">"Օգտագործել բոլոր համակարգային ներբեռնումները"</string>
+ <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"Թույլատրում է հավելվածին դիտել և փոփոխել բոլոր ներբեռնումները` կապված համակարգի ցանկացած ծրագրի հետ:"</string>
+ <string name="download_unknown_title" msgid="7015124071247271585">"&lt;Անվերնագիր&gt;"</string>
+ <string name="notification_download_complete" msgid="5443563299253103667">"Ներբեռնումն ավարտված է:"</string>
+ <string name="notification_download_failed" msgid="8612136111952014978">"Ներբեռնումը ձախողվել է:"</string>
+ <string name="notification_need_wifi_for_size" msgid="2556172885154833575">"Ներբեռնման ծավալը պահանջում է Wi-Fi:"</string>
+ <string name="notification_paused_in_background" msgid="4328508073283591772">"Ընդմիջված է հետնաշերտում:"</string>
+ <string name="wifi_required_title" msgid="1995971416871498179">"Ներբեռնումը չափազանց մեծ է օպերատորի ցանցի համար"</string>
+ <string name="wifi_required_body" msgid="3067694630143784449">"Դուք պետք է օգտագործեք Wi-Fi՝ այս <xliff:g id="SIZE">%s </xliff:g> ներբեռնումն ավարտելու համար: \n\nՀպեք <xliff:g id="QUEUE_TEXT">%s </xliff:g>՝ սկսելու այս ներբեռնումը հաջորդ անգամ, երբ միացած կլինեք որևէ Wi-Fi ցանցի:"</string>
+ <string name="wifi_recommended_title" msgid="7441589306734687400">"Հերթագրե՞լ ավելի ուշ ներբեռնելու համար:"</string>
+ <string name="wifi_recommended_body" msgid="1314735166699936073">"Այս <xliff:g id="SIZE">%s </xliff:g> ներբեռնումը հիմա սկսելը կարող է կարճեցնել ձեր մարտկոցի կյանքը և/կամ բերել ձեր բբջային տվյալների կապի ավելորդ օգտագործման, որը կարող է ուղեկցվել ծախսերով ձեր բջջային օպերատորի կողմից՝ կախված ձեր տվյալների փաթեթից:\n\n Հպեք <xliff:g id="QUEUE_TEXT">%s</xliff:g> ստորև` այս ներբեռնումը սկսելու հաջորդ անգամ, երբ միացած կլինեք որևէ Wi-Fi ցանցի:"</string>
+ <string name="button_queue_for_wifi" msgid="422576726189179221">"Հերթականություն"</string>
+ <string name="button_cancel_download" msgid="2430166148737975604">"Չեղարկել"</string>
+ <string name="button_start_now" msgid="792123674007840864">"Մեկնարկել հիմա"</string>
+ <string name="download_percent" msgid="6889426633242976698">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <plurals name="notif_summary_active">
+ <item quantity="one" msgid="8475775855911967027">"1 ֆայլ ներբեռնվում է"</item>
+ <item quantity="other" msgid="9087228371320573153">"<xliff:g id="NUMBER">%d</xliff:g> ֆայլ ներբեռնվում է"</item>
+ </plurals>
+ <plurals name="notif_summary_waiting">
+ <item quantity="one" msgid="5537481763963544278">"1 ֆայլ սպասում է"</item>
+ <item quantity="other" msgid="549229034166062887">"<xliff:g id="NUMBER">%d</xliff:g> ֆայլ սպասում է"</item>
+ </plurals>
+ <string name="download_remaining" msgid="3139295890887972718">"մինչ ավարտը՝ <xliff:g id="DURATION">%s</xliff:g>"</string>
+ <string name="download_no_application_title" msgid="7935659741162801699">"Հնարավոր չէ բացել ֆայլը"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Ներբեռնումներ"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Հերթագրված է"</string>
+ <string name="download_running" msgid="3925050393361158266">"Ընթացքի մեջ է"</string>
+ <string name="download_error" msgid="5144180777324573236">"Չի կատարվել"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Ընթացքում է՝ <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+</resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index a8474ce..71a69d3 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> lagi"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Tidak dapat membuka file"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Unduhan"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Diantrekan"</string>
+ <string name="download_running" msgid="3925050393361158266">"Sedang berlangsung"</string>
+ <string name="download_error" msgid="5144180777324573236">"Gagal"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Dalam proses, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 3f51d3c..f53b7da 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -17,16 +17,16 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="3658948994665187911">"Gestione download"</string>
- <string name="permlab_downloadManager" msgid="7779544811202855500">"Accedere alla gestione dei download."</string>
+ <string name="permlab_downloadManager" msgid="7779544811202855500">"Accesso alla gestione dei download."</string>
<string name="permdesc_downloadManager" msgid="4237406545998908947">"Consente all\'applicazione di accedere a gestione dei download e di utilizzarla per scaricare file. Le applicazioni dannose possono farne uso per disturbare i download e accedere a informazioni private."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Funzioni avanzate di gestione dei download."</string>
<string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"Consente all\'applicazione di accedere alle funzioni avanzate di gestione dei download. Le applicazioni dannose possono farne uso per disturbare i download e accedere a informazioni private."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Inviare notifiche di download."</string>
<string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"Consente all\'applicazione di inviare notifiche relative ai download completati. Le applicazioni dannose possono farne uso per confondere altre applicazioni che scaricano file."</string>
<string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"Tutti i download in archivio USB"</string>
- <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"Visualizza tutti i download sulla scheda SD"</string>
+ <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"Visualizzazione di tutti i download sulla scheda SD"</string>
<string name="permdesc_seeAllExternal" msgid="1672759909065511233">"Consente all\'applicazione di visualizzare tutti i download sulla scheda SD, a prescindere dall\'applicazione che li ha scaricati."</string>
- <string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"Conserva spazio nella cache dei download"</string>
+ <string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"Conservazione spazio nella cache dei download"</string>
<string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"Consente all\'applicazione di scaricare nella cache i file che non possono essere eliminati automaticamente quando a gestione dei download serve più spazio."</string>
<string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"download file senza notifica"</string>
<string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"Consente all\'applicazione di scaricare i file tramite gestione dei download senza mostrare alcuna notifica all\'utente."</string>
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> rimanenti"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Impossibile aprire il file"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Download"</string>
+ <string name="download_queued" msgid="3302638231377947451">"In coda"</string>
+ <string name="download_running" msgid="3925050393361158266">"In corso"</string>
+ <string name="download_error" msgid="5144180777324573236">"Operazione non riuscita"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"In corso, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 69a10d0..a5914be 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -18,29 +18,29 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="3658948994665187911">"מנהל ההורדות"</string>
<string name="permlab_downloadManager" msgid="7779544811202855500">"גישה למנהל ההורדות."</string>
- <string name="permdesc_downloadManager" msgid="4237406545998908947">"מאפשר ליישום לגשת למנהל ההורדות ולהשתמש בו לצורך הורדת קבצים. יישומים זדוניים עלולים לנצל אפשרות זו כדי לשבש הורדות ולגשת למידע פרטי."</string>
+ <string name="permdesc_downloadManager" msgid="4237406545998908947">"מאפשר לאפליקציה לגשת למנהל ההורדות ולהשתמש בו לצורך הורדת קבצים. אפליקציות זדוניות עלולות לנצל אפשרות זו כדי לשבש הורדות ולגשת למידע פרטי."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"פונקציות מתקדמות של מנהל ההורדות."</string>
- <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"מאפשר ליישום לגשת לפונקציות המתקדמות של מנהל ההורדות. יישומים זדוניים עלולים לנצל אפשרות זו כדי לשבש הורדות ולגשת למידע פרטי."</string>
+ <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"מאפשר לאפליקציה לגשת לפונקציות המתקדמות של מנהל ההורדות. אפליקציות זדוניות עלולות לנצל אפשרות זו כדי לשבש הורדות ולגשת למידע פרטי."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"שלח התראות על הורדות."</string>
- <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"מאפשר ליישום לשלוח התראות לגבי הורדות שהסתיימו. יישומים זדוניים עלולים לנצל אפשרות זו כדי לבלבל יישומים אחרים המורידים קבצים."</string>
- <string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"הצג את כל ההורדות לאמצעי אחסון מסוג USB"</string>
- <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"הצג את כל ההורדות לכרטיס SD"</string>
- <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"מאפשר ליישום לראות את כל ההורדות לכרטיס ה-SD, בלי קשר ליישום שהוריד אותן."</string>
+ <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"מאפשר לאפליקציה לשלוח התראות לגבי הורדות שהסתיימו. אפליקציות זדוניות עלולות לנצל אפשרות זו כדי לבלבל אפליקציות אחרות המורידות קבצים."</string>
+ <string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"‏הצג את כל ההורדות לאמצעי אחסון מסוג USB"</string>
+ <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"‏הצג את כל ההורדות לכרטיס SD"</string>
+ <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"‏מאפשר לאפליקציה לראות את כל ההורדות לכרטיס ה-SD, בלי קשר לאפליקציה שהורידה אותן."</string>
<string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"שמור מקום בקובץ השמור של ההורדות"</string>
- <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"מאפשר ליישום להוריד קבצים לקובץ השמור של הורדות שלא ניתן למחוק באופן אוטומטי כאשר דרוש למנהל ההורדות שטח נוסף."</string>
+ <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"מאפשר לאפליקציה להוריד קבצים לקובץ השמור של הורדות שלא ניתן למחוק באופן אוטומטי כאשר דרוש למנהל ההורדות שטח נוסף."</string>
<string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"הורד קבצים ללא התראה"</string>
- <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"מאפשר ליישום להוריד קבצים דרך מנהל ההורדות מבלי להציג התראות כלשהן בפני המשתמש."</string>
+ <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"מאפשר לאפליקציה להוריד קבצים דרך מנהל ההורדות מבלי להציג התראות כלשהן בפני המשתמש."</string>
<string name="permlab_accessAllDownloads" msgid="2436240495424393717">"גישה לכל הורדות המערכת"</string>
- <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"מאפשר ליישום להציג ולשנות את כל ההורדות שהופעלו על ידי יישום כלשהו במערכת."</string>
- <string name="download_unknown_title" msgid="7015124071247271585">"&lt;ללא כותרת&gt;"</string>
+ <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"מאפשר לאפליקציה להציג ולשנות את כל ההורדות שהופעלו על ידי אפליקציה כלשהי במערכת."</string>
+ <string name="download_unknown_title" msgid="7015124071247271585">"‏&lt;ללא כותרת&gt;"</string>
<string name="notification_download_complete" msgid="5443563299253103667">"ההורדה הסתיימה."</string>
<string name="notification_download_failed" msgid="8612136111952014978">"ההורדה נכשלה."</string>
- <string name="notification_need_wifi_for_size" msgid="2556172885154833575">"גודל ההורדה מחייב חיבור Wi-Fi"</string>
+ <string name="notification_need_wifi_for_size" msgid="2556172885154833575">"‏גודל ההורדה מחייב חיבור Wi-Fi"</string>
<string name="notification_paused_in_background" msgid="4328508073283591772">"מושהה ברקע."</string>
<string name="wifi_required_title" msgid="1995971416871498179">"ההורדה גדולה מדי לרשת המפעיל"</string>
- <string name="wifi_required_body" msgid="3067694630143784449">"עליך להשתמש ב-Wi-Fi כדי להשלים את ההורדה שגודלה <xliff:g id="SIZE">%s </xliff:g>. \n \n גע ב-<xliff:g id="QUEUE_TEXT">%s </xliff:g> כדי להפעיל את ההורדה בפעם הבאה שתתחבר לרשת Wi-Fi."</string>
+ <string name="wifi_required_body" msgid="3067694630143784449">"‏עליך להשתמש ב-Wi-Fi כדי להשלים את ההורדה שגודלה <xliff:g id="SIZE">%s </xliff:g>. \n \n גע ב-<xliff:g id="QUEUE_TEXT">%s </xliff:g> כדי להפעיל את ההורדה בפעם הבאה שתתחבר לרשת Wi-Fi."</string>
<string name="wifi_recommended_title" msgid="7441589306734687400">"להוסיף לתור כדי להוריד מאוחר יותר?"</string>
- <string name="wifi_recommended_body" msgid="1314735166699936073">"הפעלת הורדה זו (<xliff:g id="SIZE">%s </xliff:g>) עשויה לקצר את חיי הסוללה שלך ו/או לגרום לניצול מופרז של חיבור הנתונים הנייד שלך, אשר עשוי להיות כרוך בחיוב מצד ספק השירות הנייד שלך, בהתאם לתוכנית הנתונים הרלוונטית.\n\nגע ב-<xliff:g id="QUEUE_TEXT">%s</xliff:g> כדי להתחיל בהורדה בפעם הבאה שתתחבר לרשת Wi-Fi."</string>
+ <string name="wifi_recommended_body" msgid="1314735166699936073">"‏הפעלת הורדה זו (<xliff:g id="SIZE">%s </xliff:g>) עשויה לקצר את חיי הסוללה שלך ו/או לגרום לניצול מופרז של חיבור הנתונים הנייד שלך, אשר עשוי להיות כרוך בחיוב מצד ספק השירות הנייד שלך, בהתאם לתוכנית הנתונים הרלוונטית.\n\nגע ב-<xliff:g id="QUEUE_TEXT">%s</xliff:g> כדי להתחיל בהורדה בפעם הבאה שתתחבר לרשת Wi-Fi."</string>
<string name="button_queue_for_wifi" msgid="422576726189179221">"תור"</string>
<string name="button_cancel_download" msgid="2430166148737975604">"ביטול"</string>
<string name="button_start_now" msgid="792123674007840864">"התחל כעת"</string>
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> נותרו"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"לא ניתן לפתוח את הקובץ"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"הורדות"</string>
+ <string name="download_queued" msgid="3302638231377947451">"בתור"</string>
+ <string name="download_running" msgid="3925050393361158266">"מתבצע"</string>
+ <string name="download_error" msgid="5144180777324573236">"נכשל"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"מתבצע, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 14c648f..b8f5809 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"残り<xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"ファイルを開くことができません"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"ダウンロード"</string>
+ <string name="download_queued" msgid="3302638231377947451">"キューに追加済み"</string>
+ <string name="download_running" msgid="3925050393361158266">"処理中"</string>
+ <string name="download_error" msgid="5144180777324573236">"失敗しました"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"処理中(<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
</resources>
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..8da7b31
--- /dev/null
+++ b/res/values-ka-rGE/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3658948994665187911">"ჩამოტვირთვის მენეჯერი"</string>
+ <string name="permlab_downloadManager" msgid="7779544811202855500">"ჩამოტვირთვის მენეჯერზე წვდომა."</string>
+ <string name="permdesc_downloadManager" msgid="4237406545998908947">"მიეცით აპლიკაციას ჩამოტვირთვის მენეჯერის წვდომისა და ფაილების ჩამოტვირთვებისთვის მისი გამოყენების უფლება. ბოროტმოქმედმა აპლიკაციებმა შეიძლება ეს გამოიყენონ ჩამოტვირთვების დასაზიანებლად და პირად ინფორმაციაზე წვდომისათვის."</string>
+ <string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"ჩამოტვირთვის გაუმჯობესებული მენეჯერის ფუნქციები."</string>
+ <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"მიეცით აპს ჩამოტვირთვის მენეჯერის გაუმჯობესებულ ფუნქციებზე წვდომის უფლება. ბოროტმოქმედმა აპებმა შეიძლება ეს გამოიყენონ ჩამოტვირთვების დასაზიანებლად და პირად ინფორმაციაზე წვდომისათვის."</string>
+ <string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"ჩამოტვირთვის შეტყობინებების გაგზავნა."</string>
+ <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"მიეცით აპს, უფლება, გააგზავნოს შეტყობინება დასრულებული ჩამოტვირთვების შესახებ. ბოროტმოქმედმა აპლიკაციებმა შეიძლება ეს გამოიყენონ ჩამოტვირთვების დასაზიანებლად და პირად ინფორმაციაზე წვდომისათვის."</string>
+ <string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"ყველა ჩამოტვირთვის USB მეხსიერებაში ნახვა"</string>
+ <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"ყველა ჩამოტვირთვის SD ბარათზე ნახვა"</string>
+ <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"მიეცით აპს უფლება, ნახოს ყველა ჩამოტვირთვა SD ბარათზე, განურჩევლად იმისა, თუ რომელმა აპმა ჩამოტვირთა ისინი."</string>
+ <string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"ჩამოტვირთვის ქეშში სივრცის ამობრუნება"</string>
+ <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"მიეცით აპს უფლება ჩამოტვირთოს ფაილები ჩამოტვირთულ ქეშში. მისი წაშლა ავტომატურად შეუძლებელია მაშინ, როდესაც ჩამოტვირთვის მენეჯერს მეტი სივრცე სჭირდება."</string>
+ <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"ფაილების ჩამოტვირთვა შეტყობინებების გარეშე"</string>
+ <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"მიეცით აპს უფლება, ჩამოტვირთოს ფაილები ჩამოტვირთვის მენეჯერიდან მომხმარებლისთვის შეტყობინების ჩვენების გარეშე."</string>
+ <string name="permlab_accessAllDownloads" msgid="2436240495424393717">"ყველა სისტემურ ჩამოტვირთვაზე წვდომა"</string>
+ <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"მიეცით აპს უფლება ნახოს და შეცვალოს ნებისმიერი ჩამოტვირთვა, რომელიც ინიცირებული იყო სისტემის ნებისმიერი აპის მიერ."</string>
+ <string name="download_unknown_title" msgid="7015124071247271585">"&lt;უსათაურო&gt;"</string>
+ <string name="notification_download_complete" msgid="5443563299253103667">"ჩამოტვირთვა დასრულდა."</string>
+ <string name="notification_download_failed" msgid="8612136111952014978">"წარუმატებელი ჩამოტვირთვა."</string>
+ <string name="notification_need_wifi_for_size" msgid="2556172885154833575">"ჩამოტვირთვის ზომა ითხოვს Wi-Fi-ს."</string>
+ <string name="notification_paused_in_background" msgid="4328508073283591772">"უკანა ფონზე დაპაუზებული."</string>
+ <string name="wifi_required_title" msgid="1995971416871498179">"ჩამოტვირთვა ოპერატორის ქსელისთვის ძალიან დიდია"</string>
+ <string name="wifi_required_body" msgid="3067694630143784449">"ამ <xliff:g id="SIZE">%s </xliff:g> ჩამოტვირთვის განსახორციელებლად უნდა გამოიყენოთ WiFi. \n\nშეეხეთ <xliff:g id="QUEUE_TEXT">%s </xliff:g>, რათა დაიწყოთ ეს ჩამოტვირთვა მომავალში, როგორც კი ჩაერთვებით WiFi ქსელში."</string>
+ <string name="wifi_recommended_title" msgid="7441589306734687400">"ჩააყენებთ ჩამოტვირთვების რიგში?"</string>
+ <string name="wifi_recommended_body" msgid="1314735166699936073">"ამ <xliff:g id="SIZE">%s </xliff:g> ჩამოტვირთვის დაწყება ახლა შეამცირებს თქვენი ელემენტის სიცოცხლეს და/ან გამოიწვევს თქვენი მობილური ინტერნეტის ინტენსიურ გამოყენებას. ეს თავისთავად განაპირობებს თქვენი მობილური ოპერატორისთვის შესაბამისი საფასურის გადახდას თქვენი ინტერნეტ გეგმიდან გამომდინარე. \n\n შეეხეთ <xliff:g id="QUEUE_TEXT">%s</xliff:g>, რათა დაიწყოთ ეს ჩამოტვირთვა მომავალში, როგორც კი ჩაერთვებით WiFi ქსელში."</string>
+ <string name="button_queue_for_wifi" msgid="422576726189179221">"რიგი"</string>
+ <string name="button_cancel_download" msgid="2430166148737975604">"გაუქმება"</string>
+ <string name="button_start_now" msgid="792123674007840864">"დაწყება ახლავე"</string>
+ <string name="download_percent" msgid="6889426633242976698">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <plurals name="notif_summary_active">
+ <item quantity="one" msgid="8475775855911967027">"1 ფაილი იტვირთება"</item>
+ <item quantity="other" msgid="9087228371320573153">"<xliff:g id="NUMBER">%d</xliff:g> ფაილი იტვირთება"</item>
+ </plurals>
+ <plurals name="notif_summary_waiting">
+ <item quantity="one" msgid="5537481763963544278">"1 ფაილი მოლოდინის რეჟმშია"</item>
+ <item quantity="other" msgid="549229034166062887">"<xliff:g id="NUMBER">%d</xliff:g> ფაილი მოლოდინის რეჟიმშია"</item>
+ </plurals>
+ <string name="download_remaining" msgid="3139295890887972718">"დარჩა <xliff:g id="DURATION">%s</xliff:g>"</string>
+ <string name="download_no_application_title" msgid="7935659741162801699">"ფაილის გახსნა ვერ ხერხდება"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"ჩამოტვირთვები"</string>
+ <string name="download_queued" msgid="3302638231377947451">"რიგშია"</string>
+ <string name="download_running" msgid="3925050393361158266">"მიმდინარეობს"</string>
+ <string name="download_error" msgid="5144180777324573236">"ვერ განხორციელდა"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"მიმდინარეობს, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+</resources>
diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..bdb2b78
--- /dev/null
+++ b/res/values-km-rKH/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3658948994665187911">"កម្មវិធី​ទាញ​យក"</string>
+ <string name="permlab_downloadManager" msgid="7779544811202855500">"ប្រើ​កម្មវិធី​គ្រប់គ្រង​ការ​ទាញ​យក។"</string>
+ <string name="permdesc_downloadManager" msgid="4237406545998908947">"អនុញ្ញាត​ឲ្យ​កម្មវិធី​ប្រើ​កម្មវិធី​ទាញ​យក ដើម្បី​ទាញ​យក​ឯកសារ។ កម្មវិធី​មិន​ល្អ​ផ្សេងទៀត​អាច​ប្រើ​ដើម្បី​បង្អាក់​ការ​ទាញ​យក និង​ការ​ប្រើ​ព័ត៌មាន​ឯកជន។"</string>
+ <string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"មុខងារ​កម្មវិធី​គ្រប់គ្រង​ការ​ទាញ​យក​កម្រិត​ខ្ពស់។"</string>
+ <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"អនុញ្ញាត​ឲ្យ​កម្មវិធី​ប្រើ​មុខងារ​កម្រិត​ខ្ពស់​របស់​កម្មវិធី​ទាញ​យក​ការ​គ្រប់គ្រង។ កម្មវិធី​មិន​ល្អ​អាច​ប្រើ​វា​ដើម្បី​បង្អាក់​ការ​ទាញ​យក និង​ការ​ប្រើ​ព័ត៌មាន​ឯកជន។"</string>
+ <string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"ផ្ញើ​ព័ត៌មាន​ការ​ទាញ​យក។"</string>
+ <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"អនុញ្ញាត​ឲ្យ​កម្មវិធី​ផ្ញើ​ការ​ជូនដំណឹង​អំពី​ការ​បញ្ចប់​ការ​ទាញ​យក។ កម្មវិធី​មិន​ល្អ​អាច​ប្រើ​វា​ដើម្បី​រារាំង​កម្មវិធី​ទាញ​យក​ឯកសារ​ផ្សេងទៀត។"</string>
+ <string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"មើល​ការ​ទាញ​យក​ទាំងអស់​ទៅកាន់​ឧបករណ៍​ផ្ទុក​យូអេសប៊ី"</string>
+ <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"មើល​ការ​ទាញ​យក​ទាំងអស់​ទៅកាន់​កាត​អេសឌី"</string>
+ <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"អនុញ្ញាត​ឲ្យ​កម្មវិធី​​មើល​ការ​ទាញ​យក​ទាំងអស់​ទៅកាន់​ការ​អេសឌី ប្រសិនបើ​គ្មាន​កម្មវិធី​ទាញ​យក​វា។"</string>
+ <string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"បម្រុងទុក​ទំហំ​នៅ​ក្នុង​ឃ្លាំង​ទាញ​យក"</string>
+ <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"អនុញ្ញាត​ឲ្យ​កម្មវិធី​ទាញ​យក​ឯកសារ​ទៅកាន់​ឃ្លាំង​ទាញ​យក ដែល​មិន​អាច​លុប​ដោយ​ស្វ័យប្រវត្តិ ពេល​កម្មវិធី​ទាញ​យក​ត្រូវការ​ទំហំ​ច្រើន។"</string>
+ <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"ទាញ​យក​ឯកសារ​ដោយ​មិន​បាច់​ជូនដំណឹង"</string>
+ <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"អនុញ្ញាត​ឲ្យ​កម្មវិធី​ទាញ​យក​ឯកសារ​តាម​កម្មវិធី​ទាញ​យក​ការ​គ្រប់គ្រង​​ដោយ​មិន​បាច់​មាន​ការ​ជូន​ដំណឹង​ទៅ​អ្នកប្រើ។"</string>
+ <string name="permlab_accessAllDownloads" msgid="2436240495424393717">"ដំណើរការ​ទាញ​យក​​ប្រព័ន្ធ​ទាំងអស់"</string>
+ <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"អនុញ្ញាត​ឲ្យ​កម្មវិធី​មើល និង​កែ​ការ​ទាញ​យក​ទាំងអស់​ដែល​បាន​ចាប់ផ្ដើម​ដោយ​កម្មវិធី​ណាមួយ​នៅ​លើ​ប្រព័ន្ធ។"</string>
+ <string name="download_unknown_title" msgid="7015124071247271585">"&lt;Untitled&gt;"</string>
+ <string name="notification_download_complete" msgid="5443563299253103667">"បាន​បញ្ចប់​ការ​ទាញ​យក។"</string>
+ <string name="notification_download_failed" msgid="8612136111952014978">"ការ​ទាញ​យក​បាន​បរាជ័យ។"</string>
+ <string name="notification_need_wifi_for_size" msgid="2556172885154833575">"ទំហំ​ការ​ទាញ​យក​ត្រូវការ​វ៉ាយហ្វាយ។"</string>
+ <string name="notification_paused_in_background" msgid="4328508073283591772">"បាន​ផ្អាក​នៅ​ផ្ទៃ​ខាងក្រោយ។"</string>
+ <string name="wifi_required_title" msgid="1995971416871498179">"ការ​ទាញ​យក​គឺ​ធំ​ពេក​សម្រាប់​បណ្ដាញ​ប្រតិបត្តិករ"</string>
+ <string name="wifi_required_body" msgid="3067694630143784449">"អ្នក​ត្រូវតែ​ប្រើ​វ៉ាយហ្វាយ​ដើម្បី​បញ្ចប់​ការ​ទាញ​យក <xliff:g id="SIZE">%s </xliff:g> ។ \n\nប៉ះ <xliff:g id="QUEUE_TEXT">%s </xliff:g> ដើម្បី​ចាប់ផ្ដើម​ការ​ទាញ​យក​នេះ​នៅ​ពេល​អ្នក​បាន​តភ្ជាប់​បណ្ដាញ​វ៉ាយហ្វាយ។"</string>
+ <string name="wifi_recommended_title" msgid="7441589306734687400">"ដាក់​ជា​ជួរ​ដើម្បី​ទាញ​យក​បន្ទាប់?"</string>
+ <string name="wifi_recommended_body" msgid="1314735166699936073">"ចាប់ផ្ដើម​ការ​ទាញ​យក <xliff:g id="SIZE">%s </xliff:g> ឥឡូវ​អាច​បណ្ដាលឲ្យ​ថ្ម​របស់​អ្នក​មាន​អាយុ​ខ្លី និង/ឬ​បង្ហាញ​ថា​លើស​ការ​ប្រើ​នៃ​តំណ​ភ្ជាប់​ទិន្នន័យ​ទូរស័ព្ទ​របស់​អ្នក ដែល​អាច​គិត​ប្រាក់​ដោយ​ប្រតិបត្តិករ​ទូរស័ព្ទ​អាស្រ័យ​តាម​គម្រោង​ទិន្នន័យ​របស់​អ្នក។\n\n ប៉ះ <xliff:g id="QUEUE_TEXT">%s</xliff:g> ខាងក្រោម​ដើម្បី​ចាប់ផ្ដើម​ការ​ទាញ​យក​នេះ​នៅ​ពេល​អ្នក​បាន​តភ្ជាប់​បណ្ដាញ​វ៉ាយហ្វាយ។"</string>
+ <string name="button_queue_for_wifi" msgid="422576726189179221">"ជួរ"</string>
+ <string name="button_cancel_download" msgid="2430166148737975604">"បោះ​បង់​"</string>
+ <string name="button_start_now" msgid="792123674007840864">"ចាប់ផ្ដើម​ឥឡូវ"</string>
+ <string name="download_percent" msgid="6889426633242976698">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <plurals name="notif_summary_active">
+ <item quantity="one" msgid="8475775855911967027">"កំពុង​ទាញ​យក​ឯកសារ ១"</item>
+ <item quantity="other" msgid="9087228371320573153">"កំពុង​ទាញ​យក​ឯកសារ <xliff:g id="NUMBER">%d</xliff:g>"</item>
+ </plurals>
+ <plurals name="notif_summary_waiting">
+ <item quantity="one" msgid="5537481763963544278">"កំពុង​រង់ចាំ​ឯកសារ ១"</item>
+ <item quantity="other" msgid="549229034166062887">"កំពុង​រង់ចាំ​ឯកសារ <xliff:g id="NUMBER">%d</xliff:g>"</item>
+ </plurals>
+ <string name="download_remaining" msgid="3139295890887972718">"នៅសល់ <xliff:g id="DURATION">%s</xliff:g>"</string>
+ <string name="download_no_application_title" msgid="7935659741162801699">"មិន​អាច​បើក​ឯកសារ"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"ទាញ​យក"</string>
+ <string name="download_queued" msgid="3302638231377947451">"​បាន​ដាក់​ក្នុង​ជួរ"</string>
+ <string name="download_running" msgid="3925050393361158266">"កំពុង​ដំណើរការ"</string>
+ <string name="download_error" msgid="5144180777324573236">"បាន​បរាជ័យ"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"កំពុង​ដំណើរការ​, <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
+</resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 4716650..2e2a426 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> 남음"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"파일을 열 수 없음"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"다운로드"</string>
+ <string name="download_queued" msgid="3302638231377947451">"대기 중"</string>
+ <string name="download_running" msgid="3925050393361158266">"진행 중"</string>
+ <string name="download_error" msgid="5144180777324573236">"실패"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g> 진행 중"</string>
</resources>
diff --git a/res/values-lo-rLA/strings.xml b/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..c5d87f9
--- /dev/null
+++ b/res/values-lo-rLA/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3658948994665187911">"ໂຕຈັດການການດາວໂຫລດ"</string>
+ <string name="permlab_downloadManager" msgid="7779544811202855500">"ເຂົ້າເຖິງໂຕຈັດການການດາວໂຫລດ."</string>
+ <string name="permdesc_downloadManager" msgid="4237406545998908947">"ອະນຸາຍາດໃຫ້ແອັບຯ ເຂົ້າເຖິງໂຕຈັດການການດາວໂຫລດ ແລະໃຊ້ມັນເພື່ອດາວໂຫລດໄຟລ໌. ແອັບຯທີ່ມີອັນຕະລາຍສາມາດໃຊ້ການເຮັດວຽກນີ້ ເພື່ອແຊກແຊງການດາວໂຫລດ ແລະເຂົ້າເຖິງຂໍ້ມູນສ່ວນໂຕໄດ້."</string>
+ <string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"ຄວາມສາມາດຂັ້ນສູງຂອງໂຕຈັດການການດາວໂຫລດ."</string>
+ <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"ອະນຸຍາດໃຫ້ແອັບຯ ເຂົ້າເຖິງຄວາມສາມາດຂັ້ນສູງຂອງໂຕຈັດການການດາວໂຫລດ. ແອັບຯທີ່ມີອັນຕະລາຍ ສາມາດໃຊ້ການເຮັດວຽກນີ້ ເພື່ອແຊກແຊງການດາວໂຫລດ ແລະເຂົ້າເຖິງຂໍ້ມູນສ່ວນໂຕໄດ້."</string>
+ <string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"ສົ່ງການແຈ້ງເຕືອນການດາວໂຫລດ."</string>
+ <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"ອະນຸຍາດໃຫ້ແອັບຯ ສົ່ງການແຈ້ງເຕືອນເມື່ອດາວໂຫລດສຳເລັດແລ້ວ. ແອັບຯທີ່ມີອັນຕະລາຍ ສາມາດໃຊ້ການເຮັດວຽກນີ້ ສ້າງຄວາມສັບສົນໃຫ້ແອັບຯ ອື່ນໆທີ່ດາວໂຫລດໄຟລ໌ໄດ້."</string>
+ <string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"ເບິ່ງການດາວໂຫລດທັງໝົດໃນບ່ອນຈັດເກັບຂໍ້ມູນ USB"</string>
+ <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"ເບິ່ງການດາວໂຫລດທັງໝົດໃນ SD card"</string>
+ <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"ອະນຸຍາດໃຫ້ແອັບຯດັ່ງກ່າວ ເຫັນການດາວໂຫລດໃນ SD ກາດທັງໝົດ, ໂດຍບໍ່ກ່ຽວວ່າມັນດາວໂຫລດມາຈາກແອັບຯໃດ."</string>
+ <string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"ເນື້ອທີ່ສະຫງວນໃນບ່ອນເກັບການດາວໂຫລດຊົ່ວຄາວ"</string>
+ <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"ອະນຸຍາດໃຫ້ແອັບຯ ດາວໂຫລດໄຟລ໌ໄປຍັງບ່ອນເກັບການດາວໂຫລດຊົ່ວຄາວ, ທີ່ບໍ່ສາມາດລຶບໂດຍອັດຕະໂນມັດ ຫາກໂຕຈັດການການດາວໂຫລດຕ້ອງການພື້ນທີ່ເພີ່ມ."</string>
+ <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"ດາວໂຫລດໄຟລ໌ໂດຍບໍ່ແຈ້ງເຕືອນ"</string>
+ <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"ອະນຸຍາດໃຫ້ແອັບຯດັ່ງກ່າວ ດາວໂຫລດໄຟລ໌ຜ່ານໂຕຈັດການການດາວໂຫລດ ໂດຍບໍ່ແຈ້ງເຕືອນຜູ່ໃຊ້ແຕ່ຢ່າງໃດ."</string>
+ <string name="permlab_accessAllDownloads" msgid="2436240495424393717">"ເຂົ້າເຖິງການດາວໂຫລດທັງໝົດຂອງລະບົບ"</string>
+ <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"ອະນຸຍາດໃຫ້ແອັບຯ ເບິ່ງ ແລະ ແກ້ໄຂການດາວໂຫລດທັງໝົດທີ່ເລີ່ມໂດຍທຸກໆແອັບຯໃນລະບົບ."</string>
+ <string name="download_unknown_title" msgid="7015124071247271585">"&lt;ບໍ່ມີຊື່&gt;"</string>
+ <string name="notification_download_complete" msgid="5443563299253103667">"ການດາວໂຫຼດສໍາເລັດແລ້ວ."</string>
+ <string name="notification_download_failed" msgid="8612136111952014978">"ດາວໂຫຼດບໍ່ສຳເລັດ."</string>
+ <string name="notification_need_wifi_for_size" msgid="2556172885154833575">"ຂະຫນາດການດາວໂຫຼດຕ້ອງໃຊ້ການເຊື່ອມຕໍ່ Wi-Fi."</string>
+ <string name="notification_paused_in_background" msgid="4328508073283591772">"ຢຸດຊົ່ວຄາວໃນເບື້ອງຫຼັງແລ້ວ."</string>
+ <string name="wifi_required_title" msgid="1995971416871498179">"ການດາວໂຫລດໃຫຍ່ເກີນໄປທີ່ຈະດາວໂຫລດຜ່ານລະບົບອິນເຕີເນັດມືຖື"</string>
+ <string name="wifi_required_body" msgid="3067694630143784449">"ທ່ານຕ້ອງໃຊ້ Wi-Fi ເພື່ອດາວໂຫລດໄຟລ໌ຂະໜາດ <xliff:g id="SIZE">%s </xliff:g> ນີ້. \n \n ແຕະທີ່ <xliff:g id="QUEUE_TEXT">%s </xliff:g> ເພື່ອເລີ່ມການດາວໂຫລດນີ້ ເມື່ອມີການທ່ານເຊື່ອມຕໍ່ WiFi ໃນຄັ້ງຕໍ່ໄປ."</string>
+ <string name="wifi_recommended_title" msgid="7441589306734687400">"ເຂົ້າຄິວເພື່ອດາວໂຫລດໃນພາຍຫຼັງ?"</string>
+ <string name="wifi_recommended_body" msgid="1314735166699936073">"ການດາວໂຫລດໄຟລ໌ໃຫຍ່ຂະໜາດ <xliff:g id="SIZE">%s </xliff:g> ນີ້ ອາດເຮັດອາຍຸແບັດເຕີຣີຂອງທ່ານສັ້ນລົງ ຫຼື ນຳໃຊ້ຂໍ້ມູນການເຊື່ອມຕໍ່ຂໍ້ມູນຜ່ານມືຖືຫຼາຍ, ເຊິ່ງເຮັດໃຫ້ທ່ານອາດຕ້ອງເສຍຄ່າບໍລິການແພງຂຶ້ນ.\n\n ສຳຜັດ <xliff:g id="QUEUE_TEXT">%s</xliff:g> ເພື່ອເລີ່ມການດາວໂຫລດນີ້ ເມື່ອມີການທ່ານເຊື່ອມຕໍ່ WiFi ໃນຄັ້ງຕໍ່ໄປ."</string>
+ <string name="button_queue_for_wifi" msgid="422576726189179221">"ຄິວ"</string>
+ <string name="button_cancel_download" msgid="2430166148737975604">"ຍົກເລີກ"</string>
+ <string name="button_start_now" msgid="792123674007840864">"ເລີ່ມດຽວນີ້"</string>
+ <string name="download_percent" msgid="6889426633242976698">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <plurals name="notif_summary_active">
+ <item quantity="one" msgid="8475775855911967027">"ກຳລັງດາວໂຫລດ 1 ໄຟລ໌"</item>
+ <item quantity="other" msgid="9087228371320573153">"ກຳລັງດາວໂຫລດ <xliff:g id="NUMBER">%d</xliff:g> ໄຟລ໌"</item>
+ </plurals>
+ <plurals name="notif_summary_waiting">
+ <item quantity="one" msgid="5537481763963544278">"ລໍຖ້າ 1 ໄຟລ໌"</item>
+ <item quantity="other" msgid="549229034166062887">"ລໍຖ້າ <xliff:g id="NUMBER">%d</xliff:g> ໄຟລ໌"</item>
+ </plurals>
+ <string name="download_remaining" msgid="3139295890887972718">"ຍັງເຫຼືອ <xliff:g id="DURATION">%s</xliff:g>"</string>
+ <string name="download_no_application_title" msgid="7935659741162801699">"ບໍ່ສາມດາເປີດໄຟລ໌ໄດ້"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"ດາວໂຫລດ"</string>
+ <string name="download_queued" msgid="3302638231377947451">"ເຂົ້າຄິວແລ້ວ"</string>
+ <string name="download_running" msgid="3925050393361158266">"ກຳລັງດຳເນີນການ"</string>
+ <string name="download_error" msgid="5144180777324573236">"ບໍ່ສຳເລັດ"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"ກຳລັງດຳເນີນການ, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+</resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 0f78fba..dd3dd6f 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"Liko: <xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Nepavyksta atidaryti failo"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Atsisiuntimai"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Laukia eilėje"</string>
+ <string name="download_running" msgid="3925050393361158266">"Vykdoma"</string>
+ <string name="download_error" msgid="5144180777324573236">"Nesėkminga"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Vykdoma, <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 89f9e4c..c327671 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"Atlikušais laiks: <xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Nevar atvērt failu"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Lejupielādes"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Ievietots rindā"</string>
+ <string name="download_running" msgid="3925050393361158266">"Notiek lejupielāde"</string>
+ <string name="download_error" msgid="5144180777324573236">"Neizdevās"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Norise: <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000..268b699
--- /dev/null
+++ b/res/values-mn-rMN/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3658948994665187911">"Татан авалтын Менежер"</string>
+ <string name="permlab_downloadManager" msgid="7779544811202855500">"Татан авалтын менежерт хандалт хийх."</string>
+ <string name="permdesc_downloadManager" msgid="4237406545998908947">"Апп нь татан авалтын менежерт хандалт хийх, үүнийг ашиглан файл татах боломжтой. Хортой апп-ууд үүнийг ашиглан татан авалтыг тасалдуулах, хувийн мэдээлэлд хандалт хийх боломжтой."</string>
+ <string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Татан авалтын менежерийн дэлгэрэнгүй функцууд."</string>
+ <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"Апп нь татан авалтын менежерийн дэлгэрэнгүй функцуудад хандалт хийх боломжтой. Хортой апп-ууд үүнийг ашиглан татан авалтыг тасалдуулах, хувийн мэдээлэлд хандалт хийх боломжтой."</string>
+ <string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Татан авалтын мэдэгдэл илгээх."</string>
+ <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"Апп нь татан авч дууссан талаарх мэдэгдэл явуулах боломжтой. Хортой апп-ууд энийг ашиглан файл татдаг бусад апп-уудыг төөрөгдөлд оруулж болно."</string>
+ <string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"Татаж авсан бүх файлыг USB сангаас харах"</string>
+ <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"Татаж авсан бүх файлыг SD картаас харах"</string>
+ <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"Апп нь аль апп-с татсанаас хамаарахгүйгээр SD картад хадгалагдсан бүх файлыг харах боломжтой."</string>
+ <string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"Татан авалтын кеш дотор зай нөөцлөх"</string>
+ <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"Апп нь татан авалтын менежерт илүү зай хэрэгтэй болсон үед автоматаар устгалгүйгээр файлыг татан авалтын кеш-д хадгалах боломжтой."</string>
+ <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"мэдэгдэл өгөхгүйгээр файлуудыг татаж авах"</string>
+ <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"Апп нь хэрэглэгчид ямар нэгэн мэдэгдэл харуулахгүйгээр татан авагчаар дамжуулан файл татаж авах боломжтой."</string>
+ <string name="permlab_accessAllDownloads" msgid="2436240495424393717">"Системийн татан авсан бүх файлуудад хандалт хийх"</string>
+ <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"Апп нь системийн дурын апп-н эхлүүлсэн бүх татан авалтуудыг үзэх, өөрчлөх боломжтой."</string>
+ <string name="download_unknown_title" msgid="7015124071247271585">"&lt;Гарчиггүй&gt;"</string>
+ <string name="notification_download_complete" msgid="5443563299253103667">"Татаж авч дууслаа."</string>
+ <string name="notification_download_failed" msgid="8612136111952014978">"Амжилттай татаж авлаа."</string>
+ <string name="notification_need_wifi_for_size" msgid="2556172885154833575">"Татаж авах хэмжээ Wi-Fi шаардана."</string>
+ <string name="notification_paused_in_background" msgid="4328508073283591772">"Ар талд түр зогсоогдсон"</string>
+ <string name="wifi_required_title" msgid="1995971416871498179">"Татан авалт нь операторын сүлжээнд хэт том байна"</string>
+ <string name="wifi_required_body" msgid="3067694630143784449">"Та энэ <xliff:g id="SIZE">%s </xliff:g> татан авалтыг гүйцээхийн тулд Wi-Fi-д холбогдох шаардлагатай. Та дараагийн удаа Wi-Fi сүлжээнд холбогдмогц энэ татан авалтыг эхлүүлэхийн тулд \n\nХүрнэ үү <xliff:g id="QUEUE_TEXT">%s </xliff:g>"</string>
+ <string name="wifi_recommended_title" msgid="7441589306734687400">"Дараа татахаар хүлээлгэх үү?"</string>
+ <string name="wifi_recommended_body" msgid="1314735166699936073">"Энэ <xliff:g id="SIZE">%s </xliff:g> татан авалтыг одоо эхлүүлснээр таны зайны цэнэг дуусах болон/эсхүл мобайл дата холболтыг хэт их хэрэглэх, улмаар өндөр төлбөр төлөхөд хүрч болзошгүй. Дараагийн удаа WiFi сүлжээнд холбогдохдоо татаж эхлүүлэхийн тулд доорхыг \n\n Товшино уу <xliff:g id="QUEUE_TEXT">%s</xliff:g>."</string>
+ <string name="button_queue_for_wifi" msgid="422576726189179221">"Хүлээх"</string>
+ <string name="button_cancel_download" msgid="2430166148737975604">"Цуцлах"</string>
+ <string name="button_start_now" msgid="792123674007840864">"Одоо эхлүүлэх"</string>
+ <string name="download_percent" msgid="6889426633242976698">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <plurals name="notif_summary_active">
+ <item quantity="one" msgid="8475775855911967027">"1 файл татаж байна"</item>
+ <item quantity="other" msgid="9087228371320573153">"<xliff:g id="NUMBER">%d</xliff:g> файл татаж байна"</item>
+ </plurals>
+ <plurals name="notif_summary_waiting">
+ <item quantity="one" msgid="5537481763963544278">"1 файл хүлээлгэнд"</item>
+ <item quantity="other" msgid="549229034166062887">"<xliff:g id="NUMBER">%d</xliff:g> файл хүлээлгэнд"</item>
+ </plurals>
+ <string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> үлдсэн"</string>
+ <string name="download_no_application_title" msgid="7935659741162801699">"Файлыг нээж чадахгүй байна"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Татан авалтууд"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Хүлээлгэнд"</string>
+ <string name="download_running" msgid="3925050393361158266">"Үргэлжилж байгаа"</string>
+ <string name="download_error" msgid="5144180777324573236">"Амжилтгүй"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Татаж байна, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+</resources>
diff --git a/res/values-ms/strings.xml b/res/values-ms-rMY/strings.xml
index 70c3730..6832ee5 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms-rMY/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> tinggal"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Tidak dapat membuka fail"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Muat turun"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Dibaris gilir"</string>
+ <string name="download_running" msgid="3925050393361158266">"Sedang berlangsung"</string>
+ <string name="download_error" msgid="5144180777324573236">"Tidak berjaya"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Sedang berjalan, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index e064adc..5faf89e 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -17,12 +17,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="3658948994665187911">"Nedlaster"</string>
- <string name="permlab_downloadManager" msgid="7779544811202855500">"Få tilgang til nedlasteren."</string>
+ <string name="permlab_downloadManager" msgid="7779544811202855500">"Bruke nedlasting."</string>
<string name="permdesc_downloadManager" msgid="4237406545998908947">"Gir appen adgang til nedlastingsbehandlingen og bruke den til å laste ned filer. Skadelig programvare kan bruke dette til å forstyrre nedlastinger og få tilgang til privat informasjon."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Avansert nedlastingsfunksjonalitet."</string>
<string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"Gir appen adgang til avanserte funksjoner i nedlastingsbehandlingen. Skadelig programvare kan bruke dette til å forstyrre nedlastinger og få tilgang til privat informasjon."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Sende nedlastingsvarslinger"</string>
- <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"Gir appen tillatelse til å sende varslinger om fullførte nedlastinger. Skadelig programvare kan bruke dette til å forstyrre andre programmer som laster ned filer."</string>
+ <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"Gir appen tillatelse til å sende varslinger om fullførte nedlastinger. Skadelig programvare kan bruke dette til å forstyrre andre apper som laster ned filer."</string>
<string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"Se nedlastinger til USB-lagr."</string>
<string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"Se alle nedlastinger til minnekort"</string>
<string name="permdesc_seeAllExternal" msgid="1672759909065511233">"Gir appen tilgang til alle nedlastinger på SD-kortet, uavhengig av hvilken app som lastet dem ned."</string>
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> gjenstår"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Kan ikke åpne filen"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Nedlastinger"</string>
+ <string name="download_queued" msgid="3302638231377947451">"I kø"</string>
+ <string name="download_running" msgid="3925050393361158266">"Pågår"</string>
+ <string name="download_error" msgid="5144180777324573236">"Mislyktes"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Pågår – <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-ne-rNP/strings.xml b/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000..e1b2606
--- /dev/null
+++ b/res/values-ne-rNP/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3658948994665187911">"डाउनलोड प्रबन्धक"</string>
+ <string name="permlab_downloadManager" msgid="7779544811202855500">"डाउनलोड प्रबन्धक पहुँच गर्नुहोस्"</string>
+ <string name="permdesc_downloadManager" msgid="4237406545998908947">"फाइल डाउनलोड गर्नका लागि अनुप्रयोगलाई डाउनलोड प्रबन्धकको पहुँचको अनुमति दिन्छ। हानिकारक अनुप्रयोगहरूले यसलाई डाउनलोडहरू अवरूद्ध गर्न र निजी जानकारी पहुँच गर्न यसको प्रयोग गर्न सक्छन्।"</string>
+ <string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"उन्नत डाउनलोड प्रबन्धक प्रकार्यहरू"</string>
+ <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"अनुप्रयोगलाई डाउनलोड प्रबन्धकको उन्नत प्रकार्यहरू पहुँच गर्न अनुमति दिन्छ। हानिकारक अनुप्रयोगहरूले यसलाई डाउनलोड अवरूद्ध गरी निजी जानकारी पहुँच गर्न प्रयोग गर्न सक्छ।"</string>
+ <string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"डाउनलोड सूचनाहरू पठाउनुहोस्।"</string>
+ <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"अनुप्रयोगलाई समाप्त भएका डाउनलोडहरूका सूचनाहरू पठाउन अनुमति दिन्छ। हानिकारक अनुप्रयोगहरूले फाइल डाउनलोड गर्ने अन्य अनुप्रयोगलाई झुक्याउनका लागि यसलाई प्रयोग गर्न सक्छन्।"</string>
+ <string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"सबै डाउनलोडहरूलाई USB भण्डारणमा हेर्नुहोस्"</string>
+ <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"सबै डाउनलोडहरूलाई SD कार्डमा हेर्नुहोस्"</string>
+ <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"जुनसुकै अनुप्रयोगले डाउनलोड गरेको भए पनि अनुप्रयोगलाई सम्पूर्ण डाउनलोडहरूलाई SD कार्डमा देख्ने अनुमति दिन्छ ।"</string>
+ <string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"डाउनलोड केसमा ठाउँ ओगट्नुहोस्"</string>
+ <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"अनुप्रयोगलाई फाइलहरूलाई डाउनलोड केसमा डाउनलोड गर्न अनुमति दिन्छ, जुन डाउनलोड प्रबन्धकलाई थप ठाउँ चाहिएको खण्डमा स्वचालित रूपमा हटाउन सकिदैन।"</string>
+ <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"बिना सूचना फाइलहरू डाउनलोड गर्नुहोस्"</string>
+ <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"अनुप्रयोगलाई डाउनलोड प्रबन्धकका माध्ययमद्वारा प्रयोगकर्तामा सूचना नदेखाई फाइलहरू डाउनलोड गर्ने अनुमति दिन्छ।"</string>
+ <string name="permlab_accessAllDownloads" msgid="2436240495424393717">"सम्पूर्ण प्रणाली डाउनलोडहरू पहुँच गर्नुहोस्"</string>
+ <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"अनुप्रयोगलाई कुनै पनि अनुप्रयोगले प्रणालीमा पहल गरेको सम्पूर्ण डाउनलोडहरू हेर्ने र परिमार्जन गर्ने अनुमति दिन्छ।"</string>
+ <string name="download_unknown_title" msgid="7015124071247271585">"&lt;शीर्षकविहिन&gt;"</string>
+ <string name="notification_download_complete" msgid="5443563299253103667">"डाउनलोड पुरा भयो।"</string>
+ <string name="notification_download_failed" msgid="8612136111952014978">"डाउनलोड असफल"</string>
+ <string name="notification_need_wifi_for_size" msgid="2556172885154833575">"डाउनलोड आकारलाई वाइ-फाइ चाहिन्छ।"</string>
+ <string name="notification_paused_in_background" msgid="4328508073283591772">"पृष्ठभूमिमा रोकिएको छ।"</string>
+ <string name="wifi_required_title" msgid="1995971416871498179">"अपरेटर सञ्जालका लागि डाउनलोड ज्यादै ठूलो"</string>
+ <string name="wifi_required_body" msgid="3067694630143784449">"तपाईँले वाइफाइ प्रयोग गर्नु पर्छ यस <xliff:g id="SIZE">%s </xliff:g> डाउनलोड समाप्त गर्न। \n\nछुनुहोस् <xliff:g id="QUEUE_TEXT">%s </xliff:g> यस डाउनलोडलाई सुरु गर्न अर्को पटक तपाईँ वाइ-फाइ सञ्जालामा जडित भए पछि।"</string>
+ <string name="wifi_recommended_title" msgid="7441589306734687400">"पछि डाउनलोडका लागि लाममा राख्ने हो?"</string>
+ <string name="wifi_recommended_body" msgid="1314735166699936073">"यस <xliff:g id="SIZE">%s </xliff:g> डाउनलोडलाई सुरु गर्दा तपाईँको ब्याट्रिको काल छोट्टिन सक्छ र/वा तपाईँको मोबाइल डेटा जडानको अधिकतम प्रयोग भई तपाईँको डेटा योजना अनुसार मोबाइल अपरेटरले थप शुल्क लिन सक्छ। \n\n छुनुहोस् <xliff:g id="QUEUE_TEXT">%s</xliff:g>तल यस डाउनलोडलाई सुरु गर्न अर्को पटक तपाईँ वाइफाइ सन्जालमा जडित हुने बेला।"</string>
+ <string name="button_queue_for_wifi" msgid="422576726189179221">"लाम"</string>
+ <string name="button_cancel_download" msgid="2430166148737975604">"रद्द गर्नुहोस्"</string>
+ <string name="button_start_now" msgid="792123674007840864">"अहिले सुरु गर्नुहोस्"</string>
+ <string name="download_percent" msgid="6889426633242976698">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <plurals name="notif_summary_active">
+ <item quantity="one" msgid="8475775855911967027">"१ फाइल डाउनलोड हुँदै"</item>
+ <item quantity="other" msgid="9087228371320573153">"<xliff:g id="NUMBER">%d</xliff:g> फाइलहरू डाउनलोड हुँदै"</item>
+ </plurals>
+ <plurals name="notif_summary_waiting">
+ <item quantity="one" msgid="5537481763963544278">"१ फाइल पर्खँदै"</item>
+ <item quantity="other" msgid="549229034166062887">"<xliff:g id="NUMBER">%d</xliff:g> फाइलहरू पर्खँदै"</item>
+ </plurals>
+ <string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> बाँकी छ"</string>
+ <string name="download_no_application_title" msgid="7935659741162801699">"फाइल खोल्न सक्दैन"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"डाउनलोडहरू"</string>
+ <string name="download_queued" msgid="3302638231377947451">"लाममा राखियो"</string>
+ <string name="download_running" msgid="3925050393361158266">"प्रगतिमा"</string>
+ <string name="download_error" msgid="5144180777324573236">"असफल"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"प्रगतिमा, <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
+</resources>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
new file mode 100644
index 0000000..8edcad9
--- /dev/null
+++ b/res/values-ne/strings.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3658948994665187911">"डाउनलोड प्रबन्धक"</string>
+ <string name="permlab_downloadManager" msgid="7779544811202855500">"डाउनलोड प्रबन्धक पहुँच गर्नुहोस्"</string>
+ <string name="permdesc_downloadManager" msgid="4237406545998908947">"फाइल डाउनलोड गर्नका लागि अनुप्रयोगलाई डाउनलोड प्रबन्धकको पहुँचको अनुमति दिन्छ। हानिकारक अनुप्रयोगहरूले यसलाई डाउनलोडहरू अवरूद्ध गर्न र निजी जानकारी पहुँच गर्न यसको प्रयोग गर्न सक्छन्।"</string>
+ <string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"उन्नत डाउनलोड प्रबन्धक प्रकार्यहरू"</string>
+ <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"अनुप्रयोगलाई डाउनलोड प्रबन्धकको उन्नत प्रकार्यहरू पहुँच गर्न अनुमति दिन्छ। हानिकारक अनुप्रयोगहरूले यसलाई डाउनलोड अवरूद्ध गरी निजी जानकारी पहुँच गर्न प्रयोग गर्न सक्छ।"</string>
+ <string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"डाउनलोड सूचनाहरू पठाउनुहोस्।"</string>
+ <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"अनुप्रयोगलाई समाप्त भएका डाउनलोडहरूका सूचनाहरू पठाउन अनुमति दिन्छ। हानिकारक अनुप्रयोगहरूले फाइल डाउनलोड गर्ने अन्य अनुप्रयोगलाई झुक्याउनका लागि यसलाई प्रयोग गर्न सक्छन्।"</string>
+ <string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"सबै डाउनलोडहरूलाई USB भण्डारणमा हेर्नुहोस्"</string>
+ <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"सबै डाउनलोडहरूलाई SD कार्डमा हेर्नुहोस्"</string>
+ <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"जुनसुकै अनुप्रयोगले डाउनलोड गरेको भए पनि अनुप्रयोगलाई सम्पूर्ण डाउनलोडहरूलाई SD कार्डमा देख्ने अनुमति दिन्छ ।"</string>
+ <string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"डाउनलोड केसमा ठाउँ ओगट्नुहोस्"</string>
+ <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"अनुप्रयोगलाई फाइलहरूलाई डाउनलोड केसमा डाउनलोड गर्न अनुमति दिन्छ, जुन डाउनलोड प्रबन्धकलाई थप ठाउँ चाहिएको खण्डमा स्वचालित रूपमा हटाउन सकिदैन।"</string>
+ <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"बिना सूचना फाइलहरू डाउनलोड गर्नुहोस्"</string>
+ <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"अनुप्रयोगलाई डाउनलोड प्रबन्धकका माध्ययमद्वारा प्रयोगकर्तामा सूचना नदेखाई फाइलहरू डाउनलोड गर्ने अनुमति दिन्छ।"</string>
+ <string name="permlab_accessAllDownloads" msgid="2436240495424393717">"सम्पूर्ण प्रणाली डाउनलोडहरू पहुँच गर्नुहोस्"</string>
+ <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"अनुप्रयोगलाई कुनै पनि अनुप्रयोगले प्रणालीमा पहल गरेको सम्पूर्ण डाउनलोडहरू हेर्ने र परिमार्जन गर्ने अनुमति दिन्छ।"</string>
+ <string name="download_unknown_title" msgid="7015124071247271585">"&lt;शीर्षकविहिन&gt;"</string>
+ <string name="notification_download_complete" msgid="5443563299253103667">"डाउनलोड पुरा भयो।"</string>
+ <string name="notification_download_failed" msgid="8612136111952014978">"डाउनलोड असफल"</string>
+ <string name="notification_need_wifi_for_size" msgid="2556172885154833575">"डाउनलोड आकारलाई वाइ-फाइ चाहिन्छ।"</string>
+ <string name="notification_paused_in_background" msgid="4328508073283591772">"पृष्ठभूमिमा रोकिएको छ।"</string>
+ <string name="wifi_required_title" msgid="1995971416871498179">"अपरेटर सञ्जालका लागि डाउनलोड ज्यादै ठूलो"</string>
+ <string name="wifi_required_body" msgid="3067694630143784449">"तपाईँले वाइफाइ प्रयोग गर्नु पर्छ यस <xliff:g id="SIZE">%s </xliff:g> डाउनलोड समाप्त गर्न। \n\nछुनुहोस् <xliff:g id="QUEUE_TEXT">%s </xliff:g> यस डाउनलोडलाई सुरु गर्न अर्को पटक तपाईँ वाइ-फाइ सञ्जालामा जडित भए पछि।"</string>
+ <string name="wifi_recommended_title" msgid="7441589306734687400">"पछि डाउनलोडका लागि लाममा राख्ने हो?"</string>
+ <string name="wifi_recommended_body" msgid="1314735166699936073">"यस <xliff:g id="SIZE">%s </xliff:g> डाउनलोडलाई सुरु गर्दा तपाईँको ब्याट्रिको काल छोट्टिन सक्छ र/वा तपाईँको मोबाइल डेटा जडानको अधिकतम प्रयोग भई तपाईँको डेटा योजना अनुसार मोबाइल अपरेटरले थप शुल्क लिन सक्छ। \n\n छुनुहोस् <xliff:g id="QUEUE_TEXT">%s</xliff:g>तल यस डाउनलोडलाई सुरु गर्न अर्को पटक तपाईँ वाइफाइ सन्जालमा जडित हुने बेला।"</string>
+ <string name="button_queue_for_wifi" msgid="422576726189179221">"लाम"</string>
+ <string name="button_cancel_download" msgid="2430166148737975604">"रद्द गर्नुहोस्"</string>
+ <string name="button_start_now" msgid="792123674007840864">"अहिले सुरु गर्नुहोस्"</string>
+ <string name="download_percent" msgid="6889426633242976698">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <plurals name="notif_summary_active">
+ <item quantity="one" msgid="8475775855911967027">"१ फाइल डाउनलोड हुँदै"</item>
+ <item quantity="other" msgid="9087228371320573153">"<xliff:g id="NUMBER">%d</xliff:g> फाइलहरू डाउनलोड हुँदै"</item>
+ </plurals>
+ <plurals name="notif_summary_waiting">
+ <item quantity="one" msgid="5537481763963544278">"१ फाइल पर्खँदै"</item>
+ <item quantity="other" msgid="549229034166062887">"<xliff:g id="NUMBER">%d</xliff:g> फाइलहरू पर्खँदै"</item>
+ </plurals>
+ <string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> बाँकी छ"</string>
+ <string name="download_no_application_title" msgid="7935659741162801699">"फाइल खोल्न सक्दैन"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"डाउनलोडहरू"</string>
+ <string name="download_queued" msgid="3302638231377947451">"लाममा राखियो"</string>
+ <string name="download_running" msgid="3925050393361158266">"प्रगतिमा"</string>
+ <string name="download_error" msgid="5144180777324573236">"असफल"</string>
+</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 9f0cad2..6f37aff 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> resterend"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Kan bestand niet openen"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Downloads"</string>
+ <string name="download_queued" msgid="3302638231377947451">"In wachtrij"</string>
+ <string name="download_running" msgid="3925050393361158266">"In uitvoering"</string>
+ <string name="download_error" msgid="5144180777324573236">"Mislukt"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Bezig: <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index b66d092..cc57448 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -28,7 +28,7 @@
<string name="permdesc_seeAllExternal" msgid="1672759909065511233">"Zezwala aplikacji na dostęp do listy wszystkich plików pobranych na kartę SD, niezależnie od tego, w której aplikacji zostały one pobrane."</string>
<string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"Zarezerwuj miejsce w pamięci podręcznej pobierania"</string>
<string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"Zezwala aplikacji na pobieranie plików do pamięci podręcznej, która nie może zostać automatycznie usunięta, gdy menedżer pobierania potrzebuje więcej miejsca."</string>
- <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"pobieraj pliki bez powiadomienia"</string>
+ <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"pobieranie plików bez powiadomienia"</string>
<string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"Zezwala aplikacji na pobieranie plików przez menedżera pobierania bez wyświetlania powiadomień."</string>
<string name="permlab_accessAllDownloads" msgid="2436240495424393717">"Dostęp do wszystkich pobranych pozycji w systemie"</string>
<string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"Zezwala aplikacji na wyświetlanie i modyfikowanie wszystkich plików pobranych w dowolnej aplikacji w systemie."</string>
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"Pozostało: <xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Nie można otworzyć pliku"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Pobrane"</string>
+ <string name="download_queued" msgid="3302638231377947451">"W kolejce"</string>
+ <string name="download_running" msgid="3925050393361158266">"W toku"</string>
+ <string name="download_error" msgid="5144180777324573236">"Niepowodzenie"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"W toku, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 710b5f3..1bd74bb 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"Faltam <xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Não é possível abrir o ficheiro"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Transferências"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Em fila"</string>
+ <string name="download_running" msgid="3925050393361158266">"Em curso"</string>
+ <string name="download_error" msgid="5144180777324573236">"Sem êxito"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Em curso, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 03cd238..83eb688 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> restantes"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Não é possível abrir o arquivo"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Downloads"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Na fila"</string>
+ <string name="download_running" msgid="3925050393361158266">"Em andamento"</string>
+ <string name="download_error" msgid="5144180777324573236">"Falha"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Em andamento, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index a18b181..a679828 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"Timp rămas: <xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Fişierul nu poate fi deschis"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Descărcări"</string>
+ <string name="download_queued" msgid="3302638231377947451">"În coadă"</string>
+ <string name="download_running" msgid="3925050393361158266">"În desfășurare"</string>
+ <string name="download_error" msgid="5144180777324573236">"Nereușit"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"În curs, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 7e06bc1..80c3924 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"Осталось: <xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Не удается открыть файл"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Загрузки"</string>
+ <string name="download_queued" msgid="3302638231377947451">"В очереди"</string>
+ <string name="download_running" msgid="3925050393361158266">"Загружается"</string>
+ <string name="download_error" msgid="5144180777324573236">"Сбой"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Скачано <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-si-rLK/strings.xml b/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000..bbe8527
--- /dev/null
+++ b/res/values-si-rLK/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3658948994665187911">"බාගැනීමේ කළමනාකරු"</string>
+ <string name="permlab_downloadManager" msgid="7779544811202855500">"බාගැනීම් කළමනාකරු ප්‍රවේශ කරන්න."</string>
+ <string name="permdesc_downloadManager" msgid="4237406545998908947">"යෙදුම් හට මෙය භාවිතා කර බාගැනීම් කළමනාකරු ප්‍රවේශ කර ගොනු බාගැනීමට අවසර දෙන්න. කරදරකාරී යෙදුම් හට මෙය භාවිතා කර බාගැනීම් වලට බාධා පමුණුවා පෞද්ගලික තොරතුරු ප්‍රවේශ කිරීමට යොදාගත හැක."</string>
+ <string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"උසස් බාගැනීම් කළමනාකරු විශේෂාංග."</string>
+ <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"යෙදුම් හට මෙය භාවිතා කර බාගැනීම් කළමනාකරුගේ උසස් විශේෂාංග ප්‍රවේශ කර ගොනු බාගැනීමට අවසර දෙන්න. කරදරකාරී යෙදුම් හට මෙය භාවිතා කර බාගැනීම් වලට බාධා පමුණුවා පෞද්ගලික තොරතුරු ප්‍රවේශ කිරීමට යොදාගත හැක."</string>
+ <string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"බාගැනීමේ දැනුම්දීම් යවන්න."</string>
+ <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"සම්පුර්ණ වූ බාගැනීම් පිලිබඳ දැනුම්දීම් යැවීමට යෙදුමට අවසර දෙන්න. කරදරකාරී යෙදුම් වලට මෙය යොදාගනිමින් ගොනු බාගත කරන වෙනත් යෙදුම් අමාරුවේ දැමිය හැක."</string>
+ <string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"USB ආචයනය වෙත සියලු බාගැනීම් බලන්න"</string>
+ <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"SD පත වෙත සියලු බාගැනීම් බලන්න"</string>
+ <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"බාගත්තේ කුමන යෙදුමද යන්න සැලකිල්ලට නොගෙන, SD කාඩ්පත වෙත සියලු බාගැනීම් බැලීමට යෙදුමට අවසර දෙන්න."</string>
+ <string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"බාගැනීම් හැඹිලියේ ඉඩ වෙන් කරගන්න"</string>
+ <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"යෙදුමට ගොනු බාගැනීමේ හැඹිලියට බාගැනීමට අවසර දෙන්න, එය බාගැනීමේ කළමනාකරුට තවත් ඉඩ අවශ්‍ය වූ විට ස්වයංක්‍රීයව මැකිය නොහැක."</string>
+ <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"දැනුම්දීමකින් තොරව ගොනු බාගන්න"</string>
+ <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"පරිශීලකයාට කිසිඳු දැනුම්දීමක් කිරීමකින් තොරව බාගැනීම් කළමනාකරු හරහා ගොනු බාගත කරගැනීමට යෙදුමට අවසර දෙන්න."</string>
+ <string name="permlab_accessAllDownloads" msgid="2436240495424393717">"සියලු පද්ධති බාගැනීම් ප්‍රවේශ කරන්න"</string>
+ <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"පද්ධතියේ ඕනෑම යෙදුමකින් ආරම්භ කරන ලද සියලු බාගැනීම් දර්ශනය කිරීමට සහ වෙනස් කිරීමට යෙදුමට අවසර දෙන්න."</string>
+ <string name="download_unknown_title" msgid="7015124071247271585">"&lt;නම් නොකළ&gt;"</string>
+ <string name="notification_download_complete" msgid="5443563299253103667">"බාගැනීම සම්පූර්ණයි."</string>
+ <string name="notification_download_failed" msgid="8612136111952014978">"බාගැනීම අසාර්ථකයි."</string>
+ <string name="notification_need_wifi_for_size" msgid="2556172885154833575">"බාගැනීමේ ප්‍රමාණයට Wi-Fi අවශ්‍යවේ."</string>
+ <string name="notification_paused_in_background" msgid="4328508073283591772">"පසුබිමේ නවතා ඇත."</string>
+ <string name="wifi_required_title" msgid="1995971416871498179">"ක්‍රියාකරු ජාලයට බාගැනීම විශාල වැඩිය"</string>
+ <string name="wifi_required_body" msgid="3067694630143784449">"මෙම <xliff:g id="SIZE">%s </xliff:g> බාගැනීම සිදු කිරීමට ඔබ Wi-Fi භාවිතා කළ යුතුය. \n\nඔබ මීළඟට WiFi ජාලයකට සම්බන්ධ වූ පසු බාගැනීම ආරම්භ කිරීමට පහත <xliff:g id="QUEUE_TEXT">%s </xliff:g> ස්පර්ශ කරන්න."</string>
+ <string name="wifi_recommended_title" msgid="7441589306734687400">"පසුව බාගැනීමට පෝලිමේ තබන්නද?"</string>
+ <string name="wifi_recommended_body" msgid="1314735166699936073">"මෙම <xliff:g id="SIZE">%s </xliff:g> බාගැනීම දැන් ආරම්භ කිරීමෙන් ඔබගේ බැටරි ආයු කාලය අඩුවේ සහ/හෝ ඔබගේ ජංගම දත්ත සම්බන්ධතාවය භාවිතය අධික වේ, එය ඔබගේ දත්ත සැලසුමට අනුව විශාල ගෙවීමක් සිදුවිය හැක.\n\n ඔබ මීළඟට WiFi ජාලයකට සම්බන්ධ වූ පසු බාගැනීම ආරම්භ කිරීමට පහත <xliff:g id="QUEUE_TEXT">%s</xliff:g> ස්පර්ශ කරන්න."</string>
+ <string name="button_queue_for_wifi" msgid="422576726189179221">"පෝලිම"</string>
+ <string name="button_cancel_download" msgid="2430166148737975604">"අවලංගු කරන්න"</string>
+ <string name="button_start_now" msgid="792123674007840864">"දැන් අරඹන්න"</string>
+ <string name="download_percent" msgid="6889426633242976698">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <plurals name="notif_summary_active">
+ <item quantity="one" msgid="8475775855911967027">"ගොනු 1 ක් බාගත වෙමින්"</item>
+ <item quantity="other" msgid="9087228371320573153">"ගොනු <xliff:g id="NUMBER">%d</xliff:g> බාගත වෙමින්"</item>
+ </plurals>
+ <plurals name="notif_summary_waiting">
+ <item quantity="one" msgid="5537481763963544278">"ගොනු 1 රැඳී සිටිමින්"</item>
+ <item quantity="other" msgid="549229034166062887">"ගොනු <xliff:g id="NUMBER">%d</xliff:g> රැඳී සිටිමින්"</item>
+ </plurals>
+ <string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> ඉතිරියි"</string>
+ <string name="download_no_application_title" msgid="7935659741162801699">"ගොනුව විවෘත කළ නොහැකි විය"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"බාගැනීම්"</string>
+ <string name="download_queued" msgid="3302638231377947451">"පෙළ ගසන ලදි"</string>
+ <string name="download_running" msgid="3925050393361158266">"ක්‍රියාවේ පවතී"</string>
+ <string name="download_error" msgid="5144180777324573236">"අසාර්ථකයි"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"ක්‍රියාවේ පවතී, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+</resources>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
new file mode 100644
index 0000000..6780431
--- /dev/null
+++ b/res/values-si/strings.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3658948994665187911">"බාගැනීමේ කළමනාකරු"</string>
+ <string name="permlab_downloadManager" msgid="7779544811202855500">"බාගැනීම් කළමනාකරු ප්‍රවේශ කරන්න."</string>
+ <string name="permdesc_downloadManager" msgid="4237406545998908947">"යෙදුම් හට මෙය භාවිතා කර බාගැනීම් කළමනාකරු ප්‍රවේශ කර ගොනු බාගැනීමට අවසර දෙන්න. කරදරකාරී යෙදුම් හට මෙය භාවිතා කර බාගැනීම් වලට බාධා පමුණුවා පෞද්ගලික තොරතුරු ප්‍රවේශ කිරීමට යොදාගත හැක."</string>
+ <string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"උසස් බාගැනීම් කළමනාකරු විශේෂාංග."</string>
+ <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"යෙදුම් හට මෙය භාවිතා කර බාගැනීම් කළමනාකරුගේ උසස් විශේෂාංග ප්‍රවේශ කර ගොනු බාගැනීමට අවසර දෙන්න. කරදරකාරී යෙදුම් හට මෙය භාවිතා කර බාගැනීම් වලට බාධා පමුණුවා පෞද්ගලික තොරතුරු ප්‍රවේශ කිරීමට යොදාගත හැක."</string>
+ <string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"බාගැනීමේ දැනුම්දීම් යවන්න."</string>
+ <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"සම්පුර්ණ වූ බාගැනීම් පිලිබඳ දැනුම්දීම් යැවීමට යෙදුමට අවසර දෙන්න. කරදරකාරී යෙදුම් වලට මෙය යොදාගනිමින් ගොනු බාගත කරන වෙනත් යෙදුම් අමාරුවේ දැමිය හැක."</string>
+ <string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"USB ආචයනය වෙත සියලු බාගැනීම් බලන්න"</string>
+ <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"SD පත වෙත සියලු බාගැනීම් බලන්න"</string>
+ <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"බාගත්තේ කුමන යෙදුමද යන්න සැලකිල්ලට නොගෙන, SD කාඩ්පත වෙත සියලු බාගැනීම් බැලීමට යෙදුමට අවසර දෙන්න."</string>
+ <string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"බාගැනීම් හැඹිලියේ ඉඩ වෙන් කරගන්න"</string>
+ <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"යෙදුමට ගොනු බාගැනීමේ හැඹිලියට බාගැනීමට අවසර දෙන්න, එය බාගැනීමේ කළමනාකරුට තවත් ඉඩ අවශ්‍ය වූ විට ස්වයංක්‍රීයව මැකිය නොහැක."</string>
+ <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"දැනුම්දීමකින් තොරව ගොනු බාගන්න"</string>
+ <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"පරිශීලකයාට කිසිඳු දැනුම්දීමක් කිරීමකින් තොරව බාගැනීම් කළමනාකරු හරහා ගොනු බාගත කරගැනීමට යෙදුමට අවසර දෙන්න."</string>
+ <string name="permlab_accessAllDownloads" msgid="2436240495424393717">"සියලු පද්ධති බාගැනීම් ප්‍රවේශ කරන්න"</string>
+ <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"පද්ධතියේ ඕනෑම යෙදුමකින් ආරම්භ කරන ලද සියලු බාගැනීම් දර්ශනය කිරීමට සහ වෙනස් කිරීමට යෙදුමට අවසර දෙන්න."</string>
+ <string name="download_unknown_title" msgid="7015124071247271585">"&lt;නම් නොකළ&gt;"</string>
+ <string name="notification_download_complete" msgid="5443563299253103667">"බාගැනීම සම්පූර්ණයි."</string>
+ <string name="notification_download_failed" msgid="8612136111952014978">"බාගැනීම අසාර්ථකයි."</string>
+ <string name="notification_need_wifi_for_size" msgid="2556172885154833575">"බාගැනීමේ ප්‍රමාණයට Wi-Fi අවශ්‍යවේ."</string>
+ <string name="notification_paused_in_background" msgid="4328508073283591772">"පසුබිමේ නවතා ඇත."</string>
+ <string name="wifi_required_title" msgid="1995971416871498179">"ක්‍රියාකරු ජාලයට බාගැනීම විශාල වැඩිය"</string>
+ <string name="wifi_required_body" msgid="3067694630143784449">"මෙම <xliff:g id="SIZE">%s </xliff:g> බාගැනීම සිදු කිරීමට ඔබ Wi-Fi භාවිතා කළ යුතුය. \n\nඔබ මීළඟට WiFi ජාලයකට සම්බන්ධ වූ පසු බාගැනීම ආරම්භ කිරීමට පහත <xliff:g id="QUEUE_TEXT">%s </xliff:g> ස්පර්ශ කරන්න."</string>
+ <string name="wifi_recommended_title" msgid="7441589306734687400">"පසුව බාගැනීමට පෝලිමේ තබන්නද?"</string>
+ <string name="wifi_recommended_body" msgid="1314735166699936073">"මෙම <xliff:g id="SIZE">%s </xliff:g> බාගැනීම දැන් ආරම්භ කිරීමෙන් ඔබගේ බැටරි ආයු කාලය අඩුවේ සහ/හෝ ඔබගේ ජංගම දත්ත සම්බන්ධතාවය භාවිතය අධික වේ, එය ඔබගේ දත්ත සැලසුමට අනුව විශාල ගෙවීමක් සිදුවිය හැක.\n\n ඔබ මීළඟට WiFi ජාලයකට සම්බන්ධ වූ පසු බාගැනීම ආරම්භ කිරීමට පහත <xliff:g id="QUEUE_TEXT">%s</xliff:g> ස්පර්ශ කරන්න."</string>
+ <string name="button_queue_for_wifi" msgid="422576726189179221">"පෝලිම"</string>
+ <string name="button_cancel_download" msgid="2430166148737975604">"අවලංගු කරන්න"</string>
+ <string name="button_start_now" msgid="792123674007840864">"දැන් අරඹන්න"</string>
+ <string name="download_percent" msgid="6889426633242976698">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <plurals name="notif_summary_active">
+ <item quantity="one" msgid="8475775855911967027">"ගොනු 1 ක් බාගත වෙමින්"</item>
+ <item quantity="other" msgid="9087228371320573153">"ගොනු <xliff:g id="NUMBER">%d</xliff:g> බාගත වෙමින්"</item>
+ </plurals>
+ <plurals name="notif_summary_waiting">
+ <item quantity="one" msgid="5537481763963544278">"ගොනු 1 රැඳී සිටිමින්"</item>
+ <item quantity="other" msgid="549229034166062887">"ගොනු <xliff:g id="NUMBER">%d</xliff:g> රැඳී සිටිමින්"</item>
+ </plurals>
+ <string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> ඉතිරියි"</string>
+ <string name="download_no_application_title" msgid="7935659741162801699">"ගොනුව විවෘත කළ නොහැකි විය"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"බාගැනීම්"</string>
+ <string name="download_queued" msgid="3302638231377947451">"පෙළ ගසන ලදි"</string>
+ <string name="download_running" msgid="3925050393361158266">"ක්‍රියාවේ පවතී"</string>
+ <string name="download_error" msgid="5144180777324573236">"අසාර්ථකයි"</string>
+</resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 018447c..1410605 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -16,38 +16,38 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="3658948994665187911">"Správca preberania"</string>
- <string name="permlab_downloadManager" msgid="7779544811202855500">"Získať prístup k správcovi preberania."</string>
- <string name="permdesc_downloadManager" msgid="4237406545998908947">"Umožňuje aplikácii pristupovať k správcovi preberania a použiť ho na preberanie súborov. Škodlivé aplikácie to môžu využiť a narušiť preberanie alebo získať prístup k súkromným informáciám."</string>
- <string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Rozšírené funkcie správcu preberania."</string>
- <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"Umožňuje aplikácii pristupovať k rozšíreným funkciám správcu preberania. Škodlivé aplikácie to môžu využiť a narušiť preberanie alebo získať prístup k súkromným informáciám."</string>
- <string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Odoslať upozornenie o prevzatí."</string>
- <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"Umožňuje aplikácii odosielať upozornenia na dokončenie preberania. Škodlivé aplikácie môžu pomocou tohto nastavenia zmiasť iné aplikácie, ktoré preberajú súbory."</string>
+ <string name="app_label" msgid="3658948994665187911">"Správca sťahovania"</string>
+ <string name="permlab_downloadManager" msgid="7779544811202855500">"Získať prístup k správcovi sťahovania."</string>
+ <string name="permdesc_downloadManager" msgid="4237406545998908947">"Umožňuje aplikácii pristupovať k správcovi sťahovania a použiť ho na sťahovanie súborov. Škodlivé aplikácie to môžu využiť a narušiť sťahovanie alebo získať prístup k súkromným informáciám."</string>
+ <string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Rozšírené funkcie správcu sťahovania."</string>
+ <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"Umožňuje aplikácii pristupovať k rozšíreným funkciám správcu sťahovania. Škodlivé aplikácie to môžu využiť a narušiť sťahovanie alebo získať prístup k súkromným informáciám."</string>
+ <string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Odoslať upozornenie o stiahnutí."</string>
+ <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"Umožňuje aplikácii odosielať upozornenia na dokončenie sťahovania. Škodlivé aplikácie môžu pomocou tohto nastavenia zmiasť iné aplikácie, ktoré preberajú súbory."</string>
<string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"Zobr. preber. do ukl. priestoru USB"</string>
- <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"Zobrazenie všetkých položiek prevzatých na kartu SD"</string>
- <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"Povolí aplikácii zobraziť všetky súbory prevzaté na kartu SD bez ohľadu na aplikáciu, pomocou ktorej boli prevzaté."</string>
- <string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"Rezervovať miesto vo vyrovnáv. pamäti preberania"</string>
- <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"Umožňuje aplikácii preberať súbory do vyrovnávacej pamäte preberania, ktorú nie je možné automaticky odstrániť, keď správca preberania potrebuje viac miesta."</string>
- <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"preberať súbory bez upozornenia"</string>
- <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"Umožňuje aplikácii preberať súbory prostredníctvom správcu preberania bez toho, aby sa používateľovi zobrazilo upozornenie."</string>
- <string name="permlab_accessAllDownloads" msgid="2436240495424393717">"Prístup ku všetkým systémovým prevzatiam"</string>
- <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"Umožňuje aplikácii zobraziť a upravovať všetky preberania spustené ľubovoľnou aplikáciou v systéme."</string>
+ <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"Zobrazenie všetkých položiek stiahnutých na kartu SD"</string>
+ <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"Povolí aplikácii zobraziť všetky súbory stiahnuté na kartu SD bez ohľadu na aplikáciu, pomocou ktorej boli stiahnuté."</string>
+ <string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"Rezervovať miesto vo vyrovnáv. pamäti sťahovania"</string>
+ <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"Umožňuje aplikácii sťahovať súbory do vyrovnávacej pamäte sťahovania, ktorú nie je možné automaticky odstrániť, keď správca sťahovania potrebuje viac miesta."</string>
+ <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"sťahovať súbory bez upozornenia"</string>
+ <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"Umožňuje aplikácii sťahovať súbory prostredníctvom správcu sťahovania bez toho, aby sa používateľovi zobrazilo upozornenie."</string>
+ <string name="permlab_accessAllDownloads" msgid="2436240495424393717">"Prístup ku všetkým systémovým stiahnutiam"</string>
+ <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"Umožňuje aplikácii zobraziť a upravovať všetky sťahovania spustené ľubovoľnou aplikáciou v systéme."</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;Bez názvu&gt;"</string>
- <string name="notification_download_complete" msgid="5443563299253103667">"Preberanie dokončené."</string>
- <string name="notification_download_failed" msgid="8612136111952014978">"Preberanie bolo neúspešné."</string>
+ <string name="notification_download_complete" msgid="5443563299253103667">"Sťahovanie dokončené."</string>
+ <string name="notification_download_failed" msgid="8612136111952014978">"Sťahovanie bolo neúspešné."</string>
<string name="notification_need_wifi_for_size" msgid="2556172885154833575">"Vzhľadom na veľkosť preberaného súboru sa vyžaduje pripojenie Wi-Fi"</string>
<string name="notification_paused_in_background" msgid="4328508073283591772">"Pozastavené na pozadí."</string>
<string name="wifi_required_title" msgid="1995971416871498179">"Preberaný súbor je pre sieť operátora príliš veľký"</string>
- <string name="wifi_required_body" msgid="3067694630143784449">"Na dokončenie preberania tohto súboru s veľkosťou <xliff:g id="SIZE">%s </xliff:g> je potrebné pripojenie Wi-Fi. \n\nAk chcete spustiť preberanie pri ďalšom pripojení k sieti Wi-Fi, dotknite sa možnosti <xliff:g id="QUEUE_TEXT">%s </xliff:g>."</string>
- <string name="wifi_recommended_title" msgid="7441589306734687400">"Zaradiť do zoznamu na neskoršie prevzatie?"</string>
- <string name="wifi_recommended_body" msgid="1314735166699936073">"Preberanie (<xliff:g id="SIZE">%s </xliff:g>) môže skrátiť výdrž batérie alebo príliš zaťažiť mobilné pripojenie a viesť k účtovaniu poplatkov podľa dát. programu.\n\n Dotykom možnosti <xliff:g id="QUEUE_TEXT">%s</xliff:g> spustíte preberanie pri ďalšom pripojení k Wi-Fi."</string>
+ <string name="wifi_required_body" msgid="3067694630143784449">"Na dokončenie sťahovania tohto súboru s veľkosťou <xliff:g id="SIZE">%s </xliff:g> je potrebné pripojenie Wi-Fi. \n\nAk chcete spustiť sťahovanie pri ďalšom pripojení k sieti Wi-Fi, dotknite sa možnosti <xliff:g id="QUEUE_TEXT">%s </xliff:g>."</string>
+ <string name="wifi_recommended_title" msgid="7441589306734687400">"Zaradiť do zoznamu na neskoršie stiahnutie?"</string>
+ <string name="wifi_recommended_body" msgid="1314735166699936073">"Sťahovanie (<xliff:g id="SIZE">%s </xliff:g>) môže skrátiť výdrž batérie alebo príliš zaťažiť mobilné pripojenie a viesť k účtovaniu poplatkov podľa dát. programu.\n\n Dotykom možnosti <xliff:g id="QUEUE_TEXT">%s</xliff:g> spustíte sťahovanie pri ďalšom pripojení k Wi-Fi."</string>
<string name="button_queue_for_wifi" msgid="422576726189179221">"Zoznam"</string>
<string name="button_cancel_download" msgid="2430166148737975604">"Zrušiť"</string>
<string name="button_start_now" msgid="792123674007840864">"Spustiť"</string>
<string name="download_percent" msgid="6889426633242976698">"<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
<plurals name="notif_summary_active">
- <item quantity="one" msgid="8475775855911967027">"Preberá sa 1 súbor"</item>
- <item quantity="other" msgid="9087228371320573153">"Počet preberaných súborov: <xliff:g id="NUMBER">%d</xliff:g>"</item>
+ <item quantity="one" msgid="8475775855911967027">"Sťahuje sa 1 súbor"</item>
+ <item quantity="other" msgid="9087228371320573153">"Počet sťahovaných súborov: <xliff:g id="NUMBER">%d</xliff:g>"</item>
</plurals>
<plurals name="notif_summary_waiting">
<item quantity="one" msgid="5537481763963544278">"1 čakajúci súbor"</item>
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"Zostáva: <xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Súbor sa nepodarilo otvoriť"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Stiahnuté súbory"</string>
+ <string name="download_queued" msgid="3302638231377947451">"V poradí"</string>
+ <string name="download_running" msgid="3925050393361158266">"Prebieha"</string>
+ <string name="download_error" msgid="5144180777324573236">"Neúspešné"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Prebieha (<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>)"</string>
</resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 7c116a1..79e772f 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"Še <xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Datoteke ni mogoče odpreti"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Prenosi"</string>
+ <string name="download_queued" msgid="3302638231377947451">"V čakalni vrsti"</string>
+ <string name="download_running" msgid="3925050393361158266">"Poteka"</string>
+ <string name="download_error" msgid="5144180777324573236">"Neuspešno"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Poteka – <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 7d1d3a9..5585ce3 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"Још <xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Није могуће отворити датотеку"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Преузимања"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Стављено је на чекање"</string>
+ <string name="download_running" msgid="3925050393361158266">"У току је"</string>
+ <string name="download_error" msgid="5144180777324573236">"Није успело"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"У току је, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 164c527..8040730 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> återstår"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Det går inte att öppna filen"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Hämtningar"</string>
+ <string name="download_queued" msgid="3302638231377947451">"I kö"</string>
+ <string name="download_running" msgid="3925050393361158266">"Pågår"</string>
+ <string name="download_error" msgid="5144180777324573236">"Misslyckades"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Hämtningen pågår: <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 8697344..f5758db 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -18,23 +18,23 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="3658948994665187911">"Kidhibiti Vipakuliwa"</string>
<string name="permlab_downloadManager" msgid="7779544811202855500">"Fikia kidhibiti cha vipakuliwa."</string>
- <string name="permdesc_downloadManager" msgid="4237406545998908947">"Inaruhusu programu kufikia kidhibiti vipakuzi na kukitumia ili kupakua faili. Programu hasidi zinaweza kutumia hii ili kutatiza vipakuzi na kufikia maelezo ya kibinafsi."</string>
+ <string name="permdesc_downloadManager" msgid="4237406545998908947">"Huruhusu programu kufikia kidhibiti vipakuliwa na kukitumia ili kupakua faili. Programu hasidi zinaweza kutumia hii ili kutatiza vipakuliwa na kufikia maelezo ya kibinafsi."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Hatua za kina zinazoweza kufanywa na kidhibiti vipakuliwa."</string>
- <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"Inaruhusu programu kufikia vitendaji mahiri vya kidhibiti vipakuzi. Programu hasidi zinaweza kutumia hii ili kutatiza vipakuzi na kufikia maelezo ya kibinafsi."</string>
+ <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"Huruhusu programu kufikia vitendaji mahiri vya kidhibiti vipakuliwa. Programu hasidi zinaweza kutumia hii ili kutatiza vipakuliwa na kufikia maelezo ya kibinafsi."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Tuma arifa za vipakuliwa."</string>
- <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"Inaruhusu programu kutuma notisi kuhusu vipakuzi vilivyokamilika. Programu hasidi zinaweza kutumia hii kuchanganya programu zingine ambazo hupakua faili."</string>
+ <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"Huruhusu programu kutuma notisi kuhusu vipakuliwa vilivyokamilika. Programu hasidi zinaweza kutumia hii kuchanganya programu zingine ambazo hupakua faili."</string>
<string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"Angalia vipakuliwa vyote vilivyowekwa kwenye hifadhi ya USB"</string>
<string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"Tazama vipakuliwa vyote vilivyoenda kwenye kadi ya SD"</string>
- <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"Inaruhusu programu kuona vipakuzi vyote kwenye kadi ya SD, pasi kuzingatia ni programu gani iliyozipakuwa."</string>
- <string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"Geuza nafasi katika kache ya kupakua"</string>
- <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"Inaruhusu programu kupakua faili kwa kache ya vipakuzi ambayo haiwezi kufutwa kiotomatiki wakati kidhibiti upakuaji kinahitaji nafasi zaidi."</string>
- <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"Pakua faili bila kutoa arifa"</string>
+ <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"Huruhusu programu kuona vipakuliwa vyote kwenye kadi ya SD, pasi kuzingatia ni programu gani iliyozipakua."</string>
+ <string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"Hifadhi nafasi katika akiba ya upakuaji"</string>
+ <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"Huruhusu programu kupakua faili hadi akiba ya vipakuliwa ambayo haiwezi kufutwa kiotomatiki wakati kidhibiti upakuaji kinahitaji nafasi zaidi."</string>
+ <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"kupakua faili bila kutoa arifa"</string>
<string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"Huruhusu programu kupakua faili kupitia kidhibiti vipakuliwa bila mtumiaji kuonyeshwa arifa yoyote."</string>
<string name="permlab_accessAllDownloads" msgid="2436240495424393717">"Fikia vipakuliwa vyote vya mfumo"</string>
- <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"Inaruhusu programu kuona na kurekebisha vipakuzi vyote vilivyoanzishwa na programu yoyote kwenye mfumo."</string>
+ <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"Huruhusu programu kuona na kurekebisha vipakuliwa vyote vilivyoanzishwa na programu yoyote kwenye mfumo."</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;Haina Kichwa&gt;"</string>
<string name="notification_download_complete" msgid="5443563299253103667">"Upakuaji umekamilika"</string>
- <string name="notification_download_failed" msgid="8612136111952014978">"Kupakua hakujafaulu."</string>
+ <string name="notification_download_failed" msgid="8612136111952014978">"Kupakua hakukuwezekana."</string>
<string name="notification_need_wifi_for_size" msgid="2556172885154833575">"Ukubwa wa kipakuzi uhitaji Wi-Fi"</string>
<string name="notification_paused_in_background" msgid="4328508073283591772">"Imesitishwa katika usuli."</string>
<string name="wifi_required_title" msgid="1995971416871498179">"Kipakuzi ni kikubwa zaidi kwa mtandao wa mtoa huduma"</string>
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> zinazosalia"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Haiwezi kufungua faili"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Vipakuliwa"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Zilizowekwa kwenye foleni"</string>
+ <string name="download_running" msgid="3925050393361158266">"Unaendelea"</string>
+ <string name="download_error" msgid="5144180777324573236">"Haijafanikiwa"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Inaendelea, <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index fdd081b..a4f842d 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"เหลืออีก <xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"ไม่สามารถเปิดไฟล์ได้"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"ดาวน์โหลด"</string>
+ <string name="download_queued" msgid="3302638231377947451">"อยู่ในคิว"</string>
+ <string name="download_running" msgid="3925050393361158266">"กำลังดำเนินการ"</string>
+ <string name="download_error" msgid="5144180777324573236">"ไม่สำเร็จ"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"กำลังดำเนินการ <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 4580be6..ddf6b21 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> ang natitira"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Hindi mabuksan ang file"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Mga Download"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Naka-queue"</string>
+ <string name="download_running" msgid="3925050393361158266">"Isinasagawa"</string>
+ <string name="download_error" msgid="5144180777324573236">"Hindi matagumpay"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Kasalukuyang nagaganap, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 0881060..3b8c6a1 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> kaldı"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Dosya açılamıyor"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"İndirilenler"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Sıraya alındı"</string>
+ <string name="download_running" msgid="3925050393361158266">"Devam ediyor"</string>
+ <string name="download_error" msgid="5144180777324573236">"Başarısız"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Devam ediyor, <xliff:g id="PERCENT">%%</xliff:g><xliff:g id="NUMBER">%d</xliff:g>"</string>
</resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index ab9e9fa..10eeea6 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"Залишилося <xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Неможливо відкрити файл"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Завантаження"</string>
+ <string name="download_queued" msgid="3302638231377947451">"У черзі"</string>
+ <string name="download_running" msgid="3925050393361158266">"Виконується"</string>
+ <string name="download_error" msgid="5144180777324573236">"Помилка"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Виконується, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 3c99230..2067ace 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"Còn lại <xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Không thể mở tệp"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Bản tải xuống"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Đã xếp hàng"</string>
+ <string name="download_running" msgid="3925050393361158266">"Đang thực hiện"</string>
+ <string name="download_error" msgid="5144180777324573236">"Không thành công"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Đang tải xuống, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 3cf0720..d71655c 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"剩余时间:<xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"无法打开文件"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"下载"</string>
+ <string name="download_queued" msgid="3302638231377947451">"已加入队列"</string>
+ <string name="download_running" msgid="3925050393361158266">"正在下载"</string>
+ <string name="download_error" msgid="5144180777324573236">"失败"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"正在下载:<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..25ab495
--- /dev/null
+++ b/res/values-zh-rHK/strings.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3658948994665187911">"下載管理員"</string>
+ <string name="permlab_downloadManager" msgid="7779544811202855500">"存取下載管理員。"</string>
+ <string name="permdesc_downloadManager" msgid="4237406545998908947">"允許應用程式存取下載管理員,並用以下載檔案。惡意應用程式可藉此干擾檔案下載並存取私人資訊。"</string>
+ <string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"進階下載管理員功能。"</string>
+ <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"允許應用程式存取下載管理員的進階功能。惡意應用程式可藉此干擾檔案下載並存取私人資訊。"</string>
+ <string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"傳送下載通知。"</string>
+ <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"允許應用程式在完成下載時送出通知。惡意應用程式可藉此擾亂其他下載檔案的應用程式。"</string>
+ <string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"查看所有下載到 USB 儲存裝置的檔案"</string>
+ <string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"查看 SD 卡中的所有下載項目"</string>
+ <string name="permdesc_seeAllExternal" msgid="1672759909065511233">"允許應用程式查看 SD 記憶卡中所有下載項目,不論是透過何種應用程式下載。"</string>
+ <string name="permlab_downloadCacheNonPurgeable" msgid="3069534308882047412">"在下載快取預留空間"</string>
+ <string name="permdesc_downloadCacheNonPurgeable" msgid="2408760720334570420">"允許應用程式將檔案下載至下載快取空間,確保檔案不會因為下載管理員需要更多空間而自動遭到刪除。"</string>
+ <string name="permlab_downloadWithoutNotification" msgid="8837971946078327262">"不顯示通知,直接下載檔案"</string>
+ <string name="permdesc_downloadWithoutNotification" msgid="8483135034298639727">"允許應用程式不需通知用戶,即可透過下載管理員下載檔案。"</string>
+ <string name="permlab_accessAllDownloads" msgid="2436240495424393717">"存取所有系統下載檔案"</string>
+ <string name="permdesc_accessAllDownloads" msgid="1871832254578267128">"允許應用程式查看及修改系統上任何應用程式下載的所有內容。"</string>
+ <string name="download_unknown_title" msgid="7015124071247271585">"&lt;未命名&gt;"</string>
+ <string name="notification_download_complete" msgid="5443563299253103667">"下載完成。"</string>
+ <string name="notification_download_failed" msgid="8612136111952014978">"下載失敗。"</string>
+ <string name="notification_need_wifi_for_size" msgid="2556172885154833575">"這個檔案較大,需要 Wi-Fi 才能下載。"</string>
+ <string name="notification_paused_in_background" msgid="4328508073283591772">"已在背景中暫停。"</string>
+ <string name="wifi_required_title" msgid="1995971416871498179">"檔案過大,無法透過電訊公司的網絡下載"</string>
+ <string name="wifi_required_body" msgid="3067694630143784449">"您必須使用 Wi-Fi,才能完成下載這個 <xliff:g id="SIZE">%s </xliff:g> 的檔案。\n\n請在下次連接 Wi-Fi 網絡時,再輕觸 [<xliff:g id="QUEUE_TEXT">%s </xliff:g>] 開始下載。"</string>
+ <string name="wifi_recommended_title" msgid="7441589306734687400">"加入佇列供稍後下載?"</string>
+ <string name="wifi_recommended_body" msgid="1314735166699936073">"現在下載這個 <xliff:g id="SIZE">%s </xliff:g> 的檔案,可能會縮短電池的壽命,並 (或) 超出流動數據連線的用量上限,導致流動網絡供應商根據數據計劃向您收費。\n\n請在下次連接 Wi-Fi 網絡時,再輕觸 [<xliff:g id="QUEUE_TEXT">%s</xliff:g>] 開始下載。"</string>
+ <string name="button_queue_for_wifi" msgid="422576726189179221">"加入下載佇列"</string>
+ <string name="button_cancel_download" msgid="2430166148737975604">"取消"</string>
+ <string name="button_start_now" msgid="792123674007840864">"立即開始"</string>
+ <string name="download_percent" msgid="6889426633242976698">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <plurals name="notif_summary_active">
+ <item quantity="one" msgid="8475775855911967027">"正在下載 1 個檔案"</item>
+ <item quantity="other" msgid="9087228371320573153">"正在下載 <xliff:g id="NUMBER">%d</xliff:g> 個檔案"</item>
+ </plurals>
+ <plurals name="notif_summary_waiting">
+ <item quantity="one" msgid="5537481763963544278">"正在等待下載 1 個檔案"</item>
+ <item quantity="other" msgid="549229034166062887">"正在等待下載 <xliff:g id="NUMBER">%d</xliff:g> 個檔案"</item>
+ </plurals>
+ <string name="download_remaining" msgid="3139295890887972718">"剩餘 <xliff:g id="DURATION">%s</xliff:g>"</string>
+ <string name="download_no_application_title" msgid="7935659741162801699">"無法開啟檔案"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"下載內容"</string>
+ <string name="download_queued" msgid="3302638231377947451">"已加入序列"</string>
+ <string name="download_running" msgid="3925050393361158266">"進行中"</string>
+ <string name="download_error" msgid="5144180777324573236">"不成功"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"進行中,已完成 <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+</resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index e30deec..8a180b3 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"剩餘 <xliff:g id="DURATION">%s</xliff:g>"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"無法開啟檔案"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"下載項目"</string>
+ <string name="download_queued" msgid="3302638231377947451">"已加入佇列"</string>
+ <string name="download_running" msgid="3925050393361158266">"進行中"</string>
+ <string name="download_error" msgid="5144180777324573236">"失敗"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"處理中,已完成 <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index f61c521..7584bf3 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -18,11 +18,11 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="3658948994665187911">"Umphathi wokulayisha"</string>
<string name="permlab_downloadManager" msgid="7779544811202855500">"Finyelela kumphathi wokulayisha"</string>
- <string name="permdesc_downloadManager" msgid="4237406545998908947">"Ivuela insiza ukuthi ifinyelele izintweni ezijulile zomphathi wokulayisha. Izinsiza ezinobungozi zingakusebenzisa lokhu ukuphazamisa ukulanda ziphinde zifinyelele emininingwaneni eyimfihlo."</string>
+ <string name="permdesc_downloadManager" msgid="4237406545998908947">"Ivumela uhlelo lokusebenza lufinyelele isiphathi sokulandiwe namafayela alandiwe. Izinhlelo zokusebenza ezinobungozi zingakusebenzisa lokhu ukuphazamisa ukulanda ziphinde zifinyelele emininingwaneni eyimfihlo."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Izici zomphathi wokulayisha othuthukisiwe."</string>
- <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"Ivuela insiz ukuthi ifinyelele izinto ezijulile zomphathi wokulayisha. Izinsiza ezinobungozi zingakusebenzisa lokhu ukuphazamisa ukulanda ziphinde zifinyelele emininingwaneni eyimfihlo."</string>
+ <string name="permdesc_downloadManagerAdvanced" msgid="2659546004160962761">"Ivumela uhlelo lokusebenza lufinyelele izinto ezijulile zesiphathi sokulayisha. Izinhlelo zokusebenza ezinobungozi zingakusebenzisa lokhu ukuphazamisa ukulanda ziphinde zifinyelele emininingwaneni eyimfihlo."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Thumela izaziso zokulayisha"</string>
- <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"Ivumela insiza ukuthi ithumele izaziso yelana nokulayishwa okuqediwe. Izinsiza ezinobungozi zingakusebenzisa lokhu ukudida ezinye izinsiz ezilayisha amafayel."</string>
+ <string name="permdesc_downloadCompletedIntent" msgid="2094706189855699533">"Ivumela uhlelo lokusebenza ukuthi ithumele izaziso yelana nokulayishwa okuqediwe. Izuhlelo lokusebenza ezinobungozi zingakusebenzisa lokhu ukudida ezinye izinsiz ezilayisha amafayel."</string>
<string name="permlab_seeAllExternal" product="nosdcard" msgid="4084575448409212628">"Bona konke ukulanda kwisitoreji se-USB"</string>
<string name="permlab_seeAllExternal" product="default" msgid="140058400609165726">"Bona konke ukulanda ekhadini le-SD"</string>
<string name="permdesc_seeAllExternal" msgid="1672759909065511233">"Ivumela uhlelo lokusebenza ukuthi ibone konke okulandiwe ekhadini le-SD ngale kokubona ukuthi iluphi uhlelo lokusebenza elulandile."</string>
@@ -55,4 +55,9 @@
</plurals>
<string name="download_remaining" msgid="3139295890887972718">"<xliff:g id="DURATION">%s</xliff:g> asele"</string>
<string name="download_no_application_title" msgid="7935659741162801699">"Ayikwazi ukuvula ifayela"</string>
+ <string name="root_downloads" msgid="4098414876292351487">"Okulandiwe"</string>
+ <string name="download_queued" msgid="3302638231377947451">"Kusemugqeni"</string>
+ <string name="download_running" msgid="3925050393361158266">"kuyaqhubeka"</string>
+ <string name="download_error" msgid="5144180777324573236">"Akuphumelelanga"</string>
+ <string name="download_running_percent" msgid="4529799113107391817">"Iyaqhubeka, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
</resources>
diff --git a/src/com/android/providers/downloads/Constants.java b/src/com/android/providers/downloads/Constants.java
index 89210a2..2803d1c 100644
--- a/src/com/android/providers/downloads/Constants.java
+++ b/src/com/android/providers/downloads/Constants.java
@@ -80,9 +80,6 @@ public class Constants {
*/
public static final String FILENAME_SEQUENCE_SEPARATOR = "-";
- /** Where we store downloaded files on the external storage */
- public static final String DEFAULT_DL_SUBDIR = "/" + Environment.DIRECTORY_DOWNLOADS;
-
/** A magic filename that is allowed to exist within the system cache */
public static final String RECOVERY_DIRECTORY = "recovery";
@@ -123,16 +120,13 @@ public class Constants {
public static final String MIMETYPE_APK = "application/vnd.android.package";
/** The buffer size used to stream the data */
- public static final int BUFFER_SIZE = 4096;
+ public static final int BUFFER_SIZE = 8192;
/** The minimum amount of progress that has to be done before the progress bar gets updated */
- public static final int MIN_PROGRESS_STEP = 4096;
+ public static final int MIN_PROGRESS_STEP = 65536;
/** The minimum amount of time that has to elapse before the progress bar gets updated, in ms */
- public static final long MIN_PROGRESS_TIME = 1500;
-
- /** The maximum number of rows in the database (FIFO) */
- public static final int MAX_DOWNLOADS = 1000;
+ public static final long MIN_PROGRESS_TIME = 2000;
/**
* The number of times that the download manager will retry its network
@@ -177,4 +171,9 @@ public class Constants {
public static final String STORAGE_AUTHORITY = "com.android.providers.downloads.documents";
public static final String STORAGE_ROOT_ID = "downloads";
+
+ /**
+ * Name of directory on cache partition containing in-progress downloads.
+ */
+ public static final String DIRECTORY_CACHE_RUNNING = "partial_downloads";
}
diff --git a/src/com/android/providers/downloads/DownloadIdleService.java b/src/com/android/providers/downloads/DownloadIdleService.java
new file mode 100644
index 0000000..ddfeba4
--- /dev/null
+++ b/src/com/android/providers/downloads/DownloadIdleService.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.providers.downloads;
+
+import static com.android.providers.downloads.Constants.TAG;
+import static com.android.providers.downloads.StorageUtils.listFilesRecursive;
+
+import android.app.DownloadManager;
+import android.app.job.JobParameters;
+import android.app.job.JobService;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.database.Cursor;
+import android.os.Environment;
+import android.provider.Downloads;
+import android.system.ErrnoException;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import com.android.providers.downloads.StorageUtils.ConcreteFile;
+import com.google.android.collect.Lists;
+import com.google.android.collect.Sets;
+
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+
+/**
+ * Idle-time service for {@link DownloadManager}. Reconciles database
+ * metadata and files on disk, which can become inconsistent when files are
+ * deleted directly on disk.
+ */
+public class DownloadIdleService extends JobService {
+
+ private class IdleRunnable implements Runnable {
+ private JobParameters mParams;
+
+ public IdleRunnable(JobParameters params) {
+ mParams = params;
+ }
+
+ @Override
+ public void run() {
+ cleanOrphans();
+ jobFinished(mParams, false);
+ }
+ };
+
+ @Override
+ public boolean onStartJob(JobParameters params) {
+ new Thread(new IdleRunnable(params)).start();
+ return true;
+ }
+
+ @Override
+ public boolean onStopJob(JobParameters params) {
+ // We're okay being killed at any point, so we don't worry about
+ // checkpointing before tearing down.
+ return false;
+ }
+
+ private interface DownloadQuery {
+ final String[] PROJECTION = new String[] {
+ Downloads.Impl._ID,
+ Downloads.Impl._DATA };
+
+ final int _ID = 0;
+ final int _DATA = 1;
+ }
+
+ /**
+ * Clean up orphan downloads, both in database and on disk.
+ */
+ public void cleanOrphans() {
+ final ContentResolver resolver = getContentResolver();
+
+ // Collect known files from database
+ final HashSet<ConcreteFile> fromDb = Sets.newHashSet();
+ final Cursor cursor = resolver.query(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI,
+ DownloadQuery.PROJECTION, null, null, null);
+ try {
+ while (cursor.moveToNext()) {
+ final String path = cursor.getString(DownloadQuery._DATA);
+ if (TextUtils.isEmpty(path)) continue;
+
+ final File file = new File(path);
+ try {
+ fromDb.add(new ConcreteFile(file));
+ } catch (ErrnoException e) {
+ // File probably no longer exists
+ final String state = Environment.getExternalStorageState(file);
+ if (Environment.MEDIA_UNKNOWN.equals(state)
+ || Environment.MEDIA_MOUNTED.equals(state)) {
+ // File appears to live on internal storage, or a
+ // currently mounted device, so remove it from database.
+ // This logic preserves files on external storage while
+ // media is removed.
+ final long id = cursor.getLong(DownloadQuery._ID);
+ Slog.d(TAG, "Missing " + file + ", deleting " + id);
+ resolver.delete(ContentUris.withAppendedId(
+ Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, id), null, null);
+ }
+ }
+ }
+ } finally {
+ IoUtils.closeQuietly(cursor);
+ }
+
+ // Collect known files from disk
+ final int uid = android.os.Process.myUid();
+ final ArrayList<ConcreteFile> fromDisk = Lists.newArrayList();
+ fromDisk.addAll(listFilesRecursive(getCacheDir(), null, uid));
+ fromDisk.addAll(listFilesRecursive(getFilesDir(), null, uid));
+ fromDisk.addAll(listFilesRecursive(Environment.getDownloadCacheDirectory(), null, uid));
+
+ Slog.d(TAG, "Found " + fromDb.size() + " files in database");
+ Slog.d(TAG, "Found " + fromDisk.size() + " files on disk");
+
+ // Delete files no longer referenced by database
+ for (ConcreteFile file : fromDisk) {
+ if (!fromDb.contains(file)) {
+ Slog.d(TAG, "Missing db entry, deleting " + file.file);
+ file.file.delete();
+ }
+ }
+ }
+}
diff --git a/src/com/android/providers/downloads/DownloadInfo.java b/src/com/android/providers/downloads/DownloadInfo.java
index 7a912d5..3571a78 100644
--- a/src/com/android/providers/downloads/DownloadInfo.java
+++ b/src/com/android/providers/downloads/DownloadInfo.java
@@ -36,6 +36,7 @@ import android.util.Pair;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.IndentingPrintWriter;
+import java.io.CharArrayWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -45,7 +46,8 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
/**
- * Stores information about an individual download.
+ * Details about a specific download. Fields should only be mutated by updating
+ * from database query.
*/
public class DownloadInfo {
// TODO: move towards these in-memory objects being sources of truth, and
@@ -60,10 +62,9 @@ public class DownloadInfo {
mCursor = cursor;
}
- public DownloadInfo newDownloadInfo(Context context, SystemFacade systemFacade,
- StorageManager storageManager, DownloadNotifier notifier) {
- final DownloadInfo info = new DownloadInfo(
- context, systemFacade, storageManager, notifier);
+ public DownloadInfo newDownloadInfo(
+ Context context, SystemFacade systemFacade, DownloadNotifier notifier) {
+ final DownloadInfo info = new DownloadInfo(context, systemFacade, notifier);
updateFromDatabase(info);
readRequestHeaders(info);
return info;
@@ -75,7 +76,7 @@ public class DownloadInfo {
info.mNoIntegrity = getInt(Downloads.Impl.COLUMN_NO_INTEGRITY) == 1;
info.mHint = getString(Downloads.Impl.COLUMN_FILE_NAME_HINT);
info.mFileName = getString(Downloads.Impl._DATA);
- info.mMimeType = getString(Downloads.Impl.COLUMN_MIME_TYPE);
+ info.mMimeType = Intent.normalizeMimeType(getString(Downloads.Impl.COLUMN_MIME_TYPE));
info.mDestination = getInt(Downloads.Impl.COLUMN_DESTINATION);
info.mVisibility = getInt(Downloads.Impl.COLUMN_VISIBILITY);
info.mStatus = getInt(Downloads.Impl.COLUMN_STATUS);
@@ -206,6 +207,7 @@ public class DownloadInfo {
public long mId;
public String mUri;
+ @Deprecated
public boolean mNoIntegrity;
public String mHint;
public String mFileName;
@@ -254,14 +256,11 @@ public class DownloadInfo {
private final Context mContext;
private final SystemFacade mSystemFacade;
- private final StorageManager mStorageManager;
private final DownloadNotifier mNotifier;
- private DownloadInfo(Context context, SystemFacade systemFacade, StorageManager storageManager,
- DownloadNotifier notifier) {
+ private DownloadInfo(Context context, SystemFacade systemFacade, DownloadNotifier notifier) {
mContext = context;
mSystemFacade = systemFacade;
- mStorageManager = storageManager;
mNotifier = notifier;
mFuzz = Helpers.sRandom.nextInt(1001);
}
@@ -270,6 +269,14 @@ public class DownloadInfo {
return Collections.unmodifiableList(mRequestHeaders);
}
+ public String getUserAgent() {
+ if (mUserAgent != null) {
+ return mUserAgent;
+ } else {
+ return Constants.DEFAULT_USER_AGENT;
+ }
+ }
+
public void sendIntentIfRequested() {
if (mPackage == null) {
return;
@@ -329,7 +336,7 @@ public class DownloadInfo {
case Downloads.Impl.STATUS_WAITING_FOR_NETWORK:
case Downloads.Impl.STATUS_QUEUED_FOR_WIFI:
- return checkCanUseNetwork() == NetworkState.OK;
+ return checkCanUseNetwork(mTotalBytes) == NetworkState.OK;
case Downloads.Impl.STATUS_WAITING_TO_RETRY:
// download was waiting for a delayed restart
@@ -362,7 +369,7 @@ public class DownloadInfo {
/**
* Returns whether this download is allowed to use the network.
*/
- public NetworkState checkCanUseNetwork() {
+ public NetworkState checkCanUseNetwork(long totalBytes) {
final NetworkInfo info = mSystemFacade.getActiveNetworkInfo(mUid);
if (info == null || !info.isConnected()) {
return NetworkState.NO_CONNECTION;
@@ -376,7 +383,7 @@ public class DownloadInfo {
if (mSystemFacade.isActiveNetworkMetered() && !mAllowMetered) {
return NetworkState.TYPE_DISALLOWED_BY_REQUESTOR;
}
- return checkIsNetworkTypeAllowed(info.getType());
+ return checkIsNetworkTypeAllowed(info.getType(), totalBytes);
}
private boolean isRoamingAllowed() {
@@ -392,7 +399,7 @@ public class DownloadInfo {
* @param networkType a constant from ConnectivityManager.TYPE_*.
* @return one of the NETWORK_* constants
*/
- private NetworkState checkIsNetworkTypeAllowed(int networkType) {
+ private NetworkState checkIsNetworkTypeAllowed(int networkType, long totalBytes) {
if (mIsPublicApi) {
final int flag = translateNetworkTypeToApiFlag(networkType);
final boolean allowAllNetworkTypes = mAllowedNetworkTypes == ~0;
@@ -400,7 +407,7 @@ public class DownloadInfo {
return NetworkState.TYPE_DISALLOWED_BY_REQUESTOR;
}
}
- return checkSizeAllowedForNetwork(networkType);
+ return checkSizeAllowedForNetwork(networkType, totalBytes);
}
/**
@@ -427,24 +434,27 @@ public class DownloadInfo {
* Check if the download's size prohibits it from running over the current network.
* @return one of the NETWORK_* constants
*/
- private NetworkState checkSizeAllowedForNetwork(int networkType) {
- if (mTotalBytes <= 0) {
- return NetworkState.OK; // we don't know the size yet
- }
- if (networkType == ConnectivityManager.TYPE_WIFI) {
- return NetworkState.OK; // anything goes over wifi
- }
- Long maxBytesOverMobile = mSystemFacade.getMaxBytesOverMobile();
- if (maxBytesOverMobile != null && mTotalBytes > maxBytesOverMobile) {
- return NetworkState.UNUSABLE_DUE_TO_SIZE;
- }
- if (mBypassRecommendedSizeLimit == 0) {
- Long recommendedMaxBytesOverMobile = mSystemFacade.getRecommendedMaxBytesOverMobile();
- if (recommendedMaxBytesOverMobile != null
- && mTotalBytes > recommendedMaxBytesOverMobile) {
- return NetworkState.RECOMMENDED_UNUSABLE_DUE_TO_SIZE;
+ private NetworkState checkSizeAllowedForNetwork(int networkType, long totalBytes) {
+ if (totalBytes <= 0) {
+ // we don't know the size yet
+ return NetworkState.OK;
+ }
+
+ if (ConnectivityManager.isNetworkTypeMobile(networkType)) {
+ Long maxBytesOverMobile = mSystemFacade.getMaxBytesOverMobile();
+ if (maxBytesOverMobile != null && totalBytes > maxBytesOverMobile) {
+ return NetworkState.UNUSABLE_DUE_TO_SIZE;
+ }
+ if (mBypassRecommendedSizeLimit == 0) {
+ Long recommendedMaxBytesOverMobile = mSystemFacade
+ .getRecommendedMaxBytesOverMobile();
+ if (recommendedMaxBytesOverMobile != null
+ && totalBytes > recommendedMaxBytesOverMobile) {
+ return NetworkState.RECOMMENDED_UNUSABLE_DUE_TO_SIZE;
+ }
}
}
+
return NetworkState.OK;
}
@@ -467,8 +477,7 @@ public class DownloadInfo {
mContext.getContentResolver().update(getAllDownloadsUri(), values, null, null);
}
- mTask = new DownloadThread(
- mContext, mSystemFacade, this, mStorageManager, mNotifier);
+ mTask = new DownloadThread(mContext, mSystemFacade, mNotifier, this);
mSubmittedTask = executor.submit(mTask);
}
return isReady;
@@ -506,6 +515,13 @@ public class DownloadInfo {
return ContentUris.withAppendedId(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, mId);
}
+ @Override
+ public String toString() {
+ final CharArrayWriter writer = new CharArrayWriter();
+ dump(new IndentingPrintWriter(writer, " "));
+ return writer.toString();
+ }
+
public void dump(IndentingPrintWriter pw) {
pw.println("DownloadInfo:");
pw.increaseIndent();
diff --git a/src/com/android/providers/downloads/DownloadProvider.java b/src/com/android/providers/downloads/DownloadProvider.java
index 48350f6..59e753e 100644
--- a/src/com/android/providers/downloads/DownloadProvider.java
+++ b/src/com/android/providers/downloads/DownloadProvider.java
@@ -177,7 +177,6 @@ public final class DownloadProvider extends ContentProvider {
/** List of uids that can access the downloads */
private int mSystemUid = -1;
private int mDefContainerUid = -1;
- private File mDownloadsDataDir;
@VisibleForTesting
SystemFacade mSystemFacade;
@@ -463,7 +462,6 @@ public final class DownloadProvider extends ContentProvider {
// saves us by getting some initialization code in DownloadService out of the way.
Context context = getContext();
context.startService(new Intent(context, DownloadService.class));
- mDownloadsDataDir = StorageManager.getDownloadDataDirectory(getContext());
return true;
}
@@ -534,7 +532,7 @@ public final class DownloadProvider extends ContentProvider {
// validate the destination column
Integer dest = values.getAsInteger(Downloads.Impl.COLUMN_DESTINATION);
if (dest != null) {
- if (getContext().checkCallingPermission(Downloads.Impl.PERMISSION_ACCESS_ADVANCED)
+ if (getContext().checkCallingOrSelfPermission(Downloads.Impl.PERMISSION_ACCESS_ADVANCED)
!= PackageManager.PERMISSION_GRANTED
&& (dest == Downloads.Impl.DESTINATION_CACHE_PARTITION
|| dest == Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING
@@ -545,7 +543,7 @@ public final class DownloadProvider extends ContentProvider {
// for public API behavior, if an app has CACHE_NON_PURGEABLE permission, automatically
// switch to non-purgeable download
boolean hasNonPurgeablePermission =
- getContext().checkCallingPermission(
+ getContext().checkCallingOrSelfPermission(
Downloads.Impl.PERMISSION_CACHE_NON_PURGEABLE)
== PackageManager.PERMISSION_GRANTED;
if (isPublicApi && dest == Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE
@@ -632,7 +630,7 @@ public final class DownloadProvider extends ContentProvider {
copyString(Downloads.Impl.COLUMN_REFERER, values, filteredValues);
// UID, PID columns
- if (getContext().checkCallingPermission(Downloads.Impl.PERMISSION_ACCESS_ADVANCED)
+ if (getContext().checkCallingOrSelfPermission(Downloads.Impl.PERMISSION_ACCESS_ADVANCED)
== PackageManager.PERMISSION_GRANTED) {
copyInteger(Downloads.Impl.COLUMN_OTHER_UID, values, filteredValues);
}
@@ -1121,7 +1119,7 @@ public final class DownloadProvider extends ContentProvider {
selection.appendClause(Downloads.Impl._ID + " = ?", getDownloadIdFromUri(uri));
}
if ((uriMatch == MY_DOWNLOADS || uriMatch == MY_DOWNLOADS_ID)
- && getContext().checkCallingPermission(Downloads.Impl.PERMISSION_ACCESS_ALL)
+ && getContext().checkCallingOrSelfPermission(Downloads.Impl.PERMISSION_ACCESS_ALL)
!= PackageManager.PERMISSION_GRANTED) {
selection.appendClause(
Constants.UID + "= ? OR " + Downloads.Impl.COLUMN_OTHER_UID + "= ?",
@@ -1137,7 +1135,9 @@ public final class DownloadProvider extends ContentProvider {
public int delete(final Uri uri, final String where,
final String[] whereArgs) {
- Helpers.validateSelection(where, sAppReadableColumnsSet);
+ if (shouldRestrictVisibility()) {
+ Helpers.validateSelection(where, sAppReadableColumnsSet);
+ }
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int count;
@@ -1203,11 +1203,12 @@ public final class DownloadProvider extends ContentProvider {
if (path == null) {
throw new FileNotFoundException("No filename found.");
}
- if (!Helpers.isFilenameValid(path, mDownloadsDataDir)) {
- throw new FileNotFoundException("Invalid filename: " + path);
- }
final File file = new File(path);
+ if (!Helpers.isFilenameValid(getContext(), file)) {
+ throw new FileNotFoundException("Invalid file: " + file);
+ }
+
if ("r".equals(mode)) {
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
} else {
diff --git a/src/com/android/providers/downloads/DownloadReceiver.java b/src/com/android/providers/downloads/DownloadReceiver.java
index f3d2376..28e2a67 100644
--- a/src/com/android/providers/downloads/DownloadReceiver.java
+++ b/src/com/android/providers/downloads/DownloadReceiver.java
@@ -18,9 +18,11 @@ package com.android.providers.downloads;
import static android.app.DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED;
import static android.app.DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION;
+import static com.android.providers.downloads.Constants.TAG;
import android.app.DownloadManager;
import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
@@ -34,6 +36,7 @@ import android.os.HandlerThread;
import android.provider.Downloads;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Slog;
import android.widget.Toast;
import com.google.common.annotations.VisibleForTesting;
@@ -42,12 +45,10 @@ import com.google.common.annotations.VisibleForTesting;
* Receives system broadcasts (boot, network connectivity)
*/
public class DownloadReceiver extends BroadcastReceiver {
- private static final String TAG = "DownloadReceiver";
-
private static Handler sAsyncHandler;
static {
- final HandlerThread thread = new HandlerThread(TAG);
+ final HandlerThread thread = new HandlerThread("DownloadReceiver");
thread.start();
sAsyncHandler = new Handler(thread.getLooper());
}
@@ -61,31 +62,37 @@ public class DownloadReceiver extends BroadcastReceiver {
mSystemFacade = new RealSystemFacade(context);
}
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
- if (Constants.LOGVV) {
- Log.v(Constants.TAG, "Received broadcast intent for " +
- Intent.ACTION_BOOT_COMPLETED);
- }
+ final String action = intent.getAction();
+ if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
startService(context);
- } else if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
- if (Constants.LOGVV) {
- Log.v(Constants.TAG, "Received broadcast intent for " +
- Intent.ACTION_MEDIA_MOUNTED);
- }
+
+ } else if (Intent.ACTION_MEDIA_MOUNTED.equals(action)) {
startService(context);
- } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
+
+ } else if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
final ConnectivityManager connManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkInfo info = connManager.getActiveNetworkInfo();
if (info != null && info.isConnected()) {
startService(context);
}
- } else if (action.equals(Constants.ACTION_RETRY)) {
+
+ } else if (Intent.ACTION_UID_REMOVED.equals(action)) {
+ final PendingResult result = goAsync();
+ sAsyncHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ handleUidRemoved(context, intent);
+ result.finish();
+ }
+ });
+
+ } else if (Constants.ACTION_RETRY.equals(action)) {
startService(context);
- } else if (action.equals(Constants.ACTION_OPEN)
- || action.equals(Constants.ACTION_LIST)
- || action.equals(Constants.ACTION_HIDE)) {
+
+ } else if (Constants.ACTION_OPEN.equals(action)
+ || Constants.ACTION_LIST.equals(action)
+ || Constants.ACTION_HIDE.equals(action)) {
final PendingResult result = goAsync();
if (result == null) {
@@ -103,6 +110,18 @@ public class DownloadReceiver extends BroadcastReceiver {
}
}
+ private void handleUidRemoved(Context context, Intent intent) {
+ final ContentResolver resolver = context.getContentResolver();
+
+ final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
+ final int count = resolver.delete(
+ Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, Constants.UID + "=" + uid, null);
+
+ if (count > 0) {
+ Slog.d(TAG, "Deleted " + count + " downloads owned by UID " + uid);
+ }
+ }
+
/**
* Handle any broadcast related to a system notification.
*/
diff --git a/src/com/android/providers/downloads/DownloadService.java b/src/com/android/providers/downloads/DownloadService.java
index 7d746cc..58cf380 100644
--- a/src/com/android/providers/downloads/DownloadService.java
+++ b/src/com/android/providers/downloads/DownloadService.java
@@ -23,6 +23,9 @@ import android.app.AlarmManager;
import android.app.DownloadManager;
import android.app.PendingIntent;
import android.app.Service;
+import android.app.job.JobInfo;
+import android.app.job.JobScheduler;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -54,7 +57,10 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@@ -78,7 +84,6 @@ public class DownloadService extends Service {
SystemFacade mSystemFacade;
private AlarmManager mAlarmManager;
- private StorageManager mStorageManager;
/** Observer to get notified when the content observer's data changes */
private DownloadManagerContentObserver mObserver;
@@ -86,6 +91,15 @@ public class DownloadService extends Service {
/** Class to handle Notification Manager updates */
private DownloadNotifier mNotifier;
+ /** Scheduling of the periodic cleanup job */
+ private JobInfo mCleanupJob;
+
+ private static final int CLEANUP_JOB_ID = 1;
+ private static final long CLEANUP_JOB_PERIOD = 1000 * 60 * 60 * 24; // one day
+ private static ComponentName sCleanupServiceName = new ComponentName(
+ DownloadIdleService.class.getPackage().getName(),
+ DownloadIdleService.class.getName());
+
/**
* The Service's view of the list of downloads, mapping download IDs to the corresponding info
* object. This is kept independently from the content provider, and the Service only initiates
@@ -105,7 +119,28 @@ public class DownloadService extends Service {
// threads as needed (up to maximum) and reclaims them when finished.
final ThreadPoolExecutor executor = new ThreadPoolExecutor(
maxConcurrent, maxConcurrent, 10, TimeUnit.SECONDS,
- new LinkedBlockingQueue<Runnable>());
+ new LinkedBlockingQueue<Runnable>()) {
+ @Override
+ protected void afterExecute(Runnable r, Throwable t) {
+ super.afterExecute(r, t);
+
+ if (t == null && r instanceof Future<?>) {
+ try {
+ ((Future<?>) r).get();
+ } catch (CancellationException ce) {
+ t = ce;
+ } catch (ExecutionException ee) {
+ t = ee.getCause();
+ } catch (InterruptedException ie) {
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ if (t != null) {
+ Log.w(TAG, "Uncaught exception", t);
+ }
+ }
+ };
executor.allowCoreThreadTimeOut(true);
return executor;
}
@@ -157,7 +192,6 @@ public class DownloadService extends Service {
}
mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
- mStorageManager = new StorageManager(this);
mUpdateThread = new HandlerThread(TAG + "-UpdateThread");
mUpdateThread.start();
@@ -171,6 +205,28 @@ public class DownloadService extends Service {
mObserver = new DownloadManagerContentObserver();
getContentResolver().registerContentObserver(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI,
true, mObserver);
+
+ JobScheduler js = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
+ if (needToScheduleCleanup(js)) {
+ final JobInfo job = new JobInfo.Builder(CLEANUP_JOB_ID, sCleanupServiceName)
+ .setPeriodic(CLEANUP_JOB_PERIOD)
+ .setRequiresCharging(true)
+ .setRequiresDeviceIdle(true)
+ .build();
+ js.schedule(job);
+ }
+ }
+
+ private boolean needToScheduleCleanup(JobScheduler js) {
+ List<JobInfo> myJobs = js.getAllPendingJobs();
+ final int N = myJobs.size();
+ for (int i = 0; i < N; i++) {
+ if (myJobs.get(i).getId() == CLEANUP_JOB_ID) {
+ // It's already been (persistently) scheduled; no need to do it again
+ return false;
+ }
+ }
+ return true;
}
@Override
@@ -198,9 +254,11 @@ public class DownloadService extends Service {
/**
* Enqueue an {@link #updateLocked()} pass to occur in future.
*/
- private void enqueueUpdate() {
- mUpdateHandler.removeMessages(MSG_UPDATE);
- mUpdateHandler.obtainMessage(MSG_UPDATE, mLastStartId, -1).sendToTarget();
+ public void enqueueUpdate() {
+ if (mUpdateHandler != null) {
+ mUpdateHandler.removeMessages(MSG_UPDATE);
+ mUpdateHandler.obtainMessage(MSG_UPDATE, mLastStartId, -1).sendToTarget();
+ }
}
/**
@@ -376,8 +434,7 @@ public class DownloadService extends Service {
* download if appropriate.
*/
private DownloadInfo insertDownloadLocked(DownloadInfo.Reader reader, long now) {
- final DownloadInfo info = reader.newDownloadInfo(
- this, mSystemFacade, mStorageManager, mNotifier);
+ final DownloadInfo info = reader.newDownloadInfo(this, mSystemFacade, mNotifier);
mDownloads.put(info.mId, info);
if (Constants.LOGVV) {
diff --git a/src/com/android/providers/downloads/DownloadThread.java b/src/com/android/providers/downloads/DownloadThread.java
index 93f8d65..88f554e 100644
--- a/src/com/android/providers/downloads/DownloadThread.java
+++ b/src/com/android/providers/downloads/DownloadThread.java
@@ -22,6 +22,8 @@ import static android.provider.Downloads.Impl.STATUS_FILE_ERROR;
import static android.provider.Downloads.Impl.STATUS_HTTP_DATA_ERROR;
import static android.provider.Downloads.Impl.STATUS_SUCCESS;
import static android.provider.Downloads.Impl.STATUS_TOO_MANY_REDIRECTS;
+import static android.provider.Downloads.Impl.STATUS_UNHANDLED_HTTP_CODE;
+import static android.provider.Downloads.Impl.STATUS_UNKNOWN_ERROR;
import static android.provider.Downloads.Impl.STATUS_WAITING_FOR_NETWORK;
import static android.provider.Downloads.Impl.STATUS_WAITING_TO_RETRY;
import static android.text.format.DateUtils.SECOND_IN_MILLIS;
@@ -31,6 +33,7 @@ import static java.net.HttpURLConnection.HTTP_MOVED_PERM;
import static java.net.HttpURLConnection.HTTP_MOVED_TEMP;
import static java.net.HttpURLConnection.HTTP_OK;
import static java.net.HttpURLConnection.HTTP_PARTIAL;
+import static java.net.HttpURLConnection.HTTP_PRECON_FAILED;
import static java.net.HttpURLConnection.HTTP_SEE_OTHER;
import static java.net.HttpURLConnection.HTTP_UNAVAILABLE;
@@ -44,13 +47,15 @@ import android.net.INetworkPolicyListener;
import android.net.NetworkInfo;
import android.net.NetworkPolicyManager;
import android.net.TrafficStats;
-import android.os.FileUtils;
+import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.Process;
import android.os.SystemClock;
import android.os.WorkSource;
import android.provider.Downloads;
-import android.text.TextUtils;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
import android.util.Log;
import android.util.Pair;
@@ -60,132 +65,153 @@ import libcore.io.IoUtils;
import java.io.File;
import java.io.FileDescriptor;
-import java.io.FileOutputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
+import java.net.ProtocolException;
import java.net.URL;
import java.net.URLConnection;
/**
* Task which executes a given {@link DownloadInfo}: making network requests,
* persisting data to disk, and updating {@link DownloadProvider}.
+ * <p>
+ * To know if a download is successful, we need to know either the final content
+ * length to expect, or the transfer to be chunked. To resume an interrupted
+ * download, we need an ETag.
+ * <p>
+ * Failed network requests are retried several times before giving up. Local
+ * disk errors fail immediately and are not retried.
*/
public class DownloadThread implements Runnable {
// TODO: bind each download to a specific network interface to avoid state
// checking races once we have ConnectivityManager API
+ // TODO: add support for saving to content://
+
private static final int HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
private static final int HTTP_TEMP_REDIRECT = 307;
private static final int DEFAULT_TIMEOUT = (int) (20 * SECOND_IN_MILLIS);
private final Context mContext;
- private final DownloadInfo mInfo;
private final SystemFacade mSystemFacade;
- private final StorageManager mStorageManager;
private final DownloadNotifier mNotifier;
- private volatile boolean mPolicyDirty;
-
- public DownloadThread(Context context, SystemFacade systemFacade, DownloadInfo info,
- StorageManager storageManager, DownloadNotifier notifier) {
- mContext = context;
- mSystemFacade = systemFacade;
- mInfo = info;
- mStorageManager = storageManager;
- mNotifier = notifier;
- }
+ private final long mId;
/**
- * Returns the user agent provided by the initiating app, or use the default one
+ * Info object that should be treated as read-only. Any potentially mutated
+ * fields are tracked in {@link #mInfoDelta}. If a field exists in
+ * {@link #mInfoDelta}, it must not be read from {@link #mInfo}.
*/
- private String userAgent() {
- String userAgent = mInfo.mUserAgent;
- if (userAgent == null) {
- userAgent = Constants.DEFAULT_USER_AGENT;
- }
- return userAgent;
- }
+ private final DownloadInfo mInfo;
+ private final DownloadInfoDelta mInfoDelta;
+
+ private volatile boolean mPolicyDirty;
/**
- * State for the entire run() method.
+ * Local changes to {@link DownloadInfo}. These are kept local to avoid
+ * racing with the thread that updates based on change notifications.
*/
- static class State {
- public String mFilename;
+ private class DownloadInfoDelta {
+ public String mUri;
+ public String mFileName;
public String mMimeType;
- public int mRetryAfter = 0;
- public boolean mGotData = false;
- public String mRequestUri;
- public long mTotalBytes = -1;
- public long mCurrentBytes = 0;
- public String mHeaderETag;
- public boolean mContinuingDownload = false;
- public long mBytesNotified = 0;
- public long mTimeLastNotification = 0;
- public int mNetworkType = ConnectivityManager.TYPE_NONE;
-
- /** Historical bytes/second speed of this download. */
- public long mSpeed;
- /** Time when current sample started. */
- public long mSpeedSampleStart;
- /** Bytes transferred since current sample started. */
- public long mSpeedSampleBytes;
-
- public long mContentLength = -1;
- public String mContentDisposition;
- public String mContentLocation;
-
- public int mRedirectionCount;
- public URL mUrl;
-
- public State(DownloadInfo info) {
- mMimeType = Intent.normalizeMimeType(info.mMimeType);
- mRequestUri = info.mUri;
- mFilename = info.mFileName;
+ public int mStatus;
+ public int mNumFailed;
+ public int mRetryAfter;
+ public long mTotalBytes;
+ public long mCurrentBytes;
+ public String mETag;
+
+ public String mErrorMsg;
+
+ public DownloadInfoDelta(DownloadInfo info) {
+ mUri = info.mUri;
+ mFileName = info.mFileName;
+ mMimeType = info.mMimeType;
+ mStatus = info.mStatus;
+ mNumFailed = info.mNumFailed;
+ mRetryAfter = info.mRetryAfter;
mTotalBytes = info.mTotalBytes;
mCurrentBytes = info.mCurrentBytes;
+ mETag = info.mETag;
}
- public void resetBeforeExecute() {
- // Reset any state from previous execution
- mContentLength = -1;
- mContentDisposition = null;
- mContentLocation = null;
- mRedirectionCount = 0;
+ /**
+ * Push update of current delta values to provider.
+ */
+ public void writeToDatabase() {
+ final ContentValues values = new ContentValues();
+
+ values.put(Downloads.Impl.COLUMN_URI, mUri);
+ values.put(Downloads.Impl._DATA, mFileName);
+ values.put(Downloads.Impl.COLUMN_MIME_TYPE, mMimeType);
+ values.put(Downloads.Impl.COLUMN_STATUS, mStatus);
+ values.put(Downloads.Impl.COLUMN_FAILED_CONNECTIONS, mNumFailed);
+ values.put(Constants.RETRY_AFTER_X_REDIRECT_COUNT, mRetryAfter);
+ values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, mTotalBytes);
+ values.put(Downloads.Impl.COLUMN_CURRENT_BYTES, mCurrentBytes);
+ values.put(Constants.ETAG, mETag);
+
+ values.put(Downloads.Impl.COLUMN_LAST_MODIFICATION, mSystemFacade.currentTimeMillis());
+ values.put(Downloads.Impl.COLUMN_ERROR_MSG, mErrorMsg);
+
+ mContext.getContentResolver().update(mInfo.getAllDownloadsUri(), values, null, null);
}
}
+ /**
+ * Flag indicating if we've made forward progress transferring file data
+ * from a remote server.
+ */
+ private boolean mMadeProgress = false;
+
+ /**
+ * Details from the last time we pushed a database update.
+ */
+ private long mLastUpdateBytes = 0;
+ private long mLastUpdateTime = 0;
+
+ private int mNetworkType = ConnectivityManager.TYPE_NONE;
+
+ /** Historical bytes/second speed of this download. */
+ private long mSpeed;
+ /** Time when current sample started. */
+ private long mSpeedSampleStart;
+ /** Bytes transferred since current sample started. */
+ private long mSpeedSampleBytes;
+
+ public DownloadThread(Context context, SystemFacade systemFacade, DownloadNotifier notifier,
+ DownloadInfo info) {
+ mContext = context;
+ mSystemFacade = systemFacade;
+ mNotifier = notifier;
+
+ mId = info.mId;
+ mInfo = info;
+ mInfoDelta = new DownloadInfoDelta(info);
+ }
+
@Override
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
- try {
- runInternal();
- } finally {
- mNotifier.notifyDownloadSpeed(mInfo.mId, 0);
- }
- }
- private void runInternal() {
// Skip when download already marked as finished; this download was
// probably started again while racing with UpdateThread.
- if (DownloadInfo.queryDownloadStatus(mContext.getContentResolver(), mInfo.mId)
+ if (DownloadInfo.queryDownloadStatus(mContext.getContentResolver(), mId)
== Downloads.Impl.STATUS_SUCCESS) {
- Log.d(TAG, "Download " + mInfo.mId + " already finished; skipping");
+ logDebug("Already finished; skipping");
return;
}
- State state = new State(mInfo);
- PowerManager.WakeLock wakeLock = null;
- int finalStatus = Downloads.Impl.STATUS_UNKNOWN_ERROR;
- int numFailed = mInfo.mNumFailed;
- String errorMsg = null;
-
final NetworkPolicyManager netPolicy = NetworkPolicyManager.from(mContext);
+ PowerManager.WakeLock wakeLock = null;
final PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
try {
@@ -196,13 +222,13 @@ public class DownloadThread implements Runnable {
// while performing download, register for rules updates
netPolicy.registerListener(mPolicyListener);
- Log.i(Constants.TAG, "Download " + mInfo.mId + " starting");
+ logDebug("Starting");
// Remember which network this download started on; used to
// determine if errors were due to network changes.
final NetworkInfo info = mSystemFacade.getActiveNetworkInfo(mInfo.mUid);
if (info != null) {
- state.mNetworkType = info.getType();
+ mNetworkType = info.getType();
}
// Network traffic on this thread should be counted against the
@@ -210,75 +236,79 @@ public class DownloadThread implements Runnable {
TrafficStats.setThreadStatsTag(TrafficStats.TAG_SYSTEM_DOWNLOAD);
TrafficStats.setThreadStatsUid(mInfo.mUid);
- try {
- // TODO: migrate URL sanity checking into client side of API
- state.mUrl = new URL(state.mRequestUri);
- } catch (MalformedURLException e) {
- throw new StopRequestException(STATUS_BAD_REQUEST, e);
- }
+ executeDownload();
+
+ mInfoDelta.mStatus = STATUS_SUCCESS;
+ TrafficStats.incrementOperationCount(1);
- executeDownload(state);
-
- finalizeDestinationFile(state);
- finalStatus = Downloads.Impl.STATUS_SUCCESS;
- } catch (StopRequestException error) {
- // remove the cause before printing, in case it contains PII
- errorMsg = error.getMessage();
- String msg = "Aborting request for download " + mInfo.mId + ": " + errorMsg;
- Log.w(Constants.TAG, msg);
- if (Constants.LOGV) {
- Log.w(Constants.TAG, msg, error);
+ // If we just finished a chunked file, record total size
+ if (mInfoDelta.mTotalBytes == -1) {
+ mInfoDelta.mTotalBytes = mInfoDelta.mCurrentBytes;
}
- finalStatus = error.getFinalStatus();
+
+ } catch (StopRequestException e) {
+ mInfoDelta.mStatus = e.getFinalStatus();
+ mInfoDelta.mErrorMsg = e.getMessage();
+
+ logWarning("Stop requested with status "
+ + Downloads.Impl.statusToString(mInfoDelta.mStatus) + ": "
+ + mInfoDelta.mErrorMsg);
// Nobody below our level should request retries, since we handle
// failure counts at this level.
- if (finalStatus == STATUS_WAITING_TO_RETRY) {
+ if (mInfoDelta.mStatus == STATUS_WAITING_TO_RETRY) {
throw new IllegalStateException("Execution should always throw final error codes");
}
// Some errors should be retryable, unless we fail too many times.
- if (isStatusRetryable(finalStatus)) {
- if (state.mGotData) {
- numFailed = 1;
+ if (isStatusRetryable(mInfoDelta.mStatus)) {
+ if (mMadeProgress) {
+ mInfoDelta.mNumFailed = 1;
} else {
- numFailed += 1;
+ mInfoDelta.mNumFailed += 1;
}
- if (numFailed < Constants.MAX_RETRIES) {
+ if (mInfoDelta.mNumFailed < Constants.MAX_RETRIES) {
final NetworkInfo info = mSystemFacade.getActiveNetworkInfo(mInfo.mUid);
- if (info != null && info.getType() == state.mNetworkType
- && info.isConnected()) {
+ if (info != null && info.getType() == mNetworkType && info.isConnected()) {
// Underlying network is still intact, use normal backoff
- finalStatus = STATUS_WAITING_TO_RETRY;
+ mInfoDelta.mStatus = STATUS_WAITING_TO_RETRY;
} else {
// Network changed, retry on any next available
- finalStatus = STATUS_WAITING_FOR_NETWORK;
+ mInfoDelta.mStatus = STATUS_WAITING_FOR_NETWORK;
+ }
+
+ if ((mInfoDelta.mETag == null && mMadeProgress)
+ || DownloadDrmHelper.isDrmConvertNeeded(mInfoDelta.mMimeType)) {
+ // However, if we wrote data and have no ETag to verify
+ // contents against later, we can't actually resume.
+ mInfoDelta.mStatus = STATUS_CANNOT_RESUME;
}
}
}
- // fall through to finally block
- } catch (Throwable ex) {
- errorMsg = ex.getMessage();
- String msg = "Exception for id " + mInfo.mId + ": " + errorMsg;
- Log.w(Constants.TAG, msg, ex);
- finalStatus = Downloads.Impl.STATUS_UNKNOWN_ERROR;
- // falls through to the code that reports an error
+ } catch (Throwable t) {
+ mInfoDelta.mStatus = STATUS_UNKNOWN_ERROR;
+ mInfoDelta.mErrorMsg = t.toString();
+
+ logError("Failed: " + mInfoDelta.mErrorMsg, t);
+
} finally {
- if (finalStatus == STATUS_SUCCESS) {
- TrafficStats.incrementOperationCount(1);
+ logDebug("Finished with status " + Downloads.Impl.statusToString(mInfoDelta.mStatus));
+
+ mNotifier.notifyDownloadSpeed(mId, 0);
+
+ finalizeDestination();
+
+ mInfoDelta.writeToDatabase();
+
+ if (Downloads.Impl.isStatusCompleted(mInfoDelta.mStatus)) {
+ mInfo.sendIntentIfRequested();
}
TrafficStats.clearThreadStatsTag();
TrafficStats.clearThreadStatsUid();
- cleanupDestination(state, finalStatus);
- notifyDownloadCompleted(state, finalStatus, errorMsg, numFailed);
-
- Log.i(Constants.TAG, "Download " + mInfo.mId + " finished with status "
- + Downloads.Impl.statusToString(finalStatus));
-
netPolicy.unregisterListener(mPolicyListener);
if (wakeLock != null) {
@@ -286,54 +316,54 @@ public class DownloadThread implements Runnable {
wakeLock = null;
}
}
- mStorageManager.incrementNumDownloadsSoFar();
}
/**
* Fully execute a single download request. Setup and send the request,
* handle the response, and transfer the data to the destination file.
*/
- private void executeDownload(State state) throws StopRequestException {
- state.resetBeforeExecute();
- setupDestinationFile(state);
-
- // skip when already finished; remove after fixing race in 5217390
- if (state.mCurrentBytes == state.mTotalBytes) {
- Log.i(Constants.TAG, "Skipping initiating request for download " +
- mInfo.mId + "; already completed");
- return;
+ private void executeDownload() throws StopRequestException {
+ final boolean resuming = mInfoDelta.mCurrentBytes != 0;
+
+ URL url;
+ try {
+ // TODO: migrate URL sanity checking into client side of API
+ url = new URL(mInfoDelta.mUri);
+ } catch (MalformedURLException e) {
+ throw new StopRequestException(STATUS_BAD_REQUEST, e);
}
- while (state.mRedirectionCount++ < Constants.MAX_REDIRECTS) {
+ int redirectionCount = 0;
+ while (redirectionCount++ < Constants.MAX_REDIRECTS) {
// Open connection and follow any redirects until we have a useful
// response with body.
HttpURLConnection conn = null;
try {
checkConnectivity();
- conn = (HttpURLConnection) state.mUrl.openConnection();
+ conn = (HttpURLConnection) url.openConnection();
conn.setInstanceFollowRedirects(false);
conn.setConnectTimeout(DEFAULT_TIMEOUT);
conn.setReadTimeout(DEFAULT_TIMEOUT);
- addRequestHeaders(state, conn);
+ addRequestHeaders(conn, resuming);
final int responseCode = conn.getResponseCode();
switch (responseCode) {
case HTTP_OK:
- if (state.mContinuingDownload) {
+ if (resuming) {
throw new StopRequestException(
STATUS_CANNOT_RESUME, "Expected partial, but received OK");
}
- processResponseHeaders(state, conn);
- transferData(state, conn);
+ parseOkHeaders(conn);
+ transferData(conn);
return;
case HTTP_PARTIAL:
- if (!state.mContinuingDownload) {
+ if (!resuming) {
throw new StopRequestException(
STATUS_CANNOT_RESUME, "Expected OK, but received partial");
}
- transferData(state, conn);
+ transferData(conn);
return;
case HTTP_MOVED_PERM:
@@ -341,19 +371,23 @@ public class DownloadThread implements Runnable {
case HTTP_SEE_OTHER:
case HTTP_TEMP_REDIRECT:
final String location = conn.getHeaderField("Location");
- state.mUrl = new URL(state.mUrl, location);
+ url = new URL(url, location);
if (responseCode == HTTP_MOVED_PERM) {
// Push updated URL back to database
- state.mRequestUri = state.mUrl.toString();
+ mInfoDelta.mUri = url.toString();
}
continue;
+ case HTTP_PRECON_FAILED:
+ throw new StopRequestException(
+ STATUS_CANNOT_RESUME, "Precondition failed");
+
case HTTP_REQUESTED_RANGE_NOT_SATISFIABLE:
throw new StopRequestException(
STATUS_CANNOT_RESUME, "Requested range not satisfiable");
case HTTP_UNAVAILABLE:
- parseRetryAfterHeaders(state, conn);
+ parseUnavailableHeaders(conn);
throw new StopRequestException(
HTTP_UNAVAILABLE, conn.getResponseMessage());
@@ -365,9 +399,15 @@ public class DownloadThread implements Runnable {
StopRequestException.throwUnhandledHttpError(
responseCode, conn.getResponseMessage());
}
+
} catch (IOException e) {
- // Trouble with low-level sockets
- throw new StopRequestException(STATUS_HTTP_DATA_ERROR, e);
+ if (e instanceof ProtocolException
+ && e.getMessage().startsWith("Unexpected status line")) {
+ throw new StopRequestException(STATUS_UNHANDLED_HTTP_CODE, e);
+ } else {
+ // Trouble with low-level sockets
+ throw new StopRequestException(STATUS_HTTP_DATA_ERROR, e);
+ }
} finally {
if (conn != null) conn.disconnect();
@@ -380,11 +420,23 @@ public class DownloadThread implements Runnable {
/**
* Transfer data from the given connection to the destination file.
*/
- private void transferData(State state, HttpURLConnection conn) throws StopRequestException {
+ private void transferData(HttpURLConnection conn) throws StopRequestException {
+
+ // To detect when we're really finished, we either need a length or
+ // chunked encoding.
+ final boolean hasLength = mInfoDelta.mTotalBytes != -1;
+ final String transferEncoding = conn.getHeaderField("Transfer-Encoding");
+ final boolean isChunked = "chunked".equalsIgnoreCase(transferEncoding);
+ if (!hasLength && !isChunked) {
+ throw new StopRequestException(
+ STATUS_CANNOT_RESUME, "can't know size of download, giving up");
+ }
+
DrmManagerClient drmClient = null;
+ ParcelFileDescriptor outPfd = null;
+ FileDescriptor outFd = null;
InputStream in = null;
OutputStream out = null;
- FileDescriptor outFd = null;
try {
try {
in = conn.getInputStream();
@@ -393,23 +445,49 @@ public class DownloadThread implements Runnable {
}
try {
- if (DownloadDrmHelper.isDrmConvertNeeded(state.mMimeType)) {
+ outPfd = mContext.getContentResolver()
+ .openFileDescriptor(mInfo.getAllDownloadsUri(), "rw");
+ outFd = outPfd.getFileDescriptor();
+
+ if (DownloadDrmHelper.isDrmConvertNeeded(mInfoDelta.mMimeType)) {
drmClient = new DrmManagerClient(mContext);
- final RandomAccessFile file = new RandomAccessFile(
- new File(state.mFilename), "rw");
- out = new DrmOutputStream(drmClient, file, state.mMimeType);
- outFd = file.getFD();
+ out = new DrmOutputStream(drmClient, outPfd, mInfoDelta.mMimeType);
} else {
- out = new FileOutputStream(state.mFilename, true);
- outFd = ((FileOutputStream) out).getFD();
+ out = new ParcelFileDescriptor.AutoCloseOutputStream(outPfd);
+ }
+
+ // Pre-flight disk space requirements, when known
+ if (mInfoDelta.mTotalBytes > 0) {
+ final long curSize = Os.fstat(outFd).st_size;
+ final long newBytes = mInfoDelta.mTotalBytes - curSize;
+
+ StorageUtils.ensureAvailableSpace(mContext, outFd, newBytes);
+
+ try {
+ // We found enough space, so claim it for ourselves
+ Os.posix_fallocate(outFd, 0, mInfoDelta.mTotalBytes);
+ } catch (ErrnoException e) {
+ if (e.errno == OsConstants.ENOTSUP) {
+ Log.w(TAG, "fallocate() said ENOTSUP; falling back to ftruncate()");
+ Os.ftruncate(outFd, mInfoDelta.mTotalBytes);
+ } else {
+ throw e;
+ }
+ }
}
+
+ // Move into place to begin writing
+ Os.lseek(outFd, mInfoDelta.mCurrentBytes, OsConstants.SEEK_SET);
+
+ } catch (ErrnoException e) {
+ throw new StopRequestException(STATUS_FILE_ERROR, e);
} catch (IOException e) {
throw new StopRequestException(STATUS_FILE_ERROR, e);
}
// Start streaming data, periodically watch for pause/cancel
// commands and checking disk space as needed.
- transferData(state, in, out);
+ transferData(in, out, outFd);
try {
if (out instanceof DrmOutputStream) {
@@ -437,83 +515,138 @@ public class DownloadThread implements Runnable {
}
/**
- * Check if current connectivity is valid for this request.
- */
- private void checkConnectivity() throws StopRequestException {
- // checking connectivity will apply current policy
- mPolicyDirty = false;
-
- final NetworkState networkUsable = mInfo.checkCanUseNetwork();
- if (networkUsable != NetworkState.OK) {
- int status = Downloads.Impl.STATUS_WAITING_FOR_NETWORK;
- if (networkUsable == NetworkState.UNUSABLE_DUE_TO_SIZE) {
- status = Downloads.Impl.STATUS_QUEUED_FOR_WIFI;
- mInfo.notifyPauseDueToSize(true);
- } else if (networkUsable == NetworkState.RECOMMENDED_UNUSABLE_DUE_TO_SIZE) {
- status = Downloads.Impl.STATUS_QUEUED_FOR_WIFI;
- mInfo.notifyPauseDueToSize(false);
- }
- throw new StopRequestException(status, networkUsable.name());
- }
- }
-
- /**
* Transfer as much data as possible from the HTTP response to the
* destination file.
*/
- private void transferData(State state, InputStream in, OutputStream out)
+ private void transferData(InputStream in, OutputStream out, FileDescriptor outFd)
throws StopRequestException {
- final byte data[] = new byte[Constants.BUFFER_SIZE];
- for (;;) {
- int bytesRead = readFromResponse(state, data, in);
- if (bytesRead == -1) { // success, end of stream already reached
- handleEndOfStream(state);
- return;
+ final byte buffer[] = new byte[Constants.BUFFER_SIZE];
+ while (true) {
+ checkPausedOrCanceled();
+
+ int len = -1;
+ try {
+ len = in.read(buffer);
+ } catch (IOException e) {
+ throw new StopRequestException(
+ STATUS_HTTP_DATA_ERROR, "Failed reading response: " + e, e);
+ }
+
+ if (len == -1) {
+ break;
}
- state.mGotData = true;
- writeDataToDestination(state, data, bytesRead, out);
- state.mCurrentBytes += bytesRead;
- reportProgress(state);
+ try {
+ // When streaming, ensure space before each write
+ if (mInfoDelta.mTotalBytes == -1) {
+ final long curSize = Os.fstat(outFd).st_size;
+ final long newBytes = (mInfoDelta.mCurrentBytes + len) - curSize;
- if (Constants.LOGVV) {
- Log.v(Constants.TAG, "downloaded " + state.mCurrentBytes + " for "
- + mInfo.mUri);
+ StorageUtils.ensureAvailableSpace(mContext, outFd, newBytes);
+ }
+
+ out.write(buffer, 0, len);
+
+ mMadeProgress = true;
+ mInfoDelta.mCurrentBytes += len;
+
+ updateProgress(outFd);
+
+ } catch (ErrnoException e) {
+ throw new StopRequestException(STATUS_FILE_ERROR, e);
+ } catch (IOException e) {
+ throw new StopRequestException(STATUS_FILE_ERROR, e);
}
+ }
- checkPausedOrCanceled(state);
+ // Finished without error; verify length if known
+ if (mInfoDelta.mTotalBytes != -1 && mInfoDelta.mCurrentBytes != mInfoDelta.mTotalBytes) {
+ throw new StopRequestException(STATUS_HTTP_DATA_ERROR, "Content length mismatch");
}
}
/**
- * Called after a successful completion to take any necessary action on the downloaded file.
+ * Called just before the thread finishes, regardless of status, to take any
+ * necessary action on the downloaded file.
*/
- private void finalizeDestinationFile(State state) {
- if (state.mFilename != null) {
- // make sure the file is readable
- FileUtils.setPermissions(state.mFilename, 0644, -1, -1);
+ private void finalizeDestination() {
+ if (Downloads.Impl.isStatusError(mInfoDelta.mStatus)) {
+ // When error, free up any disk space
+ try {
+ final ParcelFileDescriptor target = mContext.getContentResolver()
+ .openFileDescriptor(mInfo.getAllDownloadsUri(), "rw");
+ try {
+ Os.ftruncate(target.getFileDescriptor(), 0);
+ } catch (ErrnoException ignored) {
+ } finally {
+ IoUtils.closeQuietly(target);
+ }
+ } catch (FileNotFoundException ignored) {
+ }
+
+ // Delete if local file
+ if (mInfoDelta.mFileName != null) {
+ new File(mInfoDelta.mFileName).delete();
+ mInfoDelta.mFileName = null;
+ }
+
+ } else if (Downloads.Impl.isStatusSuccess(mInfoDelta.mStatus)) {
+ // When success, open access if local file
+ if (mInfoDelta.mFileName != null) {
+ try {
+ // TODO: remove this once PackageInstaller works with content://
+ Os.chmod(mInfoDelta.mFileName, 0644);
+ } catch (ErrnoException ignored) {
+ }
+
+ if (mInfo.mDestination != Downloads.Impl.DESTINATION_FILE_URI) {
+ try {
+ // Move into final resting place, if needed
+ final File before = new File(mInfoDelta.mFileName);
+ final File beforeDir = Helpers.getRunningDestinationDirectory(
+ mContext, mInfo.mDestination);
+ final File afterDir = Helpers.getSuccessDestinationDirectory(
+ mContext, mInfo.mDestination);
+ if (!beforeDir.equals(afterDir)
+ && before.getParentFile().equals(beforeDir)) {
+ final File after = new File(afterDir, before.getName());
+ if (before.renameTo(after)) {
+ mInfoDelta.mFileName = after.getAbsolutePath();
+ }
+ }
+ } catch (IOException ignored) {
+ }
+ }
+ }
}
}
/**
- * Called just before the thread finishes, regardless of status, to take any necessary action on
- * the downloaded file.
+ * Check if current connectivity is valid for this request.
*/
- private void cleanupDestination(State state, int finalStatus) {
- if (state.mFilename != null && Downloads.Impl.isStatusError(finalStatus)) {
- if (Constants.LOGVV) {
- Log.d(TAG, "cleanupDestination() deleting " + state.mFilename);
+ private void checkConnectivity() throws StopRequestException {
+ // checking connectivity will apply current policy
+ mPolicyDirty = false;
+
+ final NetworkState networkUsable = mInfo.checkCanUseNetwork(mInfoDelta.mTotalBytes);
+ if (networkUsable != NetworkState.OK) {
+ int status = Downloads.Impl.STATUS_WAITING_FOR_NETWORK;
+ if (networkUsable == NetworkState.UNUSABLE_DUE_TO_SIZE) {
+ status = Downloads.Impl.STATUS_QUEUED_FOR_WIFI;
+ mInfo.notifyPauseDueToSize(true);
+ } else if (networkUsable == NetworkState.RECOMMENDED_UNUSABLE_DUE_TO_SIZE) {
+ status = Downloads.Impl.STATUS_QUEUED_FOR_WIFI;
+ mInfo.notifyPauseDueToSize(false);
}
- new File(state.mFilename).delete();
- state.mFilename = null;
+ throw new StopRequestException(status, networkUsable.name());
}
}
/**
- * Check if the download has been paused or canceled, stopping the request appropriately if it
- * has been.
+ * Check if the download has been paused or canceled, stopping the request
+ * appropriately if it has been.
*/
- private void checkPausedOrCanceled(State state) throws StopRequestException {
+ private void checkPausedOrCanceled() throws StopRequestException {
synchronized (mInfo) {
if (mInfo.mControl == Downloads.Impl.CONTROL_PAUSED) {
throw new StopRequestException(
@@ -533,340 +666,133 @@ public class DownloadThread implements Runnable {
/**
* Report download progress through the database if necessary.
*/
- private void reportProgress(State state) {
+ private void updateProgress(FileDescriptor outFd) throws IOException {
final long now = SystemClock.elapsedRealtime();
+ final long currentBytes = mInfoDelta.mCurrentBytes;
- final long sampleDelta = now - state.mSpeedSampleStart;
+ final long sampleDelta = now - mSpeedSampleStart;
if (sampleDelta > 500) {
- final long sampleSpeed = ((state.mCurrentBytes - state.mSpeedSampleBytes) * 1000)
+ final long sampleSpeed = ((currentBytes - mSpeedSampleBytes) * 1000)
/ sampleDelta;
- if (state.mSpeed == 0) {
- state.mSpeed = sampleSpeed;
+ if (mSpeed == 0) {
+ mSpeed = sampleSpeed;
} else {
- state.mSpeed = ((state.mSpeed * 3) + sampleSpeed) / 4;
+ mSpeed = ((mSpeed * 3) + sampleSpeed) / 4;
}
// Only notify once we have a full sample window
- if (state.mSpeedSampleStart != 0) {
- mNotifier.notifyDownloadSpeed(mInfo.mId, state.mSpeed);
+ if (mSpeedSampleStart != 0) {
+ mNotifier.notifyDownloadSpeed(mId, mSpeed);
}
- state.mSpeedSampleStart = now;
- state.mSpeedSampleBytes = state.mCurrentBytes;
+ mSpeedSampleStart = now;
+ mSpeedSampleBytes = currentBytes;
}
- if (state.mCurrentBytes - state.mBytesNotified > Constants.MIN_PROGRESS_STEP &&
- now - state.mTimeLastNotification > Constants.MIN_PROGRESS_TIME) {
- ContentValues values = new ContentValues();
- values.put(Downloads.Impl.COLUMN_CURRENT_BYTES, state.mCurrentBytes);
- mContext.getContentResolver().update(mInfo.getAllDownloadsUri(), values, null, null);
- state.mBytesNotified = state.mCurrentBytes;
- state.mTimeLastNotification = now;
- }
- }
-
- /**
- * Write a data buffer to the destination file.
- * @param data buffer containing the data to write
- * @param bytesRead how many bytes to write from the buffer
- */
- private void writeDataToDestination(State state, byte[] data, int bytesRead, OutputStream out)
- throws StopRequestException {
- mStorageManager.verifySpaceBeforeWritingToFile(
- mInfo.mDestination, state.mFilename, bytesRead);
+ final long bytesDelta = currentBytes - mLastUpdateBytes;
+ final long timeDelta = now - mLastUpdateTime;
+ if (bytesDelta > Constants.MIN_PROGRESS_STEP && timeDelta > Constants.MIN_PROGRESS_TIME) {
+ // fsync() to ensure that current progress has been flushed to disk,
+ // so we can always resume based on latest database information.
+ outFd.sync();
- boolean forceVerified = false;
- while (true) {
- try {
- out.write(data, 0, bytesRead);
- return;
- } catch (IOException ex) {
- // TODO: better differentiate between DRM and disk failures
- if (!forceVerified) {
- // couldn't write to file. are we out of space? check.
- mStorageManager.verifySpace(mInfo.mDestination, state.mFilename, bytesRead);
- forceVerified = true;
- } else {
- throw new StopRequestException(Downloads.Impl.STATUS_FILE_ERROR,
- "Failed to write data: " + ex);
- }
- }
- }
- }
+ mInfoDelta.writeToDatabase();
- /**
- * Called when we've reached the end of the HTTP response stream, to update the database and
- * check for consistency.
- */
- private void handleEndOfStream(State state) throws StopRequestException {
- ContentValues values = new ContentValues();
- values.put(Downloads.Impl.COLUMN_CURRENT_BYTES, state.mCurrentBytes);
- if (state.mContentLength == -1) {
- values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, state.mCurrentBytes);
- }
- mContext.getContentResolver().update(mInfo.getAllDownloadsUri(), values, null, null);
-
- final boolean lengthMismatched = (state.mContentLength != -1)
- && (state.mCurrentBytes != state.mContentLength);
- if (lengthMismatched) {
- if (cannotResume(state)) {
- throw new StopRequestException(STATUS_CANNOT_RESUME,
- "mismatched content length; unable to resume");
- } else {
- throw new StopRequestException(STATUS_HTTP_DATA_ERROR,
- "closed socket before end of file");
- }
+ mLastUpdateBytes = currentBytes;
+ mLastUpdateTime = now;
}
}
- private boolean cannotResume(State state) {
- return (state.mCurrentBytes > 0 && !mInfo.mNoIntegrity && state.mHeaderETag == null)
- || DownloadDrmHelper.isDrmConvertNeeded(state.mMimeType);
- }
-
/**
- * Read some data from the HTTP response stream, handling I/O errors.
- * @param data buffer to use to read data
- * @param entityStream stream for reading the HTTP response entity
- * @return the number of bytes actually read or -1 if the end of the stream has been reached
+ * Process response headers from first server response. This derives its
+ * filename, size, and ETag.
*/
- private int readFromResponse(State state, byte[] data, InputStream entityStream)
- throws StopRequestException {
- try {
- return entityStream.read(data);
- } catch (IOException ex) {
- // TODO: handle stream errors the same as other retries
- if ("unexpected end of stream".equals(ex.getMessage())) {
- return -1;
- }
+ private void parseOkHeaders(HttpURLConnection conn) throws StopRequestException {
+ if (mInfoDelta.mFileName == null) {
+ final String contentDisposition = conn.getHeaderField("Content-Disposition");
+ final String contentLocation = conn.getHeaderField("Content-Location");
- ContentValues values = new ContentValues();
- values.put(Downloads.Impl.COLUMN_CURRENT_BYTES, state.mCurrentBytes);
- mContext.getContentResolver().update(mInfo.getAllDownloadsUri(), values, null, null);
- if (cannotResume(state)) {
- throw new StopRequestException(STATUS_CANNOT_RESUME,
- "Failed reading response: " + ex + "; unable to resume", ex);
- } else {
- throw new StopRequestException(STATUS_HTTP_DATA_ERROR,
- "Failed reading response: " + ex, ex);
+ try {
+ mInfoDelta.mFileName = Helpers.generateSaveFile(mContext, mInfoDelta.mUri,
+ mInfo.mHint, contentDisposition, contentLocation, mInfoDelta.mMimeType,
+ mInfo.mDestination);
+ } catch (IOException e) {
+ throw new StopRequestException(
+ Downloads.Impl.STATUS_FILE_ERROR, "Failed to generate filename: " + e);
}
}
- }
-
- /**
- * Prepare target file based on given network response. Derives filename and
- * target size as needed.
- */
- private void processResponseHeaders(State state, HttpURLConnection conn)
- throws StopRequestException {
- // TODO: fallocate the entire file if header gave us specific length
-
- readResponseHeaders(state, conn);
-
- state.mFilename = Helpers.generateSaveFile(
- mContext,
- mInfo.mUri,
- mInfo.mHint,
- state.mContentDisposition,
- state.mContentLocation,
- state.mMimeType,
- mInfo.mDestination,
- state.mContentLength,
- mStorageManager);
-
- updateDatabaseFromHeaders(state);
- // check connectivity again now that we know the total size
- checkConnectivity();
- }
-
- /**
- * Update necessary database fields based on values of HTTP response headers that have been
- * read.
- */
- private void updateDatabaseFromHeaders(State state) {
- ContentValues values = new ContentValues();
- values.put(Downloads.Impl._DATA, state.mFilename);
- if (state.mHeaderETag != null) {
- values.put(Constants.ETAG, state.mHeaderETag);
- }
- if (state.mMimeType != null) {
- values.put(Downloads.Impl.COLUMN_MIME_TYPE, state.mMimeType);
- }
- values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, mInfo.mTotalBytes);
- mContext.getContentResolver().update(mInfo.getAllDownloadsUri(), values, null, null);
- }
-
- /**
- * Read headers from the HTTP response and store them into local state.
- */
- private void readResponseHeaders(State state, HttpURLConnection conn)
- throws StopRequestException {
- state.mContentDisposition = conn.getHeaderField("Content-Disposition");
- state.mContentLocation = conn.getHeaderField("Content-Location");
- if (state.mMimeType == null) {
- state.mMimeType = Intent.normalizeMimeType(conn.getContentType());
+ if (mInfoDelta.mMimeType == null) {
+ mInfoDelta.mMimeType = Intent.normalizeMimeType(conn.getContentType());
}
- state.mHeaderETag = conn.getHeaderField("ETag");
-
final String transferEncoding = conn.getHeaderField("Transfer-Encoding");
if (transferEncoding == null) {
- state.mContentLength = getHeaderFieldLong(conn, "Content-Length", -1);
+ mInfoDelta.mTotalBytes = getHeaderFieldLong(conn, "Content-Length", -1);
} else {
- Log.i(TAG, "Ignoring Content-Length since Transfer-Encoding is also defined");
- state.mContentLength = -1;
+ mInfoDelta.mTotalBytes = -1;
}
- state.mTotalBytes = state.mContentLength;
- mInfo.mTotalBytes = state.mContentLength;
+ mInfoDelta.mETag = conn.getHeaderField("ETag");
- final boolean noSizeInfo = state.mContentLength == -1
- && (transferEncoding == null || !transferEncoding.equalsIgnoreCase("chunked"));
- if (!mInfo.mNoIntegrity && noSizeInfo) {
- throw new StopRequestException(STATUS_CANNOT_RESUME,
- "can't know size of download, giving up");
- }
+ mInfoDelta.writeToDatabase();
+
+ // Check connectivity again now that we know the total size
+ checkConnectivity();
}
- private void parseRetryAfterHeaders(State state, HttpURLConnection conn) {
- state.mRetryAfter = conn.getHeaderFieldInt("Retry-After", -1);
- if (state.mRetryAfter < 0) {
- state.mRetryAfter = 0;
+ private void parseUnavailableHeaders(HttpURLConnection conn) {
+ long retryAfter = conn.getHeaderFieldInt("Retry-After", -1);
+ if (retryAfter < 0) {
+ retryAfter = 0;
} else {
- if (state.mRetryAfter < Constants.MIN_RETRY_AFTER) {
- state.mRetryAfter = Constants.MIN_RETRY_AFTER;
- } else if (state.mRetryAfter > Constants.MAX_RETRY_AFTER) {
- state.mRetryAfter = Constants.MAX_RETRY_AFTER;
+ if (retryAfter < Constants.MIN_RETRY_AFTER) {
+ retryAfter = Constants.MIN_RETRY_AFTER;
+ } else if (retryAfter > Constants.MAX_RETRY_AFTER) {
+ retryAfter = Constants.MAX_RETRY_AFTER;
}
- state.mRetryAfter += Helpers.sRandom.nextInt(Constants.MIN_RETRY_AFTER + 1);
- state.mRetryAfter *= 1000;
+ retryAfter += Helpers.sRandom.nextInt(Constants.MIN_RETRY_AFTER + 1);
}
- }
- /**
- * Prepare the destination file to receive data. If the file already exists, we'll set up
- * appropriately for resumption.
- */
- private void setupDestinationFile(State state) throws StopRequestException {
- if (!TextUtils.isEmpty(state.mFilename)) { // only true if we've already run a thread for this download
- if (Constants.LOGV) {
- Log.i(Constants.TAG, "have run thread before for id: " + mInfo.mId +
- ", and state.mFilename: " + state.mFilename);
- }
- if (!Helpers.isFilenameValid(state.mFilename,
- mStorageManager.getDownloadDataDirectory())) {
- // this should never happen
- throw new StopRequestException(Downloads.Impl.STATUS_FILE_ERROR,
- "found invalid internal destination filename");
- }
- // We're resuming a download that got interrupted
- File f = new File(state.mFilename);
- if (f.exists()) {
- if (Constants.LOGV) {
- Log.i(Constants.TAG, "resuming download for id: " + mInfo.mId +
- ", and state.mFilename: " + state.mFilename);
- }
- long fileLength = f.length();
- if (fileLength == 0) {
- // The download hadn't actually started, we can restart from scratch
- if (Constants.LOGVV) {
- Log.d(TAG, "setupDestinationFile() found fileLength=0, deleting "
- + state.mFilename);
- }
- f.delete();
- state.mFilename = null;
- if (Constants.LOGV) {
- Log.i(Constants.TAG, "resuming download for id: " + mInfo.mId +
- ", BUT starting from scratch again: ");
- }
- } else if (mInfo.mETag == null && !mInfo.mNoIntegrity) {
- // This should've been caught upon failure
- if (Constants.LOGVV) {
- Log.d(TAG, "setupDestinationFile() unable to resume download, deleting "
- + state.mFilename);
- }
- f.delete();
- throw new StopRequestException(Downloads.Impl.STATUS_CANNOT_RESUME,
- "Trying to resume a download that can't be resumed");
- } else {
- // All right, we'll be able to resume this download
- if (Constants.LOGV) {
- Log.i(Constants.TAG, "resuming download for id: " + mInfo.mId +
- ", and starting with file of length: " + fileLength);
- }
- state.mCurrentBytes = (int) fileLength;
- if (mInfo.mTotalBytes != -1) {
- state.mContentLength = mInfo.mTotalBytes;
- }
- state.mHeaderETag = mInfo.mETag;
- state.mContinuingDownload = true;
- if (Constants.LOGV) {
- Log.i(Constants.TAG, "resuming download for id: " + mInfo.mId +
- ", state.mCurrentBytes: " + state.mCurrentBytes +
- ", and setting mContinuingDownload to true: ");
- }
- }
- }
- }
+ mInfoDelta.mRetryAfter = (int) (retryAfter * SECOND_IN_MILLIS);
}
/**
* Add custom headers for this download to the HTTP request.
*/
- private void addRequestHeaders(State state, HttpURLConnection conn) {
+ private void addRequestHeaders(HttpURLConnection conn, boolean resuming) {
for (Pair<String, String> header : mInfo.getHeaders()) {
conn.addRequestProperty(header.first, header.second);
}
// Only splice in user agent when not already defined
if (conn.getRequestProperty("User-Agent") == null) {
- conn.addRequestProperty("User-Agent", userAgent());
+ conn.addRequestProperty("User-Agent", mInfo.getUserAgent());
}
// Defeat transparent gzip compression, since it doesn't allow us to
// easily resume partial downloads.
conn.setRequestProperty("Accept-Encoding", "identity");
- if (state.mContinuingDownload) {
- if (state.mHeaderETag != null) {
- conn.addRequestProperty("If-Match", state.mHeaderETag);
+ if (resuming) {
+ if (mInfoDelta.mETag != null) {
+ conn.addRequestProperty("If-Match", mInfoDelta.mETag);
}
- conn.addRequestProperty("Range", "bytes=" + state.mCurrentBytes + "-");
+ conn.addRequestProperty("Range", "bytes=" + mInfoDelta.mCurrentBytes + "-");
}
}
- /**
- * Stores information about the completed download, and notifies the initiating application.
- */
- private void notifyDownloadCompleted(
- State state, int finalStatus, String errorMsg, int numFailed) {
- notifyThroughDatabase(state, finalStatus, errorMsg, numFailed);
- if (Downloads.Impl.isStatusCompleted(finalStatus)) {
- mInfo.sendIntentIfRequested();
- }
+ private void logDebug(String msg) {
+ Log.d(TAG, "[" + mId + "] " + msg);
}
- private void notifyThroughDatabase(
- State state, int finalStatus, String errorMsg, int numFailed) {
- ContentValues values = new ContentValues();
- values.put(Downloads.Impl.COLUMN_STATUS, finalStatus);
- values.put(Downloads.Impl._DATA, state.mFilename);
- values.put(Downloads.Impl.COLUMN_MIME_TYPE, state.mMimeType);
- values.put(Downloads.Impl.COLUMN_LAST_MODIFICATION, mSystemFacade.currentTimeMillis());
- values.put(Downloads.Impl.COLUMN_FAILED_CONNECTIONS, numFailed);
- values.put(Constants.RETRY_AFTER_X_REDIRECT_COUNT, state.mRetryAfter);
-
- if (!TextUtils.equals(mInfo.mUri, state.mRequestUri)) {
- values.put(Downloads.Impl.COLUMN_URI, state.mRequestUri);
- }
+ private void logWarning(String msg) {
+ Log.w(TAG, "[" + mId + "] " + msg);
+ }
- // save the error message. could be useful to developers.
- if (!TextUtils.isEmpty(errorMsg)) {
- values.put(Downloads.Impl.COLUMN_ERROR_MSG, errorMsg);
- }
- mContext.getContentResolver().update(mInfo.getAllDownloadsUri(), values, null, null);
+ private void logError(String msg, Throwable t) {
+ Log.e(TAG, "[" + mId + "] " + msg, t);
}
private INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() {
@@ -891,7 +817,7 @@ public class DownloadThread implements Runnable {
}
};
- public static long getHeaderFieldLong(URLConnection conn, String field, long defaultValue) {
+ private static long getHeaderFieldLong(URLConnection conn, String field, long defaultValue) {
try {
return Long.parseLong(conn.getHeaderField(field));
} catch (NumberFormatException e) {
diff --git a/src/com/android/providers/downloads/Helpers.java b/src/com/android/providers/downloads/Helpers.java
index 3562dac..eb07139 100644
--- a/src/com/android/providers/downloads/Helpers.java
+++ b/src/com/android/providers/downloads/Helpers.java
@@ -21,6 +21,7 @@ import static com.android.providers.downloads.Constants.TAG;
import android.content.Context;
import android.net.Uri;
import android.os.Environment;
+import android.os.FileUtils;
import android.os.SystemClock;
import android.provider.Downloads;
import android.util.Log;
@@ -68,98 +69,79 @@ public class Helpers {
/**
* Creates a filename (where the file should be saved) from info about a download.
+ * This file will be touched to reserve it.
*/
- static String generateSaveFile(
- Context context,
- String url,
- String hint,
- String contentDisposition,
- String contentLocation,
- String mimeType,
- int destination,
- long contentLength,
- StorageManager storageManager) throws StopRequestException {
- if (contentLength < 0) {
- contentLength = 0;
- }
- String path;
- File base = null;
+ static String generateSaveFile(Context context, String url, String hint,
+ String contentDisposition, String contentLocation, String mimeType, int destination)
+ throws IOException {
+
+ final File parent;
+ final File[] parentTest;
+ String name = null;
+
if (destination == Downloads.Impl.DESTINATION_FILE_URI) {
- path = Uri.parse(hint).getPath();
+ final File file = new File(Uri.parse(hint).getPath());
+ parent = file.getParentFile().getAbsoluteFile();
+ parentTest = new File[] { parent };
+ name = file.getName();
} else {
- base = storageManager.locateDestinationDirectory(mimeType, destination,
- contentLength);
- path = chooseFilename(url, hint, contentDisposition, contentLocation,
- destination);
+ parent = getRunningDestinationDirectory(context, destination);
+ parentTest = new File[] {
+ parent,
+ getSuccessDestinationDirectory(context, destination)
+ };
+ name = chooseFilename(url, hint, contentDisposition, contentLocation);
+ }
+
+ // Ensure target directories are ready
+ for (File test : parentTest) {
+ if (!(test.isDirectory() || test.mkdirs())) {
+ throw new IOException("Failed to create parent for " + test);
+ }
}
- storageManager.verifySpace(destination, path, contentLength);
+
if (DownloadDrmHelper.isDrmConvertNeeded(mimeType)) {
- path = DownloadDrmHelper.modifyDrmFwLockFileExtension(path);
+ name = DownloadDrmHelper.modifyDrmFwLockFileExtension(name);
}
- path = getFullPath(path, mimeType, destination, base);
- return path;
- }
- static String getFullPath(String filename, String mimeType, int destination, File base)
- throws StopRequestException {
- String extension = null;
- int dotIndex = filename.lastIndexOf('.');
- boolean missingExtension = dotIndex < 0 || dotIndex < filename.lastIndexOf('/');
+ final String prefix;
+ final String suffix;
+ final int dotIndex = name.lastIndexOf('.');
+ final boolean missingExtension = dotIndex < 0;
if (destination == Downloads.Impl.DESTINATION_FILE_URI) {
// Destination is explicitly set - do not change the extension
if (missingExtension) {
- extension = "";
+ prefix = name;
+ suffix = "";
} else {
- extension = filename.substring(dotIndex);
- filename = filename.substring(0, dotIndex);
+ prefix = name.substring(0, dotIndex);
+ suffix = name.substring(dotIndex);
}
} else {
// Split filename between base and extension
// Add an extension if filename does not have one
if (missingExtension) {
- extension = chooseExtensionFromMimeType(mimeType, true);
+ prefix = name;
+ suffix = chooseExtensionFromMimeType(mimeType, true);
} else {
- extension = chooseExtensionFromFilename(mimeType, destination, filename, dotIndex);
- filename = filename.substring(0, dotIndex);
+ prefix = name.substring(0, dotIndex);
+ suffix = chooseExtensionFromFilename(mimeType, destination, name, dotIndex);
}
}
- boolean recoveryDir = Constants.RECOVERY_DIRECTORY.equalsIgnoreCase(filename + extension);
-
- if (base != null) {
- filename = base.getPath() + File.separator + filename;
- }
-
- if (Constants.LOGVV) {
- Log.v(Constants.TAG, "target file: " + filename + extension);
- }
-
synchronized (sUniqueLock) {
- final String path = chooseUniqueFilenameLocked(
- destination, filename, extension, recoveryDir);
+ name = generateAvailableFilenameLocked(parentTest, prefix, suffix);
// Claim this filename inside lock to prevent other threads from
// clobbering us. We're not paranoid enough to use O_EXCL.
- try {
- File file = new File(path);
- File parent = file.getParentFile();
-
- // Make sure the parent directories exists before generates new file
- if (parent != null && !parent.exists()) {
- parent.mkdirs();
- }
-
- file.createNewFile();
- } catch (IOException e) {
- throw new StopRequestException(Downloads.Impl.STATUS_FILE_ERROR,
- "Failed to create target file " + path, e);
- }
- return path;
+ final File file = new File(parent, name);
+ file.createNewFile();
+ return file.getAbsolutePath();
}
}
private static String chooseFilename(String url, String hint, String contentDisposition,
- String contentLocation, int destination) {
+ String contentLocation) {
String filename = null;
// First, try to use the hint from the application, if there's one
@@ -305,18 +287,25 @@ public class Helpers {
return extension;
}
- private static String chooseUniqueFilenameLocked(int destination, String filename,
- String extension, boolean recoveryDir) throws StopRequestException {
- String fullFilename = filename + extension;
- if (!new File(fullFilename).exists()
- && (!recoveryDir ||
- (destination != Downloads.Impl.DESTINATION_CACHE_PARTITION &&
- destination != Downloads.Impl.DESTINATION_SYSTEMCACHE_PARTITION &&
- destination != Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE &&
- destination != Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING))) {
- return fullFilename;
- }
- filename = filename + Constants.FILENAME_SEQUENCE_SEPARATOR;
+ private static boolean isFilenameAvailableLocked(File[] parents, String name) {
+ if (Constants.RECOVERY_DIRECTORY.equalsIgnoreCase(name)) return false;
+
+ for (File parent : parents) {
+ if (new File(parent, name).exists()) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private static String generateAvailableFilenameLocked(
+ File[] parents, String prefix, String suffix) throws IOException {
+ String name = prefix + suffix;
+ if (isFilenameAvailableLocked(parents, name)) {
+ return name;
+ }
+
/*
* This number is used to generate partially randomized filenames to avoid
* collisions.
@@ -334,39 +323,38 @@ public class Helpers {
int sequence = 1;
for (int magnitude = 1; magnitude < 1000000000; magnitude *= 10) {
for (int iteration = 0; iteration < 9; ++iteration) {
- fullFilename = filename + sequence + extension;
- if (!new File(fullFilename).exists()) {
- return fullFilename;
- }
- if (Constants.LOGVV) {
- Log.v(Constants.TAG, "file with sequence number " + sequence + " exists");
+ name = prefix + Constants.FILENAME_SEQUENCE_SEPARATOR + sequence + suffix;
+ if (isFilenameAvailableLocked(parents, name)) {
+ return name;
}
sequence += sRandom.nextInt(magnitude) + 1;
}
}
- throw new StopRequestException(Downloads.Impl.STATUS_FILE_ERROR,
- "failed to generate an unused filename on internal download storage");
+
+ throw new IOException("Failed to generate an available filename");
}
/**
- * Checks whether the filename looks legitimate
+ * Checks whether the filename looks legitimate for security purposes. This
+ * prevents us from opening files that aren't actually downloads.
*/
- static boolean isFilenameValid(String filename, File downloadsDataDir) {
- final String[] whitelist;
+ static boolean isFilenameValid(Context context, File file) {
+ final File[] whitelist;
try {
- filename = new File(filename).getCanonicalPath();
- whitelist = new String[] {
- downloadsDataDir.getCanonicalPath(),
- Environment.getDownloadCacheDirectory().getCanonicalPath(),
- Environment.getExternalStorageDirectory().getCanonicalPath(),
+ file = file.getCanonicalFile();
+ whitelist = new File[] {
+ context.getFilesDir().getCanonicalFile(),
+ context.getCacheDir().getCanonicalFile(),
+ Environment.getDownloadCacheDirectory().getCanonicalFile(),
+ Environment.getExternalStorageDirectory().getCanonicalFile(),
};
} catch (IOException e) {
Log.w(TAG, "Failed to resolve canonical path: " + e);
return false;
}
- for (String test : whitelist) {
- if (filename.startsWith(test)) {
+ for (File testDir : whitelist) {
+ if (FileUtils.contains(testDir, file)) {
return true;
}
}
@@ -374,6 +362,49 @@ public class Helpers {
return false;
}
+ public static File getRunningDestinationDirectory(Context context, int destination)
+ throws IOException {
+ return getDestinationDirectory(context, destination, true);
+ }
+
+ public static File getSuccessDestinationDirectory(Context context, int destination)
+ throws IOException {
+ return getDestinationDirectory(context, destination, false);
+ }
+
+ private static File getDestinationDirectory(Context context, int destination, boolean running)
+ throws IOException {
+ switch (destination) {
+ case Downloads.Impl.DESTINATION_CACHE_PARTITION:
+ case Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE:
+ case Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING:
+ if (running) {
+ return context.getFilesDir();
+ } else {
+ return context.getCacheDir();
+ }
+
+ case Downloads.Impl.DESTINATION_SYSTEMCACHE_PARTITION:
+ if (running) {
+ return new File(Environment.getDownloadCacheDirectory(),
+ Constants.DIRECTORY_CACHE_RUNNING);
+ } else {
+ return Environment.getDownloadCacheDirectory();
+ }
+
+ case Downloads.Impl.DESTINATION_EXTERNAL:
+ final File target = new File(
+ Environment.getExternalStorageDirectory(), Environment.DIRECTORY_DOWNLOADS);
+ if (!target.isDirectory() && target.mkdirs()) {
+ throw new IOException("unable to create external downloads directory");
+ }
+ return target;
+
+ default:
+ throw new IllegalStateException("unexpected destination: " + destination);
+ }
+ }
+
/**
* Checks whether this looks like a legitimate selection parameter
*/
diff --git a/src/com/android/providers/downloads/StopRequestException.java b/src/com/android/providers/downloads/StopRequestException.java
index a2b642d..07bd628 100644
--- a/src/com/android/providers/downloads/StopRequestException.java
+++ b/src/com/android/providers/downloads/StopRequestException.java
@@ -34,13 +34,13 @@ class StopRequestException extends Exception {
}
public StopRequestException(int finalStatus, Throwable t) {
- super(t);
- mFinalStatus = finalStatus;
+ this(finalStatus, t.getMessage());
+ initCause(t);
}
public StopRequestException(int finalStatus, String message, Throwable t) {
- super(message, t);
- mFinalStatus = finalStatus;
+ this(finalStatus, message);
+ initCause(t);
}
public int getFinalStatus() {
diff --git a/src/com/android/providers/downloads/StorageManager.java b/src/com/android/providers/downloads/StorageManager.java
deleted file mode 100644
index b8cd6c7..0000000
--- a/src/com/android/providers/downloads/StorageManager.java
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.providers.downloads;
-
-import static com.android.providers.downloads.Constants.LOGV;
-import static com.android.providers.downloads.Constants.TAG;
-
-import android.content.ContentUris;
-import android.content.Context;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteException;
-import android.net.Uri;
-import android.os.Environment;
-import android.os.StatFs;
-import android.provider.Downloads;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.R;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.StructStat;
-
-/**
- * Manages the storage space consumed by Downloads Data dir. When space falls below
- * a threshold limit (set in resource xml files), starts cleanup of the Downloads data dir
- * to free up space.
- */
-class StorageManager {
- /** the max amount of space allowed to be taken up by the downloads data dir */
- private static final long sMaxdownloadDataDirSize =
- Resources.getSystem().getInteger(R.integer.config_downloadDataDirSize) * 1024 * 1024;
-
- /** threshold (in bytes) beyond which the low space warning kicks in and attempt is made to
- * purge some downloaded files to make space
- */
- private static final long sDownloadDataDirLowSpaceThreshold =
- Resources.getSystem().getInteger(
- R.integer.config_downloadDataDirLowSpaceThreshold)
- * sMaxdownloadDataDirSize / 100;
-
- /** see {@link Environment#getExternalStorageDirectory()} */
- private final File mExternalStorageDir;
-
- /** see {@link Environment#getDownloadCacheDirectory()} */
- private final File mSystemCacheDir;
-
- /** The downloaded files are saved to this dir. it is the value returned by
- * {@link Context#getCacheDir()}.
- */
- private final File mDownloadDataDir;
-
- /** how often do we need to perform checks on space to make sure space is available */
- private static final int FREQUENCY_OF_CHECKS_ON_SPACE_AVAILABILITY = 1024 * 1024; // 1MB
- private int mBytesDownloadedSinceLastCheckOnSpace = 0;
-
- /** misc members */
- private final Context mContext;
-
- public StorageManager(Context context) {
- mContext = context;
- mDownloadDataDir = getDownloadDataDirectory(context);
- mExternalStorageDir = Environment.getExternalStorageDirectory();
- mSystemCacheDir = Environment.getDownloadCacheDirectory();
- startThreadToCleanupDatabaseAndPurgeFileSystem();
- }
-
- /** How often should database and filesystem be cleaned up to remove spurious files
- * from the file system and
- * The value is specified in terms of num of downloads since last time the cleanup was done.
- */
- private static final int FREQUENCY_OF_DATABASE_N_FILESYSTEM_CLEANUP = 250;
- private int mNumDownloadsSoFar = 0;
-
- synchronized void incrementNumDownloadsSoFar() {
- if (++mNumDownloadsSoFar % FREQUENCY_OF_DATABASE_N_FILESYSTEM_CLEANUP == 0) {
- startThreadToCleanupDatabaseAndPurgeFileSystem();
- }
- }
- /* start a thread to cleanup the following
- * remove spurious files from the file system
- * remove excess entries from the database
- */
- private Thread mCleanupThread = null;
- private synchronized void startThreadToCleanupDatabaseAndPurgeFileSystem() {
- if (mCleanupThread != null && mCleanupThread.isAlive()) {
- return;
- }
- mCleanupThread = new Thread() {
- @Override public void run() {
- removeSpuriousFiles();
- trimDatabase();
- }
- };
- mCleanupThread.start();
- }
-
- void verifySpaceBeforeWritingToFile(int destination, String path, long length)
- throws StopRequestException {
- // do this check only once for every 1MB of downloaded data
- if (incrementBytesDownloadedSinceLastCheckOnSpace(length) <
- FREQUENCY_OF_CHECKS_ON_SPACE_AVAILABILITY) {
- return;
- }
- verifySpace(destination, path, length);
- }
-
- void verifySpace(int destination, String path, long length) throws StopRequestException {
- resetBytesDownloadedSinceLastCheckOnSpace();
- File dir = null;
- if (Constants.LOGV) {
- Log.i(Constants.TAG, "in verifySpace, destination: " + destination +
- ", path: " + path + ", length: " + length);
- }
- if (path == null) {
- throw new IllegalArgumentException("path can't be null");
- }
- switch (destination) {
- case Downloads.Impl.DESTINATION_CACHE_PARTITION:
- case Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING:
- case Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE:
- dir = mDownloadDataDir;
- break;
- case Downloads.Impl.DESTINATION_EXTERNAL:
- dir = mExternalStorageDir;
- break;
- case Downloads.Impl.DESTINATION_SYSTEMCACHE_PARTITION:
- dir = mSystemCacheDir;
- break;
- case Downloads.Impl.DESTINATION_FILE_URI:
- if (path.startsWith(mExternalStorageDir.getPath())) {
- dir = mExternalStorageDir;
- } else if (path.startsWith(mDownloadDataDir.getPath())) {
- dir = mDownloadDataDir;
- } else if (path.startsWith(mSystemCacheDir.getPath())) {
- dir = mSystemCacheDir;
- }
- break;
- }
- if (dir == null) {
- throw new IllegalStateException("invalid combination of destination: " + destination +
- ", path: " + path);
- }
- findSpace(dir, length, destination);
- }
-
- /**
- * finds space in the given filesystem (input param: root) to accommodate # of bytes
- * specified by the input param(targetBytes).
- * returns true if found. false otherwise.
- */
- private synchronized void findSpace(File root, long targetBytes, int destination)
- throws StopRequestException {
- if (targetBytes == 0) {
- return;
- }
- if (destination == Downloads.Impl.DESTINATION_FILE_URI ||
- destination == Downloads.Impl.DESTINATION_EXTERNAL) {
- if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- throw new StopRequestException(Downloads.Impl.STATUS_DEVICE_NOT_FOUND_ERROR,
- "external media not mounted");
- }
- }
- // is there enough space in the file system of the given param 'root'.
- long bytesAvailable = getAvailableBytesInFileSystemAtGivenRoot(root);
- if (bytesAvailable < sDownloadDataDirLowSpaceThreshold) {
- /* filesystem's available space is below threshold for low space warning.
- * threshold typically is 10% of download data dir space quota.
- * try to cleanup and see if the low space situation goes away.
- */
- discardPurgeableFiles(destination, sDownloadDataDirLowSpaceThreshold);
- removeSpuriousFiles();
- bytesAvailable = getAvailableBytesInFileSystemAtGivenRoot(root);
- if (bytesAvailable < sDownloadDataDirLowSpaceThreshold) {
- /*
- * available space is still below the threshold limit.
- *
- * If this is system cache dir, print a warning.
- * otherwise, don't allow downloading until more space
- * is available because downloadmanager shouldn't end up taking those last
- * few MB of space left on the filesystem.
- */
- if (root.equals(mSystemCacheDir)) {
- Log.w(Constants.TAG, "System cache dir ('/cache') is running low on space." +
- "space available (in bytes): " + bytesAvailable);
- } else {
- throw new StopRequestException(Downloads.Impl.STATUS_INSUFFICIENT_SPACE_ERROR,
- "space in the filesystem rooted at: " + root +
- " is below 10% availability. stopping this download.");
- }
- }
- }
- if (root.equals(mDownloadDataDir)) {
- // this download is going into downloads data dir. check space in that specific dir.
- bytesAvailable = getAvailableBytesInDownloadsDataDir(mDownloadDataDir);
- if (bytesAvailable < sDownloadDataDirLowSpaceThreshold) {
- // print a warning
- Log.w(Constants.TAG, "Downloads data dir: " + root +
- " is running low on space. space available (in bytes): " + bytesAvailable);
- }
- if (bytesAvailable < targetBytes) {
- // Insufficient space; make space.
- discardPurgeableFiles(destination, sDownloadDataDirLowSpaceThreshold);
- removeSpuriousFiles();
- bytesAvailable = getAvailableBytesInDownloadsDataDir(mDownloadDataDir);
- }
- }
- if (bytesAvailable < targetBytes) {
- throw new StopRequestException(Downloads.Impl.STATUS_INSUFFICIENT_SPACE_ERROR,
- "not enough free space in the filesystem rooted at: " + root +
- " and unable to free any more");
- }
- }
-
- /**
- * returns the number of bytes available in the downloads data dir
- * TODO this implementation is too slow. optimize it.
- */
- private long getAvailableBytesInDownloadsDataDir(File root) {
- File[] files = root.listFiles();
- long space = sMaxdownloadDataDirSize;
- if (files == null) {
- return space;
- }
- int size = files.length;
- for (int i = 0; i < size; i++) {
- space -= files[i].length();
- }
- if (Constants.LOGV) {
- Log.i(Constants.TAG, "available space (in bytes) in downloads data dir: " + space);
- }
- return space;
- }
-
- private long getAvailableBytesInFileSystemAtGivenRoot(File root) {
- StatFs stat = new StatFs(root.getPath());
- // put a bit of margin (in case creating the file grows the system by a few blocks)
- long availableBlocks = (long) stat.getAvailableBlocks() - 4;
- long size = stat.getBlockSize() * availableBlocks;
- if (Constants.LOGV) {
- Log.i(Constants.TAG, "available space (in bytes) in filesystem rooted at: " +
- root.getPath() + " is: " + size);
- }
- return size;
- }
-
- File locateDestinationDirectory(String mimeType, int destination, long contentLength)
- throws StopRequestException {
- switch (destination) {
- case Downloads.Impl.DESTINATION_CACHE_PARTITION:
- case Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE:
- case Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING:
- return mDownloadDataDir;
- case Downloads.Impl.DESTINATION_SYSTEMCACHE_PARTITION:
- return mSystemCacheDir;
- case Downloads.Impl.DESTINATION_EXTERNAL:
- File base = new File(mExternalStorageDir.getPath() + Constants.DEFAULT_DL_SUBDIR);
- if (!base.isDirectory() && !base.mkdir()) {
- // Can't create download directory, e.g. because a file called "download"
- // already exists at the root level, or the SD card filesystem is read-only.
- throw new StopRequestException(Downloads.Impl.STATUS_FILE_ERROR,
- "unable to create external downloads directory " + base.getPath());
- }
- return base;
- default:
- throw new IllegalStateException("unexpected value for destination: " + destination);
- }
- }
-
- File getDownloadDataDirectory() {
- return mDownloadDataDir;
- }
-
- public static File getDownloadDataDirectory(Context context) {
- return context.getCacheDir();
- }
-
- /**
- * Deletes purgeable files from the cache partition. This also deletes
- * the matching database entries. Files are deleted in LRU order until
- * the total byte size is greater than targetBytes
- */
- private long discardPurgeableFiles(int destination, long targetBytes) {
- if (true || Constants.LOGV) {
- Log.i(Constants.TAG, "discardPurgeableFiles: destination = " + destination +
- ", targetBytes = " + targetBytes);
- }
- String destStr = (destination == Downloads.Impl.DESTINATION_SYSTEMCACHE_PARTITION) ?
- String.valueOf(destination) :
- String.valueOf(Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE);
- String[] bindArgs = new String[]{destStr};
- Cursor cursor = mContext.getContentResolver().query(
- Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI,
- null,
- "( " +
- Downloads.Impl.COLUMN_STATUS + " = '" + Downloads.Impl.STATUS_SUCCESS + "' AND " +
- Downloads.Impl.COLUMN_DESTINATION + " = ? )",
- bindArgs,
- Downloads.Impl.COLUMN_LAST_MODIFICATION);
- if (cursor == null) {
- return 0;
- }
- long totalFreed = 0;
- try {
- final int dataIndex = cursor.getColumnIndex(Downloads.Impl._DATA);
- while (cursor.moveToNext() && totalFreed < targetBytes) {
- final String data = cursor.getString(dataIndex);
- if (TextUtils.isEmpty(data)) continue;
-
- File file = new File(data);
- if (Constants.LOGV) {
- Log.d(Constants.TAG, "purging " + file.getAbsolutePath() + " for "
- + file.length() + " bytes");
- }
- totalFreed += file.length();
- file.delete();
- long id = cursor.getLong(cursor.getColumnIndex(Downloads.Impl._ID));
- mContext.getContentResolver().delete(
- ContentUris.withAppendedId(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, id),
- null, null);
- }
- } finally {
- cursor.close();
- }
- if (true || Constants.LOGV) {
- Log.i(Constants.TAG, "Purged files, freed " + totalFreed + " for " +
- targetBytes + " requested");
- }
- return totalFreed;
- }
-
- /**
- * Removes files in the systemcache and downloads data dir without corresponding entries in
- * the downloads database.
- * This can occur if a delete is done on the database but the file is not removed from the
- * filesystem (due to sudden death of the process, for example).
- * This is not a very common occurrence. So, do this only once in a while.
- */
- private void removeSpuriousFiles() {
- if (Constants.LOGV) {
- Log.i(Constants.TAG, "in removeSpuriousFiles");
- }
- // get a list of all files in system cache dir and downloads data dir
- List<File> files = new ArrayList<File>();
- File[] listOfFiles = mSystemCacheDir.listFiles();
- if (listOfFiles != null) {
- files.addAll(Arrays.asList(listOfFiles));
- }
- listOfFiles = mDownloadDataDir.listFiles();
- if (listOfFiles != null) {
- files.addAll(Arrays.asList(listOfFiles));
- }
- if (files.size() == 0) {
- return;
- }
- Cursor cursor = mContext.getContentResolver().query(
- Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI,
- new String[] { Downloads.Impl._DATA }, null, null, null);
- try {
- if (cursor != null) {
- while (cursor.moveToNext()) {
- String filename = cursor.getString(0);
- if (!TextUtils.isEmpty(filename)) {
- if (LOGV) {
- Log.i(Constants.TAG, "in removeSpuriousFiles, preserving file " +
- filename);
- }
- files.remove(new File(filename));
- }
- }
- }
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
-
- // delete files owned by us, but that don't appear in our database
- final int myUid = android.os.Process.myUid();
- for (File file : files) {
- final String path = file.getAbsolutePath();
- try {
- final StructStat stat = Os.stat(path);
- if (stat.st_uid == myUid) {
- if (Constants.LOGVV) {
- Log.d(TAG, "deleting spurious file " + path);
- }
- file.delete();
- }
- } catch (ErrnoException e) {
- Log.w(TAG, "stat(" + path + ") result: " + e);
- }
- }
- }
-
- /**
- * Drops old rows from the database to prevent it from growing too large
- * TODO logic in this method needs to be optimized. maintain the number of downloads
- * in memory - so that this method can limit the amount of data read.
- */
- private void trimDatabase() {
- if (Constants.LOGV) {
- Log.i(Constants.TAG, "in trimDatabase");
- }
- Cursor cursor = null;
- try {
- cursor = mContext.getContentResolver().query(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI,
- new String[] { Downloads.Impl._ID },
- Downloads.Impl.COLUMN_STATUS + " >= '200'", null,
- Downloads.Impl.COLUMN_LAST_MODIFICATION);
- if (cursor == null) {
- // This isn't good - if we can't do basic queries in our database,
- // nothing's gonna work
- Log.e(Constants.TAG, "null cursor in trimDatabase");
- return;
- }
- if (cursor.moveToFirst()) {
- int numDelete = cursor.getCount() - Constants.MAX_DOWNLOADS;
- int columnId = cursor.getColumnIndexOrThrow(Downloads.Impl._ID);
- while (numDelete > 0) {
- Uri downloadUri = ContentUris.withAppendedId(
- Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, cursor.getLong(columnId));
- mContext.getContentResolver().delete(downloadUri, null, null);
- if (!cursor.moveToNext()) {
- break;
- }
- numDelete--;
- }
- }
- } catch (SQLiteException e) {
- // trimming the database raised an exception. alright, ignore the exception
- // and return silently. trimming database is not exactly a critical operation
- // and there is no need to propagate the exception.
- Log.w(Constants.TAG, "trimDatabase failed with exception: " + e.getMessage());
- return;
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
- }
-
- private synchronized int incrementBytesDownloadedSinceLastCheckOnSpace(long val) {
- mBytesDownloadedSinceLastCheckOnSpace += val;
- return mBytesDownloadedSinceLastCheckOnSpace;
- }
-
- private synchronized void resetBytesDownloadedSinceLastCheckOnSpace() {
- mBytesDownloadedSinceLastCheckOnSpace = 0;
- }
-}
diff --git a/src/com/android/providers/downloads/StorageUtils.java b/src/com/android/providers/downloads/StorageUtils.java
new file mode 100644
index 0000000..1817c75
--- /dev/null
+++ b/src/com/android/providers/downloads/StorageUtils.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.providers.downloads;
+
+import static android.net.TrafficStats.MB_IN_BYTES;
+import static android.provider.Downloads.Impl.STATUS_INSUFFICIENT_SPACE_ERROR;
+import static android.text.format.DateUtils.DAY_IN_MILLIS;
+import static com.android.providers.downloads.Constants.TAG;
+
+import android.app.DownloadManager;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.Context;
+import android.content.pm.IPackageDataObserver;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.os.Environment;
+import android.provider.Downloads;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.StructStat;
+import android.system.StructStatVfs;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.google.android.collect.Lists;
+import com.google.android.collect.Sets;
+
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Utility methods for managing storage space related to
+ * {@link DownloadManager}.
+ */
+public class StorageUtils {
+
+ /**
+ * Minimum age for a file to be considered for deletion.
+ */
+ static final long MIN_DELETE_AGE = DAY_IN_MILLIS;
+
+ /**
+ * Reserved disk space to avoid filling disk.
+ */
+ static final long RESERVED_BYTES = 32 * MB_IN_BYTES;
+
+ @VisibleForTesting
+ static boolean sForceFullEviction = false;
+
+ /**
+ * Ensure that requested free space exists on the partition backing the
+ * given {@link FileDescriptor}. If not enough space is available, it tries
+ * freeing up space as follows:
+ * <ul>
+ * <li>If backed by the data partition (including emulated external
+ * storage), then ask {@link PackageManager} to free space from cache
+ * directories.
+ * <li>If backed by the cache partition, then try deleting older downloads
+ * to free space.
+ * </ul>
+ */
+ public static void ensureAvailableSpace(Context context, FileDescriptor fd, long bytes)
+ throws IOException, StopRequestException {
+
+ long availBytes = getAvailableBytes(fd);
+ if (availBytes >= bytes) {
+ // Underlying partition has enough space; go ahead
+ return;
+ }
+
+ // Not enough space, let's try freeing some up. Start by tracking down
+ // the backing partition.
+ final long dev;
+ try {
+ dev = Os.fstat(fd).st_dev;
+ } catch (ErrnoException e) {
+ throw e.rethrowAsIOException();
+ }
+
+ final long dataDev = getDeviceId(Environment.getDataDirectory());
+ final long cacheDev = getDeviceId(Environment.getDownloadCacheDirectory());
+ final long externalDev = getDeviceId(Environment.getExternalStorageDirectory());
+
+ if (dev == dataDev || (dev == externalDev && Environment.isExternalStorageEmulated())) {
+ // File lives on internal storage; ask PackageManager to try freeing
+ // up space from cache directories.
+ final PackageManager pm = context.getPackageManager();
+ final ObserverLatch observer = new ObserverLatch();
+ pm.freeStorageAndNotify(sForceFullEviction ? Long.MAX_VALUE : bytes, observer);
+
+ try {
+ if (!observer.latch.await(30, TimeUnit.SECONDS)) {
+ throw new IOException("Timeout while freeing disk space");
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+
+ } else if (dev == cacheDev) {
+ // Try removing old files on cache partition
+ freeCacheStorage(bytes);
+ }
+
+ // Did we free enough space?
+ availBytes = getAvailableBytes(fd);
+ if (availBytes < bytes) {
+ throw new StopRequestException(STATUS_INSUFFICIENT_SPACE_ERROR,
+ "Not enough free space; " + bytes + " requested, " + availBytes + " available");
+ }
+ }
+
+ /**
+ * Free requested space on cache partition, deleting oldest files first.
+ * We're only focused on freeing up disk space, and rely on the next orphan
+ * pass to clean up database entries.
+ */
+ private static void freeCacheStorage(long bytes) {
+ // Only consider finished downloads
+ final List<ConcreteFile> files = listFilesRecursive(
+ Environment.getDownloadCacheDirectory(), Constants.DIRECTORY_CACHE_RUNNING,
+ android.os.Process.myUid());
+
+ Slog.d(TAG, "Found " + files.size() + " downloads on cache");
+
+ Collections.sort(files, new Comparator<ConcreteFile>() {
+ @Override
+ public int compare(ConcreteFile lhs, ConcreteFile rhs) {
+ return (int) (lhs.file.lastModified() - rhs.file.lastModified());
+ }
+ });
+
+ final long now = System.currentTimeMillis();
+ for (ConcreteFile file : files) {
+ if (bytes <= 0) break;
+
+ if (now - file.file.lastModified() < MIN_DELETE_AGE) {
+ Slog.d(TAG, "Skipping recently modified " + file.file);
+ } else {
+ final long len = file.file.length();
+ Slog.d(TAG, "Deleting " + file.file + " to reclaim " + len);
+ bytes -= len;
+ file.file.delete();
+ }
+ }
+ }
+
+ /**
+ * Return number of available bytes on the filesystem backing the given
+ * {@link FileDescriptor}, minus any {@link #RESERVED_BYTES} buffer.
+ */
+ private static long getAvailableBytes(FileDescriptor fd) throws IOException {
+ try {
+ final StructStatVfs stat = Os.fstatvfs(fd);
+ return (stat.f_bavail * stat.f_bsize) - RESERVED_BYTES;
+ } catch (ErrnoException e) {
+ throw e.rethrowAsIOException();
+ }
+ }
+
+ private static long getDeviceId(File file) {
+ try {
+ return Os.stat(file.getAbsolutePath()).st_dev;
+ } catch (ErrnoException e) {
+ // Safe since dev_t is uint
+ return -1;
+ }
+ }
+
+ /**
+ * Return list of all normal files under the given directory, traversing
+ * directories recursively.
+ *
+ * @param exclude ignore dirs with this name, or {@code null} to ignore.
+ * @param uid only return files owned by this UID, or {@code -1} to ignore.
+ */
+ static List<ConcreteFile> listFilesRecursive(File startDir, String exclude, int uid) {
+ final ArrayList<ConcreteFile> files = Lists.newArrayList();
+ final LinkedList<File> dirs = new LinkedList<File>();
+ dirs.add(startDir);
+ while (!dirs.isEmpty()) {
+ final File dir = dirs.removeFirst();
+ if (Objects.equals(dir.getName(), exclude)) continue;
+
+ final File[] children = dir.listFiles();
+ if (children == null) continue;
+
+ for (File child : children) {
+ if (child.isDirectory()) {
+ dirs.add(child);
+ } else if (child.isFile()) {
+ try {
+ final ConcreteFile file = new ConcreteFile(child);
+ if (uid == -1 || file.stat.st_uid == uid) {
+ files.add(file);
+ }
+ } catch (ErrnoException ignored) {
+ }
+ }
+ }
+ }
+ return files;
+ }
+
+ /**
+ * Concrete file on disk that has a backing device and inode. Faster than
+ * {@code realpath()} when looking for identical files.
+ */
+ static class ConcreteFile {
+ public final File file;
+ public final StructStat stat;
+
+ public ConcreteFile(File file) throws ErrnoException {
+ this.file = file;
+ this.stat = Os.lstat(file.getAbsolutePath());
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 1;
+ result = 31 * result + (int) (stat.st_dev ^ (stat.st_dev >>> 32));
+ result = 31 * result + (int) (stat.st_ino ^ (stat.st_ino >>> 32));
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof ConcreteFile) {
+ final ConcreteFile f = (ConcreteFile) o;
+ return (f.stat.st_dev == stat.st_dev) && (f.stat.st_ino == stat.st_ino);
+ }
+ return false;
+ }
+ }
+
+ static class ObserverLatch extends IPackageDataObserver.Stub {
+ public final CountDownLatch latch = new CountDownLatch(1);
+
+ @Override
+ public void onRemoveCompleted(String packageName, boolean succeeded) {
+ latch.countDown();
+ }
+ }
+}
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index d520123..ec73ca2 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -19,6 +19,8 @@
package="com.android.providers.downloads.tests"
android:sharedUserId="android.media">
+ <uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER_ADVANCED" />
+
<application>
<uses-library android:name="android.test.runner" />
</application>
diff --git a/tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java b/tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java
index 3b93738..28c5dc7 100644
--- a/tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java
+++ b/tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java
@@ -74,15 +74,18 @@ public abstract class AbstractDownloadProviderFunctionalTest extends
static class MockContentResolverWithNotify extends MockContentResolver {
public boolean mNotifyWasCalled = false;
+ public MockContentResolverWithNotify(Context context) {
+ super(context);
+ }
+
public synchronized void resetNotified() {
mNotifyWasCalled = false;
}
@Override
- public synchronized void notifyChange(Uri uri, ContentObserver observer,
- boolean syncToNetwork) {
+ public synchronized void notifyChange(
+ Uri uri, ContentObserver observer, boolean syncToNetwork) {
mNotifyWasCalled = true;
- notifyAll();
}
}
@@ -94,20 +97,17 @@ public abstract class AbstractDownloadProviderFunctionalTest extends
static class TestContext extends RenamingDelegatingContext {
private static final String FILENAME_PREFIX = "test.";
- private ContentResolver mResolver;
+ private final ContentResolver mResolver;
private final NotificationManager mNotifManager;
boolean mHasServiceBeenStarted = false;
public TestContext(Context realContext) {
super(realContext, FILENAME_PREFIX);
+ mResolver = new MockContentResolverWithNotify(this);
mNotifManager = mock(NotificationManager.class);
}
- public void setResolver(ContentResolver resolver) {
- mResolver = resolver;
- }
-
/**
* Direct DownloadService to our test instance of DownloadProvider.
*/
@@ -156,12 +156,20 @@ public abstract class AbstractDownloadProviderFunctionalTest extends
System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
final Context realContext = getContext();
+
mTestContext = new TestContext(realContext);
- setupProviderAndResolver();
- mTestContext.setResolver(mResolver);
+ mResolver = (MockContentResolverWithNotify) mTestContext.getContentResolver();
+
+ final DownloadProvider provider = new DownloadProvider();
+ provider.mSystemFacade = mSystemFacade;
+ provider.attachInfo(mTestContext, null);
+
+ mResolver.addProvider(PROVIDER_AUTHORITY, provider);
+
setContext(mTestContext);
setupService();
getService().mSystemFacade = mSystemFacade;
+
mSystemFacade.setUp();
assertTrue(isDatabaseEmpty()); // ensure we're not messing with real data
mServer = new MockWebServer();
@@ -186,14 +194,6 @@ public abstract class AbstractDownloadProviderFunctionalTest extends
}
}
- void setupProviderAndResolver() {
- DownloadProvider provider = new DownloadProvider();
- provider.mSystemFacade = mSystemFacade;
- provider.attachInfo(mTestContext, null);
- mResolver = new MockContentResolverWithNotify();
- mResolver.addProvider(PROVIDER_AUTHORITY, provider);
- }
-
/**
* Remove any downloaded files and delete any lingering downloads.
*/
diff --git a/tests/src/com/android/providers/downloads/AbstractPublicApiTest.java b/tests/src/com/android/providers/downloads/AbstractPublicApiTest.java
index 348dbd1..2846c7a 100644
--- a/tests/src/com/android/providers/downloads/AbstractPublicApiTest.java
+++ b/tests/src/com/android/providers/downloads/AbstractPublicApiTest.java
@@ -28,6 +28,9 @@ import android.os.ParcelFileDescriptor;
import android.os.SystemClock;
import android.util.Log;
+import libcore.io.IoUtils;
+import libcore.io.Streams;
+
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
@@ -91,19 +94,23 @@ public abstract class AbstractPublicApiTest extends AbstractDownloadProviderFunc
}
}
- String getContents() throws Exception {
+ byte[] getRawContents() throws Exception {
ParcelFileDescriptor downloadedFile = mManager.openDownloadedFile(mId);
assertTrue("Invalid file descriptor: " + downloadedFile,
downloadedFile.getFileDescriptor().valid());
- final InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(
+ final InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(
downloadedFile);
try {
- return readStream(stream);
+ return Streams.readFully(is);
} finally {
- stream.close();
+ IoUtils.closeQuietly(is);
}
}
+ String getContents() throws Exception {
+ return new String(getRawContents());
+ }
+
void runUntilStatus(int status) throws TimeoutException {
final long startMillis = mSystemFacade.currentTimeMillis();
startService(null);
diff --git a/tests/src/com/android/providers/downloads/FakeSystemFacade.java b/tests/src/com/android/providers/downloads/FakeSystemFacade.java
index d54c122..5a15d39 100644
--- a/tests/src/com/android/providers/downloads/FakeSystemFacade.java
+++ b/tests/src/com/android/providers/downloads/FakeSystemFacade.java
@@ -64,12 +64,12 @@ public class FakeSystemFacade implements SystemFacade {
@Override
public Long getMaxBytesOverMobile() {
- return mMaxBytesOverMobile ;
+ return mMaxBytesOverMobile;
}
@Override
public Long getRecommendedMaxBytesOverMobile() {
- return mRecommendedMaxBytesOverMobile ;
+ return mRecommendedMaxBytesOverMobile;
}
@Override
diff --git a/tests/src/com/android/providers/downloads/HelpersTest.java b/tests/src/com/android/providers/downloads/HelpersTest.java
index 50f4c44..121b7cd 100644
--- a/tests/src/com/android/providers/downloads/HelpersTest.java
+++ b/tests/src/com/android/providers/downloads/HelpersTest.java
@@ -16,29 +16,73 @@
package com.android.providers.downloads;
+import android.net.Uri;
import android.provider.Downloads;
import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import libcore.io.IoUtils;
+
+import java.io.File;
/**
* This test exercises methods in the {@Helpers} utility class.
*/
-@LargeTest
+@SmallTest
public class HelpersTest extends AndroidTestCase {
- public HelpersTest() {
+ @Override
+ protected void tearDown() throws Exception {
+ IoUtils.deleteContents(getContext().getFilesDir());
+ IoUtils.deleteContents(getContext().getCacheDir());
+
+ super.tearDown();
+ }
+
+ public void testGenerateSaveFile() throws Exception {
+ final File expected = new File(getContext().getFilesDir(), "file.mp4");
+ final String actual = Helpers.generateSaveFile(getContext(),
+ "http://example.com/file.txt", null, null, null,
+ "video/mp4", Downloads.Impl.DESTINATION_CACHE_PARTITION);
+ assertEquals(expected.getAbsolutePath(), actual);
+ }
+
+ public void testGenerateSaveFileDupes() throws Exception {
+ final File expected1 = new File(getContext().getFilesDir(), "file.txt");
+ final String actual1 = Helpers.generateSaveFile(getContext(), "http://example.com/file.txt",
+ null, null, null, null, Downloads.Impl.DESTINATION_CACHE_PARTITION);
+
+ final File expected2 = new File(getContext().getFilesDir(), "file-1.txt");
+ final String actual2 = Helpers.generateSaveFile(getContext(), "http://example.com/file.txt",
+ null, null, null, null, Downloads.Impl.DESTINATION_CACHE_PARTITION);
+
+ assertEquals(expected1.getAbsolutePath(), actual1);
+ assertEquals(expected2.getAbsolutePath(), actual2);
}
- public void testGetFullPath() throws Exception {
- String hint = "file:///com.android.providers.downloads/test";
+ public void testGenerateSaveFileNoExtension() throws Exception {
+ final File expected = new File(getContext().getFilesDir(), "file.mp4");
+ final String actual = Helpers.generateSaveFile(getContext(),
+ "http://example.com/file", null, null, null,
+ "video/mp4", Downloads.Impl.DESTINATION_CACHE_PARTITION);
+ assertEquals(expected.getAbsolutePath(), actual);
+ }
+
+ public void testGenerateSaveFileHint() throws Exception {
+ final File expected = new File(getContext().getFilesDir(), "meow");
+ final String hint = Uri.fromFile(expected).toString();
- // Test that we never change requested filename.
- String fileName = Helpers.getFullPath(
- hint,
- "video/mp4", // MIME type corresponding to file extension .mp4
- Downloads.Impl.DESTINATION_FILE_URI,
- null);
- assertEquals(hint, fileName);
+ // Test that we never change requested filename.
+ final String actual = Helpers.generateSaveFile(getContext(), "url", hint,
+ "dispo", "locat", "video/mp4", Downloads.Impl.DESTINATION_FILE_URI);
+ assertEquals(expected.getAbsolutePath(), actual);
}
+ public void testGenerateSaveFileDisposition() throws Exception {
+ final File expected = new File(getContext().getFilesDir(), "real.mp4");
+ final String actual = Helpers.generateSaveFile(getContext(),
+ "http://example.com/file.txt", null, "attachment; filename=\"subdir/real.pdf\"",
+ null, "video/mp4", Downloads.Impl.DESTINATION_CACHE_PARTITION);
+ assertEquals(expected.getAbsolutePath(), actual);
+ }
}
diff --git a/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java b/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java
index bde9581..d7b389c 100644
--- a/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java
+++ b/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java
@@ -53,6 +53,8 @@ import com.google.mockwebserver.MockResponse;
import com.google.mockwebserver.RecordedRequest;
import com.google.mockwebserver.SocketPolicy;
+import libcore.io.IoUtils;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -83,9 +85,7 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
mTestDirectory = new File(Environment.getExternalStorageDirectory() + File.separator
+ "download_manager_functional_test");
if (mTestDirectory.exists()) {
- for (File file : mTestDirectory.listFiles()) {
- file.delete();
- }
+ IoUtils.deleteContents(mTestDirectory);
} else {
mTestDirectory.mkdir();
}
@@ -94,9 +94,7 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
@Override
protected void tearDown() throws Exception {
if (mTestDirectory != null && mTestDirectory.exists()) {
- for (File file : mTestDirectory.listFiles()) {
- file.delete();
- }
+ IoUtils.deleteContents(mTestDirectory);
mTestDirectory.delete();
}
super.tearDown();
@@ -223,7 +221,7 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
boolean isFirstResponse = (start == 0);
int status = isFirstResponse ? HTTP_OK : HTTP_PARTIAL;
MockResponse response = buildResponse(status, FILE_CONTENT.substring(start, end))
- .setHeader("Content-length", totalLength)
+ .setHeader("Content-length", isFirstResponse ? totalLength : (end - start))
.setHeader("Etag", ETAG);
if (!isFirstResponse) {
response.setHeader(
@@ -475,7 +473,7 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
// 2. Try resuming A, but fail ETag check
mSystemFacade.incrementTimeMillis(RETRY_DELAY_MILLIS);
download.runUntilStatus(STATUS_FAILED);
- assertEquals(HTTP_PRECON_FAILED, download.getReason());
+ assertEquals(DownloadManager.ERROR_CANNOT_RESUME, download.getReason());
req = takeRequest();
assertEquals("bytes=2-", getHeaderValue(req, "Range"));
assertEquals(A, getHeaderValue(req, "If-Match"));
diff --git a/tests/src/com/android/providers/downloads/StorageTest.java b/tests/src/com/android/providers/downloads/StorageTest.java
new file mode 100644
index 0000000..8ba3cbc
--- /dev/null
+++ b/tests/src/com/android/providers/downloads/StorageTest.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.providers.downloads;
+
+import static android.app.DownloadManager.COLUMN_REASON;
+import static android.app.DownloadManager.ERROR_INSUFFICIENT_SPACE;
+import static android.app.DownloadManager.STATUS_FAILED;
+import static android.app.DownloadManager.STATUS_SUCCESSFUL;
+import static android.provider.Downloads.Impl.DESTINATION_CACHE_PARTITION;
+import static android.provider.Downloads.Impl.DESTINATION_SYSTEMCACHE_PARTITION;
+
+import android.app.DownloadManager;
+import android.content.pm.PackageManager;
+import android.os.Environment;
+import android.os.StatFs;
+import android.provider.Downloads.Impl;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.StructStatVfs;
+import android.test.MoreAsserts;
+import android.util.Log;
+
+import com.android.providers.downloads.StorageUtils.ObserverLatch;
+import com.google.mockwebserver.MockResponse;
+import com.google.mockwebserver.SocketPolicy;
+
+import libcore.io.ForwardingOs;
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+public class StorageTest extends AbstractPublicApiTest {
+ private static final String TAG = "StorageTest";
+
+ private static final int DOWNLOAD_SIZE = 512 * 1024;
+ private static final byte[] DOWNLOAD_BODY;
+
+ static {
+ DOWNLOAD_BODY = new byte[DOWNLOAD_SIZE];
+ for (int i = 0; i < DOWNLOAD_SIZE; i++) {
+ DOWNLOAD_BODY[i] = (byte) (i % 32);
+ }
+ }
+
+ private libcore.io.Os mOriginal;
+ private long mStealBytes;
+
+ public StorageTest() {
+ super(new FakeSystemFacade());
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ StorageUtils.sForceFullEviction = true;
+ mStealBytes = 0;
+
+ mOriginal = libcore.io.Libcore.os;
+ libcore.io.Libcore.os = new ForwardingOs(mOriginal) {
+ @Override
+ public StructStatVfs statvfs(String path) throws ErrnoException {
+ return stealBytes(os.statvfs(path));
+ }
+
+ @Override
+ public StructStatVfs fstatvfs(FileDescriptor fd) throws ErrnoException {
+ return stealBytes(os.fstatvfs(fd));
+ }
+
+ private StructStatVfs stealBytes(StructStatVfs s) {
+ final long stealBlocks = (mStealBytes + (s.f_bsize - 1)) / s.f_bsize;
+ final long f_bavail = s.f_bavail - stealBlocks;
+ return new StructStatVfs(s.f_bsize, s.f_frsize, s.f_blocks, s.f_bfree, f_bavail,
+ s.f_files, s.f_ffree, s.f_favail, s.f_fsid, s.f_flag, s.f_namemax);
+ }
+ };
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+
+ StorageUtils.sForceFullEviction = false;
+ mStealBytes = 0;
+
+ if (mOriginal != null) {
+ libcore.io.Libcore.os = mOriginal;
+ }
+ }
+
+ private enum CacheStatus { CLEAN, DIRTY }
+ private enum BodyType { COMPLETE, CHUNKED }
+
+ public void testDataDirtyComplete() throws Exception {
+ prepareAndRunDownload(DESTINATION_CACHE_PARTITION,
+ CacheStatus.DIRTY, BodyType.COMPLETE,
+ STATUS_SUCCESSFUL, -1);
+ }
+
+ public void testDataDirtyChunked() throws Exception {
+ prepareAndRunDownload(DESTINATION_CACHE_PARTITION,
+ CacheStatus.DIRTY, BodyType.CHUNKED,
+ STATUS_SUCCESSFUL, -1);
+ }
+
+ public void testDataCleanComplete() throws Exception {
+ prepareAndRunDownload(DESTINATION_CACHE_PARTITION,
+ CacheStatus.CLEAN, BodyType.COMPLETE,
+ STATUS_FAILED, ERROR_INSUFFICIENT_SPACE);
+ }
+
+ public void testDataCleanChunked() throws Exception {
+ prepareAndRunDownload(DESTINATION_CACHE_PARTITION,
+ CacheStatus.CLEAN, BodyType.CHUNKED,
+ STATUS_FAILED, ERROR_INSUFFICIENT_SPACE);
+ }
+
+ public void testCacheDirtyComplete() throws Exception {
+ prepareAndRunDownload(DESTINATION_SYSTEMCACHE_PARTITION,
+ CacheStatus.DIRTY, BodyType.COMPLETE,
+ STATUS_SUCCESSFUL, -1);
+ }
+
+ public void testCacheDirtyChunked() throws Exception {
+ prepareAndRunDownload(DESTINATION_SYSTEMCACHE_PARTITION,
+ CacheStatus.DIRTY, BodyType.CHUNKED,
+ STATUS_SUCCESSFUL, -1);
+ }
+
+ public void testCacheCleanComplete() throws Exception {
+ prepareAndRunDownload(DESTINATION_SYSTEMCACHE_PARTITION,
+ CacheStatus.CLEAN, BodyType.COMPLETE,
+ STATUS_FAILED, ERROR_INSUFFICIENT_SPACE);
+ }
+
+ public void testCacheCleanChunked() throws Exception {
+ prepareAndRunDownload(DESTINATION_SYSTEMCACHE_PARTITION,
+ CacheStatus.CLEAN, BodyType.CHUNKED,
+ STATUS_FAILED, ERROR_INSUFFICIENT_SPACE);
+ }
+
+ private void prepareAndRunDownload(
+ int dest, CacheStatus cache, BodyType body, int expectedStatus, int expectedReason)
+ throws Exception {
+
+ // Ensure that we've purged everything possible for destination
+ final File dirtyDir;
+ if (dest == DESTINATION_CACHE_PARTITION) {
+ final PackageManager pm = getContext().getPackageManager();
+ final ObserverLatch observer = new ObserverLatch();
+ pm.freeStorageAndNotify(Long.MAX_VALUE, observer);
+
+ try {
+ if (!observer.latch.await(30, TimeUnit.SECONDS)) {
+ throw new IOException("Timeout while freeing disk space");
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+
+ dirtyDir = getContext().getCacheDir();
+
+ } else if (dest == DESTINATION_SYSTEMCACHE_PARTITION) {
+ IoUtils.deleteContents(Environment.getDownloadCacheDirectory());
+ dirtyDir = Environment.getDownloadCacheDirectory();
+
+ } else {
+ throw new IllegalArgumentException("Unknown destination");
+ }
+
+ // Allocate a cache file, if requested, making it large enough and old
+ // enough to clear.
+ final File dirtyFile;
+ if (cache == CacheStatus.DIRTY) {
+ dirtyFile = new File(dirtyDir, "cache_file.bin");
+ assertTrue(dirtyFile.createNewFile());
+ final FileOutputStream os = new FileOutputStream(dirtyFile);
+ final int dirtySize = (DOWNLOAD_SIZE * 3) / 2;
+ Os.posix_fallocate(os.getFD(), 0, dirtySize);
+ IoUtils.closeQuietly(os);
+
+ dirtyFile.setLastModified(
+ System.currentTimeMillis() - (StorageUtils.MIN_DELETE_AGE * 2));
+ } else {
+ dirtyFile = null;
+ }
+
+ // At this point, hide all other disk space to make the download fail;
+ // if we have a dirty cache file it can be cleared to let us proceed.
+ final long targetFree = StorageUtils.RESERVED_BYTES + (DOWNLOAD_SIZE / 2);
+
+ final StatFs stat = new StatFs(dirtyDir.getAbsolutePath());
+ Log.d(TAG, "Available bytes (before steal): " + stat.getAvailableBytes());
+ mStealBytes = stat.getAvailableBytes() - targetFree;
+
+ stat.restat(dirtyDir.getAbsolutePath());
+ Log.d(TAG, "Available bytes (after steal): " + stat.getAvailableBytes());
+
+ final MockResponse resp = new MockResponse().setResponseCode(200)
+ .setHeader("Content-type", "text/plain")
+ .setSocketPolicy(SocketPolicy.DISCONNECT_AT_END);
+ if (body == BodyType.CHUNKED) {
+ resp.setChunkedBody(DOWNLOAD_BODY, 1021);
+ } else {
+ resp.setBody(DOWNLOAD_BODY);
+ }
+ enqueueResponse(resp);
+
+ final DownloadManager.Request req = getRequest();
+ if (dest == Impl.DESTINATION_SYSTEMCACHE_PARTITION) {
+ req.setDestinationToSystemCache();
+ }
+ final Download download = enqueueRequest(req);
+ download.runUntilStatus(expectedStatus);
+
+ if (expectedStatus == STATUS_SUCCESSFUL) {
+ MoreAsserts.assertEquals(DOWNLOAD_BODY, download.getRawContents());
+ }
+
+ if (expectedReason != -1) {
+ assertEquals(expectedReason, download.getLongField(COLUMN_REASON));
+ }
+
+ if (dirtyFile != null) {
+ assertFalse(dirtyFile.exists());
+ }
+ }
+}
diff --git a/tests/src/com/android/providers/downloads/ThreadingTest.java b/tests/src/com/android/providers/downloads/ThreadingTest.java
index 920f703..1e50144 100644
--- a/tests/src/com/android/providers/downloads/ThreadingTest.java
+++ b/tests/src/com/android/providers/downloads/ThreadingTest.java
@@ -27,6 +27,7 @@ import com.google.android.collect.Sets;
import com.google.mockwebserver.MockResponse;
import com.google.mockwebserver.SocketPolicy;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -60,9 +61,10 @@ public class ThreadingTest extends AbstractPublicApiTest {
public void testFilenameRace() throws Exception {
final List<Pair<Download, String>> downloads = Lists.newArrayList();
+ final HashSet<String> expectedBodies = Sets.newHashSet();
// Request dozen files at once with same name
- for (int i = 0; i < 12; i++) {
+ for (int i = 0; i < 32; i++) {
final String body = "DOWNLOAD " + i + " CONTENTS";
enqueueResponse(new MockResponse().setResponseCode(HTTP_OK).setBody(body)
.setHeader("Content-type", "text/plain")
@@ -70,6 +72,7 @@ public class ThreadingTest extends AbstractPublicApiTest {
final Download d = enqueueRequest(getRequest());
downloads.add(Pair.create(d, body));
+ expectedBodies.add(body);
}
// Kick off downloads in parallel
@@ -82,6 +85,7 @@ public class ThreadingTest extends AbstractPublicApiTest {
// Ensure that contents are clean and filenames unique
final Set<String> seenFiles = Sets.newHashSet();
+ final HashSet<String> actualBodies = Sets.newHashSet();
for (Pair<Download, String> d : downloads) {
final String file = d.first.getStringField(DownloadManager.COLUMN_LOCAL_FILENAME);
@@ -91,7 +95,10 @@ public class ThreadingTest extends AbstractPublicApiTest {
final String expected = d.second;
final String actual = d.first.getContents();
- assertEquals(expected, actual);
+
+ actualBodies.add(actual);
}
+
+ assertEquals(expectedBodies, actualBodies);
}
}
diff --git a/ui/res/values-ar/strings.xml b/ui/res/values-ar/strings.xml
index f39fdad..99638b3 100644
--- a/ui/res/values-ar/strings.xml
+++ b/ui/res/values-ar/strings.xml
@@ -20,7 +20,7 @@
<string name="download_title_sorted_by_date" msgid="5898014492155434221">"عمليات التنزيل - مصنفة بحسب التاريخ"</string>
<string name="download_title_sorted_by_size" msgid="1417193166677094813">"عمليات التنزيل - مصنفة بحسب الحجم"</string>
<string name="no_downloads" msgid="1029667411186146836">"ليس هناك أي تنزيلات"</string>
- <string name="missing_title" msgid="830115697868833773">"&lt;غير معروف&gt;"</string>
+ <string name="missing_title" msgid="830115697868833773">"‏&lt;غير معروف&gt;"</string>
<string name="button_sort_by_size" msgid="7331549713691146251">"التصنيف بحسب الحجم"</string>
<string name="button_sort_by_date" msgid="8800842892684101528">"التصنيف بحسب التاريخ"</string>
<string name="download_queued" msgid="104973307780629904">"في الانتظار"</string>
diff --git a/ui/res/values-az-rAZ/strings.xml b/ui/res/values-az-rAZ/strings.xml
new file mode 100644
index 0000000..5ee50df
--- /dev/null
+++ b/ui/res/values-az-rAZ/strings.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3070921713463294774">"Endirmələr"</string>
+ <string name="download_title_sorted_by_date" msgid="5898014492155434221">"Endirilənlər - Tarixə görə sıralanıb"</string>
+ <string name="download_title_sorted_by_size" msgid="1417193166677094813">"Endirilənlər - Ölçüsünə görə sıralanıb"</string>
+ <string name="no_downloads" msgid="1029667411186146836">"Endirmə yoxdur."</string>
+ <string name="missing_title" msgid="830115697868833773">"&lt;Bilinməyən&gt;"</string>
+ <string name="button_sort_by_size" msgid="7331549713691146251">"Ölçüsünə görə sırala"</string>
+ <string name="button_sort_by_date" msgid="8800842892684101528">"Tarixə görə sırala"</string>
+ <string name="download_queued" msgid="104973307780629904">"Növbəyə salınıb"</string>
+ <string name="download_running" msgid="4656462962155580641">"Davam edir"</string>
+ <string name="download_success" msgid="7006048006543495236">"Tamamlandı"</string>
+ <string name="download_error" msgid="8081329546008568251">"Nəticəsiz"</string>
+ <string name="dialog_title_not_available" msgid="5746317632356158515">"Endirilmədi"</string>
+ <string name="dialog_failed_body" msgid="587545111677064427">"Faylı yenidən endirmək istəyirsiniz yoxsa sıradan silmək istəyirsiniz?"</string>
+ <string name="dialog_title_queued_body" msgid="6760681913815015219">"Növbədəki fayl"</string>
+ <string name="dialog_queued_body" msgid="708552801635572720">"Bu fayl gələcək endirmə üçün növbəyə salındı, buna görə hələ mövcud deyil."</string>
+ <string name="dialog_file_missing_body" msgid="3223012612774276284">"Endirilmiş fayl tapılmır."</string>
+ <string name="dialog_insufficient_space_on_external" msgid="8692452156251449195">"Endirmə tamamlanmadı. Xarici yaddaşda kifayət qədər yer yoxdur"</string>
+ <string name="dialog_insufficient_space_on_cache" msgid="6313630206163908994">"Endirmə tamamlanmadı. Daxili endirmə yaddaşında kifayət qədər yer yoxdur."</string>
+ <string name="dialog_cannot_resume" msgid="8664509751358983543">"Endirmə kəsildi və bərpa edilə bilməz."</string>
+ <string name="dialog_file_already_exists" msgid="8308563940663449590">"Endirilmir. Hədəf fayl artıq mövcuddur."</string>
+ <string name="dialog_media_not_found" msgid="4468088418758018765">"Endirilmədi. Xarici media mövcud deyil."</string>
+ <string name="download_no_application_title" msgid="7024782176657362251">"Fayl açılmır"</string>
+ <string name="remove_download" msgid="6372920256257247857">"Yığışdır"</string>
+ <string name="delete_download" msgid="76629022653866471">"Sil"</string>
+ <string name="keep_queued_download" msgid="5144882786014818569">"Saxla"</string>
+ <string name="cancel_running_download" msgid="5232704030969221112">"Ləğv et"</string>
+ <string name="retry_download" msgid="7617100787922717912">"Yeniden yoxla"</string>
+ <string name="deselect_all" msgid="6348198946254776764">"Hamısını qaldır"</string>
+ <string name="select_all" msgid="634074918366265804">"Hamısını seç"</string>
+ <string name="selected_count" msgid="2101564570019753277">"<xliff:g id="TOTAL">%2$d</xliff:g> içindən seçilmiş <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+ <string name="download_share_dialog" msgid="3355867339806448955">"Vasitəsilə paylaş"</string>
+</resources>
diff --git a/ui/res/values-az/strings.xml b/ui/res/values-az/strings.xml
new file mode 100644
index 0000000..5ee50df
--- /dev/null
+++ b/ui/res/values-az/strings.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3070921713463294774">"Endirmələr"</string>
+ <string name="download_title_sorted_by_date" msgid="5898014492155434221">"Endirilənlər - Tarixə görə sıralanıb"</string>
+ <string name="download_title_sorted_by_size" msgid="1417193166677094813">"Endirilənlər - Ölçüsünə görə sıralanıb"</string>
+ <string name="no_downloads" msgid="1029667411186146836">"Endirmə yoxdur."</string>
+ <string name="missing_title" msgid="830115697868833773">"&lt;Bilinməyən&gt;"</string>
+ <string name="button_sort_by_size" msgid="7331549713691146251">"Ölçüsünə görə sırala"</string>
+ <string name="button_sort_by_date" msgid="8800842892684101528">"Tarixə görə sırala"</string>
+ <string name="download_queued" msgid="104973307780629904">"Növbəyə salınıb"</string>
+ <string name="download_running" msgid="4656462962155580641">"Davam edir"</string>
+ <string name="download_success" msgid="7006048006543495236">"Tamamlandı"</string>
+ <string name="download_error" msgid="8081329546008568251">"Nəticəsiz"</string>
+ <string name="dialog_title_not_available" msgid="5746317632356158515">"Endirilmədi"</string>
+ <string name="dialog_failed_body" msgid="587545111677064427">"Faylı yenidən endirmək istəyirsiniz yoxsa sıradan silmək istəyirsiniz?"</string>
+ <string name="dialog_title_queued_body" msgid="6760681913815015219">"Növbədəki fayl"</string>
+ <string name="dialog_queued_body" msgid="708552801635572720">"Bu fayl gələcək endirmə üçün növbəyə salındı, buna görə hələ mövcud deyil."</string>
+ <string name="dialog_file_missing_body" msgid="3223012612774276284">"Endirilmiş fayl tapılmır."</string>
+ <string name="dialog_insufficient_space_on_external" msgid="8692452156251449195">"Endirmə tamamlanmadı. Xarici yaddaşda kifayət qədər yer yoxdur"</string>
+ <string name="dialog_insufficient_space_on_cache" msgid="6313630206163908994">"Endirmə tamamlanmadı. Daxili endirmə yaddaşında kifayət qədər yer yoxdur."</string>
+ <string name="dialog_cannot_resume" msgid="8664509751358983543">"Endirmə kəsildi və bərpa edilə bilməz."</string>
+ <string name="dialog_file_already_exists" msgid="8308563940663449590">"Endirilmir. Hədəf fayl artıq mövcuddur."</string>
+ <string name="dialog_media_not_found" msgid="4468088418758018765">"Endirilmədi. Xarici media mövcud deyil."</string>
+ <string name="download_no_application_title" msgid="7024782176657362251">"Fayl açılmır"</string>
+ <string name="remove_download" msgid="6372920256257247857">"Yığışdır"</string>
+ <string name="delete_download" msgid="76629022653866471">"Sil"</string>
+ <string name="keep_queued_download" msgid="5144882786014818569">"Saxla"</string>
+ <string name="cancel_running_download" msgid="5232704030969221112">"Ləğv et"</string>
+ <string name="retry_download" msgid="7617100787922717912">"Yeniden yoxla"</string>
+ <string name="deselect_all" msgid="6348198946254776764">"Hamısını qaldır"</string>
+ <string name="select_all" msgid="634074918366265804">"Hamısını seç"</string>
+ <string name="selected_count" msgid="2101564570019753277">"<xliff:g id="TOTAL">%2$d</xliff:g> içindən seçilmiş <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+ <string name="download_share_dialog" msgid="3355867339806448955">"Vasitəsilə paylaş"</string>
+</resources>
diff --git a/ui/res/values-be/strings.xml b/ui/res/values-be/strings.xml
deleted file mode 100644
index 6d0ca93..0000000
--- a/ui/res/values-be/strings.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="3070921713463294774">"Спампоўкі"</string>
- <string name="download_title_sorted_by_date" msgid="5898014492155434221">"Запампаванае - Сартаванне паводле даты"</string>
- <string name="download_title_sorted_by_size" msgid="1417193166677094813">"Запампаванае - Сартаванне паводле памеру"</string>
- <string name="no_downloads" msgid="1029667411186146836">"Няма спамповак."</string>
- <string name="missing_title" msgid="830115697868833773">"Невядомы"</string>
- <string name="button_sort_by_size" msgid="7331549713691146251">"Сартаваць паводле памеру"</string>
- <string name="button_sort_by_date" msgid="8800842892684101528">"Сартаваць паводле даты"</string>
- <string name="download_queued" msgid="104973307780629904">"У чарзе"</string>
- <string name="download_running" msgid="4656462962155580641">"Выконваецца"</string>
- <string name="download_success" msgid="7006048006543495236">"Гатова"</string>
- <string name="download_error" msgid="8081329546008568251">"Няўдала"</string>
- <string name="dialog_title_not_available" msgid="5746317632356158515">"Не атрымалася спампаваць"</string>
- <string name="dialog_failed_body" msgid="587545111677064427">"Жадаеце паўтарыць спампоўванне файла пазней або выдаліць яго з чаргі?"</string>
- <string name="dialog_title_queued_body" msgid="6760681913815015219">"Файл у чарзе"</string>
- <string name="dialog_queued_body" msgid="708552801635572720">"Гэты файл знаходзіцца ў чарзе на спампоўку і пакуль недаступны."</string>
- <string name="dialog_file_missing_body" msgid="3223012612774276284">"Немагчыма знайсці спампаваны файл."</string>
- <string name="dialog_insufficient_space_on_external" msgid="8692452156251449195">"Немагчыма завершыць спампоўку. Не хапае месца на знешнім назапашвальнiку."</string>
- <string name="dialog_insufficient_space_on_cache" msgid="6313630206163908994">"Немагчыма скончыць спампоўку. Не хапае месца ва ўнутраным сховішчы."</string>
- <string name="dialog_cannot_resume" msgid="8664509751358983543">"Спампоўка перапынена і не можа быць адноўлена."</string>
- <string name="dialog_file_already_exists" msgid="8308563940663449590">"Немагчыма спампаваць. Мэтавы файл ужо існуе."</string>
- <string name="dialog_media_not_found" msgid="4468088418758018765">"Немагчыма спампаваць. Не падключаны знешнi назапашвальнiк."</string>
- <string name="download_no_application_title" msgid="7024782176657362251">"Немагчыма адкрыць файл"</string>
- <string name="remove_download" msgid="6372920256257247857">"Выдаліць"</string>
- <string name="delete_download" msgid="76629022653866471">"Выдаліць"</string>
- <string name="keep_queued_download" msgid="5144882786014818569">"Пакінуць"</string>
- <string name="cancel_running_download" msgid="5232704030969221112">"Адмена"</string>
- <string name="retry_download" msgid="7617100787922717912">"Паўтарыць"</string>
- <string name="deselect_all" msgid="6348198946254776764">"Адмяніць выбар усяго"</string>
- <string name="select_all" msgid="634074918366265804">"Выбраць усё"</string>
- <string name="selected_count" msgid="2101564570019753277">"Выбрана <xliff:g id="NUMBER">%1$d</xliff:g> з <xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="download_share_dialog" msgid="3355867339806448955">"Апублікаваць у"</string>
-</resources>
diff --git a/ui/res/values-ca/strings.xml b/ui/res/values-ca/strings.xml
index 072ca53..f9fc286 100644
--- a/ui/res/values-ca/strings.xml
+++ b/ui/res/values-ca/strings.xml
@@ -35,7 +35,7 @@
<string name="dialog_insufficient_space_on_external" msgid="8692452156251449195">"No es pot finalitzar la baixada. No hi ha prou espai a l\'emmagatzematge extern."</string>
<string name="dialog_insufficient_space_on_cache" msgid="6313630206163908994">"No es pot finalitzar la baixada. No hi ha prou espai a l\'emmagatzematge intern."</string>
<string name="dialog_cannot_resume" msgid="8664509751358983543">"S\'ha interromput la baixada i no es pot reprendre."</string>
- <string name="dialog_file_already_exists" msgid="8308563940663449590">"No es pot baixar. El fitxer de destí ja existeix."</string>
+ <string name="dialog_file_already_exists" msgid="8308563940663449590">"No es pot baixar. El fitxer de destinació ja existeix."</string>
<string name="dialog_media_not_found" msgid="4468088418758018765">"No es pot baixar. El mitjà extern no està disponible."</string>
<string name="download_no_application_title" msgid="7024782176657362251">"No es pot obrir el fitxer"</string>
<string name="remove_download" msgid="6372920256257247857">"Elimina"</string>
diff --git a/ui/res/values-en-rIN/strings.xml b/ui/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..15cab92
--- /dev/null
+++ b/ui/res/values-en-rIN/strings.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3070921713463294774">"Downloads"</string>
+ <string name="download_title_sorted_by_date" msgid="5898014492155434221">"Downloads - Sorted by date"</string>
+ <string name="download_title_sorted_by_size" msgid="1417193166677094813">"Downloads - Sorted by size"</string>
+ <string name="no_downloads" msgid="1029667411186146836">"No downloads."</string>
+ <string name="missing_title" msgid="830115697868833773">"&lt;Unknown&gt;"</string>
+ <string name="button_sort_by_size" msgid="7331549713691146251">"Sort by size"</string>
+ <string name="button_sort_by_date" msgid="8800842892684101528">"Sort by date"</string>
+ <string name="download_queued" msgid="104973307780629904">"Queued"</string>
+ <string name="download_running" msgid="4656462962155580641">"In progress"</string>
+ <string name="download_success" msgid="7006048006543495236">"Complete"</string>
+ <string name="download_error" msgid="8081329546008568251">"Unsuccessful"</string>
+ <string name="dialog_title_not_available" msgid="5746317632356158515">"Couldn\'t download"</string>
+ <string name="dialog_failed_body" msgid="587545111677064427">"Do you want to retry downloading the file later or delete it from the queue?"</string>
+ <string name="dialog_title_queued_body" msgid="6760681913815015219">"File in queue"</string>
+ <string name="dialog_queued_body" msgid="708552801635572720">"This file is queued for future download, so isn\'t available yet."</string>
+ <string name="dialog_file_missing_body" msgid="3223012612774276284">"Can\'t find the downloaded file."</string>
+ <string name="dialog_insufficient_space_on_external" msgid="8692452156251449195">"Can\'t finish download. There isn\'t enough space on external storage."</string>
+ <string name="dialog_insufficient_space_on_cache" msgid="6313630206163908994">"Cannot finish download. There is not enough space on internal download storage."</string>
+ <string name="dialog_cannot_resume" msgid="8664509751358983543">"Download was interrupted and can\'t be resumed."</string>
+ <string name="dialog_file_already_exists" msgid="8308563940663449590">"Can\'t download. The destination file already exists."</string>
+ <string name="dialog_media_not_found" msgid="4468088418758018765">"Cannot download. The external media are not available."</string>
+ <string name="download_no_application_title" msgid="7024782176657362251">"Can\'t open file"</string>
+ <string name="remove_download" msgid="6372920256257247857">"Remove"</string>
+ <string name="delete_download" msgid="76629022653866471">"Delete"</string>
+ <string name="keep_queued_download" msgid="5144882786014818569">"Keep"</string>
+ <string name="cancel_running_download" msgid="5232704030969221112">"Cancel"</string>
+ <string name="retry_download" msgid="7617100787922717912">"Retry"</string>
+ <string name="deselect_all" msgid="6348198946254776764">"Deselect all"</string>
+ <string name="select_all" msgid="634074918366265804">"Select all"</string>
+ <string name="selected_count" msgid="2101564570019753277">"Selected <xliff:g id="NUMBER">%1$d</xliff:g> out of <xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <string name="download_share_dialog" msgid="3355867339806448955">"Share via"</string>
+</resources>
diff --git a/ui/res/values-et/strings.xml b/ui/res/values-et-rEE/strings.xml
index e2602e5..e2602e5 100644
--- a/ui/res/values-et/strings.xml
+++ b/ui/res/values-et-rEE/strings.xml
diff --git a/ui/res/values-fa/strings.xml b/ui/res/values-fa/strings.xml
index 8650ce3..eeb855e 100644
--- a/ui/res/values-fa/strings.xml
+++ b/ui/res/values-fa/strings.xml
@@ -20,7 +20,7 @@
<string name="download_title_sorted_by_date" msgid="5898014492155434221">"دانلودها - مرتب شده بر اساس تاریخ"</string>
<string name="download_title_sorted_by_size" msgid="1417193166677094813">"دانلودها - مرتب شده بر اساس اندازه"</string>
<string name="no_downloads" msgid="1029667411186146836">"خیر دانلودها."</string>
- <string name="missing_title" msgid="830115697868833773">"&lt;ناشناس&gt;"</string>
+ <string name="missing_title" msgid="830115697868833773">"‏&lt;ناشناس&gt;"</string>
<string name="button_sort_by_size" msgid="7331549713691146251">"بر اساس اندازه مرتب شود"</string>
<string name="button_sort_by_date" msgid="8800842892684101528">"ترتیب براساس تاریخ"</string>
<string name="download_queued" msgid="104973307780629904">"در صف"</string>
diff --git a/ui/res/values-fr-rCA/strings.xml b/ui/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..69dacc9
--- /dev/null
+++ b/ui/res/values-fr-rCA/strings.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3070921713463294774">"Téléchargements"</string>
+ <string name="download_title_sorted_by_date" msgid="5898014492155434221">"Téléchargements : triés par date"</string>
+ <string name="download_title_sorted_by_size" msgid="1417193166677094813">"Téléchargements : triés par taille"</string>
+ <string name="no_downloads" msgid="1029667411186146836">"Aucun téléchargement"</string>
+ <string name="missing_title" msgid="830115697868833773">"&lt;Inconnu&gt;"</string>
+ <string name="button_sort_by_size" msgid="7331549713691146251">"Trier par taille"</string>
+ <string name="button_sort_by_date" msgid="8800842892684101528">"Trier par date"</string>
+ <string name="download_queued" msgid="104973307780629904">"Placée en file d\'attente"</string>
+ <string name="download_running" msgid="4656462962155580641">"En cours de traitement"</string>
+ <string name="download_success" msgid="7006048006543495236">"Terminé"</string>
+ <string name="download_error" msgid="8081329546008568251">"Échec"</string>
+ <string name="dialog_title_not_available" msgid="5746317632356158515">"Téléchargement impossible"</string>
+ <string name="dialog_failed_body" msgid="587545111677064427">"Souhaitez-vous réessayer de télécharger le fichier plus tard ou préférez-vous le supprimer de la file d\'attente?"</string>
+ <string name="dialog_title_queued_body" msgid="6760681913815015219">"Fichier en attente"</string>
+ <string name="dialog_queued_body" msgid="708552801635572720">"Ce fichier est en attente de téléchargement et n\'est donc pas encore disponible."</string>
+ <string name="dialog_file_missing_body" msgid="3223012612774276284">"Impossible de trouver le fichier téléchargé."</string>
+ <string name="dialog_insufficient_space_on_external" msgid="8692452156251449195">"Impossible de terminer le téléchargement. L\'espace disponible sur la mémoire de stockage externe est insuffisant."</string>
+ <string name="dialog_insufficient_space_on_cache" msgid="6313630206163908994">"Impossible de terminer le téléchargement. L\'espace disponible sur la mémoire de stockage interne est insuffisant."</string>
+ <string name="dialog_cannot_resume" msgid="8664509751358983543">"Le téléchargement a été interrompu et ne peut pas être repris."</string>
+ <string name="dialog_file_already_exists" msgid="8308563940663449590">"Impossible de procéder au téléchargement. Le fichier de destination existe déjà."</string>
+ <string name="dialog_media_not_found" msgid="4468088418758018765">"Impossible de procéder au téléchargement. Le support externe n\'est pas disponible."</string>
+ <string name="download_no_application_title" msgid="7024782176657362251">"Impossible d\'ouvrir le fichier."</string>
+ <string name="remove_download" msgid="6372920256257247857">"Supprimer"</string>
+ <string name="delete_download" msgid="76629022653866471">"Supprimer"</string>
+ <string name="keep_queued_download" msgid="5144882786014818569">"Conserver"</string>
+ <string name="cancel_running_download" msgid="5232704030969221112">"Annuler"</string>
+ <string name="retry_download" msgid="7617100787922717912">"Réessayer"</string>
+ <string name="deselect_all" msgid="6348198946254776764">"Tout désélectionner"</string>
+ <string name="select_all" msgid="634074918366265804">"Tout sélectionner"</string>
+ <string name="selected_count" msgid="2101564570019753277">"<xliff:g id="NUMBER">%1$d</xliff:g> téléchargements sélectionnés sur <xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <string name="download_share_dialog" msgid="3355867339806448955">"Partager via"</string>
+</resources>
diff --git a/ui/res/values-hy-rAM/strings.xml b/ui/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000..0b494a6
--- /dev/null
+++ b/ui/res/values-hy-rAM/strings.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3070921713463294774">"Ներբեռնումներ"</string>
+ <string name="download_title_sorted_by_date" msgid="5898014492155434221">"Ներբեռնումներ՝ դասավորված ըստ ամսաթվի"</string>
+ <string name="download_title_sorted_by_size" msgid="1417193166677094813">"Ներբեռնումներ՝ դասավորված ըստ չափի"</string>
+ <string name="no_downloads" msgid="1029667411186146836">"Ներբեռնումներ չկան:"</string>
+ <string name="missing_title" msgid="830115697868833773">"&lt;Անհայտ&gt;"</string>
+ <string name="button_sort_by_size" msgid="7331549713691146251">"Դասավորել ըստ չափի"</string>
+ <string name="button_sort_by_date" msgid="8800842892684101528">"Դասավորել ըստ ամսաթվի"</string>
+ <string name="download_queued" msgid="104973307780629904">"Հերթագրված է"</string>
+ <string name="download_running" msgid="4656462962155580641">"Ընթացքի մեջ է"</string>
+ <string name="download_success" msgid="7006048006543495236">"Ավարտված է"</string>
+ <string name="download_error" msgid="8081329546008568251">"Ձախողվել է"</string>
+ <string name="dialog_title_not_available" msgid="5746317632356158515">"Հնարավոր չէ ներբեռնել"</string>
+ <string name="dialog_failed_body" msgid="587545111677064427">"Ցանկանու՞մ եք կրկնել ֆայլի ներբեռնումը ավելի ուշ, թե՞ ջնջել այն հերթացանկից:"</string>
+ <string name="dialog_title_queued_body" msgid="6760681913815015219">"Ֆայլը հերթացանկում է"</string>
+ <string name="dialog_queued_body" msgid="708552801635572720">"Այս ֆայլը հերթագրված է հետագայում ներբեռնման համար, այնպես որ` դեռ հասանելի չէ:"</string>
+ <string name="dialog_file_missing_body" msgid="3223012612774276284">"Հնարավոր չէ գնտել ներբեռնված ֆայլը:"</string>
+ <string name="dialog_insufficient_space_on_external" msgid="8692452156251449195">"Հնարավոր չէ ավարտել ներբեռնումը: Չկա բավարար տարածություն արտաքին պահուստում:"</string>
+ <string name="dialog_insufficient_space_on_cache" msgid="6313630206163908994">"Հնարավոր չէ ավարտել ներբեռնումը: Չկա բավարար տարածություն ներքին ներբեռնման պահուստում:"</string>
+ <string name="dialog_cannot_resume" msgid="8664509751358983543">"Ներբեռնումը խզվել է, և այն հնարավոր չէ վերականգնել:"</string>
+ <string name="dialog_file_already_exists" msgid="8308563940663449590">"Հնարավոր չէ ներբեռնել: Նպատակային ֆայլն արդեն գոյություն ունի:"</string>
+ <string name="dialog_media_not_found" msgid="4468088418758018765">"Հնարավոր չէ ներբեռնել: Արտաքին կրիչը հասանելի չէ:"</string>
+ <string name="download_no_application_title" msgid="7024782176657362251">"Հնարավոր չէ բացել ֆայլը"</string>
+ <string name="remove_download" msgid="6372920256257247857">"Հեռացնել"</string>
+ <string name="delete_download" msgid="76629022653866471">"Ջնջել"</string>
+ <string name="keep_queued_download" msgid="5144882786014818569">"Պահել"</string>
+ <string name="cancel_running_download" msgid="5232704030969221112">"Չեղարկել"</string>
+ <string name="retry_download" msgid="7617100787922717912">"Կրկնել"</string>
+ <string name="deselect_all" msgid="6348198946254776764">"Ապանշել բոլորը"</string>
+ <string name="select_all" msgid="634074918366265804">"Ընտրել բոլորը"</string>
+ <string name="selected_count" msgid="2101564570019753277">"Ընտրված են <xliff:g id="NUMBER">%1$d</xliff:g>-ը <xliff:g id="TOTAL">%2$d</xliff:g>-ից"</string>
+ <string name="download_share_dialog" msgid="3355867339806448955">"Տարածել"</string>
+</resources>
diff --git a/ui/res/values-in/strings.xml b/ui/res/values-in/strings.xml
index f3bfe35..72cb437 100644
--- a/ui/res/values-in/strings.xml
+++ b/ui/res/values-in/strings.xml
@@ -21,8 +21,8 @@
<string name="download_title_sorted_by_size" msgid="1417193166677094813">"Unduhan - Disortir menurut ukuran"</string>
<string name="no_downloads" msgid="1029667411186146836">"Tidak ada unduhan."</string>
<string name="missing_title" msgid="830115697868833773">"&lt;Tidak diketahui&gt;"</string>
- <string name="button_sort_by_size" msgid="7331549713691146251">"Sortir menurut ukuran"</string>
- <string name="button_sort_by_date" msgid="8800842892684101528">"Sortir menurut tanggal"</string>
+ <string name="button_sort_by_size" msgid="7331549713691146251">"Urutkan menurut ukuran"</string>
+ <string name="button_sort_by_date" msgid="8800842892684101528">"Urutkan menurut tanggal"</string>
<string name="download_queued" msgid="104973307780629904">"Dalam antrean"</string>
<string name="download_running" msgid="4656462962155580641">"Sedang berlangsung"</string>
<string name="download_success" msgid="7006048006543495236">"Selesai"</string>
diff --git a/ui/res/values-iw/strings.xml b/ui/res/values-iw/strings.xml
index ca58ef6..8b7965f 100644
--- a/ui/res/values-iw/strings.xml
+++ b/ui/res/values-iw/strings.xml
@@ -20,7 +20,7 @@
<string name="download_title_sorted_by_date" msgid="5898014492155434221">"הורדות - ממוינות לפי תאריך"</string>
<string name="download_title_sorted_by_size" msgid="1417193166677094813">"הורדות - ממוינות לפי גודל"</string>
<string name="no_downloads" msgid="1029667411186146836">"אין הורדות."</string>
- <string name="missing_title" msgid="830115697868833773">"&lt;לא ידוע&gt;"</string>
+ <string name="missing_title" msgid="830115697868833773">"‏&lt;לא ידוע&gt;"</string>
<string name="button_sort_by_size" msgid="7331549713691146251">"מיין לפי גודל"</string>
<string name="button_sort_by_date" msgid="8800842892684101528">"מיין לפי תאריך"</string>
<string name="download_queued" msgid="104973307780629904">"בהמתנה בתור"</string>
diff --git a/ui/res/values-ka-rGE/strings.xml b/ui/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..17dab2a
--- /dev/null
+++ b/ui/res/values-ka-rGE/strings.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3070921713463294774">"ჩამოტვირთულები"</string>
+ <string name="download_title_sorted_by_date" msgid="5898014492155434221">"ჩამოტვირთულები - სორტირებულია თარიღის მიხედვით"</string>
+ <string name="download_title_sorted_by_size" msgid="1417193166677094813">"ჩამოტვირთულები - სორტირებულია ზომის მიხედვით"</string>
+ <string name="no_downloads" msgid="1029667411186146836">"ჩამოტვირთულები არ არის."</string>
+ <string name="missing_title" msgid="830115697868833773">"&lt;უცნობი&gt;"</string>
+ <string name="button_sort_by_size" msgid="7331549713691146251">"სორტირება ზომის მიხედვით"</string>
+ <string name="button_sort_by_date" msgid="8800842892684101528">"სორტირება თარიღის მიხედვით"</string>
+ <string name="download_queued" msgid="104973307780629904">"რიგშია"</string>
+ <string name="download_running" msgid="4656462962155580641">"მიმდინარეობს"</string>
+ <string name="download_success" msgid="7006048006543495236">"დასრულება"</string>
+ <string name="download_error" msgid="8081329546008568251">"წარუმატებელი"</string>
+ <string name="dialog_title_not_available" msgid="5746317632356158515">"ჩამოტვირთვა ვერ განხორციელდა"</string>
+ <string name="dialog_failed_body" msgid="587545111677064427">"გსურთ, ფაილის ჩამოტვირთვა სცადოთ ხელახლა მოგვიანებით თუ წაშალოთ ის რიგიდან?"</string>
+ <string name="dialog_title_queued_body" msgid="6760681913815015219">"ფაილი რიგშია"</string>
+ <string name="dialog_queued_body" msgid="708552801635572720">"ეს ფაილი რიგშია მომავალი ჩამოტვირთვისთვის და ჯერ მიუწვდომელია."</string>
+ <string name="dialog_file_missing_body" msgid="3223012612774276284">"ჩამოტვირთული ფაილის მოძიება ვერ ხერხდება."</string>
+ <string name="dialog_insufficient_space_on_external" msgid="8692452156251449195">"ჩამოტვირთვა ვერ დასრულდა. გარე მეხსიერებაში არ არის საკმარისი სივრცე."</string>
+ <string name="dialog_insufficient_space_on_cache" msgid="6313630206163908994">"Can\'t finish download. There isn\'t enough space on internal download storage."</string>
+ <string name="dialog_cannot_resume" msgid="8664509751358983543">"ჩამოტვირთვა შეწყდა და გაგრძელება შეუძლებელია."</string>
+ <string name="dialog_file_already_exists" msgid="8308563940663449590">"ჩამოტვირთვა შეუძლებელია. დანიშნულების ფაილი უკვე არსებობს."</string>
+ <string name="dialog_media_not_found" msgid="4468088418758018765">"ჩამოტვირთვა ვერ ხერხდება. გარე მედია მიუწვდომელია."</string>
+ <string name="download_no_application_title" msgid="7024782176657362251">"ფაილის გახსნა ვერ ხერხდება"</string>
+ <string name="remove_download" msgid="6372920256257247857">"წაშლა"</string>
+ <string name="delete_download" msgid="76629022653866471">"წაშლა"</string>
+ <string name="keep_queued_download" msgid="5144882786014818569">"შენარჩუნება"</string>
+ <string name="cancel_running_download" msgid="5232704030969221112">"გაუქმება"</string>
+ <string name="retry_download" msgid="7617100787922717912">"გამეორება"</string>
+ <string name="deselect_all" msgid="6348198946254776764">"ყველა მონიშვნის მოხსნა"</string>
+ <string name="select_all" msgid="634074918366265804">"ყველას არჩევა"</string>
+ <string name="selected_count" msgid="2101564570019753277">"მონიშნულია <xliff:g id="NUMBER">%1$d</xliff:g>, სულ <xliff:g id="TOTAL">%2$d</xliff:g>-დან"</string>
+ <string name="download_share_dialog" msgid="3355867339806448955">"გაზიარება"</string>
+</resources>
diff --git a/ui/res/values-km-rKH/strings.xml b/ui/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..cc5f49b
--- /dev/null
+++ b/ui/res/values-km-rKH/strings.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3070921713463294774">"ទាញ​យក"</string>
+ <string name="download_title_sorted_by_date" msgid="5898014492155434221">"ទាញ​យក-តម្រៀប​តាម​កាលបរិច្ឆេទ"</string>
+ <string name="download_title_sorted_by_size" msgid="1417193166677094813">"ទាញ​យក-តម្រៀប​តាម​ទំហំ"</string>
+ <string name="no_downloads" msgid="1029667411186146836">"មិន​មាន​ការ​ទាញ​យក"</string>
+ <string name="missing_title" msgid="830115697868833773">"&lt;មិន​ស្គាល់&gt;"</string>
+ <string name="button_sort_by_size" msgid="7331549713691146251">"តម្រៀប​តាម​ទំហំ"</string>
+ <string name="button_sort_by_date" msgid="8800842892684101528">"តម្រៀប​តាម​ថ្ងៃ"</string>
+ <string name="download_queued" msgid="104973307780629904">"​បាន​ដាក់​ជា​ជួរ"</string>
+ <string name="download_running" msgid="4656462962155580641">"កំពុង​ដំណើរការ"</string>
+ <string name="download_success" msgid="7006048006543495236">"រួចរាល់"</string>
+ <string name="download_error" msgid="8081329546008568251">"បរាជ័យ"</string>
+ <string name="dialog_title_not_available" msgid="5746317632356158515">"មិន​អាច​ទាញ​យក"</string>
+ <string name="dialog_failed_body" msgid="587545111677064427">"តើ​អ្នក​ចង់​ព្យាយាម​ទាញ​យក​ឯកសារ​ម្ដងទៀត​នៅ​ពេល​ក្រោយ ឬ​លុប​វា​ចេញពី​ជួរ?"</string>
+ <string name="dialog_title_queued_body" msgid="6760681913815015219">"ឯកសារ​ស្ថិត​ក្នុង​ជួរ"</string>
+ <string name="dialog_queued_body" msgid="708552801635572720">"ឯកសារ​គឺ​ស្ថិត​ក្នុង​ជួរ​សម្រាប់​ការ​ទាញ​យក​បន្ទាប់ ដូច្នេះ​វា​មិន​មាន​នៅឡើយ​ទេ។"</string>
+ <string name="dialog_file_missing_body" msgid="3223012612774276284">"រក​មិន​ឃើញ​ឯកសារ​ដែល​បាន​ទាញ​យក។"</string>
+ <string name="dialog_insufficient_space_on_external" msgid="8692452156251449195">"មិន​អាច​បញ្ចប់​ការ​ទាញ​យក។ មិន​មាន​ទំហំ​គ្រប់គ្រាន់​នៅ​លើ​ឧបករណ៍​ផ្ទុក​ការ​ទាញ​យក​ខាងក្រៅ។"</string>
+ <string name="dialog_insufficient_space_on_cache" msgid="6313630206163908994">"មិន​អាច​បញ្ចប់​ការ​ទាញ​យក។ មិន​មាន​ទំហំ​គ្រប់គ្រាន់​នៅ​លើ​ឧបករណ៍​ផ្ទុក​ការ​ទាញ​យក​ខាងក្នុង។"</string>
+ <string name="dialog_cannot_resume" msgid="8664509751358983543">"បាន​បង្អាក់​ការ​ទាញ​យក ហើយ​វា​មិន​អាច​បន្ត​ទៀត​បាន​ទេ។"</string>
+ <string name="dialog_file_already_exists" msgid="8308563940663449590">"មិន​អាច​ទាញ​យក, ឯកសារ​ទិសដៅ​មាន​រួចហើយ។"</string>
+ <string name="dialog_media_not_found" msgid="4468088418758018765">"មិន​អាច​បញ្ចប់​ការ​ទាញ​យក។ មិន​មាន​មេឌៀ​ខាងក្រៅ។"</string>
+ <string name="download_no_application_title" msgid="7024782176657362251">"មិន​អាច​បើក​ឯកសារ"</string>
+ <string name="remove_download" msgid="6372920256257247857">"លុប​ចេញ"</string>
+ <string name="delete_download" msgid="76629022653866471">"លុប"</string>
+ <string name="keep_queued_download" msgid="5144882786014818569">"បន្ត"</string>
+ <string name="cancel_running_download" msgid="5232704030969221112">"បោះ​បង់​"</string>
+ <string name="retry_download" msgid="7617100787922717912">"សាកល្បង​ម្ដងទៀត"</string>
+ <string name="deselect_all" msgid="6348198946254776764">"មិន​ជ្រើស​ទាំងអស់"</string>
+ <string name="select_all" msgid="634074918366265804">"ជ្រើស​ទាំងអស់"</string>
+ <string name="selected_count" msgid="2101564570019753277">"បាន​ជ្រើស <xliff:g id="NUMBER">%1$d</xliff:g> ក្នុង​ចំណោម <xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <string name="download_share_dialog" msgid="3355867339806448955">"ចែករំលែក​តាម"</string>
+</resources>
diff --git a/ui/res/values-lo-rLA/strings.xml b/ui/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..70eb8d6
--- /dev/null
+++ b/ui/res/values-lo-rLA/strings.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3070921713463294774">"ດາວໂຫລດ"</string>
+ <string name="download_title_sorted_by_date" msgid="5898014492155434221">"ດາວໂຫລດ - ຮຽງຕາມວັນທີ"</string>
+ <string name="download_title_sorted_by_size" msgid="1417193166677094813">"ດາວໂຫລດ - ຮຽງຕາມຂະຫນາດ"</string>
+ <string name="no_downloads" msgid="1029667411186146836">"ບໍ່ມີການດາວໂຫລດ."</string>
+ <string name="missing_title" msgid="830115697868833773">"&lt;ບໍ່ຮູ້ຈັກ&gt;"</string>
+ <string name="button_sort_by_size" msgid="7331549713691146251">"ຮຽງຕາມຂະຫນາດ"</string>
+ <string name="button_sort_by_date" msgid="8800842892684101528">"ຮຽງຕາມວັນທີ"</string>
+ <string name="download_queued" msgid="104973307780629904">"ເຂົ້າຄິວແລ້ວ"</string>
+ <string name="download_running" msgid="4656462962155580641">"ກຳລັງດຳເນີນການ"</string>
+ <string name="download_success" msgid="7006048006543495236">"ສໍາເລັດ"</string>
+ <string name="download_error" msgid="8081329546008568251">"ບໍ່ສຳເລັດ"</string>
+ <string name="dialog_title_not_available" msgid="5746317632356158515">"ບໍ່ສາມາດດາວໂຫລດໄດ້"</string>
+ <string name="dialog_failed_body" msgid="587545111677064427">"ທ່ານຕ້ອງການລອງດາວໂຫລດໄຟລ໌ນີ້ໃໝ່ໃນພາຍຫຼັງບໍ່ ຫຼືຈະລຶບມັນອອກຈາກຄິວ?"</string>
+ <string name="dialog_title_queued_body" msgid="6760681913815015219">"ໄຟລ໌ຢູ່ໃນຄິວ"</string>
+ <string name="dialog_queued_body" msgid="708552801635572720">"ໄຟລ໌ນີ້ຖືກເຂົ້າຄິວໄວ້ເພື່ອການດາວໂຫລດໃນອະນາຄົດ ມັນຍັງບໍ່ສາມາດໃຊ້ໄດ້ເທື່ອ."</string>
+ <string name="dialog_file_missing_body" msgid="3223012612774276284">"ບໍ່ສາມາດຊອກຫາໄຟລ໌ທີ່ດາວໂຫລດມາໄດ້."</string>
+ <string name="dialog_insufficient_space_on_external" msgid="8692452156251449195">"ບໍ່ສາມາດດາວໂຫລດໃຫ້ສຳເລັດໄດ້. ບ່ອນຈັດເກັບຂໍ້ມູນດາວໂຫລດພາຍນອກບໍ່ພຽງພໍ."</string>
+ <string name="dialog_insufficient_space_on_cache" msgid="6313630206163908994">"ບໍ່ສາມາດດາວໂຫລດໃຫ້ສຳເລັດໄດ້. ບ່ອນຈັດເກັບຂໍ້ມູນດາວໂຫລດພາຍໃນບໍ່ພຽງພໍ."</string>
+ <string name="dialog_cannot_resume" msgid="8664509751358983543">"ການດາວໂຫລດຖືກລົບກວນ ແລະບໍ່ສາມາດສືບຕໍ່ໄດ້."</string>
+ <string name="dialog_file_already_exists" msgid="8308563940663449590">"ບໍ່ສາມາດດາວໂຫລດໄດ້. ໄຟລ໌ເປົ້າໝາຍມີຢູ່ແລ້ວ."</string>
+ <string name="dialog_media_not_found" msgid="4468088418758018765">"ບໍ່ສາມາດດາວໂຫລດໄດ້. ອຸປະກອນພາຍນອກບໍ່ສາມາດນຳໃຊ້ໄດ້."</string>
+ <string name="download_no_application_title" msgid="7024782176657362251">"ບໍ່ສາມາດເປີດໄຟລ໌"</string>
+ <string name="remove_download" msgid="6372920256257247857">"ລຶບ"</string>
+ <string name="delete_download" msgid="76629022653866471">"ລຶບ"</string>
+ <string name="keep_queued_download" msgid="5144882786014818569">"ເກັບໄວ້"</string>
+ <string name="cancel_running_download" msgid="5232704030969221112">"ຍົກເລີກ"</string>
+ <string name="retry_download" msgid="7617100787922717912">"ລອງໃໝ່"</string>
+ <string name="deselect_all" msgid="6348198946254776764">"ບໍ່ເລືອກທັງໝົດ"</string>
+ <string name="select_all" msgid="634074918366265804">"ເລືອກທັງຫມົດ"</string>
+ <string name="selected_count" msgid="2101564570019753277">"ເລືອກ <xliff:g id="NUMBER">%1$d</xliff:g> ຈາກ <xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <string name="download_share_dialog" msgid="3355867339806448955">"ແບ່ງປັນຜ່ານ"</string>
+</resources>
diff --git a/ui/res/values-mn-rMN/strings.xml b/ui/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000..3890a24
--- /dev/null
+++ b/ui/res/values-mn-rMN/strings.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3070921713463294774">"Татан авалтууд"</string>
+ <string name="download_title_sorted_by_date" msgid="5898014492155434221">"Татан авалтууд - Хугацаагаар эрэмбэлсэн"</string>
+ <string name="download_title_sorted_by_size" msgid="1417193166677094813">"Татан авалтууд - Хэмжээгээр эрэмбэлэгдсэн"</string>
+ <string name="no_downloads" msgid="1029667411186146836">"Татан авалт байхгүй."</string>
+ <string name="missing_title" msgid="830115697868833773">"&lt;Тодорхойгүй&gt;"</string>
+ <string name="button_sort_by_size" msgid="7331549713691146251">"Хэмжээгээр эрэмбэлэх"</string>
+ <string name="button_sort_by_date" msgid="8800842892684101528">"Огноогоор эрэмбэлэх"</string>
+ <string name="download_queued" msgid="104973307780629904">"Хүлээлгэнд"</string>
+ <string name="download_running" msgid="4656462962155580641">"Үргэлжилж байгаа"</string>
+ <string name="download_success" msgid="7006048006543495236">"Дуусгах"</string>
+ <string name="download_error" msgid="8081329546008568251">"Амжилтгүй"</string>
+ <string name="dialog_title_not_available" msgid="5746317632356158515">"Татан авч чадсангүй"</string>
+ <string name="dialog_failed_body" msgid="587545111677064427">"Та файлыг дараа татан авахаар үлдээх үү эсхүл хүлээлгээс хасах уу?"</string>
+ <string name="dialog_title_queued_body" msgid="6760681913815015219">"Файл хүлээлгэнд"</string>
+ <string name="dialog_queued_body" msgid="708552801635572720">"Файлыг ирээдүйд татаж авахаар хүлээлгэнд оруулсан бөгөөд одоо алга байна."</string>
+ <string name="dialog_file_missing_body" msgid="3223012612774276284">"Татаж авсан файлыг олох боломжгүй байна."</string>
+ <string name="dialog_insufficient_space_on_external" msgid="8692452156251449195">"Татан авалтыг дуусгаж чадангүй. Гадаад татан авалтын санд хангалттай зай байхгүй байна."</string>
+ <string name="dialog_insufficient_space_on_cache" msgid="6313630206163908994">"Татан авалтыг дуусгаж чадангүй. Дотоод татан авалтын санд хангалттай зай байхгүй байна."</string>
+ <string name="dialog_cannot_resume" msgid="8664509751358983543">"Татан авалт таслагдсан бөгөөд дахин үргэлжлүүлэх боломжгүй."</string>
+ <string name="dialog_file_already_exists" msgid="8308563940663449590">"Татаж авах боломжгүй. Хуулах файл байна."</string>
+ <string name="dialog_media_not_found" msgid="4468088418758018765">"Татаж авах боломжгүй. Гадаад медиа холбох боломжгүй."</string>
+ <string name="download_no_application_title" msgid="7024782176657362251">"Файлыг нээх боломжгүй"</string>
+ <string name="remove_download" msgid="6372920256257247857">"Устгах"</string>
+ <string name="delete_download" msgid="76629022653866471">"Устгах"</string>
+ <string name="keep_queued_download" msgid="5144882786014818569">"Байлгах"</string>
+ <string name="cancel_running_download" msgid="5232704030969221112">"Цуцлах"</string>
+ <string name="retry_download" msgid="7617100787922717912">"Дахин оролдох"</string>
+ <string name="deselect_all" msgid="6348198946254776764">"Бүгдийг сонгохгүй"</string>
+ <string name="select_all" msgid="634074918366265804">"Бүгдийг сонгох"</string>
+ <string name="selected_count" msgid="2101564570019753277">"<xliff:g id="TOTAL">%2$d</xliff:g>-с <xliff:g id="NUMBER">%1$d</xliff:g> нь сонгогдсон"</string>
+ <string name="download_share_dialog" msgid="3355867339806448955">"Дараахаар дамжуулан хуваалцах"</string>
+</resources>
diff --git a/ui/res/values-ms/strings.xml b/ui/res/values-ms-rMY/strings.xml
index e1e9f66..e1e9f66 100644
--- a/ui/res/values-ms/strings.xml
+++ b/ui/res/values-ms-rMY/strings.xml
diff --git a/ui/res/values-ne-rNP/strings.xml b/ui/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000..2a7389b
--- /dev/null
+++ b/ui/res/values-ne-rNP/strings.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3070921713463294774">"डाउनलोडहरू"</string>
+ <string name="download_title_sorted_by_date" msgid="5898014492155434221">"डाउनलोडहरू - मिति अनुसार क्रमबद्ध गरिएका"</string>
+ <string name="download_title_sorted_by_size" msgid="1417193166677094813">"डाउनलोडहरू - आकार अनुसार क्रमबद्ध गरिएका"</string>
+ <string name="no_downloads" msgid="1029667411186146836">"कुनै डाउनलोडहरू छैनन्।"</string>
+ <string name="missing_title" msgid="830115697868833773">"&lt;अज्ञात&gt;"</string>
+ <string name="button_sort_by_size" msgid="7331549713691146251">"आकार अनुसार क्रमबद्ध गर्नुहोस्"</string>
+ <string name="button_sort_by_date" msgid="8800842892684101528">"मिति अनुसार क्रमबद्ध गर्नुहोस्"</string>
+ <string name="download_queued" msgid="104973307780629904">"लाममा राखियो"</string>
+ <string name="download_running" msgid="4656462962155580641">"प्रगतिमा"</string>
+ <string name="download_success" msgid="7006048006543495236">"पुरा गर्नुहोस्"</string>
+ <string name="download_error" msgid="8081329546008568251">"असफल"</string>
+ <string name="dialog_title_not_available" msgid="5746317632356158515">"डाउनलोड गर्न सकेन"</string>
+ <string name="dialog_failed_body" msgid="587545111677064427">"तपाईँ पछि फेरि फाइल डाउनलोड गर्ने प्रयास गर्न चाहनुहुन्छ कि लामबाट हटाउन चाहनुहुन्छ?"</string>
+ <string name="dialog_title_queued_body" msgid="6760681913815015219">"फाइल लाममा छ"</string>
+ <string name="dialog_queued_body" msgid="708552801635572720">"फाइल भविष्यमा डाउनलोड गर्नका लागि लाममा राखिएको छ, यसैले अझै उपलब्ध छैन।"</string>
+ <string name="dialog_file_missing_body" msgid="3223012612774276284">"डाउनलोड गरिएको फाइल फेला पार्न सकेन।"</string>
+ <string name="dialog_insufficient_space_on_external" msgid="8692452156251449195">"डाउनलोड समाप्त पार्न सकेन। बाह्य भण्डारणमा पर्याप्त ठाउँ छैन।"</string>
+ <string name="dialog_insufficient_space_on_cache" msgid="6313630206163908994">"डाउनलोड समाप्त पार्न सकेन। आन्तरिक डाउनलोड भण्डारणमा पर्याप्त ठाउँ छैन।"</string>
+ <string name="dialog_cannot_resume" msgid="8664509751358983543">"डाउनलोड अवरूद्ध भयो र यो पुनः सुरु गर्न सकिन्न।"</string>
+ <string name="dialog_file_already_exists" msgid="8308563940663449590">"डाउनलोड गर्न सकेन। लक्षित फाइल पहिले नै छ।"</string>
+ <string name="dialog_media_not_found" msgid="4468088418758018765">"डाउनलोड गर्न सकेन। बाह्य मिडिया उपलब्ध छैन।"</string>
+ <string name="download_no_application_title" msgid="7024782176657362251">"फाइल खोल्न सकिँदैन"</string>
+ <string name="remove_download" msgid="6372920256257247857">"हटाउनुहोस्"</string>
+ <string name="delete_download" msgid="76629022653866471">"मेटाउनुहोस्"</string>
+ <string name="keep_queued_download" msgid="5144882786014818569">"राख्नुहोस्"</string>
+ <string name="cancel_running_download" msgid="5232704030969221112">"रद्द गर्नुहोस्"</string>
+ <string name="retry_download" msgid="7617100787922717912">"पुनःप्रयास गर्नुहोस्"</string>
+ <string name="deselect_all" msgid="6348198946254776764">"सबै अचयन गर्नुहोस्"</string>
+ <string name="select_all" msgid="634074918366265804">"सबै चयन गर्नुहोस्"</string>
+ <string name="selected_count" msgid="2101564570019753277">"छानिएको <xliff:g id="TOTAL">%2$d</xliff:g> को <xliff:g id="NUMBER">%1$d</xliff:g> बाट"</string>
+ <string name="download_share_dialog" msgid="3355867339806448955">"द्वारा साझेदारी गर्नुहोस्"</string>
+</resources>
diff --git a/ui/res/values-ne/strings.xml b/ui/res/values-ne/strings.xml
new file mode 100644
index 0000000..2a7389b
--- /dev/null
+++ b/ui/res/values-ne/strings.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3070921713463294774">"डाउनलोडहरू"</string>
+ <string name="download_title_sorted_by_date" msgid="5898014492155434221">"डाउनलोडहरू - मिति अनुसार क्रमबद्ध गरिएका"</string>
+ <string name="download_title_sorted_by_size" msgid="1417193166677094813">"डाउनलोडहरू - आकार अनुसार क्रमबद्ध गरिएका"</string>
+ <string name="no_downloads" msgid="1029667411186146836">"कुनै डाउनलोडहरू छैनन्।"</string>
+ <string name="missing_title" msgid="830115697868833773">"&lt;अज्ञात&gt;"</string>
+ <string name="button_sort_by_size" msgid="7331549713691146251">"आकार अनुसार क्रमबद्ध गर्नुहोस्"</string>
+ <string name="button_sort_by_date" msgid="8800842892684101528">"मिति अनुसार क्रमबद्ध गर्नुहोस्"</string>
+ <string name="download_queued" msgid="104973307780629904">"लाममा राखियो"</string>
+ <string name="download_running" msgid="4656462962155580641">"प्रगतिमा"</string>
+ <string name="download_success" msgid="7006048006543495236">"पुरा गर्नुहोस्"</string>
+ <string name="download_error" msgid="8081329546008568251">"असफल"</string>
+ <string name="dialog_title_not_available" msgid="5746317632356158515">"डाउनलोड गर्न सकेन"</string>
+ <string name="dialog_failed_body" msgid="587545111677064427">"तपाईँ पछि फेरि फाइल डाउनलोड गर्ने प्रयास गर्न चाहनुहुन्छ कि लामबाट हटाउन चाहनुहुन्छ?"</string>
+ <string name="dialog_title_queued_body" msgid="6760681913815015219">"फाइल लाममा छ"</string>
+ <string name="dialog_queued_body" msgid="708552801635572720">"फाइल भविष्यमा डाउनलोड गर्नका लागि लाममा राखिएको छ, यसैले अझै उपलब्ध छैन।"</string>
+ <string name="dialog_file_missing_body" msgid="3223012612774276284">"डाउनलोड गरिएको फाइल फेला पार्न सकेन।"</string>
+ <string name="dialog_insufficient_space_on_external" msgid="8692452156251449195">"डाउनलोड समाप्त पार्न सकेन। बाह्य भण्डारणमा पर्याप्त ठाउँ छैन।"</string>
+ <string name="dialog_insufficient_space_on_cache" msgid="6313630206163908994">"डाउनलोड समाप्त पार्न सकेन। आन्तरिक डाउनलोड भण्डारणमा पर्याप्त ठाउँ छैन।"</string>
+ <string name="dialog_cannot_resume" msgid="8664509751358983543">"डाउनलोड अवरूद्ध भयो र यो पुनः सुरु गर्न सकिन्न।"</string>
+ <string name="dialog_file_already_exists" msgid="8308563940663449590">"डाउनलोड गर्न सकेन। लक्षित फाइल पहिले नै छ।"</string>
+ <string name="dialog_media_not_found" msgid="4468088418758018765">"डाउनलोड गर्न सकेन। बाह्य मिडिया उपलब्ध छैन।"</string>
+ <string name="download_no_application_title" msgid="7024782176657362251">"फाइल खोल्न सकिँदैन"</string>
+ <string name="remove_download" msgid="6372920256257247857">"हटाउनुहोस्"</string>
+ <string name="delete_download" msgid="76629022653866471">"मेटाउनुहोस्"</string>
+ <string name="keep_queued_download" msgid="5144882786014818569">"राख्नुहोस्"</string>
+ <string name="cancel_running_download" msgid="5232704030969221112">"रद्द गर्नुहोस्"</string>
+ <string name="retry_download" msgid="7617100787922717912">"पुनःप्रयास गर्नुहोस्"</string>
+ <string name="deselect_all" msgid="6348198946254776764">"सबै अचयन गर्नुहोस्"</string>
+ <string name="select_all" msgid="634074918366265804">"सबै चयन गर्नुहोस्"</string>
+ <string name="selected_count" msgid="2101564570019753277">"छानिएको <xliff:g id="TOTAL">%2$d</xliff:g> को <xliff:g id="NUMBER">%1$d</xliff:g> बाट"</string>
+ <string name="download_share_dialog" msgid="3355867339806448955">"द्वारा साझेदारी गर्नुहोस्"</string>
+</resources>
diff --git a/ui/res/values-si-rLK/strings.xml b/ui/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000..1187387
--- /dev/null
+++ b/ui/res/values-si-rLK/strings.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3070921713463294774">"බාගැනීම්"</string>
+ <string name="download_title_sorted_by_date" msgid="5898014492155434221">"බාගැනීම් - දිනය අනුව පෙළගස්වන ලද"</string>
+ <string name="download_title_sorted_by_size" msgid="1417193166677094813">"බාගැනීම් - ප්‍රමාණය අනුව පෙළගස්වන ලද"</string>
+ <string name="no_downloads" msgid="1029667411186146836">"බාගැනීම් නොමැත."</string>
+ <string name="missing_title" msgid="830115697868833773">"&lt;නොදනී&gt;"</string>
+ <string name="button_sort_by_size" msgid="7331549713691146251">"ප්‍රමාණය අනුව අනුපිළිවෙලට සකසන්න"</string>
+ <string name="button_sort_by_date" msgid="8800842892684101528">"දිනය අනුව අනුපිළිවෙලට සකසන්න"</string>
+ <string name="download_queued" msgid="104973307780629904">"පෙළ ගැස්විණි"</string>
+ <string name="download_running" msgid="4656462962155580641">"ක්‍රියාවේ පවතී"</string>
+ <string name="download_success" msgid="7006048006543495236">"සම්පුර්ණයි"</string>
+ <string name="download_error" msgid="8081329546008568251">"අසාර්ථකයි"</string>
+ <string name="dialog_title_not_available" msgid="5746317632356158515">"බාගත නොහැකි විය"</string>
+ <string name="dialog_failed_body" msgid="587545111677064427">"ඔබට ගොනු පසුව බාගැනීමට උත්සාහ කිරීමට අවශ්‍යද නැතිනම් එය පෝලිමෙන් මැකීමට අවශ්‍යද?"</string>
+ <string name="dialog_title_queued_body" msgid="6760681913815015219">"ගොනුව පේළියෙහි තිබේ"</string>
+ <string name="dialog_queued_body" msgid="708552801635572720">"අනාගත බාගැනීම් සඳහා මෙම ගොනුව පෙළගස්වා ඇත එබැවින් එය තවම ලබාගත නොහැක."</string>
+ <string name="dialog_file_missing_body" msgid="3223012612774276284">"බාගත් ගොනුව සොයා ගත නොහැක."</string>
+ <string name="dialog_insufficient_space_on_external" msgid="8692452156251449195">"බාගැනීම අවසන් කළ නොහැක. බාහිර බාගැනීම් ආචයනයේ අවශ්‍ය තරම් ඉඩක් නොමැත."</string>
+ <string name="dialog_insufficient_space_on_cache" msgid="6313630206163908994">"බාගැනීම අවසන් කළ නොහැක. අභ්‍යන්තර බාගැනීම් ආචයනයේ අවශ්‍ය තරම් ඉඩක් නොමැත."</string>
+ <string name="dialog_cannot_resume" msgid="8664509751358983543">"බාගැනීමට බාධා ඇතිවූ අතර එය යළි ආරම්භ කළ නොහැක."</string>
+ <string name="dialog_file_already_exists" msgid="8308563940663449590">"බාගත නොහැක. ගමනාන්තයේ ගොනුව දැනටමත් ඇත."</string>
+ <string name="dialog_media_not_found" msgid="4468088418758018765">"බාගත නොහැක. බාහිර මාධ්‍ය නොමැත."</string>
+ <string name="download_no_application_title" msgid="7024782176657362251">"ගොනුව විවෘත කළ නොහැකි විය"</string>
+ <string name="remove_download" msgid="6372920256257247857">"ඉවත් කරන්න"</string>
+ <string name="delete_download" msgid="76629022653866471">"මකන්න"</string>
+ <string name="keep_queued_download" msgid="5144882786014818569">"තබාගැනීම"</string>
+ <string name="cancel_running_download" msgid="5232704030969221112">"අවලංගු කරන්න"</string>
+ <string name="retry_download" msgid="7617100787922717912">"නැවත උත්සාහ කරන්න"</string>
+ <string name="deselect_all" msgid="6348198946254776764">"සියල්ල තේරීම අත්හරින්න"</string>
+ <string name="select_all" msgid="634074918366265804">"සියල්ල තෝරන්න"</string>
+ <string name="selected_count" msgid="2101564570019753277">"<xliff:g id="TOTAL">%2$d</xliff:g> ගෙන් <xliff:g id="NUMBER">%1$d</xliff:g> ක් තෝරා ගන්නා ලදී"</string>
+ <string name="download_share_dialog" msgid="3355867339806448955">"බෙදාගන්නේ"</string>
+</resources>
diff --git a/ui/res/values-si/strings.xml b/ui/res/values-si/strings.xml
new file mode 100644
index 0000000..1187387
--- /dev/null
+++ b/ui/res/values-si/strings.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3070921713463294774">"බාගැනීම්"</string>
+ <string name="download_title_sorted_by_date" msgid="5898014492155434221">"බාගැනීම් - දිනය අනුව පෙළගස්වන ලද"</string>
+ <string name="download_title_sorted_by_size" msgid="1417193166677094813">"බාගැනීම් - ප්‍රමාණය අනුව පෙළගස්වන ලද"</string>
+ <string name="no_downloads" msgid="1029667411186146836">"බාගැනීම් නොමැත."</string>
+ <string name="missing_title" msgid="830115697868833773">"&lt;නොදනී&gt;"</string>
+ <string name="button_sort_by_size" msgid="7331549713691146251">"ප්‍රමාණය අනුව අනුපිළිවෙලට සකසන්න"</string>
+ <string name="button_sort_by_date" msgid="8800842892684101528">"දිනය අනුව අනුපිළිවෙලට සකසන්න"</string>
+ <string name="download_queued" msgid="104973307780629904">"පෙළ ගැස්විණි"</string>
+ <string name="download_running" msgid="4656462962155580641">"ක්‍රියාවේ පවතී"</string>
+ <string name="download_success" msgid="7006048006543495236">"සම්පුර්ණයි"</string>
+ <string name="download_error" msgid="8081329546008568251">"අසාර්ථකයි"</string>
+ <string name="dialog_title_not_available" msgid="5746317632356158515">"බාගත නොහැකි විය"</string>
+ <string name="dialog_failed_body" msgid="587545111677064427">"ඔබට ගොනු පසුව බාගැනීමට උත්සාහ කිරීමට අවශ්‍යද නැතිනම් එය පෝලිමෙන් මැකීමට අවශ්‍යද?"</string>
+ <string name="dialog_title_queued_body" msgid="6760681913815015219">"ගොනුව පේළියෙහි තිබේ"</string>
+ <string name="dialog_queued_body" msgid="708552801635572720">"අනාගත බාගැනීම් සඳහා මෙම ගොනුව පෙළගස්වා ඇත එබැවින් එය තවම ලබාගත නොහැක."</string>
+ <string name="dialog_file_missing_body" msgid="3223012612774276284">"බාගත් ගොනුව සොයා ගත නොහැක."</string>
+ <string name="dialog_insufficient_space_on_external" msgid="8692452156251449195">"බාගැනීම අවසන් කළ නොහැක. බාහිර බාගැනීම් ආචයනයේ අවශ්‍ය තරම් ඉඩක් නොමැත."</string>
+ <string name="dialog_insufficient_space_on_cache" msgid="6313630206163908994">"බාගැනීම අවසන් කළ නොහැක. අභ්‍යන්තර බාගැනීම් ආචයනයේ අවශ්‍ය තරම් ඉඩක් නොමැත."</string>
+ <string name="dialog_cannot_resume" msgid="8664509751358983543">"බාගැනීමට බාධා ඇතිවූ අතර එය යළි ආරම්භ කළ නොහැක."</string>
+ <string name="dialog_file_already_exists" msgid="8308563940663449590">"බාගත නොහැක. ගමනාන්තයේ ගොනුව දැනටමත් ඇත."</string>
+ <string name="dialog_media_not_found" msgid="4468088418758018765">"බාගත නොහැක. බාහිර මාධ්‍ය නොමැත."</string>
+ <string name="download_no_application_title" msgid="7024782176657362251">"ගොනුව විවෘත කළ නොහැකි විය"</string>
+ <string name="remove_download" msgid="6372920256257247857">"ඉවත් කරන්න"</string>
+ <string name="delete_download" msgid="76629022653866471">"මකන්න"</string>
+ <string name="keep_queued_download" msgid="5144882786014818569">"තබාගැනීම"</string>
+ <string name="cancel_running_download" msgid="5232704030969221112">"අවලංගු කරන්න"</string>
+ <string name="retry_download" msgid="7617100787922717912">"නැවත උත්සාහ කරන්න"</string>
+ <string name="deselect_all" msgid="6348198946254776764">"සියල්ල තේරීම අත්හරින්න"</string>
+ <string name="select_all" msgid="634074918366265804">"සියල්ල තෝරන්න"</string>
+ <string name="selected_count" msgid="2101564570019753277">"<xliff:g id="TOTAL">%2$d</xliff:g> ගෙන් <xliff:g id="NUMBER">%1$d</xliff:g> ක් තෝරා ගන්නා ලදී"</string>
+ <string name="download_share_dialog" msgid="3355867339806448955">"බෙදාගන්නේ"</string>
+</resources>
diff --git a/ui/res/values-sk/strings.xml b/ui/res/values-sk/strings.xml
index e3d3cd1..5e19134 100644
--- a/ui/res/values-sk/strings.xml
+++ b/ui/res/values-sk/strings.xml
@@ -16,10 +16,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="3070921713463294774">"Prevzatia"</string>
- <string name="download_title_sorted_by_date" msgid="5898014492155434221">"Prevzatia – zoradené podľa dátumu"</string>
- <string name="download_title_sorted_by_size" msgid="1417193166677094813">"Prevzatia – zoradené podľa veľkosti"</string>
- <string name="no_downloads" msgid="1029667411186146836">"Žiadne preberania"</string>
+ <string name="app_label" msgid="3070921713463294774">"Stiahnuté"</string>
+ <string name="download_title_sorted_by_date" msgid="5898014492155434221">"Stiahnutia – zoradené podľa dátumu"</string>
+ <string name="download_title_sorted_by_size" msgid="1417193166677094813">"Stiahnutia – zoradené podľa veľkosti"</string>
+ <string name="no_downloads" msgid="1029667411186146836">"Žiadne sťahovania"</string>
<string name="missing_title" msgid="830115697868833773">"&lt;Neznáme&gt;"</string>
<string name="button_sort_by_size" msgid="7331549713691146251">"Zoradiť podľa veľkosti"</string>
<string name="button_sort_by_date" msgid="8800842892684101528">"Zoradiť podľa dátumu"</string>
@@ -27,16 +27,16 @@
<string name="download_running" msgid="4656462962155580641">"Prebieha"</string>
<string name="download_success" msgid="7006048006543495236">"Dokončené"</string>
<string name="download_error" msgid="8081329546008568251">"Neúspešné"</string>
- <string name="dialog_title_not_available" msgid="5746317632356158515">"Nepodarilo sa prevziať"</string>
- <string name="dialog_failed_body" msgid="587545111677064427">"Chcete tento súbor skúsiť znova prevziať neskôr, alebo ho chcete zo zoznamu odstrániť?"</string>
+ <string name="dialog_title_not_available" msgid="5746317632356158515">"Nepodarilo sa stiahnuť"</string>
+ <string name="dialog_failed_body" msgid="587545111677064427">"Chcete tento súbor skúsiť znova stiahnuť neskôr, alebo ho chcete zo zoznamu odstrániť?"</string>
<string name="dialog_title_queued_body" msgid="6760681913815015219">"Súbor v poradí"</string>
- <string name="dialog_queued_body" msgid="708552801635572720">"Súbor zatiaľ nie je k dispozícii, pretože je v poradí na budúce prevzatie."</string>
- <string name="dialog_file_missing_body" msgid="3223012612774276284">"Prevzatý súbor sa nepodarilo nájsť."</string>
- <string name="dialog_insufficient_space_on_external" msgid="8692452156251449195">"Preberanie nie je možné dokončiť. V externom úložisku nie je dostatok miesta."</string>
- <string name="dialog_insufficient_space_on_cache" msgid="6313630206163908994">"Preberanie nie je možné dokončiť. V internom úložisku na prevzaté súbory nie je dostatok miesta."</string>
- <string name="dialog_cannot_resume" msgid="8664509751358983543">"Preberanie bolo prerušené a nie je možné v ňom pokračovať."</string>
- <string name="dialog_file_already_exists" msgid="8308563940663449590">"Nepodarilo sa prevziať. Cieľový súbor už existuje."</string>
- <string name="dialog_media_not_found" msgid="4468088418758018765">"Nepodarilo sa prevziať. Externé médium nie je k dispozícii."</string>
+ <string name="dialog_queued_body" msgid="708552801635572720">"Súbor zatiaľ nie je k dispozícii, pretože je v poradí na budúce stiahnutie."</string>
+ <string name="dialog_file_missing_body" msgid="3223012612774276284">"Stiahnutý súbor sa nepodarilo nájsť."</string>
+ <string name="dialog_insufficient_space_on_external" msgid="8692452156251449195">"Sťahovanie nie je možné dokončiť. V externom úložisku nie je dostatok miesta."</string>
+ <string name="dialog_insufficient_space_on_cache" msgid="6313630206163908994">"Sťahovanie nie je možné dokončiť. V internom úložisku na stiahnuté súbory nie je dostatok miesta."</string>
+ <string name="dialog_cannot_resume" msgid="8664509751358983543">"Sťahovanie bolo prerušené a nie je možné v ňom pokračovať."</string>
+ <string name="dialog_file_already_exists" msgid="8308563940663449590">"Nepodarilo sa stiahnuť. Cieľový súbor už existuje."</string>
+ <string name="dialog_media_not_found" msgid="4468088418758018765">"Nepodarilo sa stiahnuť. Externé médium nie je k dispozícii."</string>
<string name="download_no_application_title" msgid="7024782176657362251">"Súbor nie je možné otvoriť"</string>
<string name="remove_download" msgid="6372920256257247857">"Odstrániť"</string>
<string name="delete_download" msgid="76629022653866471">"Odstrániť"</string>
diff --git a/ui/res/values-th/strings.xml b/ui/res/values-th/strings.xml
index fd4f16f..a1e51e3 100644
--- a/ui/res/values-th/strings.xml
+++ b/ui/res/values-th/strings.xml
@@ -46,5 +46,5 @@
<string name="deselect_all" msgid="6348198946254776764">"ยกเลิกการเลือกทั้งหมด"</string>
<string name="select_all" msgid="634074918366265804">"เลือกทั้งหมด"</string>
<string name="selected_count" msgid="2101564570019753277">"เลือก <xliff:g id="NUMBER">%1$d</xliff:g> จาก <xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="download_share_dialog" msgid="3355867339806448955">"แบ่งปันผ่าน"</string>
+ <string name="download_share_dialog" msgid="3355867339806448955">"แชร์ผ่าน"</string>
</resources>
diff --git a/ui/res/values-zh-rHK/strings.xml b/ui/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..c8cd577
--- /dev/null
+++ b/ui/res/values-zh-rHK/strings.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="3070921713463294774">"下載"</string>
+ <string name="download_title_sorted_by_date" msgid="5898014492155434221">"下載項目 - 依日期排序"</string>
+ <string name="download_title_sorted_by_size" msgid="1417193166677094813">"下載項目 - 依大小排序"</string>
+ <string name="no_downloads" msgid="1029667411186146836">"沒有下載。"</string>
+ <string name="missing_title" msgid="830115697868833773">"&lt;未知&gt;"</string>
+ <string name="button_sort_by_size" msgid="7331549713691146251">"依大小排序"</string>
+ <string name="button_sort_by_date" msgid="8800842892684101528">"依日期排序"</string>
+ <string name="download_queued" msgid="104973307780629904">"已加入下載佇列"</string>
+ <string name="download_running" msgid="4656462962155580641">"進行中"</string>
+ <string name="download_success" msgid="7006048006543495236">"完成"</string>
+ <string name="download_error" msgid="8081329546008568251">"失敗"</string>
+ <string name="dialog_title_not_available" msgid="5746317632356158515">"無法下載"</string>
+ <string name="dialog_failed_body" msgid="587545111677064427">"您要稍後再重試下載檔案,或是從下載佇列中刪除檔案?"</string>
+ <string name="dialog_title_queued_body" msgid="6760681913815015219">"佇列中的檔案"</string>
+ <string name="dialog_queued_body" msgid="708552801635572720">"檔案已排入之後要下載的佇列中,因此目前尚無法取得。"</string>
+ <string name="dialog_file_missing_body" msgid="3223012612774276284">"找不到已下載的檔案。"</string>
+ <string name="dialog_insufficient_space_on_external" msgid="8692452156251449195">"無法完成下載,外部儲存空間不足。"</string>
+ <string name="dialog_insufficient_space_on_cache" msgid="6313630206163908994">"無法完成下載,內部下載儲存空間不足。"</string>
+ <string name="dialog_cannot_resume" msgid="8664509751358983543">"下載中斷,無法恢復。"</string>
+ <string name="dialog_file_already_exists" msgid="8308563940663449590">"無法下載,目標位置已有相同檔案。"</string>
+ <string name="dialog_media_not_found" msgid="4468088418758018765">"無法下載,外部媒體無法使用。"</string>
+ <string name="download_no_application_title" msgid="7024782176657362251">"無法開啟檔案"</string>
+ <string name="remove_download" msgid="6372920256257247857">"移除"</string>
+ <string name="delete_download" msgid="76629022653866471">"刪除"</string>
+ <string name="keep_queued_download" msgid="5144882786014818569">"保留"</string>
+ <string name="cancel_running_download" msgid="5232704030969221112">"取消"</string>
+ <string name="retry_download" msgid="7617100787922717912">"重試"</string>
+ <string name="deselect_all" msgid="6348198946254776764">"全部不選"</string>
+ <string name="select_all" msgid="634074918366265804">"全部選取"</string>
+ <string name="selected_count" msgid="2101564570019753277">"已選取 <xliff:g id="NUMBER">%1$d</xliff:g> 個,共 <xliff:g id="TOTAL">%2$d</xliff:g> 個"</string>
+ <string name="download_share_dialog" msgid="3355867339806448955">"分享方式:"</string>
+</resources>