summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk5
-rw-r--r--AndroidManifest.xml11
-rw-r--r--CleanSpec.mk49
-rw-r--r--res/layout/status_bar_ongoing_event_progress_bar.xml20
-rw-r--r--res/values-cs/strings.xml11
-rw-r--r--res/values-da/strings.xml9
-rw-r--r--res/values-de/strings.xml9
-rw-r--r--res/values-el/strings.xml9
-rw-r--r--res/values-es-rUS/strings.xml13
-rw-r--r--res/values-es/strings.xml9
-rw-r--r--res/values-fr/strings.xml9
-rw-r--r--res/values-it/strings.xml9
-rw-r--r--res/values-ja/strings.xml9
-rw-r--r--res/values-ko/strings.xml9
-rw-r--r--res/values-nb/strings.xml9
-rw-r--r--res/values-nl/strings.xml9
-rw-r--r--res/values-pl/strings.xml9
-rw-r--r--res/values-pt-rPT/strings.xml9
-rw-r--r--res/values-pt/strings.xml9
-rw-r--r--res/values-ru/strings.xml9
-rw-r--r--res/values-sv/strings.xml9
-rw-r--r--res/values-tr/strings.xml11
-rw-r--r--res/values-zh-rCN/strings.xml13
-rw-r--r--res/values-zh-rTW/strings.xml9
-rw-r--r--res/values/strings.xml26
-rw-r--r--src/com/android/providers/downloads/DownloadInfo.java24
-rw-r--r--src/com/android/providers/downloads/DownloadNotification.java81
-rw-r--r--src/com/android/providers/downloads/DownloadProvider.java252
-rw-r--r--src/com/android/providers/downloads/DownloadReceiver.java39
-rw-r--r--src/com/android/providers/downloads/DownloadService.java179
-rw-r--r--src/com/android/providers/downloads/DownloadThread.java123
-rw-r--r--src/com/android/providers/downloads/Helpers.java107
-rw-r--r--tests/permission/src/com/android/providers/downloads/permission/tests/DownloadProviderPermissionsTest.java6
33 files changed, 629 insertions, 485 deletions
diff --git a/Android.mk b/Android.mk
index ee7dca29..97f8a315 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,9 +1,14 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := optional
+
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME := DownloadProvider
LOCAL_CERTIFICATE := media
include $(BUILD_PACKAGE)
+
+# additionally, call tests makefiles
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index b7730cbe..1b111f06 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -15,18 +15,17 @@
android:description="@string/permdesc_downloadManagerAdvanced"
android:protectionLevel="signatureOrSystem" />
- <!-- Allows filesystem access to /cache -->
- <permission android:name="android.permission.ACCESS_CACHE_FILESYSTEM"
- android:label="@string/permlab_cacheFilesystem"
- android:description="@string/permdesc_cacheFilesystem"
- android:protectionLevel="signature" />
-
<!-- Allows to send download completed intents -->
<permission android:name="android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS"
android:label="@string/permlab_downloadCompletedIntent"
android:description="@string/permdesc_downloadCompletedIntent"
android:protectionLevel="signature" />
+ <permission android:name="android.permission.SEE_ALL_EXTERNAL"
+ android:label="@string/permlab_seeAllExternal"
+ android:description="@string/permdesc_seeAllExternal"
+ android:protectionLevel="normal"/>
+
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER" />
<uses-permission android:name="android.permission.ACCESS_DRM" />
diff --git a/CleanSpec.mk b/CleanSpec.mk
new file mode 100644
index 00000000..b84e1b65
--- /dev/null
+++ b/CleanSpec.mk
@@ -0,0 +1,49 @@
+# 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.
+#
+
+# If you don't need to do a full clean build but would like to touch
+# a file or delete some intermediate files, add a clean step to the end
+# of the list. These steps will only be run once, if they haven't been
+# run before.
+#
+# E.g.:
+# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
+# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
+#
+# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
+# files that are missing or have been moved.
+#
+# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
+# Use $(OUT_DIR) to refer to the "out" directory.
+#
+# If you need to re-do something that's already mentioned, just copy
+# the command and add it to the bottom of the list. E.g., if a change
+# that you made last week required touching a file and a change you
+# made today requires touching the same file, just copy the old
+# touch step and add it to the end of the list.
+#
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
+# For example:
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
+#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
+#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
diff --git a/res/layout/status_bar_ongoing_event_progress_bar.xml b/res/layout/status_bar_ongoing_event_progress_bar.xml
index d81c42ba..65c31560 100644
--- a/res/layout/status_bar_ongoing_event_progress_bar.xml
+++ b/res/layout/status_bar_ongoing_event_progress_bar.xml
@@ -18,21 +18,21 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
android:orientation="vertical"
android:background="@android:drawable/status_bar_item_app_background"
>
<LinearLayout
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
android:orientation="horizontal"
>
<LinearLayout
android:layout_width="40dp"
- android:layout_height="fill_parent"
+ android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="8dp"
android:focusable="true"
@@ -56,14 +56,14 @@
</LinearLayout>
<RelativeLayout
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
android:orientation="vertical"
android:focusable="true"
android:clickable="true"
>
<LinearLayout
- android:layout_width="fill_parent"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:focusable="true"
@@ -90,7 +90,7 @@
</LinearLayout>
<ProgressBar android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
- android:layout_width="fill_parent"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:paddingBottom="8dp"
@@ -100,7 +100,7 @@
</LinearLayout>
<com.android.server.status.AnimatedImageView
- android:layout_width="fill_parent"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@android:drawable/divider_horizontal_bright"
/>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 8ea00577..78561d7b 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- 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.
@@ -12,7 +12,8 @@
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">"Správce stahování"</string>
@@ -20,13 +21,13 @@
<string name="permdesc_downloadManager" msgid="4240298564918160337">"Umožní aplikaci získat přístup ke správci stahování a stahovat pomocí něj soubory. Škodlivé aplikace mohou pomocí tohoto nastavení narušit stahování a získat přístup k soukromým informacím."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Pokročilé funkce správce stahování."</string>
<string name="permdesc_downloadManagerAdvanced" msgid="6985743912436565114">"Umožňuje aplikaci přístup k pokročilým funkcím správce stahování. Škodlivé aplikace toho mohou využít a narušit stahování nebo získat přístup k důvěrným informacím."</string>
- <string name="permlab_cacheFilesystem" msgid="6987994626343144212">"Použít mezipaměť systému."</string>
- <string name="permdesc_cacheFilesystem" msgid="7301787168569544726">"Umožní aplikaci získat přímý přístup k mezipaměti systému, měnit ji a mazat. Škodlivé aplikace mohou pomocí tohoto nastavení vážně narušit stahování a ostatní aplikace a získat přístup k soukromým datům."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Odeslat oznámení o stahování."</string>
<string name="permdesc_downloadCompletedIntent" msgid="8672701687104399228">"Umožní aplikaci odeslat oznámení o dokončení stahování. Škodlivé aplikace mohou pomocí tohoto nastavení zmást jiné aplikace, které stahují soubory."</string>
+ <string name="permlab_seeAllExternal" msgid="140058400609165726">"Zobrazení všech položek stažených na kartu SD"</string>
+ <string name="permdesc_seeAllExternal" msgid="3298948060016417104">"Umožňuje aplikaci zobrazit všechny položky stažené na kartu SD bez ohledu na to, která aplikace je stáhla."</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;Bez názvu&gt;"</string>
<string name="notification_filename_separator" msgid="7147189522857807618">", "</string>
<string name="notification_filename_extras" msgid="5549729917695688191">" a ještě <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="notification_download_complete" msgid="840713937779273632">"Stahování bylo dokončeno"</string>
- <string name="notification_download_failed" msgid="5343637375905111462">"Stahování bylo neúspěšné"</string>
+ <string name="notification_download_failed" msgid="5343637375905111462">"Stažení se nezdařilo."</string>
</resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 58659e9b..c74ffecd 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- 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.
@@ -12,7 +12,8 @@
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">"Downloadadministrator"</string>
@@ -20,10 +21,10 @@
<string name="permdesc_downloadManager" msgid="4240298564918160337">"Tillader, at programmet får adgang til downloadadministratoren og bruger det til at få adgang til downloadede filer. Ondsindede programmer kan bruge det 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="6985743912436565114">"Tillader, at programmet får adgang til de avancerede funktioner i downloadadministratoren. Ondsindede programmer kan bruge dette til at afbryde downloads og få adgang til personlige oplysninger."</string>
- <string name="permlab_cacheFilesystem" msgid="6987994626343144212">"Brug systemcache."</string>
- <string name="permdesc_cacheFilesystem" msgid="7301787168569544726">"Tillader, at programmet får direkte adgang til at ændre og slette systemcachen. Ondsindede programmer kan bruge dette til i alvorlig grad at afbryde downloads og andre programmer samt få adgang til personlige oplysninger."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Send downloadmeddelelser."</string>
<string name="permdesc_downloadCompletedIntent" msgid="8672701687104399228">"Tillader, at programmet sender meddelelser om afsluttede downloads. Ondsindede programmer kan bruge dette til at forvirre andre programmer, der downloader filer."</string>
+ <string name="permlab_seeAllExternal" msgid="140058400609165726">"Se alle downloads til SD-kort"</string>
+ <string name="permdesc_seeAllExternal" msgid="3298948060016417104">"Gør det muligt for programmet at se alle downloads til SD-kortet, uanset hvilket program, der downloadede dem."</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;Uden titel&gt;"</string>
<string name="notification_filename_separator" msgid="7147189522857807618">", "</string>
<string name="notification_filename_extras" msgid="5549729917695688191">" og <xliff:g id="NUMBER">%d</xliff:g> mere"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index cfbccd79..323963bb 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- 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.
@@ -12,7 +12,8 @@
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>
@@ -20,10 +21,10 @@
<string name="permdesc_downloadManager" msgid="4240298564918160337">"Ermöglicht der Anwendung den Zugriff auf den Download-Manager zum Herunterladen von Dateien. Diese Funktion kann von bösartigen Anwendungen dazu verwendet werden, Ladevorgänge zu unterbrechen und auf private Daten zuzugreifen."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Erweiterte Funktionen des Download-Managers."</string>
<string name="permdesc_downloadManagerAdvanced" msgid="6985743912436565114">"Der Anwendung wird ermöglicht, auf die erweiterten Funktionen des Download-Managers zuzugreifen. Schädliche Anwendungen können so Downloads unterbrechen und auf persönliche Daten zugreifen."</string>
- <string name="permlab_cacheFilesystem" msgid="6987994626343144212">"Systemcache verwenden"</string>
- <string name="permdesc_cacheFilesystem" msgid="7301787168569544726">"Ermöglicht es der Anwendung, direkt auf den Systemcache zuzugreifen und diesen zu ändern oder zu löschen. Diese Funktion kann von bösartigen Anwendungen dazu verwendet werden, Ladevorgänge und andere Anwendungen schwerwiegend zu stören sowie auf private Daten zuzugreifen."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Benachrichtigungen zu Ladevorgängen senden"</string>
<string name="permdesc_downloadCompletedIntent" msgid="8672701687104399228">"Ermöglicht es der Anwendung, Benachrichtigungen zu abgeschlossenen Ladevorgängen zu senden. Diese Funktion kann von bösartigen Anwendungen dazu verwendet werden, den Ladevorgang anderer Anwendungen zu stören."</string>
+ <string name="permlab_seeAllExternal" msgid="140058400609165726">"Alle Downloads an SD-Karte anzeigen"</string>
+ <string name="permdesc_seeAllExternal" msgid="3298948060016417104">"Ermöglicht der Anwendung, alle Downloads an die SD-Karte anzuzeigen, unabhängig davon, von welcher Anwendung sie heruntergeladen wurden."</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;Unbenannt&gt;"</string>
<string name="notification_filename_separator" msgid="7147189522857807618">", "</string>
<string name="notification_filename_extras" msgid="5549729917695688191">" und <xliff:g id="NUMBER">%d</xliff:g> weitere"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 704eccb3..01f30ac7 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- 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.
@@ -12,7 +12,8 @@
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>
@@ -20,10 +21,10 @@
<string name="permdesc_downloadManager" msgid="4240298564918160337">"Επιτρέπει στην εφαρμογή την πρόσβαση στο πρόγραμμα διαχείρισης λήψεων και τη χρήση του για τη λήψη αρχείων. Κακόβουλες εφαρμογές μπορούν να το χρησιμοποιήσουν για να διακόψουν λήψεις και για να αποκτήσουν πρόσβαση σε προσωπικές πληροφορίες."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Σύνθετες λειτουργίες προγράμματος διαχείρισης λήψεων."</string>
<string name="permdesc_downloadManagerAdvanced" msgid="6985743912436565114">"Επιτρέπει στην εφαρμογή την πρόσβαση στις σύνθετες λειτουργίες των προγραμμάτων διαχείρισης λήψεων. Κακόβουλες εφαρμογές μπορούν να το χρησιμοποιήσουν για να διακόψουν λήψεις και για να αποκτήσουν πρόσβαση σε προσωπικές πληροφορίες."</string>
- <string name="permlab_cacheFilesystem" msgid="6987994626343144212">"Χρήση της προσωρινής μνήμης συστήματος."</string>
- <string name="permdesc_cacheFilesystem" msgid="7301787168569544726">"Επιτρέπει στην εφαρμογή την πρόσβαση, την τροποποίηση και τη διαγραφή της προσωρινής μνήμης συστήματος. Κακόβουλες εφαρμογές μπορούν να το χρησιμοποιήσουν για να διακόψουν λήψεις ή τη λειτουργία άλλων εφαρμογών, καθώς και για να αποκτήσουν πρόσβαση σε προσωπικά δεδομένα."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Αποστολή ειδοποιήσεων λήψης."</string>
<string name="permdesc_downloadCompletedIntent" msgid="8672701687104399228">"Επιτρέπει στην εφαρμογή να στέλνει ειδοποιήσεις σχετικά με τις ολοκληρωμένες λήψεις. Κακόβουλες εφαρμογές μπορούν να το χρησιμοποιήσουν για να μπερδέψουν άλλες εφαρμογές που πραγματοποιούν λήψεις αρχείων."</string>
+ <string name="permlab_seeAllExternal" msgid="140058400609165726">"Εμφάνιση όλων των λήψεων στην κάρτα SD"</string>
+ <string name="permdesc_seeAllExternal" msgid="3298948060016417104">"Επιτρέπει στην εφαρμογή την εμφάνιση όλων των λήψεων στην κάρτα SD, ανεξάρτητα από την εφαρμογή που πραγματοποίησε τις λήψεις τους."</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;Χωρίς τίτλο&gt;"</string>
<string name="notification_filename_separator" msgid="7147189522857807618">", "</string>
<string name="notification_filename_extras" msgid="5549729917695688191">" και <xliff:g id="NUMBER">%d</xliff:g> ακόμα"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 48d10723..945229a8 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- 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.
@@ -12,21 +12,22 @@
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">"Administrador de carga"</string>
- <string name="permlab_downloadManager" msgid="7779544811202855500">"Acceder al administrador de descarga."</string>
+ <string name="permlab_downloadManager" msgid="7779544811202855500">"Accede al administrador de descarga."</string>
<string name="permdesc_downloadManager" msgid="4240298564918160337">"Permite a la aplicación acceder al administrador de descarga y utilizarlo para descargar archivos. Las aplicaciones maliciosas pueden utilizarlo para interrumpir las descargas y acceder a información privada."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Funciones avanzadas del administrador de descarga"</string>
<string name="permdesc_downloadManagerAdvanced" msgid="6985743912436565114">"Permite a la aplicación acceder a las funciones avanzadas del administrador de descarga. Las aplicaciones maliciosas pueden utilizarlo para interrumpir las descargas y acceder a información privada."</string>
- <string name="permlab_cacheFilesystem" msgid="6987994626343144212">"Usar caché del sistema"</string>
- <string name="permdesc_cacheFilesystem" msgid="7301787168569544726">"Permite a la aplicación acceder, modificar y eliminar el caché del sistema directamente. Las aplicaciones maliciosas pueden utilizarlo para interrumpir gravemente las descargas y otras aplicaciones, y acceder a información privada."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Enviar notificaciones de descarga."</string>
<string name="permdesc_downloadCompletedIntent" msgid="8672701687104399228">"Permite a la aplicación enviar notificaciones acerca de las descargas completadas. Las aplicaciones maliciosas pueden utilizarlo para confundir a otras aplicaciones que descargan archivos."</string>
+ <string name="permlab_seeAllExternal" msgid="140058400609165726">"Ver todas las descargas de la tarjeta SD"</string>
+ <string name="permdesc_seeAllExternal" msgid="3298948060016417104">"Permite que la aplicación vea todas las descargas de la tarjeta SD, independientemente de qué aplicación las descargó."</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;Sin título&gt;"</string>
<string name="notification_filename_separator" msgid="7147189522857807618">", "</string>
<string name="notification_filename_extras" msgid="5549729917695688191">" y <xliff:g id="NUMBER">%d</xliff:g> más"</string>
<string name="notification_download_complete" msgid="840713937779273632">"Descarga completa"</string>
- <string name="notification_download_failed" msgid="5343637375905111462">"Descarga incorrecta"</string>
+ <string name="notification_download_failed" msgid="5343637375905111462">"La descarga no se ha realizado correctamente"</string>
</resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 5affad7e..eb9e3e46 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- 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.
@@ -12,7 +12,8 @@
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">"Administrador de descargas"</string>
@@ -20,10 +21,10 @@
<string name="permdesc_downloadManager" msgid="4240298564918160337">"Permite que la aplicación acceda al administrador de descargas y lo utilice para descargar archivos. Las aplicaciones malintencionadas pueden utilizar este permiso para provocar daños en las descargas y acceder a información privada."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Funciones avanzadas del administrador de descargas"</string>
<string name="permdesc_downloadManagerAdvanced" msgid="6985743912436565114">"Permite que la aplicación acceda a las funciones avanzadas del administrador de descargas. Las aplicaciones malintencionadas pueden utilizar este permiso para provocar daños en las descargas y acceder a información privada."</string>
- <string name="permlab_cacheFilesystem" msgid="6987994626343144212">"Uso de la memoria caché del sistema"</string>
- <string name="permdesc_cacheFilesystem" msgid="7301787168569544726">"Permite que la aplicación acceda directamente a la memoria caché del sistema, la modifique y la elimine. Las aplicaciones malintencionadas pueden utilizar este permiso para provocar graves daños en las descargas y en otras aplicaciones, así como para acceder a datos privados."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Envío de notificaciones de descarga"</string>
<string name="permdesc_downloadCompletedIntent" msgid="8672701687104399228">"Permite que la aplicación envíe notificaciones sobre descargas completadas. Las aplicaciones malintencionadas pueden utilizar este permiso para confundir a otras aplicaciones que descarguen archivos."</string>
+ <string name="permlab_seeAllExternal" msgid="140058400609165726">"Ver todas las descargas en tarjeta SD"</string>
+ <string name="permdesc_seeAllExternal" msgid="3298948060016417104">"Permite que la aplicación vea todas las descargas en la tarjeta SD, independientemente de la aplicación que las haya descargado."</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;Sin título&gt;"</string>
<string name="notification_filename_separator" msgid="7147189522857807618">", "</string>
<string name="notification_filename_extras" msgid="5549729917695688191">" y <xliff:g id="NUMBER">%d</xliff:g> más"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index e57a8845..f6181669 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- 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.
@@ -12,7 +12,8 @@
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>
@@ -20,10 +21,10 @@
<string name="permdesc_downloadManager" msgid="4240298564918160337">"Permet à l\'application d\'accéder au gestionnaire de téléchargement et de l\'utiliser pour télécharger des fichiers. Les applications malveillantes peuvent s\'en servir pour entraver les téléchargements et accéder aux informations personnelles."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Fonctions avancées du gestionnaire de téléchargement."</string>
<string name="permdesc_downloadManagerAdvanced" msgid="6985743912436565114">"Permet à l\'application d\'accéder aux fonctions avancées du gestionnaire de téléchargements. Des applications malveillantes peuvent utiliser cette option pour perturber les téléchargements et accéder à des informations personnelles."</string>
- <string name="permlab_cacheFilesystem" msgid="6987994626343144212">"Utiliser le cache système"</string>
- <string name="permdesc_cacheFilesystem" msgid="7301787168569544726">"Permet à l\'application d\'accéder directement au cache système, de le modifier et de le supprimer. Les applications malveillantes peuvent s\'en servir pour entraver sévèrement les téléchargements et autres applications et pour accéder à des données personnelles."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Envoyer des notifications de téléchargement."</string>
<string name="permdesc_downloadCompletedIntent" msgid="8672701687104399228">"Permet à l\'application d\'envoyer des notifications concernant les téléchargements effectués. Les applications malveillantes peuvent s\'en servir pour tromper les autres applications de téléchargement de fichiers."</string>
+ <string name="permlab_seeAllExternal" msgid="140058400609165726">"Voir tous les téléchargements effectués sur la carte SD"</string>
+ <string name="permdesc_seeAllExternal" msgid="3298948060016417104">"Permet à l\'application d\'afficher tous les téléchargements effectués sur la carte SD, quelle que soit l\'application de téléchargement utilisée."</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;Sans_titre&gt;"</string>
<string name="notification_filename_separator" msgid="7147189522857807618">", "</string>
<string name="notification_filename_extras" msgid="5549729917695688191">" et <xliff:g id="NUMBER">%d</xliff:g> autres"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 7b77538d..2a8de4f0 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- 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.
@@ -12,7 +12,8 @@
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">"Gestore dei download"</string>
@@ -20,10 +21,10 @@
<string name="permdesc_downloadManager" msgid="4240298564918160337">"Consente l\'accesso dell\'applicazione al gestore dei download e il suo utilizzo per scaricare file. Le applicazioni dannose possono sfruttare questa possibilità per interrompere download e accedere a informazioni riservate."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Funzioni avanzate del gestore dei download."</string>
<string name="permdesc_downloadManagerAdvanced" msgid="6985743912436565114">"Consente l\'accesso dell\'applicazione alle funzioni avanzate del gestore dei download. Le applicazioni dannose possono sfruttare questa possibilità per interrompere download e accedere a informazioni riservate."</string>
- <string name="permlab_cacheFilesystem" msgid="6987994626343144212">"Usare la cache del sistema."</string>
- <string name="permdesc_cacheFilesystem" msgid="7301787168569544726">"Consente l\'accesso diretto dell\'applicazione alla cache del sistema, nonché la modifica e l\'eliminazione della cache. Le applicazioni dannose possono sfruttare questa possibilità per interrompere download e altre applicazioni e accedere a dati riservati."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Inviare notifiche di download."</string>
<string name="permdesc_downloadCompletedIntent" msgid="8672701687104399228">"Consente l\'invio da parte dell\'applicazione di notifiche relative ai download completati. Le applicazioni dannose possono sfruttare questa possibilità per \"confondere\" altre applicazioni usate per scaricare file."</string>
+ <string name="permlab_seeAllExternal" msgid="140058400609165726">"Visualizza tutti i download sulla scheda SD"</string>
+ <string name="permdesc_seeAllExternal" msgid="3298948060016417104">"Consente all\'applicazione di visualizzare tutti i download sulla scheda SD, indipendentemente dall\'applicazione che li ha scaricati."</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;Senza nome&gt;"</string>
<string name="notification_filename_separator" msgid="7147189522857807618">", "</string>
<string name="notification_filename_extras" msgid="5549729917695688191">" e <xliff:g id="NUMBER">%d</xliff:g> altri"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 1189b0c0..ccc17992 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- 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.
@@ -12,7 +12,8 @@
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>
@@ -20,10 +21,10 @@
<string name="permdesc_downloadManager" msgid="4240298564918160337">"ダウンロードマネージャーにアクセスしてファイルをダウンロードすることをアプリケーションに許可します。悪意のあるアプリケーションがこれを利用して、ダウンロードに深刻な影響を与えたり、個人データにアクセスしたりする恐れがあり。"</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"ダウンロードマネージャーの高度な機能です。"</string>
<string name="permdesc_downloadManagerAdvanced" msgid="6985743912436565114">"ダウンロードマネージャーの高度な機能にアプリケーションからアクセスできるようにします。これにより、悪意のあるアプリケーションがダウンロードに深刻な影響を与えたり個人情報にアクセスしたりできるようになります。"</string>
- <string name="permlab_cacheFilesystem" msgid="6987994626343144212">"システムキャッシュを使用します。"</string>
- <string name="permdesc_cacheFilesystem" msgid="7301787168569544726">"システムキャッシュの直接アクセス、変更、削除をアプリケーションに許可します。悪意のあるアプリケーションがダウンロードや他のアプリケーションに深刻な影響を与えたり、個人データにアクセスする恐れがあります。"</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"ダウンロード通知を送信します。"</string>
<string name="permdesc_downloadCompletedIntent" msgid="8672701687104399228">"ダウンロード完了の通知の送信をアプリケーションに許可します。悪意のあるアプリケーションがファイルをダウンロードする他のアプリケーションの処理を妨害する恐れがあります。"</string>
+ <string name="permlab_seeAllExternal" msgid="140058400609165726">"SDカードへのダウンロードをすべて参照する"</string>
+ <string name="permdesc_seeAllExternal" msgid="3298948060016417104">"どのアプリケーションでダウンロードされたかにかかわらず、SDカードにダウンロードされたすべてのファイルの参照をアプリケーションに許可します。"</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;無題&gt;"</string>
<string name="notification_filename_separator" msgid="7147189522857807618">"、 "</string>
<string name="notification_filename_extras" msgid="5549729917695688191">" その他<xliff:g id="NUMBER">%d</xliff:g>件"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index da8ad492..982649ae 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- 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.
@@ -12,7 +12,8 @@
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>
@@ -20,10 +21,10 @@
<string name="permdesc_downloadManager" msgid="4240298564918160337">"응용프로그램이 다운로드 관리자에 액세스하여 파일을 다운로드하도록 허용합니다. 이 경우 악성 응용프로그램이 다운로드를 중단시키고 비공개 정보에 액세스할 수 있습니다."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"고급 다운로드 관리자 기능입니다."</string>
<string name="permdesc_downloadManagerAdvanced" msgid="6985743912436565114">"응용프로그램이 다운로드 관리자의 고급 기능에 액세스할 수 있도록 허용합니다. 이 경우 악성 응용프로그램이 다운로드를 중단시키고 개인 정보에 액세스할 수 있습니다."</string>
- <string name="permlab_cacheFilesystem" msgid="6987994626343144212">"시스템 캐시를 사용합니다."</string>
- <string name="permdesc_cacheFilesystem" msgid="7301787168569544726">"응용프로그램이 시스템 캐시에 직접 액세스, 수정 및 삭제할 수 있도록 허용합니다. 이 경우 악성 응용프로그램이 다운로드와 기타 응용프로그램을 심각하게 방해하고 비공개 데이터에 액세스할 수 있습니다."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"다운로드 알림을 전송합니다."</string>
<string name="permdesc_downloadCompletedIntent" msgid="8672701687104399228">"응용프로그램이 완료된 다운로드에 대한 알림을 보낼 수 있도록 허용합니다. 이 경우 악성 응용프로그램이 파일을 다운로드하는 다른 응용프로그램에 혼란을 야기할 할 수 있습니다."</string>
+ <string name="permlab_seeAllExternal" msgid="140058400609165726">"SD 카드에 다운로드한 모든 항목 보기"</string>
+ <string name="permdesc_seeAllExternal" msgid="3298948060016417104">"어떤 응용프로그램을 사용하여 다운로드했는지에 관계없이 SD 카드에 다운로드한 모든 항목을 응용프로그램에 표시합니다."</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;제목 없음&gt;"</string>
<string name="notification_filename_separator" msgid="7147189522857807618">", "</string>
<string name="notification_filename_extras" msgid="5549729917695688191">" 외 <xliff:g id="NUMBER">%d</xliff:g>개"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 129c7bee..12cebf8b 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- 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.
@@ -12,7 +12,8 @@
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">"Nedlaster"</string>
@@ -20,10 +21,10 @@
<string name="permdesc_downloadManager" msgid="4240298564918160337">"Gir applikasjonen tilgang til nedlasteren, og å bruke den til å laste ned filer. Ondsinnede applikasjoner 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="6985743912436565114">"Gir programmet tilgang til avanserte funksjoner i nedlastingsprogrammene. Skadelige programmer kan bruke dette til å forstyrre nedlastninger og gi tilgang til privat informasjon."</string>
- <string name="permlab_cacheFilesystem" msgid="6987994626343144212">"Bruke systemets hurtigbuffer."</string>
- <string name="permdesc_cacheFilesystem" msgid="7301787168569544726">"Gir applikasjonen direkte tilgang til systemets hurtigbuffer, inkludert å redigere og slette den. Ondsinnede applikasjoner kan bruke dette til å forstyrre nedlastinger og andre applikasjoner, og til å få tilgang til privat informasjon."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Sende nedlastingsvarslinger"</string>
<string name="permdesc_downloadCompletedIntent" msgid="8672701687104399228">"Lar applikasjonen sende varslinger om ferdige nedlastinger. Ondsinnede applikasjoner kan bruke dette for å forvirre andre applikasjoner som laster ned filer."</string>
+ <string name="permlab_seeAllExternal" msgid="140058400609165726">"Vis alle nedlastinger til SD-kort"</string>
+ <string name="permdesc_seeAllExternal" msgid="3298948060016417104">"Programmet viser alle nedlastinger til SD-kort, uavhengig av hvilket program de ble lastet ned fra."</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;Uten navn&gt;"</string>
<string name="notification_filename_separator" msgid="7147189522857807618">", "</string>
<string name="notification_filename_extras" msgid="5549729917695688191">" og <xliff:g id="NUMBER">%d</xliff:g> til"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index e276f4ee..96203c33 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- 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.
@@ -12,7 +12,8 @@
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">"Downloadbeheer"</string>
@@ -20,10 +21,10 @@
<string name="permdesc_downloadManager" msgid="4240298564918160337">"Hiermee kan de toepassing Downloadbeheer gebruiken om bestanden te downloaden. Kwaadwillende toepassingen kunnen hiervan gebruikmaken om downloads te verstoren en om toegang te krijgen tot privégegevens."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Geavanceerde functies van de downloadbeheerder."</string>
<string name="permdesc_downloadManagerAdvanced" msgid="6985743912436565114">"Hiermee krijgt de toepassing toegang tot de geavanceerde functies van de downloadbeheerder. Schadelijke toepassingen kunnen hiermee downloads onderbreken en toegang krijgen tot uw privégegevens."</string>
- <string name="permlab_cacheFilesystem" msgid="6987994626343144212">"Systeemcache gebruiken."</string>
- <string name="permdesc_cacheFilesystem" msgid="7301787168569544726">"Hiermee kan de toepassing rechtstreeks de systeemcache openen, aanpassen of wissen. Kwaadwillende toepassingen kunnen hiervan gebruikmaken om downloads en andere toepassingen te verstoren en om toegang te krijgen tot privégegevens."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Downloadmeldingen verzenden."</string>
<string name="permdesc_downloadCompletedIntent" msgid="8672701687104399228">"Hiermee ontvangt u een melding zodra een download is voltooid. Kwaadwillende toepassingen kunnen hiervan gebruikmaken om andere toepassingen die bestanden downloaden, in de war te brengen."</string>
+ <string name="permlab_seeAllExternal" msgid="140058400609165726">"Alle downloads naar SD-kaart weergeven"</string>
+ <string name="permdesc_seeAllExternal" msgid="3298948060016417104">"Staat de toepassing toe alle downloads naar de SD-kaart weer te geven, ongeacht op welke toepassing de download is uitgevoerd."</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;Zonder titel&gt;"</string>
<string name="notification_filename_separator" msgid="7147189522857807618">", "</string>
<string name="notification_filename_extras" msgid="5549729917695688191">" en nog <xliff:g id="NUMBER">%d</xliff:g> meer"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 4dff7929..2e138ab8 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- 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.
@@ -12,7 +12,8 @@
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">"Menedżer pobierania"</string>
@@ -20,10 +21,10 @@
<string name="permdesc_downloadManager" msgid="4240298564918160337">"Umożliwia programowi dostęp do menedżera pobierania i pobieranie plików przy jego użyciu. Szkodliwe programy mogą w ten sposób zakłócić pobieranie i uzyskać dostęp do prywatnych informacji."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Zaawansowane funkcje menedżera pobierania."</string>
<string name="permdesc_downloadManagerAdvanced" msgid="6985743912436565114">"Zezwala aplikacji na uzyskiwanie dostępu do zaawansowanych funkcji menedżera pobierania. Złośliwe aplikacje mogą wykorzystać tę możliwość w celu zakłócenia pobierania i uzyskania dostępu do informacji prywatnych."</string>
- <string name="permlab_cacheFilesystem" msgid="6987994626343144212">"Korzystanie z systemowej pamięci podręcznej."</string>
- <string name="permdesc_cacheFilesystem" msgid="7301787168569544726">"Umożliwia programowi bezpośredni dostęp do systemowej pamięci podręcznej, jej modyfikację oraz usuwanie. Szkodliwe programy mogą w ten sposób poważnie zakłócić pobieranie plików i działanie innych programów, a także uzyskać dostęp do prywatnych informacji."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Wysyłanie powiadomień o pobraniu."</string>
<string name="permdesc_downloadCompletedIntent" msgid="8672701687104399228">"Umożliwia programowi wysyłanie powiadomień o ukończeniu pobierania. Szkodliwe programy mogą korzystać z tego uprawnienia, aby zakłócić działanie innych programów pobierających pliki."</string>
+ <string name="permlab_seeAllExternal" msgid="140058400609165726">"Sprawdzanie wszystkich plików pobranych na kartę SD"</string>
+ <string name="permdesc_seeAllExternal" msgid="3298948060016417104">"Zezwala aplikacji na sprawdzanie wszystkich plików pobranych na kartę SD niezależnie od tego, która aplikacja je pobrała."</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;Bez nazwy&gt;"</string>
<string name="notification_filename_separator" msgid="7147189522857807618">", "</string>
<string name="notification_filename_extras" msgid="5549729917695688191">" i inne (<xliff:g id="NUMBER">%d</xliff:g>)"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 2b2e02ec..0bde6f1e 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- 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.
@@ -12,7 +12,8 @@
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">"Gestor de Transferências"</string>
@@ -20,10 +21,10 @@
<string name="permdesc_downloadManager" msgid="4240298564918160337">"Permite que a aplicação aceda ao gestor de transferências e o utilize para transferir ficheiros. As aplicações maliciosas podem utilizar esta permissão para interromper transferências e aceder a informações privadas."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Funções avançadas do gestor de transferências"</string>
<string name="permdesc_downloadManagerAdvanced" msgid="6985743912436565114">"Permite que a aplicação aceda às funções avançadas do gestor de transferências. As aplicações maliciosas podem utilizar esta permissão para interromper transferências e aceder a informações privadas."</string>
- <string name="permlab_cacheFilesystem" msgid="6987994626343144212">"Utilizar a cache do sistema."</string>
- <string name="permdesc_cacheFilesystem" msgid="7301787168569544726">"Permite que a aplicação aceda, modifique e elimine directamente a cache do sistema. As aplicações maliciosas podem utilizar esta permissão para interromper gravemente transferências e outras aplicações e aceder a dados privados."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Enviar notificações de transferências."</string>
<string name="permdesc_downloadCompletedIntent" msgid="8672701687104399228">"Permite que a aplicação envie notificações acerca de transferências concluídas. As aplicações maliciosas podem utilizar esta permissão para confundir outras aplicações que transfiram ficheiros."</string>
+ <string name="permlab_seeAllExternal" msgid="140058400609165726">"Ver todas as transferências para o cartão SD"</string>
+ <string name="permdesc_seeAllExternal" msgid="3298948060016417104">"Permite à aplicação ver todas as transferências efectuadas para o cartão SD, independentemente da aplicação utilizada nas transferências."</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;Sem nome&gt;"</string>
<string name="notification_filename_separator" msgid="7147189522857807618">", "</string>
<string name="notification_filename_extras" msgid="5549729917695688191">" e mais <xliff:g id="NUMBER">%d</xliff:g>"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 24f88f53..7b9ca9fb 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- 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.
@@ -12,7 +12,8 @@
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">"Gerenciador de downloads"</string>
@@ -20,10 +21,10 @@
<string name="permdesc_downloadManager" msgid="4240298564918160337">"Permite que o aplicativo acesse o gerenciador de download e use-o para fazer o download de arquivos. Aplicativos maliciosos podem usar isso para interromper os downloads e acessar informações particulares."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Funções avançadas do gerenciador de download."</string>
<string name="permdesc_downloadManagerAdvanced" msgid="6985743912436565114">"Permite que o aplicativo acesse as funções avançadas do gerenciador de downloads. Aplicativos maliciosos podem usar isso para interromper os downloads e acessar informações particulares."</string>
- <string name="permlab_cacheFilesystem" msgid="6987994626343144212">"Usar cache do sistema."</string>
- <string name="permdesc_cacheFilesystem" msgid="7301787168569544726">"Permite que o aplicativo acesse, modifique e exclua diretamente o cache do sistema. Aplicativos maliciosos podem usar isso para interromper os downloads e outros aplicativos e para acessar dados particulares."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Enviar notificações de download."</string>
<string name="permdesc_downloadCompletedIntent" msgid="8672701687104399228">"Permite que o aplicativo envie notificações sobre downloads concluídos. Aplicativos maliciosos podem usar isso para confundir outros aplicativos que fazem download de arquivos."</string>
+ <string name="permlab_seeAllExternal" msgid="140058400609165726">"Ver todos os downloads para o cartão SD"</string>
+ <string name="permdesc_seeAllExternal" msgid="3298948060016417104">"Permite que o aplicativo veja todos os downloads feitos no cartão SD, independentemente do aplicativo que fez o download."</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;Sem título&gt;"</string>
<string name="notification_filename_separator" msgid="7147189522857807618">", "</string>
<string name="notification_filename_extras" msgid="5549729917695688191">" e <xliff:g id="NUMBER">%d</xliff:g> mais"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index c1b0856f..175fdacd 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- 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.
@@ -12,7 +12,8 @@
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>
@@ -20,10 +21,10 @@
<string name="permdesc_downloadManager" msgid="4240298564918160337">"Предоставляет приложению доступ к менеджеру загрузки и позволяет использовать его для загрузки файлов. Вредоносное ПО может пользоваться этим для прерывания загрузок и доступа к личной информации."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Расширенные функции менеджера загрузки."</string>
<string name="permdesc_downloadManagerAdvanced" msgid="6985743912436565114">"Предоставляет приложению доступ к расширенным функциям диспетчера загрузки. Вредоносное ПО может этим воспользоваться для прерывания загрузки и доступа к личной информации."</string>
- <string name="permlab_cacheFilesystem" msgid="6987994626343144212">"Использовать системный кэш."</string>
- <string name="permdesc_cacheFilesystem" msgid="7301787168569544726">"Позволяет приложению получать прямой доступ, изменять и удалять системный кэш. Вредоносное ПО может пользоваться этим для прерывания загрузок и других приложений, а также для доступа к личной информации."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Отправить оповещение о загрузке."</string>
<string name="permdesc_downloadCompletedIntent" msgid="8672701687104399228">"Позволяет приложению отправлять оповещения о завершенных загрузках. Вредоносное ПО может пользоваться этим, мешая работе приложений, загружающих файлы."</string>
+ <string name="permlab_seeAllExternal" msgid="140058400609165726">"Просмотреть все загрузки на SD-карту"</string>
+ <string name="permdesc_seeAllExternal" msgid="3298948060016417104">"Разрешить программе доступ ко всем загрузкам на SD-карту независимо от того, через какое приложение они были загружены."</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;без названия&gt;"</string>
<string name="notification_filename_separator" msgid="7147189522857807618">", "</string>
<string name="notification_filename_extras" msgid="5549729917695688191">" и еще <xliff:g id="NUMBER">%d</xliff:g>"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 7a1084cf..82645b41 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- 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.
@@ -12,7 +12,8 @@
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">"Hämtningshanterare"</string>
@@ -20,10 +21,10 @@
<string name="permdesc_downloadManager" msgid="4240298564918160337">"Tillåter att ett program får åtkomst till hämtningshanteraren och hämtar filer med den. Skadliga program kan använda detta för att störa hämtningar och komma åt privat information."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Avancerade funktioner för hämtningshanterare."</string>
<string name="permdesc_downloadManagerAdvanced" msgid="6985743912436565114">"Tillåter att ett program får åtkomst till hämtningshanterarens avancerade funktioner. Skadliga program kan använda detta för att störa hämtningar och komma åt privat information."</string>
- <string name="permlab_cacheFilesystem" msgid="6987994626343144212">"Använd systemets cacheminne."</string>
- <string name="permdesc_cacheFilesystem" msgid="7301787168569544726">"Tillåter att ett program får direktåtkomst till systemets cacheminne och kan göra ändringar och borttagningar. Skadliga program kan använda detta för att störa hämtningar och andra program, och för att komma åt privat information."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"Skicka meddelande om hämtning."</string>
<string name="permdesc_downloadCompletedIntent" msgid="8672701687104399228">"Tillåter att ett program skickar meddelanden om slutförda hämtningar. Skadliga program kan använda detta för att störa andra program som hämtar filer."</string>
+ <string name="permlab_seeAllExternal" msgid="140058400609165726">"Visa alla hämtningar till SD-kort"</string>
+ <string name="permdesc_seeAllExternal" msgid="3298948060016417104">"Tillåter att programmet ser alla hämtningar till SD-kortet, oavsett vilket program som hämtat innehållet."</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;Okänd&gt;"</string>
<string name="notification_filename_separator" msgid="7147189522857807618">", "</string>
<string name="notification_filename_extras" msgid="5549729917695688191">" och <xliff:g id="NUMBER">%d</xliff:g> till"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 722e8b6f..52270907 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- 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.
@@ -12,18 +12,19 @@
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">"İndirme Yöneticisi"</string>
- <string name="permlab_downloadManager" msgid="7779544811202855500">"İndirme yöneticisine eriş."</string>
+ <string name="permlab_downloadManager" msgid="7779544811202855500">"İndirme yöneticisine erişin."</string>
<string name="permdesc_downloadManager" msgid="4240298564918160337">"Uygulamaya indirme yöneticisine erişme ve bunu dosyaları indirmek için kullanma izni verir. Kötü amaçlı uygulamalar bunu indirme işlemlerini bozmak ve özel bilgilere erişmek için kullanabilir."</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"Gelişmiş indirme yöneticisi işlevleri."</string>
<string name="permdesc_downloadManagerAdvanced" msgid="6985743912436565114">"Uygulamaya indirme yöneticisinin gelişmiş işlevlerine erişme izni verir. Kötü niyetli uygulamalar, indirme işlemlerini bozmak ve özel bilgilere erişmek için bunu kullanabilir."</string>
- <string name="permlab_cacheFilesystem" msgid="6987994626343144212">"Sistem önbelleğini kullan."</string>
- <string name="permdesc_cacheFilesystem" msgid="7301787168569544726">"Uygulamaya sistem önbelleğine doğrudan erişme, değiştirme ve silme izni verir. Kötü amaçlı uygulamalar bunu indirme işlemlerini ve diğer uygulamaları bozmak ve özel bilgilere erişmek için kullanabilir."</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"İndirme bildirimleri gönder."</string>
<string name="permdesc_downloadCompletedIntent" msgid="8672701687104399228">"Uygulamaya tamamlanan indirme işlemleri ile ilgili bildirimler gönderme izni verir. Kötü amaçlı uygulamalar bunu dosya indiren diğer uygulamaları yanıltmak için kullanabilir."</string>
+ <string name="permlab_seeAllExternal" msgid="140058400609165726">"SD karta yapılan tüm indirmeleri gör"</string>
+ <string name="permdesc_seeAllExternal" msgid="3298948060016417104">"Uygulamanın SD karta yapılan tüm indirmeleri, indirme işlemini yapan uygulamadan bağımsız olarak görmesine izin verir."</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;Adsız&gt;"</string>
<string name="notification_filename_separator" msgid="7147189522857807618">", "</string>
<string name="notification_filename_extras" msgid="5549729917695688191">" ve <xliff:g id="NUMBER">%d</xliff:g> adet daha"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index e494e1e9..fdab921e 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- 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.
@@ -12,7 +12,8 @@
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>
@@ -20,13 +21,13 @@
<string name="permdesc_downloadManager" msgid="4240298564918160337">"允许应用程序访问下载管理器以及用它下载文件。恶意应用程序可借此干扰下载,以及访问隐私信息。"</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"高级下载管理器功能。"</string>
<string name="permdesc_downloadManagerAdvanced" msgid="6985743912436565114">"允许应用程序使用下载管理器的高级功能。恶意应用程序可能会借此中断下载以及访问私密信息。"</string>
- <string name="permlab_cacheFilesystem" msgid="6987994626343144212">"使用系统缓存。"</string>
- <string name="permdesc_cacheFilesystem" msgid="7301787168569544726">"允许应用程序直接访问、修改和删除系统缓存。恶意应用程序可借此严重干扰下载和其他应用程序,以及访问保密数据。"</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"发送下载通知。"</string>
<string name="permdesc_downloadCompletedIntent" msgid="8672701687104399228">"允许应用程序发送关于已完成下载的通知。恶意应用程序可借此干扰下载文件的其他应用程序。"</string>
+ <string name="permlab_seeAllExternal" msgid="140058400609165726">"查看下载到 SD 卡的全部内容"</string>
+ <string name="permdesc_seeAllExternal" msgid="3298948060016417104">"无论下载到 SD 卡的内容是由什么应用程序下载的,都允许该应用程序查看所有这些内容。"</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;未命名&gt;"</string>
- <string name="notification_filename_separator" msgid="7147189522857807618">"、 "</string>
+ <string name="notification_filename_separator" msgid="7147189522857807618">", "</string>
<string name="notification_filename_extras" msgid="5549729917695688191">" 还有 <xliff:g id="NUMBER">%d</xliff:g> 项"</string>
<string name="notification_download_complete" msgid="840713937779273632">"下载完成"</string>
- <string name="notification_download_failed" msgid="5343637375905111462">"下载不成功"</string>
+ <string name="notification_download_failed" msgid="5343637375905111462">"下载失败"</string>
</resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 2ce08810..7aa4a752 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- 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.
@@ -12,7 +12,8 @@
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>
@@ -20,10 +21,10 @@
<string name="permdesc_downloadManager" msgid="4240298564918160337">"允許應用程式存取下載管理員,並使用它下載檔案。請注意:惡意程式可能使用此功能,影響下載並存取個人資料。"</string>
<string name="permlab_downloadManagerAdvanced" msgid="7103642833308809655">"下載管理員進階功能。"</string>
<string name="permdesc_downloadManagerAdvanced" msgid="6985743912436565114">"允許應用程式存取下載管理員的進階功能 (惡意應用程式可能會利用此功能讓下載發生錯誤並存取私人資訊)。"</string>
- <string name="permlab_cacheFilesystem" msgid="6987994626343144212">"使用系統快取。"</string>
- <string name="permdesc_cacheFilesystem" msgid="7301787168569544726">"允許應用程式直接存取、修改與刪除系統快取。請注意:惡意程式可能使用此功能,嚴重影響下載與其他應用程式,並存取個人資料。"</string>
<string name="permlab_downloadCompletedIntent" msgid="945913803765675685">"傳送下載通知。"</string>
<string name="permdesc_downloadCompletedIntent" msgid="8672701687104399228">"下載完成時,允許應用程式送出通知。請注意:惡意程式可能使用此功能干擾其他下載檔案的應用程式。"</string>
+ <string name="permlab_seeAllExternal" msgid="140058400609165726">"查看 SD 卡中的所有下載項目"</string>
+ <string name="permdesc_seeAllExternal" msgid="3298948060016417104">"允許應用程式查看 SD 卡中的所有下載項目,無論這些項目是透過何種應用程式進行下載。"</string>
<string name="download_unknown_title" msgid="7015124071247271585">"&lt;未命名&gt;"</string>
<string name="notification_filename_separator" msgid="7147189522857807618">", "</string>
<string name="notification_filename_extras" msgid="5549729917695688191">" 以及其他 <xliff:g id="NUMBER">%d</xliff:g> 個"</string>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f340c95a..7e40b608 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4,9 +4,9 @@
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.
@@ -55,22 +55,6 @@
Malicious applications can use this to disrupt downloads and access
private information.</string>
- <!-- This is the short description of a permission associated with the
- Android Download Manager. It is displayed as part of the description
- of any application that was granted that permission.
- This specific permission controls access to the Download Manager's
- private storage area. -->
- <string name="permlab_cacheFilesystem">Use system cache.</string>
- <!-- This is the long description of a permission associated with the
- Android Download Manager. It is displayed as part of the description
- of any application that was granted that permission.
- This specific permission controls access to the Download Manager's
- private storage area. -->
- <string name="permdesc_cacheFilesystem">Allows the application
- to directly access, modify and delete the system cache. Malicious
- applications can use this to severely disrupt downloads and
- other applications, and to access private data.</string>
-
<string name="permlab_downloadCompletedIntent">Send download
notifications.</string>
<!-- This is the long description of a permission associated with the
@@ -83,6 +67,12 @@
can use this to confuse other applications that download
files.</string>
+ <!-- Title for permission to see all downloads to EXTERNAL -->
+ <string name="permlab_seeAllExternal">See all downloads to SD card</string>
+ <!-- Description for the permission to see all downloads to EXTERNAL -->
+ <string name="permdesc_seeAllExternal">Allows the application to see all
+ downloads to the SD card, regardless of which application downloaded
+ them.</string>
<!-- This is the title that is used when displaying the notification
for a download that doesn't have a title associated with it. -->
<string name="download_unknown_title">&lt;Untitled&gt;</string>
diff --git a/src/com/android/providers/downloads/DownloadInfo.java b/src/com/android/providers/downloads/DownloadInfo.java
index 88cdede2..81895439 100644
--- a/src/com/android/providers/downloads/DownloadInfo.java
+++ b/src/com/android/providers/downloads/DownloadInfo.java
@@ -90,10 +90,10 @@ public class DownloadInfo {
public void sendIntentIfRequested(Uri contentUri, Context context) {
if (mPackage != null && mClass != null) {
- Intent intent = new Intent(Downloads.ACTION_DOWNLOAD_COMPLETED);
+ Intent intent = new Intent(Downloads.Impl.ACTION_DOWNLOAD_COMPLETED);
intent.setClassName(mPackage, mClass);
if (mExtras != null) {
- intent.putExtra(Downloads.COLUMN_NOTIFICATION_EXTRAS, mExtras);
+ intent.putExtra(Downloads.Impl.COLUMN_NOTIFICATION_EXTRAS, mExtras);
}
// We only send the content: URI, for security reasons. Otherwise, malicious
// applications would have an easier time spoofing download results by
@@ -121,7 +121,7 @@ public class DownloadInfo {
* should be started.
*/
public boolean isReadyToStart(long now) {
- if (mControl == Downloads.CONTROL_PAUSED) {
+ if (mControl == Downloads.Impl.CONTROL_PAUSED) {
// the download is paused, so it's not going to start
return false;
}
@@ -129,16 +129,16 @@ public class DownloadInfo {
// status hasn't been initialized yet, this is a new download
return true;
}
- if (mStatus == Downloads.STATUS_PENDING) {
+ if (mStatus == Downloads.Impl.STATUS_PENDING) {
// download is explicit marked as ready to start
return true;
}
- if (mStatus == Downloads.STATUS_RUNNING) {
+ if (mStatus == Downloads.Impl.STATUS_RUNNING) {
// download was interrupted (process killed, loss of power) while it was running,
// without a chance to update the database
return true;
}
- if (mStatus == Downloads.STATUS_RUNNING_PAUSED) {
+ if (mStatus == Downloads.Impl.STATUS_RUNNING_PAUSED) {
if (mNumFailed == 0) {
// download is waiting for network connectivity to return before it can resume
return true;
@@ -160,7 +160,7 @@ public class DownloadInfo {
* by checking the status.
*/
public boolean isReadyToRestart(long now) {
- if (mControl == Downloads.CONTROL_PAUSED) {
+ if (mControl == Downloads.Impl.CONTROL_PAUSED) {
// the download is paused, so it's not going to restart
return false;
}
@@ -168,11 +168,11 @@ public class DownloadInfo {
// download hadn't been initialized yet
return true;
}
- if (mStatus == Downloads.STATUS_PENDING) {
+ if (mStatus == Downloads.Impl.STATUS_PENDING) {
// download is explicit marked as ready to start
return true;
}
- if (mStatus == Downloads.STATUS_RUNNING_PAUSED) {
+ if (mStatus == Downloads.Impl.STATUS_RUNNING_PAUSED) {
if (mNumFailed == 0) {
// download is waiting for network connectivity to return before it can resume
return true;
@@ -190,10 +190,10 @@ public class DownloadInfo {
* completion.
*/
public boolean hasCompletionNotification() {
- if (!Downloads.isStatusCompleted(mStatus)) {
+ if (!Downloads.Impl.isStatusCompleted(mStatus)) {
return false;
}
- if (mVisibility == Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) {
+ if (mVisibility == Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) {
return true;
}
return false;
@@ -206,7 +206,7 @@ public class DownloadInfo {
if (!available) {
return false;
}
- if (mDestination == Downloads.DESTINATION_CACHE_PARTITION_NOROAMING) {
+ if (mDestination == Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING) {
return !roaming;
} else {
return true;
diff --git a/src/com/android/providers/downloads/DownloadNotification.java b/src/com/android/providers/downloads/DownloadNotification.java
index f7c10073..e9c0d4e6 100644
--- a/src/com/android/providers/downloads/DownloadNotification.java
+++ b/src/com/android/providers/downloads/DownloadNotification.java
@@ -43,15 +43,16 @@ class DownloadNotification {
static final String LOGTAG = "DownloadNotification";
static final String WHERE_RUNNING =
- "(" + Downloads.COLUMN_STATUS + " >= '100') AND (" +
- Downloads.COLUMN_STATUS + " <= '199') AND (" +
- Downloads.COLUMN_VISIBILITY + " IS NULL OR " +
- Downloads.COLUMN_VISIBILITY + " == '" + Downloads.VISIBILITY_VISIBLE + "' OR " +
- Downloads.COLUMN_VISIBILITY +
- " == '" + Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED + "')";
+ "(" + Downloads.Impl.COLUMN_STATUS + " >= '100') AND (" +
+ Downloads.Impl.COLUMN_STATUS + " <= '199') AND (" +
+ Downloads.Impl.COLUMN_VISIBILITY + " IS NULL OR " +
+ Downloads.Impl.COLUMN_VISIBILITY + " == '" + Downloads.Impl.VISIBILITY_VISIBLE + "' OR " +
+ Downloads.Impl.COLUMN_VISIBILITY +
+ " == '" + Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED + "')";
static final String WHERE_COMPLETED =
- Downloads.COLUMN_STATUS + " >= '200' AND " +
- Downloads.COLUMN_VISIBILITY + " == '" + Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED + "'";
+ Downloads.Impl.COLUMN_STATUS + " >= '200' AND " +
+ Downloads.Impl.COLUMN_VISIBILITY +
+ " == '" + Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED + "'";
/**
@@ -110,17 +111,17 @@ class DownloadNotification {
private void updateActiveNotification() {
// Active downloads
Cursor c = mContext.getContentResolver().query(
- Downloads.CONTENT_URI, new String [] {
- Downloads._ID,
- Downloads.COLUMN_TITLE,
- Downloads.COLUMN_DESCRIPTION,
- Downloads.COLUMN_NOTIFICATION_PACKAGE,
- Downloads.COLUMN_NOTIFICATION_CLASS,
- Downloads.COLUMN_CURRENT_BYTES,
- Downloads.COLUMN_TOTAL_BYTES,
- Downloads.COLUMN_STATUS, Downloads._DATA
+ Downloads.Impl.CONTENT_URI, new String [] {
+ Downloads.Impl._ID,
+ Downloads.Impl.COLUMN_TITLE,
+ Downloads.Impl.COLUMN_DESCRIPTION,
+ Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE,
+ Downloads.Impl.COLUMN_NOTIFICATION_CLASS,
+ Downloads.Impl.COLUMN_CURRENT_BYTES,
+ Downloads.Impl.COLUMN_TOTAL_BYTES,
+ Downloads.Impl.COLUMN_STATUS
},
- WHERE_RUNNING, null, Downloads._ID);
+ WHERE_RUNNING, null, Downloads.Impl._ID);
if (c == null) {
return;
@@ -135,7 +136,6 @@ class DownloadNotification {
final int currentBytesColumn = 5;
final int totalBytesColumn = 6;
final int statusColumn = 7;
- final int filenameColumnId = 8;
// Collate the notifications
mNotifications.clear();
@@ -143,6 +143,7 @@ class DownloadNotification {
String packageName = c.getString(ownerColumn);
int max = c.getInt(totalBytesColumn);
int progress = c.getInt(currentBytesColumn);
+ long id = c.getLong(idColumn);
String title = c.getString(titleColumn);
if (title == null || title.length() == 0) {
title = mContext.getResources().getString(
@@ -152,7 +153,7 @@ class DownloadNotification {
mNotifications.get(packageName).addItem(title, progress, max);
} else {
NotificationItem item = new NotificationItem();
- item.mId = c.getInt(idColumn);
+ item.mId = (int) id;
item.mPackageName = packageName;
item.mDescription = c.getString(descColumn);
String className = c.getString(classOwnerColumn);
@@ -202,7 +203,7 @@ class DownloadNotification {
Intent intent = new Intent(Constants.ACTION_LIST);
intent.setClassName("com.android.providers.downloads",
DownloadReceiver.class.getName());
- intent.setData(Uri.parse(Downloads.CONTENT_URI + "/" + item.mId));
+ intent.setData(Uri.parse(Downloads.Impl.CONTENT_URI + "/" + item.mId));
intent.putExtra("multiple", item.mTitleCount > 1);
n.contentIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
@@ -215,20 +216,19 @@ class DownloadNotification {
private void updateCompletedNotification() {
// Completed downloads
Cursor c = mContext.getContentResolver().query(
- Downloads.CONTENT_URI, new String [] {
- Downloads._ID,
- Downloads.COLUMN_TITLE,
- Downloads.COLUMN_DESCRIPTION,
- Downloads.COLUMN_NOTIFICATION_PACKAGE,
- Downloads.COLUMN_NOTIFICATION_CLASS,
- Downloads.COLUMN_CURRENT_BYTES,
- Downloads.COLUMN_TOTAL_BYTES,
- Downloads.COLUMN_STATUS,
- Downloads._DATA,
- Downloads.COLUMN_LAST_MODIFICATION,
- Downloads.COLUMN_DESTINATION
+ Downloads.Impl.CONTENT_URI, new String [] {
+ Downloads.Impl._ID,
+ Downloads.Impl.COLUMN_TITLE,
+ Downloads.Impl.COLUMN_DESCRIPTION,
+ Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE,
+ Downloads.Impl.COLUMN_NOTIFICATION_CLASS,
+ Downloads.Impl.COLUMN_CURRENT_BYTES,
+ Downloads.Impl.COLUMN_TOTAL_BYTES,
+ Downloads.Impl.COLUMN_STATUS,
+ Downloads.Impl.COLUMN_LAST_MODIFICATION,
+ Downloads.Impl.COLUMN_DESTINATION
},
- WHERE_COMPLETED, null, Downloads._ID);
+ WHERE_COMPLETED, null, Downloads.Impl._ID);
if (c == null) {
return;
@@ -243,31 +243,31 @@ class DownloadNotification {
final int currentBytesColumn = 5;
final int totalBytesColumn = 6;
final int statusColumn = 7;
- final int filenameColumnId = 8;
- final int lastModColumnId = 9;
- final int destinationColumnId = 10;
+ final int lastModColumnId = 8;
+ final int destinationColumnId = 9;
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
// Add the notifications
Notification n = new Notification();
n.icon = android.R.drawable.stat_sys_download_done;
+ long id = c.getLong(idColumn);
String title = c.getString(titleColumn);
if (title == null || title.length() == 0) {
title = mContext.getResources().getString(
R.string.download_unknown_title);
}
- Uri contentUri = Uri.parse(Downloads.CONTENT_URI + "/" + c.getInt(idColumn));
+ Uri contentUri = Uri.parse(Downloads.Impl.CONTENT_URI + "/" + id);
String caption;
Intent intent;
- if (Downloads.isStatusError(c.getInt(statusColumn))) {
+ if (Downloads.Impl.isStatusError(c.getInt(statusColumn))) {
caption = mContext.getResources()
.getString(R.string.notification_download_failed);
intent = new Intent(Constants.ACTION_LIST);
} else {
caption = mContext.getResources()
.getString(R.string.notification_download_complete);
- if (c.getInt(destinationColumnId) == Downloads.DESTINATION_EXTERNAL) {
+ if (c.getInt(destinationColumnId) == Downloads.Impl.DESTINATION_EXTERNAL) {
intent = new Intent(Constants.ACTION_OPEN);
} else {
intent = new Intent(Constants.ACTION_LIST);
@@ -276,6 +276,7 @@ class DownloadNotification {
intent.setClassName("com.android.providers.downloads",
DownloadReceiver.class.getName());
intent.setData(contentUri);
+
n.when = c.getLong(lastModColumnId);
n.setLatestEventInfo(mContext, title, caption,
PendingIntent.getBroadcast(mContext, 0, intent, 0));
diff --git a/src/com/android/providers/downloads/DownloadProvider.java b/src/com/android/providers/downloads/DownloadProvider.java
index f0190fd1..d7c24f9a 100644
--- a/src/com/android/providers/downloads/DownloadProvider.java
+++ b/src/com/android/providers/downloads/DownloadProvider.java
@@ -21,7 +21,9 @@ import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.UriMatcher;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.database.CrossProcessCursor;
import android.database.Cursor;
import android.database.CursorWindow;
@@ -76,21 +78,21 @@ public final class DownloadProvider extends ContentProvider {
}
private static final String[] sAppReadableColumnsArray = new String[] {
- Downloads._ID,
- Downloads.COLUMN_APP_DATA,
- Downloads._DATA,
- Downloads.COLUMN_MIME_TYPE,
- Downloads.COLUMN_VISIBILITY,
- Downloads.COLUMN_DESTINATION,
- Downloads.COLUMN_CONTROL,
- Downloads.COLUMN_STATUS,
- Downloads.COLUMN_LAST_MODIFICATION,
- Downloads.COLUMN_NOTIFICATION_PACKAGE,
- Downloads.COLUMN_NOTIFICATION_CLASS,
- Downloads.COLUMN_TOTAL_BYTES,
- Downloads.COLUMN_CURRENT_BYTES,
- Downloads.COLUMN_TITLE,
- Downloads.COLUMN_DESCRIPTION
+ Downloads.Impl._ID,
+ Downloads.Impl.COLUMN_APP_DATA,
+ Downloads.Impl._DATA,
+ Downloads.Impl.COLUMN_MIME_TYPE,
+ Downloads.Impl.COLUMN_VISIBILITY,
+ Downloads.Impl.COLUMN_DESTINATION,
+ Downloads.Impl.COLUMN_CONTROL,
+ Downloads.Impl.COLUMN_STATUS,
+ Downloads.Impl.COLUMN_LAST_MODIFICATION,
+ Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE,
+ Downloads.Impl.COLUMN_NOTIFICATION_CLASS,
+ Downloads.Impl.COLUMN_TOTAL_BYTES,
+ Downloads.Impl.COLUMN_CURRENT_BYTES,
+ Downloads.Impl.COLUMN_TITLE,
+ Downloads.Impl.COLUMN_DESCRIPTION
};
private static HashSet<String> sAppReadableColumnsSet;
@@ -104,6 +106,10 @@ public final class DownloadProvider extends ContentProvider {
/** The database that lies underneath this content provider */
private SQLiteOpenHelper mOpenHelper = null;
+ /** List of uids that can access the downloads */
+ private int mSystemUid = -1;
+ private int mDefContainerUid = -1;
+
/**
* Creates and updated database on demand when opening it.
* Helper class to create database the first time the provider is
@@ -167,6 +173,21 @@ public final class DownloadProvider extends ContentProvider {
@Override
public boolean onCreate() {
mOpenHelper = new DatabaseHelper(getContext());
+ // Initialize the system uid
+ mSystemUid = Process.SYSTEM_UID;
+ // Initialize the default container uid. Package name hardcoded
+ // for now.
+ ApplicationInfo appInfo = null;
+ try {
+ appInfo = getContext().getPackageManager().
+ getApplicationInfo("com.android.defcontainer", 0);
+ } catch (NameNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ if (appInfo != null) {
+ mDefContainerUid = appInfo.uid;
+ }
return true;
}
@@ -199,35 +220,35 @@ public final class DownloadProvider extends ContentProvider {
private void createTable(SQLiteDatabase db) {
try {
db.execSQL("CREATE TABLE " + DB_TABLE + "(" +
- Downloads._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
- Downloads.COLUMN_URI + " TEXT, " +
+ Downloads.Impl._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
+ Downloads.Impl.COLUMN_URI + " TEXT, " +
Constants.RETRY_AFTER_X_REDIRECT_COUNT + " INTEGER, " +
- Downloads.COLUMN_APP_DATA + " TEXT, " +
- Downloads.COLUMN_NO_INTEGRITY + " BOOLEAN, " +
- Downloads.COLUMN_FILE_NAME_HINT + " TEXT, " +
+ Downloads.Impl.COLUMN_APP_DATA + " TEXT, " +
+ Downloads.Impl.COLUMN_NO_INTEGRITY + " BOOLEAN, " +
+ Downloads.Impl.COLUMN_FILE_NAME_HINT + " TEXT, " +
Constants.OTA_UPDATE + " BOOLEAN, " +
- Downloads._DATA + " TEXT, " +
- Downloads.COLUMN_MIME_TYPE + " TEXT, " +
- Downloads.COLUMN_DESTINATION + " INTEGER, " +
+ Downloads.Impl._DATA + " TEXT, " +
+ Downloads.Impl.COLUMN_MIME_TYPE + " TEXT, " +
+ Downloads.Impl.COLUMN_DESTINATION + " INTEGER, " +
Constants.NO_SYSTEM_FILES + " BOOLEAN, " +
- Downloads.COLUMN_VISIBILITY + " INTEGER, " +
- Downloads.COLUMN_CONTROL + " INTEGER, " +
- Downloads.COLUMN_STATUS + " INTEGER, " +
+ Downloads.Impl.COLUMN_VISIBILITY + " INTEGER, " +
+ Downloads.Impl.COLUMN_CONTROL + " INTEGER, " +
+ Downloads.Impl.COLUMN_STATUS + " INTEGER, " +
Constants.FAILED_CONNECTIONS + " INTEGER, " +
- Downloads.COLUMN_LAST_MODIFICATION + " BIGINT, " +
- Downloads.COLUMN_NOTIFICATION_PACKAGE + " TEXT, " +
- Downloads.COLUMN_NOTIFICATION_CLASS + " TEXT, " +
- Downloads.COLUMN_NOTIFICATION_EXTRAS + " TEXT, " +
- Downloads.COLUMN_COOKIE_DATA + " TEXT, " +
- Downloads.COLUMN_USER_AGENT + " TEXT, " +
- Downloads.COLUMN_REFERER + " TEXT, " +
- Downloads.COLUMN_TOTAL_BYTES + " INTEGER, " +
- Downloads.COLUMN_CURRENT_BYTES + " INTEGER, " +
+ Downloads.Impl.COLUMN_LAST_MODIFICATION + " BIGINT, " +
+ Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE + " TEXT, " +
+ Downloads.Impl.COLUMN_NOTIFICATION_CLASS + " TEXT, " +
+ Downloads.Impl.COLUMN_NOTIFICATION_EXTRAS + " TEXT, " +
+ Downloads.Impl.COLUMN_COOKIE_DATA + " TEXT, " +
+ Downloads.Impl.COLUMN_USER_AGENT + " TEXT, " +
+ Downloads.Impl.COLUMN_REFERER + " TEXT, " +
+ Downloads.Impl.COLUMN_TOTAL_BYTES + " INTEGER, " +
+ Downloads.Impl.COLUMN_CURRENT_BYTES + " INTEGER, " +
Constants.ETAG + " TEXT, " +
Constants.UID + " INTEGER, " +
- Downloads.COLUMN_OTHER_UID + " INTEGER, " +
- Downloads.COLUMN_TITLE + " TEXT, " +
- Downloads.COLUMN_DESCRIPTION + " TEXT, " +
+ Downloads.Impl.COLUMN_OTHER_UID + " INTEGER, " +
+ Downloads.Impl.COLUMN_TITLE + " TEXT, " +
+ Downloads.Impl.COLUMN_DESCRIPTION + " TEXT, " +
Constants.MEDIA_SCANNED + " BOOLEAN);");
} catch (SQLException ex) {
Log.e(Constants.TAG, "couldn't create table in downloads database");
@@ -263,70 +284,71 @@ public final class DownloadProvider extends ContentProvider {
ContentValues filteredValues = new ContentValues();
- copyString(Downloads.COLUMN_URI, values, filteredValues);
- copyString(Downloads.COLUMN_APP_DATA, values, filteredValues);
- copyBoolean(Downloads.COLUMN_NO_INTEGRITY, values, filteredValues);
- copyString(Downloads.COLUMN_FILE_NAME_HINT, values, filteredValues);
- copyString(Downloads.COLUMN_MIME_TYPE, values, filteredValues);
- Integer dest = values.getAsInteger(Downloads.COLUMN_DESTINATION);
+ copyString(Downloads.Impl.COLUMN_URI, values, filteredValues);
+ copyString(Downloads.Impl.COLUMN_APP_DATA, values, filteredValues);
+ copyBoolean(Downloads.Impl.COLUMN_NO_INTEGRITY, values, filteredValues);
+ copyString(Downloads.Impl.COLUMN_FILE_NAME_HINT, values, filteredValues);
+ copyString(Downloads.Impl.COLUMN_MIME_TYPE, values, filteredValues);
+ Integer dest = values.getAsInteger(Downloads.Impl.COLUMN_DESTINATION);
if (dest != null) {
- if (getContext().checkCallingPermission(Downloads.PERMISSION_ACCESS_ADVANCED)
+ if (getContext().checkCallingPermission(Downloads.Impl.PERMISSION_ACCESS_ADVANCED)
!= PackageManager.PERMISSION_GRANTED
- && dest != Downloads.DESTINATION_EXTERNAL
- && dest != Downloads.DESTINATION_CACHE_PARTITION_PURGEABLE) {
+ && dest != Downloads.Impl.DESTINATION_EXTERNAL
+ && dest != Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE) {
throw new SecurityException("unauthorized destination code");
}
- filteredValues.put(Downloads.COLUMN_DESTINATION, dest);
+ filteredValues.put(Downloads.Impl.COLUMN_DESTINATION, dest);
}
- Integer vis = values.getAsInteger(Downloads.COLUMN_VISIBILITY);
+ Integer vis = values.getAsInteger(Downloads.Impl.COLUMN_VISIBILITY);
if (vis == null) {
- if (dest == Downloads.DESTINATION_EXTERNAL) {
- filteredValues.put(Downloads.COLUMN_VISIBILITY,
- Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
+ if (dest == Downloads.Impl.DESTINATION_EXTERNAL) {
+ filteredValues.put(Downloads.Impl.COLUMN_VISIBILITY,
+ Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
} else {
- filteredValues.put(Downloads.COLUMN_VISIBILITY, Downloads.VISIBILITY_HIDDEN);
+ filteredValues.put(Downloads.Impl.COLUMN_VISIBILITY,
+ Downloads.Impl.VISIBILITY_HIDDEN);
}
} else {
- filteredValues.put(Downloads.COLUMN_VISIBILITY, vis);
+ filteredValues.put(Downloads.Impl.COLUMN_VISIBILITY, vis);
}
- copyInteger(Downloads.COLUMN_CONTROL, values, filteredValues);
- filteredValues.put(Downloads.COLUMN_STATUS, Downloads.STATUS_PENDING);
- filteredValues.put(Downloads.COLUMN_LAST_MODIFICATION, System.currentTimeMillis());
- String pckg = values.getAsString(Downloads.COLUMN_NOTIFICATION_PACKAGE);
- String clazz = values.getAsString(Downloads.COLUMN_NOTIFICATION_CLASS);
+ copyInteger(Downloads.Impl.COLUMN_CONTROL, values, filteredValues);
+ filteredValues.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_PENDING);
+ filteredValues.put(Downloads.Impl.COLUMN_LAST_MODIFICATION, System.currentTimeMillis());
+ String pckg = values.getAsString(Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE);
+ String clazz = values.getAsString(Downloads.Impl.COLUMN_NOTIFICATION_CLASS);
if (pckg != null && clazz != null) {
int uid = Binder.getCallingUid();
try {
if (uid == 0 ||
getContext().getPackageManager().getApplicationInfo(pckg, 0).uid == uid) {
- filteredValues.put(Downloads.COLUMN_NOTIFICATION_PACKAGE, pckg);
- filteredValues.put(Downloads.COLUMN_NOTIFICATION_CLASS, clazz);
+ filteredValues.put(Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE, pckg);
+ filteredValues.put(Downloads.Impl.COLUMN_NOTIFICATION_CLASS, clazz);
}
} catch (PackageManager.NameNotFoundException ex) {
/* ignored for now */
}
}
- copyString(Downloads.COLUMN_NOTIFICATION_EXTRAS, values, filteredValues);
- copyString(Downloads.COLUMN_COOKIE_DATA, values, filteredValues);
- copyString(Downloads.COLUMN_USER_AGENT, values, filteredValues);
- copyString(Downloads.COLUMN_REFERER, values, filteredValues);
- if (getContext().checkCallingPermission(Downloads.PERMISSION_ACCESS_ADVANCED)
+ copyString(Downloads.Impl.COLUMN_NOTIFICATION_EXTRAS, values, filteredValues);
+ copyString(Downloads.Impl.COLUMN_COOKIE_DATA, values, filteredValues);
+ copyString(Downloads.Impl.COLUMN_USER_AGENT, values, filteredValues);
+ copyString(Downloads.Impl.COLUMN_REFERER, values, filteredValues);
+ if (getContext().checkCallingPermission(Downloads.Impl.PERMISSION_ACCESS_ADVANCED)
== PackageManager.PERMISSION_GRANTED) {
- copyInteger(Downloads.COLUMN_OTHER_UID, values, filteredValues);
+ copyInteger(Downloads.Impl.COLUMN_OTHER_UID, values, filteredValues);
}
filteredValues.put(Constants.UID, Binder.getCallingUid());
if (Binder.getCallingUid() == 0) {
copyInteger(Constants.UID, values, filteredValues);
}
- copyString(Downloads.COLUMN_TITLE, values, filteredValues);
- copyString(Downloads.COLUMN_DESCRIPTION, values, filteredValues);
+ copyString(Downloads.Impl.COLUMN_TITLE, values, filteredValues);
+ copyString(Downloads.Impl.COLUMN_DESCRIPTION, values, filteredValues);
if (Constants.LOGVV) {
Log.v(Constants.TAG, "initiating download with UID "
+ filteredValues.getAsInteger(Constants.UID));
- if (filteredValues.containsKey(Downloads.COLUMN_OTHER_UID)) {
+ if (filteredValues.containsKey(Downloads.Impl.COLUMN_OTHER_UID)) {
Log.v(Constants.TAG, "other UID " +
- filteredValues.getAsInteger(Downloads.COLUMN_OTHER_UID));
+ filteredValues.getAsInteger(Downloads.Impl.COLUMN_OTHER_UID));
}
}
@@ -339,7 +361,7 @@ public final class DownloadProvider extends ContentProvider {
if (rowID != -1) {
context.startService(new Intent(context, DownloadService.class));
- ret = Uri.parse(Downloads.CONTENT_URI + "/" + rowID);
+ ret = Uri.parse(Downloads.Impl.CONTENT_URI + "/" + rowID);
context.getContentResolver().notifyChange(uri, null);
} else {
if (Config.LOGD) {
@@ -373,7 +395,7 @@ public final class DownloadProvider extends ContentProvider {
}
case DOWNLOADS_ID: {
qb.setTables(DB_TABLE);
- qb.appendWhere(Downloads._ID + "=");
+ qb.appendWhere(Downloads.Impl._ID + "=");
qb.appendWhere(uri.getPathSegments().get(1));
emptyWhere = false;
break;
@@ -386,25 +408,45 @@ public final class DownloadProvider extends ContentProvider {
}
}
- if (Binder.getCallingPid() != Process.myPid() && Binder.getCallingUid() != 0 &&
+ int callingUid = Binder.getCallingUid();
+ if (Binder.getCallingPid() != Process.myPid() &&
+ callingUid != mSystemUid &&
+ callingUid != mDefContainerUid &&
Process.supportsProcesses()) {
- if (!emptyWhere) {
- qb.appendWhere(" AND ");
- }
- qb.appendWhere("( " + Constants.UID + "=" + Binder.getCallingUid() + " OR "
- + Downloads.COLUMN_OTHER_UID + "=" + Binder.getCallingUid() + " )");
- emptyWhere = false;
-
+ boolean canSeeAllExternal;
if (projection == null) {
projection = sAppReadableColumnsArray;
+ // sAppReadableColumnsArray includes _DATA, which is not allowed
+ // to be seen except by the initiating application
+ canSeeAllExternal = false;
} else {
+ canSeeAllExternal = getContext().checkCallingPermission(
+ Downloads.Impl.PERMISSION_SEE_ALL_EXTERNAL)
+ == PackageManager.PERMISSION_GRANTED;
for (int i = 0; i < projection.length; ++i) {
if (!sAppReadableColumnsSet.contains(projection[i])) {
throw new IllegalArgumentException(
"column " + projection[i] + " is not allowed in queries");
}
+ canSeeAllExternal = canSeeAllExternal
+ && !projection[i].equals(Downloads.Impl._DATA);
}
}
+ if (!emptyWhere) {
+ qb.appendWhere(" AND ");
+ emptyWhere = false;
+ }
+ String validUid = "( " + Constants.UID + "="
+ + Binder.getCallingUid() + " OR "
+ + Downloads.Impl.COLUMN_OTHER_UID + "="
+ + Binder.getCallingUid() + " )";
+ if (canSeeAllExternal) {
+ qb.appendWhere("( " + validUid + " OR "
+ + Downloads.Impl.DESTINATION_EXTERNAL + " = "
+ + Downloads.Impl.COLUMN_DESTINATION + " )");
+ } else {
+ qb.appendWhere(validUid);
+ }
}
if (Constants.LOGVV) {
@@ -489,18 +531,28 @@ public final class DownloadProvider extends ContentProvider {
ContentValues filteredValues;
if (Binder.getCallingPid() != Process.myPid()) {
filteredValues = new ContentValues();
- copyString(Downloads.COLUMN_APP_DATA, values, filteredValues);
- copyInteger(Downloads.COLUMN_VISIBILITY, values, filteredValues);
- Integer i = values.getAsInteger(Downloads.COLUMN_CONTROL);
+ copyString(Downloads.Impl.COLUMN_APP_DATA, values, filteredValues);
+ copyInteger(Downloads.Impl.COLUMN_VISIBILITY, values, filteredValues);
+ Integer i = values.getAsInteger(Downloads.Impl.COLUMN_CONTROL);
if (i != null) {
- filteredValues.put(Downloads.COLUMN_CONTROL, i);
+ filteredValues.put(Downloads.Impl.COLUMN_CONTROL, i);
startService = true;
}
- copyInteger(Downloads.COLUMN_CONTROL, values, filteredValues);
- copyString(Downloads.COLUMN_TITLE, values, filteredValues);
- copyString(Downloads.COLUMN_DESCRIPTION, values, filteredValues);
+ copyInteger(Downloads.Impl.COLUMN_CONTROL, values, filteredValues);
+ copyString(Downloads.Impl.COLUMN_TITLE, values, filteredValues);
+ copyString(Downloads.Impl.COLUMN_DESCRIPTION, values, filteredValues);
} else {
filteredValues = values;
+ String filename = values.getAsString(Downloads.Impl._DATA);
+ if (filename != null) {
+ Cursor c = query(uri, new String[]
+ { Downloads.Impl.COLUMN_TITLE }, null, null, null);
+ if (!c.moveToFirst() || c.getString(0) == null) {
+ values.put(Downloads.Impl.COLUMN_TITLE,
+ new File(filename).getName());
+ }
+ c.close();
+ }
}
int match = sURIMatcher.match(uri);
switch (match) {
@@ -519,11 +571,14 @@ public final class DownloadProvider extends ContentProvider {
if (match == DOWNLOADS_ID) {
String segment = uri.getPathSegments().get(1);
rowId = Long.parseLong(segment);
- myWhere += " ( " + Downloads._ID + " = " + rowId + " ) ";
+ myWhere += " ( " + Downloads.Impl._ID + " = " + rowId + " ) ";
}
- if (Binder.getCallingPid() != Process.myPid() && Binder.getCallingUid() != 0) {
+ int callingUid = Binder.getCallingUid();
+ if (Binder.getCallingPid() != Process.myPid() &&
+ callingUid != mSystemUid &&
+ callingUid != mDefContainerUid) {
myWhere += " AND ( " + Constants.UID + "=" + Binder.getCallingUid() + " OR "
- + Downloads.COLUMN_OTHER_UID + "=" + Binder.getCallingUid() + " )";
+ + Downloads.Impl.COLUMN_OTHER_UID + "=" + Binder.getCallingUid() + " )";
}
if (filteredValues.size() > 0) {
count = db.update(DB_TABLE, filteredValues, myWhere, whereArgs);
@@ -575,11 +630,15 @@ public final class DownloadProvider extends ContentProvider {
if (match == DOWNLOADS_ID) {
String segment = uri.getPathSegments().get(1);
long rowId = Long.parseLong(segment);
- myWhere += " ( " + Downloads._ID + " = " + rowId + " ) ";
+ myWhere += " ( " + Downloads.Impl._ID + " = " + rowId + " ) ";
}
- if (Binder.getCallingPid() != Process.myPid() && Binder.getCallingUid() != 0) {
+ int callingUid = Binder.getCallingUid();
+ if (Binder.getCallingPid() != Process.myPid() &&
+ callingUid != mSystemUid &&
+ callingUid != mDefContainerUid) {
myWhere += " AND ( " + Constants.UID + "=" + Binder.getCallingUid() + " OR "
- + Downloads.COLUMN_OTHER_UID + "=" + Binder.getCallingUid() + " )";
+ + Downloads.Impl.COLUMN_OTHER_UID + "="
+ + Binder.getCallingUid() + " )";
}
count = db.delete(DB_TABLE, myWhere, whereArgs);
break;
@@ -604,7 +663,8 @@ public final class DownloadProvider extends ContentProvider {
if (Constants.LOGVV) {
Log.v(Constants.TAG, "openFile uri: " + uri + ", mode: " + mode
+ ", uid: " + Binder.getCallingUid());
- Cursor cursor = query(Downloads.CONTENT_URI, new String[] { "_id" }, null, null, "_id");
+ Cursor cursor = query(Downloads.Impl.CONTENT_URI,
+ new String[] { "_id" }, null, null, "_id");
if (cursor == null) {
Log.v(Constants.TAG, "null cursor in openFile");
} else {
@@ -673,7 +733,7 @@ public final class DownloadProvider extends ContentProvider {
throw new FileNotFoundException("couldn't open file");
} else {
ContentValues values = new ContentValues();
- values.put(Downloads.COLUMN_LAST_MODIFICATION, System.currentTimeMillis());
+ values.put(Downloads.Impl.COLUMN_LAST_MODIFICATION, System.currentTimeMillis());
update(uri, values, null, null);
}
return ret;
diff --git a/src/com/android/providers/downloads/DownloadReceiver.java b/src/com/android/providers/downloads/DownloadReceiver.java
index 2065c649..e8f10e7d 100644
--- a/src/com/android/providers/downloads/DownloadReceiver.java
+++ b/src/com/android/providers/downloads/DownloadReceiver.java
@@ -86,22 +86,23 @@ public class DownloadReceiver extends BroadcastReceiver {
intent.getData(), null, null, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
- int statusColumn = cursor.getColumnIndexOrThrow(Downloads.COLUMN_STATUS);
+ int statusColumn = cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_STATUS);
int status = cursor.getInt(statusColumn);
int visibilityColumn =
- cursor.getColumnIndexOrThrow(Downloads.COLUMN_VISIBILITY);
+ cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_VISIBILITY);
int visibility = cursor.getInt(visibilityColumn);
- if (Downloads.isStatusCompleted(status)
- && visibility == Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) {
+ if (Downloads.Impl.isStatusCompleted(status)
+ && visibility == Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) {
ContentValues values = new ContentValues();
- values.put(Downloads.COLUMN_VISIBILITY, Downloads.VISIBILITY_VISIBLE);
+ values.put(Downloads.Impl.COLUMN_VISIBILITY,
+ Downloads.Impl.VISIBILITY_VISIBLE);
context.getContentResolver().update(intent.getData(), values, null, null);
}
if (intent.getAction().equals(Constants.ACTION_OPEN)) {
- int filenameColumn = cursor.getColumnIndexOrThrow(Downloads._DATA);
+ int filenameColumn = cursor.getColumnIndexOrThrow(Downloads.Impl._DATA);
int mimetypeColumn =
- cursor.getColumnIndexOrThrow(Downloads.COLUMN_MIME_TYPE);
+ cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_MIME_TYPE);
String filename = cursor.getString(filenameColumn);
String mimetype = cursor.getString(mimetypeColumn);
Uri path = Uri.parse(filename);
@@ -122,17 +123,18 @@ public class DownloadReceiver extends BroadcastReceiver {
// swallow the exception entirely
}
} else {
- int packageColumn =
- cursor.getColumnIndexOrThrow(Downloads.COLUMN_NOTIFICATION_PACKAGE);
- int classColumn =
- cursor.getColumnIndexOrThrow(Downloads.COLUMN_NOTIFICATION_CLASS);
+ int packageColumn = cursor.getColumnIndexOrThrow(
+ Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE);
+ int classColumn = cursor.getColumnIndexOrThrow(
+ Downloads.Impl.COLUMN_NOTIFICATION_CLASS);
String pckg = cursor.getString(packageColumn);
String clazz = cursor.getString(classColumn);
if (pckg != null && clazz != null) {
- Intent appIntent = new Intent(Downloads.ACTION_NOTIFICATION_CLICKED);
+ Intent appIntent =
+ new Intent(Downloads.Impl.ACTION_NOTIFICATION_CLICKED);
appIntent.setClassName(pckg, clazz);
if (intent.getBooleanExtra("multiple", true)) {
- appIntent.setData(Downloads.CONTENT_URI);
+ appIntent.setData(Downloads.Impl.CONTENT_URI);
} else {
appIntent.setData(intent.getData());
}
@@ -155,15 +157,16 @@ public class DownloadReceiver extends BroadcastReceiver {
intent.getData(), null, null, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
- int statusColumn = cursor.getColumnIndexOrThrow(Downloads.COLUMN_STATUS);
+ int statusColumn = cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_STATUS);
int status = cursor.getInt(statusColumn);
int visibilityColumn =
- cursor.getColumnIndexOrThrow(Downloads.COLUMN_VISIBILITY);
+ cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_VISIBILITY);
int visibility = cursor.getInt(visibilityColumn);
- if (Downloads.isStatusCompleted(status)
- && visibility == Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) {
+ if (Downloads.Impl.isStatusCompleted(status)
+ && visibility == Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) {
ContentValues values = new ContentValues();
- values.put(Downloads.COLUMN_VISIBILITY, Downloads.VISIBILITY_VISIBLE);
+ values.put(Downloads.Impl.COLUMN_VISIBILITY,
+ Downloads.Impl.VISIBILITY_VISIBLE);
context.getContentResolver().update(intent.getData(), values, null, null);
}
}
diff --git a/src/com/android/providers/downloads/DownloadService.java b/src/com/android/providers/downloads/DownloadService.java
index a246d29f..9e890ea0 100644
--- a/src/com/android/providers/downloads/DownloadService.java
+++ b/src/com/android/providers/downloads/DownloadService.java
@@ -203,7 +203,7 @@ public class DownloadService extends Service {
mDownloads = Lists.newArrayList();
mObserver = new DownloadManagerContentObserver();
- getContentResolver().registerContentObserver(Downloads.CONTENT_URI,
+ getContentResolver().registerContentObserver(Downloads.Impl.CONTENT_URI,
true, mObserver);
mMediaScannerService = null;
@@ -307,8 +307,8 @@ public class DownloadService extends Service {
boolean networkRoaming = Helpers.isNetworkRoaming(DownloadService.this);
long now = System.currentTimeMillis();
- Cursor cursor = getContentResolver().query(Downloads.CONTENT_URI,
- null, null, null, Downloads._ID);
+ Cursor cursor = getContentResolver().query(Downloads.Impl.CONTENT_URI,
+ null, null, null, Downloads.Impl._ID);
if (cursor == null) {
// TODO: this doesn't look right, it'd leave the loop in an inconsistent state
@@ -325,7 +325,7 @@ public class DownloadService extends Service {
boolean isAfterLast = cursor.isAfterLast();
- int idColumn = cursor.getColumnIndexOrThrow(Downloads._ID);
+ int idColumn = cursor.getColumnIndexOrThrow(Downloads.Impl._ID);
/*
* Walk the cursor and the local array to keep them in sync. The key
@@ -491,8 +491,8 @@ public class DownloadService extends Service {
fileSet.add(files[i].getPath());
}
- Cursor cursor = getContentResolver().query(Downloads.CONTENT_URI,
- new String[] { Downloads._DATA }, null, null, null);
+ Cursor cursor = getContentResolver().query(Downloads.Impl.CONTENT_URI,
+ new String[] { Downloads.Impl._DATA }, null, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
@@ -515,10 +515,10 @@ public class DownloadService extends Service {
* Drops old rows from the database to prevent it from growing too large
*/
private void trimDatabase() {
- Cursor cursor = getContentResolver().query(Downloads.CONTENT_URI,
- new String[] { Downloads._ID },
- Downloads.COLUMN_STATUS + " >= '200'", null,
- Downloads.COLUMN_LAST_MODIFICATION);
+ Cursor cursor = getContentResolver().query(Downloads.Impl.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");
@@ -526,11 +526,11 @@ public class DownloadService extends Service {
}
if (cursor.moveToFirst()) {
int numDelete = cursor.getCount() - Constants.MAX_DOWNLOADS;
- int columnId = cursor.getColumnIndexOrThrow(Downloads._ID);
+ int columnId = cursor.getColumnIndexOrThrow(Downloads.Impl._ID);
while (numDelete > 0) {
getContentResolver().delete(
- ContentUris.withAppendedId(Downloads.CONTENT_URI, cursor.getLong(columnId)),
- null, null);
+ ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI,
+ cursor.getLong(columnId)), null, null);
if (!cursor.moveToNext()) {
break;
}
@@ -547,35 +547,39 @@ public class DownloadService extends Service {
private void insertDownload(
Cursor cursor, int arrayPos,
boolean networkAvailable, boolean networkRoaming, long now) {
- int statusColumn = cursor.getColumnIndexOrThrow(Downloads.COLUMN_STATUS);
+ int statusColumn = cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_STATUS);
int failedColumn = cursor.getColumnIndexOrThrow(Constants.FAILED_CONNECTIONS);
int retryRedirect =
cursor.getInt(cursor.getColumnIndexOrThrow(Constants.RETRY_AFTER_X_REDIRECT_COUNT));
DownloadInfo info = new DownloadInfo(
- cursor.getInt(cursor.getColumnIndexOrThrow(Downloads._ID)),
- cursor.getString(cursor.getColumnIndexOrThrow(Downloads.COLUMN_URI)),
- cursor.getInt(cursor.getColumnIndexOrThrow(Downloads.COLUMN_NO_INTEGRITY)) == 1,
- cursor.getString(cursor.getColumnIndexOrThrow(Downloads.COLUMN_FILE_NAME_HINT)),
- cursor.getString(cursor.getColumnIndexOrThrow(Downloads._DATA)),
- cursor.getString(cursor.getColumnIndexOrThrow(Downloads.COLUMN_MIME_TYPE)),
- cursor.getInt(cursor.getColumnIndexOrThrow(Downloads.COLUMN_DESTINATION)),
- cursor.getInt(cursor.getColumnIndexOrThrow(Downloads.COLUMN_VISIBILITY)),
- cursor.getInt(cursor.getColumnIndexOrThrow(Downloads.COLUMN_CONTROL)),
+ cursor.getInt(cursor.getColumnIndexOrThrow(Downloads.Impl._ID)),
+ cursor.getString(cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_URI)),
+ cursor.getInt(cursor.getColumnIndexOrThrow(
+ Downloads.Impl.COLUMN_NO_INTEGRITY)) == 1,
+ cursor.getString(cursor.getColumnIndexOrThrow(
+ Downloads.Impl.COLUMN_FILE_NAME_HINT)),
+ cursor.getString(cursor.getColumnIndexOrThrow(Downloads.Impl._DATA)),
+ cursor.getString(cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_MIME_TYPE)),
+ cursor.getInt(cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_DESTINATION)),
+ cursor.getInt(cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_VISIBILITY)),
+ cursor.getInt(cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_CONTROL)),
cursor.getInt(statusColumn),
cursor.getInt(failedColumn),
retryRedirect & 0xfffffff,
retryRedirect >> 28,
- cursor.getLong(cursor.getColumnIndexOrThrow(Downloads.COLUMN_LAST_MODIFICATION)),
+ cursor.getLong(cursor.getColumnIndexOrThrow(
+ Downloads.Impl.COLUMN_LAST_MODIFICATION)),
+ cursor.getString(cursor.getColumnIndexOrThrow(
+ Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE)),
cursor.getString(cursor.getColumnIndexOrThrow(
- Downloads.COLUMN_NOTIFICATION_PACKAGE)),
- cursor.getString(cursor.getColumnIndexOrThrow(Downloads.COLUMN_NOTIFICATION_CLASS)),
+ Downloads.Impl.COLUMN_NOTIFICATION_CLASS)),
cursor.getString(cursor.getColumnIndexOrThrow(
- Downloads.COLUMN_NOTIFICATION_EXTRAS)),
- cursor.getString(cursor.getColumnIndexOrThrow(Downloads.COLUMN_COOKIE_DATA)),
- cursor.getString(cursor.getColumnIndexOrThrow(Downloads.COLUMN_USER_AGENT)),
- cursor.getString(cursor.getColumnIndexOrThrow(Downloads.COLUMN_REFERER)),
- cursor.getInt(cursor.getColumnIndexOrThrow(Downloads.COLUMN_TOTAL_BYTES)),
- cursor.getInt(cursor.getColumnIndexOrThrow(Downloads.COLUMN_CURRENT_BYTES)),
+ Downloads.Impl.COLUMN_NOTIFICATION_EXTRAS)),
+ cursor.getString(cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_COOKIE_DATA)),
+ cursor.getString(cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_USER_AGENT)),
+ cursor.getString(cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_REFERER)),
+ cursor.getInt(cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_TOTAL_BYTES)),
+ cursor.getInt(cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_CURRENT_BYTES)),
cursor.getString(cursor.getColumnIndexOrThrow(Constants.ETAG)),
cursor.getInt(cursor.getColumnIndexOrThrow(Constants.MEDIA_SCANNED)) == 1);
@@ -609,36 +613,36 @@ public class DownloadService extends Service {
mDownloads.add(arrayPos, info);
if (info.mStatus == 0
- && (info.mDestination == Downloads.DESTINATION_EXTERNAL
- || info.mDestination == Downloads.DESTINATION_CACHE_PARTITION_PURGEABLE)
+ && (info.mDestination == Downloads.Impl.DESTINATION_EXTERNAL
+ || info.mDestination == Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE)
&& info.mMimeType != null
&& !DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING.equalsIgnoreCase(info.mMimeType)) {
// Check to see if we are allowed to download this file. Only files
// that can be handled by the platform can be downloaded.
// special case DRM files, which we should always allow downloading.
Intent mimetypeIntent = new Intent(Intent.ACTION_VIEW);
-
+
// We can provide data as either content: or file: URIs,
// so allow both. (I think it would be nice if we just did
// everything as content: URIs)
// Actually, right now the download manager's UId restrictions
// prevent use from using content: so it's got to be file: or
// nothing
-
+
mimetypeIntent.setDataAndType(Uri.fromParts("file", "", null), info.mMimeType);
ResolveInfo ri = getPackageManager().resolveActivity(mimetypeIntent,
PackageManager.MATCH_DEFAULT_ONLY);
//Log.i(Constants.TAG, "*** QUERY " + mimetypeIntent + ": " + list);
-
+
if (ri == null) {
if (Config.LOGD) {
Log.d(Constants.TAG, "no application to handle MIME type " + info.mMimeType);
}
- info.mStatus = Downloads.STATUS_NOT_ACCEPTABLE;
+ info.mStatus = Downloads.Impl.STATUS_NOT_ACCEPTABLE;
- Uri uri = ContentUris.withAppendedId(Downloads.CONTENT_URI, info.mId);
+ Uri uri = ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, info.mId);
ContentValues values = new ContentValues();
- values.put(Downloads.COLUMN_STATUS, Downloads.STATUS_NOT_ACCEPTABLE);
+ values.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_NOT_ACCEPTABLE);
getContentResolver().update(uri, values, null, null);
info.sendIntentIfRequested(uri, this);
return;
@@ -654,12 +658,12 @@ public class DownloadService extends Service {
if (info.mHasActiveThread) {
throw new IllegalStateException("Multiple threads on same download on insert");
}
- if (info.mStatus != Downloads.STATUS_RUNNING) {
- info.mStatus = Downloads.STATUS_RUNNING;
+ if (info.mStatus != Downloads.Impl.STATUS_RUNNING) {
+ info.mStatus = Downloads.Impl.STATUS_RUNNING;
ContentValues values = new ContentValues();
- values.put(Downloads.COLUMN_STATUS, info.mStatus);
+ values.put(Downloads.Impl.COLUMN_STATUS, info.mStatus);
getContentResolver().update(
- ContentUris.withAppendedId(Downloads.CONTENT_URI, info.mId),
+ ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, info.mId),
values, null, null);
}
DownloadThread downloader = new DownloadThread(this, info);
@@ -668,12 +672,12 @@ public class DownloadService extends Service {
}
} else {
if (info.mStatus == 0
- || info.mStatus == Downloads.STATUS_PENDING
- || info.mStatus == Downloads.STATUS_RUNNING) {
- info.mStatus = Downloads.STATUS_RUNNING_PAUSED;
- Uri uri = ContentUris.withAppendedId(Downloads.CONTENT_URI, info.mId);
+ || info.mStatus == Downloads.Impl.STATUS_PENDING
+ || info.mStatus == Downloads.Impl.STATUS_RUNNING) {
+ info.mStatus = Downloads.Impl.STATUS_RUNNING_PAUSED;
+ Uri uri = ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, info.mId);
ContentValues values = new ContentValues();
- values.put(Downloads.COLUMN_STATUS, Downloads.STATUS_RUNNING_PAUSED);
+ values.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_RUNNING_PAUSED);
getContentResolver().update(uri, values, null, null);
}
}
@@ -686,30 +690,32 @@ public class DownloadService extends Service {
Cursor cursor, int arrayPos,
boolean networkAvailable, boolean networkRoaming, long now) {
DownloadInfo info = (DownloadInfo) mDownloads.get(arrayPos);
- int statusColumn = cursor.getColumnIndexOrThrow(Downloads.COLUMN_STATUS);
+ int statusColumn = cursor.getColumnIndexOrThrow(Downloads.Impl.COLUMN_STATUS);
int failedColumn = cursor.getColumnIndexOrThrow(Constants.FAILED_CONNECTIONS);
- info.mId = cursor.getInt(cursor.getColumnIndexOrThrow(Downloads._ID));
- info.mUri = stringFromCursor(info.mUri, cursor, Downloads.COLUMN_URI);
- info.mNoIntegrity =
- cursor.getInt(cursor.getColumnIndexOrThrow(Downloads.COLUMN_NO_INTEGRITY)) == 1;
- info.mHint = stringFromCursor(info.mHint, cursor, Downloads.COLUMN_FILE_NAME_HINT);
- info.mFileName = stringFromCursor(info.mFileName, cursor, Downloads._DATA);
- info.mMimeType = stringFromCursor(info.mMimeType, cursor, Downloads.COLUMN_MIME_TYPE);
+ info.mId = cursor.getInt(cursor.getColumnIndexOrThrow(Downloads.Impl._ID));
+ info.mUri = stringFromCursor(info.mUri, cursor, Downloads.Impl.COLUMN_URI);
+ info.mNoIntegrity = cursor.getInt(cursor.getColumnIndexOrThrow(
+ Downloads.Impl.COLUMN_NO_INTEGRITY)) == 1;
+ info.mHint = stringFromCursor(info.mHint, cursor, Downloads.Impl.COLUMN_FILE_NAME_HINT);
+ info.mFileName = stringFromCursor(info.mFileName, cursor, Downloads.Impl._DATA);
+ info.mMimeType = stringFromCursor(info.mMimeType, cursor, Downloads.Impl.COLUMN_MIME_TYPE);
info.mDestination = cursor.getInt(cursor.getColumnIndexOrThrow(
- Downloads.COLUMN_DESTINATION));
+ Downloads.Impl.COLUMN_DESTINATION));
int newVisibility = cursor.getInt(cursor.getColumnIndexOrThrow(
- Downloads.COLUMN_VISIBILITY));
- if (info.mVisibility == Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED
- && newVisibility != Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED
- && Downloads.isStatusCompleted(info.mStatus)) {
+ Downloads.Impl.COLUMN_VISIBILITY));
+ if (info.mVisibility == Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED
+ && newVisibility != Downloads.Impl.VISIBILITY_VISIBLE_NOTIFY_COMPLETED
+ && Downloads.Impl.isStatusCompleted(info.mStatus)) {
mNotifier.mNotificationMgr.cancel(info.mId);
}
info.mVisibility = newVisibility;
synchronized (info) {
- info.mControl = cursor.getInt(cursor.getColumnIndexOrThrow(Downloads.COLUMN_CONTROL));
+ info.mControl = cursor.getInt(cursor.getColumnIndexOrThrow(
+ Downloads.Impl.COLUMN_CONTROL));
}
int newStatus = cursor.getInt(statusColumn);
- if (!Downloads.isStatusCompleted(info.mStatus) && Downloads.isStatusCompleted(newStatus)) {
+ if (!Downloads.Impl.isStatusCompleted(info.mStatus) &&
+ Downloads.Impl.isStatusCompleted(newStatus)) {
mNotifier.mNotificationMgr.cancel(info.mId);
}
info.mStatus = newStatus;
@@ -719,17 +725,19 @@ public class DownloadService extends Service {
info.mRetryAfter = retryRedirect & 0xfffffff;
info.mRedirectCount = retryRedirect >> 28;
info.mLastMod = cursor.getLong(cursor.getColumnIndexOrThrow(
- Downloads.COLUMN_LAST_MODIFICATION));
+ Downloads.Impl.COLUMN_LAST_MODIFICATION));
info.mPackage = stringFromCursor(
- info.mPackage, cursor, Downloads.COLUMN_NOTIFICATION_PACKAGE);
- info.mClass = stringFromCursor(info.mClass, cursor, Downloads.COLUMN_NOTIFICATION_CLASS);
- info.mCookies = stringFromCursor(info.mCookies, cursor, Downloads.COLUMN_COOKIE_DATA);
- info.mUserAgent = stringFromCursor(info.mUserAgent, cursor, Downloads.COLUMN_USER_AGENT);
- info.mReferer = stringFromCursor(info.mReferer, cursor, Downloads.COLUMN_REFERER);
+ info.mPackage, cursor, Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE);
+ info.mClass = stringFromCursor(
+ info.mClass, cursor, Downloads.Impl.COLUMN_NOTIFICATION_CLASS);
+ info.mCookies = stringFromCursor(info.mCookies, cursor, Downloads.Impl.COLUMN_COOKIE_DATA);
+ info.mUserAgent = stringFromCursor(
+ info.mUserAgent, cursor, Downloads.Impl.COLUMN_USER_AGENT);
+ info.mReferer = stringFromCursor(info.mReferer, cursor, Downloads.Impl.COLUMN_REFERER);
info.mTotalBytes = cursor.getInt(cursor.getColumnIndexOrThrow(
- Downloads.COLUMN_TOTAL_BYTES));
+ Downloads.Impl.COLUMN_TOTAL_BYTES));
info.mCurrentBytes = cursor.getInt(cursor.getColumnIndexOrThrow(
- Downloads.COLUMN_CURRENT_BYTES));
+ Downloads.Impl.COLUMN_CURRENT_BYTES));
info.mETag = stringFromCursor(info.mETag, cursor, Constants.ETAG);
info.mMediaScanned =
cursor.getInt(cursor.getColumnIndexOrThrow(Constants.MEDIA_SCANNED)) == 1;
@@ -743,11 +751,11 @@ public class DownloadService extends Service {
if (info.mHasActiveThread) {
throw new IllegalStateException("Multiple threads on same download on update");
}
- info.mStatus = Downloads.STATUS_RUNNING;
+ info.mStatus = Downloads.Impl.STATUS_RUNNING;
ContentValues values = new ContentValues();
- values.put(Downloads.COLUMN_STATUS, info.mStatus);
+ values.put(Downloads.Impl.COLUMN_STATUS, info.mStatus);
getContentResolver().update(
- ContentUris.withAppendedId(Downloads.CONTENT_URI, info.mId),
+ ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, info.mId),
values, null, null);
DownloadThread downloader = new DownloadThread(this, info);
info.mHasActiveThread = true;
@@ -792,9 +800,10 @@ public class DownloadService extends Service {
*/
private void deleteDownload(int arrayPos) {
DownloadInfo info = (DownloadInfo) mDownloads.get(arrayPos);
- if (info.mStatus == Downloads.STATUS_RUNNING) {
- info.mStatus = Downloads.STATUS_CANCELED;
- } else if (info.mDestination != Downloads.DESTINATION_EXTERNAL && info.mFileName != null) {
+ if (info.mStatus == Downloads.Impl.STATUS_RUNNING) {
+ info.mStatus = Downloads.Impl.STATUS_CANCELED;
+ } else if (info.mDestination != Downloads.Impl.DESTINATION_EXTERNAL
+ && info.mFileName != null) {
new File(info.mFileName).delete();
}
mNotifier.mNotificationMgr.cancel(info.mId);
@@ -811,10 +820,10 @@ public class DownloadService extends Service {
*/
private long nextAction(int arrayPos, long now) {
DownloadInfo info = (DownloadInfo) mDownloads.get(arrayPos);
- if (Downloads.isStatusCompleted(info.mStatus)) {
+ if (Downloads.Impl.isStatusCompleted(info.mStatus)) {
return -1;
}
- if (info.mStatus != Downloads.STATUS_RUNNING_PAUSED) {
+ if (info.mStatus != Downloads.Impl.STATUS_RUNNING_PAUSED) {
return 0;
}
if (info.mNumFailed == 0) {
@@ -841,8 +850,8 @@ public class DownloadService extends Service {
private boolean shouldScanFile(int arrayPos) {
DownloadInfo info = (DownloadInfo) mDownloads.get(arrayPos);
return !info.mMediaScanned
- && info.mDestination == Downloads.DESTINATION_EXTERNAL
- && Downloads.isStatusSuccess(info.mStatus)
+ && info.mDestination == Downloads.Impl.DESTINATION_EXTERNAL
+ && Downloads.Impl.isStatusSuccess(info.mStatus)
&& !DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING.equalsIgnoreCase(info.mMimeType);
}
@@ -869,9 +878,9 @@ public class DownloadService extends Service {
if (cursor != null) {
ContentValues values = new ContentValues();
values.put(Constants.MEDIA_SCANNED, 1);
- getContentResolver().update(
- ContentUris.withAppendedId(Downloads.CONTENT_URI,
- cursor.getLong(cursor.getColumnIndexOrThrow(Downloads._ID))),
+ getContentResolver().update(ContentUris.withAppendedId(
+ Downloads.Impl.CONTENT_URI, cursor.getLong(
+ cursor.getColumnIndexOrThrow(Downloads.Impl._ID))),
values, null, null);
}
return true;
diff --git a/src/com/android/providers/downloads/DownloadThread.java b/src/com/android/providers/downloads/DownloadThread.java
index 1ad1d4f9..d2bd3220 100644
--- a/src/com/android/providers/downloads/DownloadThread.java
+++ b/src/com/android/providers/downloads/DownloadThread.java
@@ -37,6 +37,7 @@ import android.provider.DrmStore;
import android.util.Config;
import android.util.Log;
+
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
@@ -80,7 +81,7 @@ public class DownloadThread extends Thread {
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
- int finalStatus = Downloads.STATUS_UNKNOWN_ERROR;
+ int finalStatus = Downloads.Impl.STATUS_UNKNOWN_ERROR;
boolean countRetry = false;
int retryAfter = 0;
int redirectCount = mInfo.mRedirectCount;
@@ -91,7 +92,7 @@ public class DownloadThread extends Thread {
FileOutputStream stream = null;
AndroidHttpClient client = null;
PowerManager.WakeLock wakeLock = null;
- Uri contentUri = Uri.parse(Downloads.CONTENT_URI + "/" + mInfo.mId);
+ Uri contentUri = Uri.parse(Downloads.Impl.CONTENT_URI + "/" + mInfo.mId);
try {
boolean continuingDownload = false;
@@ -113,7 +114,7 @@ public class DownloadThread extends Thread {
filename = mInfo.mFileName;
if (filename != null) {
if (!Helpers.isFilenameValid(filename)) {
- finalStatus = Downloads.STATUS_FILE_ERROR;
+ finalStatus = Downloads.Impl.STATUS_FILE_ERROR;
notifyDownloadCompleted(
finalStatus, false, 0, 0, false, filename, null, mInfo.mMimeType);
return;
@@ -133,7 +134,7 @@ public class DownloadThread extends Thread {
"can't resume interrupted non-resumable download");
}
f.delete();
- finalStatus = Downloads.STATUS_PRECONDITION_FAILED;
+ finalStatus = Downloads.Impl.STATUS_PRECONDITION_FAILED;
notifyDownloadCompleted(
finalStatus, false, 0, 0, false, filename, null, mInfo.mMimeType);
return;
@@ -155,9 +156,9 @@ public class DownloadThread extends Thread {
// progress to the database
long timeLastNotification = 0;
- client = AndroidHttpClient.newInstance(userAgent());
+ client = AndroidHttpClient.newInstance(userAgent(), mContext);
- if (stream != null && mInfo.mDestination == Downloads.DESTINATION_EXTERNAL
+ if (stream != null && mInfo.mDestination == Downloads.Impl.DESTINATION_EXTERNAL
&& !DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING
.equalsIgnoreCase(mimeType)) {
try {
@@ -210,7 +211,7 @@ http_request_loop:
Log.d(Constants.TAG, "Arg exception trying to execute request for " +
mInfo.mId + " : " + ex);
}
- finalStatus = Downloads.STATUS_BAD_REQUEST;
+ finalStatus = Downloads.Impl.STATUS_BAD_REQUEST;
request.abort();
break http_request_loop;
} catch (IOException ex) {
@@ -222,9 +223,9 @@ http_request_loop:
}
}
if (!Helpers.isNetworkAvailable(mContext)) {
- finalStatus = Downloads.STATUS_RUNNING_PAUSED;
+ finalStatus = Downloads.Impl.STATUS_RUNNING_PAUSED;
} else if (mInfo.mNumFailed < Constants.MAX_RETRIES) {
- finalStatus = Downloads.STATUS_RUNNING_PAUSED;
+ finalStatus = Downloads.Impl.STATUS_RUNNING_PAUSED;
countRetry = true;
} else {
if (Constants.LOGV) {
@@ -234,7 +235,7 @@ http_request_loop:
Log.d(Constants.TAG, "IOException trying to execute request for " +
mInfo.mId + " : " + ex);
}
- finalStatus = Downloads.STATUS_HTTP_DATA_ERROR;
+ finalStatus = Downloads.Impl.STATUS_HTTP_DATA_ERROR;
}
request.abort();
break http_request_loop;
@@ -245,7 +246,7 @@ http_request_loop:
if (Constants.LOGVV) {
Log.v(Constants.TAG, "got HTTP response code 503");
}
- finalStatus = Downloads.STATUS_RUNNING_PAUSED;
+ finalStatus = Downloads.Impl.STATUS_RUNNING_PAUSED;
countRetry = true;
Header header = response.getFirstHeader("Retry-After");
if (header != null) {
@@ -286,7 +287,7 @@ http_request_loop:
} else if (Config.LOGD) {
Log.d(Constants.TAG, "too many redirects for download " + mInfo.mId);
}
- finalStatus = Downloads.STATUS_TOO_MANY_REDIRECTS;
+ finalStatus = Downloads.Impl.STATUS_TOO_MANY_REDIRECTS;
request.abort();
break http_request_loop;
}
@@ -311,17 +312,17 @@ http_request_loop:
"Couldn't resolve redirect URI for download " +
mInfo.mId);
}
- finalStatus = Downloads.STATUS_BAD_REQUEST;
+ finalStatus = Downloads.Impl.STATUS_BAD_REQUEST;
request.abort();
break http_request_loop;
}
++redirectCount;
- finalStatus = Downloads.STATUS_RUNNING_PAUSED;
+ finalStatus = Downloads.Impl.STATUS_RUNNING_PAUSED;
request.abort();
break http_request_loop;
}
}
- if ((!continuingDownload && statusCode != Downloads.STATUS_SUCCESS)
+ if ((!continuingDownload && statusCode != Downloads.Impl.STATUS_SUCCESS)
|| (continuingDownload && statusCode != 206)) {
if (Constants.LOGV) {
Log.d(Constants.TAG, "http error " + statusCode + " for " + mInfo.mUri);
@@ -329,14 +330,14 @@ http_request_loop:
Log.d(Constants.TAG, "http error " + statusCode + " for download " +
mInfo.mId);
}
- if (Downloads.isStatusError(statusCode)) {
+ if (Downloads.Impl.isStatusError(statusCode)) {
finalStatus = statusCode;
} else if (statusCode >= 300 && statusCode < 400) {
- finalStatus = Downloads.STATUS_UNHANDLED_REDIRECT;
- } else if (continuingDownload && statusCode == Downloads.STATUS_SUCCESS) {
- finalStatus = Downloads.STATUS_PRECONDITION_FAILED;
+ finalStatus = Downloads.Impl.STATUS_UNHANDLED_REDIRECT;
+ } else if (continuingDownload && statusCode == Downloads.Impl.STATUS_SUCCESS) {
+ finalStatus = Downloads.Impl.STATUS_PRECONDITION_FAILED;
} else {
- finalStatus = Downloads.STATUS_UNHANDLED_HTTP_CODE;
+ finalStatus = Downloads.Impl.STATUS_UNHANDLED_HTTP_CODE;
}
request.abort();
break http_request_loop;
@@ -403,7 +404,7 @@ http_request_loop:
if (Config.LOGD) {
Log.d(Constants.TAG, "can't know size of download, giving up");
}
- finalStatus = Downloads.STATUS_LENGTH_REQUIRED;
+ finalStatus = Downloads.Impl.STATUS_LENGTH_REQUIRED;
request.abort();
break http_request_loop;
}
@@ -430,18 +431,18 @@ http_request_loop:
}
ContentValues values = new ContentValues();
- values.put(Downloads._DATA, filename);
+ values.put(Downloads.Impl._DATA, filename);
if (headerETag != null) {
values.put(Constants.ETAG, headerETag);
}
if (mimeType != null) {
- values.put(Downloads.COLUMN_MIME_TYPE, mimeType);
+ values.put(Downloads.Impl.COLUMN_MIME_TYPE, mimeType);
}
int contentLength = -1;
if (headerContentLength != null) {
contentLength = Integer.parseInt(headerContentLength);
}
- values.put(Downloads.COLUMN_TOTAL_BYTES, contentLength);
+ values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, contentLength);
mContext.getContentResolver().update(contentUri, values, null, null);
}
@@ -457,9 +458,9 @@ http_request_loop:
}
}
if (!Helpers.isNetworkAvailable(mContext)) {
- finalStatus = Downloads.STATUS_RUNNING_PAUSED;
+ finalStatus = Downloads.Impl.STATUS_RUNNING_PAUSED;
} else if (mInfo.mNumFailed < Constants.MAX_RETRIES) {
- finalStatus = Downloads.STATUS_RUNNING_PAUSED;
+ finalStatus = Downloads.Impl.STATUS_RUNNING_PAUSED;
countRetry = true;
} else {
if (Constants.LOGV) {
@@ -472,7 +473,7 @@ http_request_loop:
Log.d(Constants.TAG, "IOException getting entity for download " +
mInfo.mId + " : " + ex);
}
- finalStatus = Downloads.STATUS_HTTP_DATA_ERROR;
+ finalStatus = Downloads.Impl.STATUS_HTTP_DATA_ERROR;
}
request.abort();
break http_request_loop;
@@ -490,7 +491,7 @@ http_request_loop:
}
}
ContentValues values = new ContentValues();
- values.put(Downloads.COLUMN_CURRENT_BYTES, bytesSoFar);
+ values.put(Downloads.Impl.COLUMN_CURRENT_BYTES, bytesSoFar);
mContext.getContentResolver().update(contentUri, values, null, null);
if (!mInfo.mNoIntegrity && headerETag == null) {
if (Constants.LOGV) {
@@ -504,11 +505,11 @@ http_request_loop:
Log.d(Constants.TAG,
"can't resume interrupted download with no ETag");
}
- finalStatus = Downloads.STATUS_PRECONDITION_FAILED;
+ finalStatus = Downloads.Impl.STATUS_PRECONDITION_FAILED;
} else if (!Helpers.isNetworkAvailable(mContext)) {
- finalStatus = Downloads.STATUS_RUNNING_PAUSED;
+ finalStatus = Downloads.Impl.STATUS_RUNNING_PAUSED;
} else if (mInfo.mNumFailed < Constants.MAX_RETRIES) {
- finalStatus = Downloads.STATUS_RUNNING_PAUSED;
+ finalStatus = Downloads.Impl.STATUS_RUNNING_PAUSED;
countRetry = true;
} else {
if (Constants.LOGV) {
@@ -518,16 +519,16 @@ http_request_loop:
Log.d(Constants.TAG, "download IOException for download " +
mInfo.mId + " : " + ex);
}
- finalStatus = Downloads.STATUS_HTTP_DATA_ERROR;
+ finalStatus = Downloads.Impl.STATUS_HTTP_DATA_ERROR;
}
request.abort();
break http_request_loop;
}
if (bytesRead == -1) { // success
ContentValues values = new ContentValues();
- values.put(Downloads.COLUMN_CURRENT_BYTES, bytesSoFar);
+ values.put(Downloads.Impl.COLUMN_CURRENT_BYTES, bytesSoFar);
if (headerContentLength == null) {
- values.put(Downloads.COLUMN_TOTAL_BYTES, bytesSoFar);
+ values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, bytesSoFar);
}
mContext.getContentResolver().update(contentUri, values, null, null);
if ((headerContentLength != null)
@@ -541,11 +542,11 @@ http_request_loop:
Log.d(Constants.TAG, "mismatched content length for " +
mInfo.mId);
}
- finalStatus = Downloads.STATUS_LENGTH_REQUIRED;
+ finalStatus = Downloads.Impl.STATUS_LENGTH_REQUIRED;
} else if (!Helpers.isNetworkAvailable(mContext)) {
- finalStatus = Downloads.STATUS_RUNNING_PAUSED;
+ finalStatus = Downloads.Impl.STATUS_RUNNING_PAUSED;
} else if (mInfo.mNumFailed < Constants.MAX_RETRIES) {
- finalStatus = Downloads.STATUS_RUNNING_PAUSED;
+ finalStatus = Downloads.Impl.STATUS_RUNNING_PAUSED;
countRetry = true;
} else {
if (Constants.LOGV) {
@@ -554,7 +555,7 @@ http_request_loop:
Log.d(Constants.TAG, "closed socket for download " +
mInfo.mId);
}
- finalStatus = Downloads.STATUS_HTTP_DATA_ERROR;
+ finalStatus = Downloads.Impl.STATUS_HTTP_DATA_ERROR;
}
break http_request_loop;
}
@@ -567,7 +568,7 @@ http_request_loop:
stream = new FileOutputStream(filename, true);
}
stream.write(data, 0, bytesRead);
- if (mInfo.mDestination == Downloads.DESTINATION_EXTERNAL
+ if (mInfo.mDestination == Downloads.Impl.DESTINATION_EXTERNAL
&& !DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING
.equalsIgnoreCase(mimeType)) {
try {
@@ -586,7 +587,7 @@ http_request_loop:
} catch (IOException ex) {
if (!Helpers.discardPurgeableFiles(
mContext, Constants.BUFFER_SIZE)) {
- finalStatus = Downloads.STATUS_FILE_ERROR;
+ finalStatus = Downloads.Impl.STATUS_FILE_ERROR;
break http_request_loop;
}
}
@@ -597,7 +598,7 @@ http_request_loop:
&& now - timeLastNotification
> Constants.MIN_PROGRESS_TIME) {
ContentValues values = new ContentValues();
- values.put(Downloads.COLUMN_CURRENT_BYTES, bytesSoFar);
+ values.put(Downloads.Impl.COLUMN_CURRENT_BYTES, bytesSoFar);
mContext.getContentResolver().update(
contentUri, values, null, null);
bytesNotified = bytesSoFar;
@@ -608,29 +609,29 @@ http_request_loop:
Log.v(Constants.TAG, "downloaded " + bytesSoFar + " for " + mInfo.mUri);
}
synchronized (mInfo) {
- if (mInfo.mControl == Downloads.CONTROL_PAUSED) {
+ if (mInfo.mControl == Downloads.Impl.CONTROL_PAUSED) {
if (Constants.LOGV) {
Log.v(Constants.TAG, "paused " + mInfo.mUri);
}
- finalStatus = Downloads.STATUS_RUNNING_PAUSED;
+ finalStatus = Downloads.Impl.STATUS_RUNNING_PAUSED;
request.abort();
break http_request_loop;
}
}
- if (mInfo.mStatus == Downloads.STATUS_CANCELED) {
+ if (mInfo.mStatus == Downloads.Impl.STATUS_CANCELED) {
if (Constants.LOGV) {
Log.d(Constants.TAG, "canceled " + mInfo.mUri);
} else if (Config.LOGD) {
// Log.d(Constants.TAG, "canceled id " + mInfo.mId);
}
- finalStatus = Downloads.STATUS_CANCELED;
+ finalStatus = Downloads.Impl.STATUS_CANCELED;
break http_request_loop;
}
}
if (Constants.LOGV) {
Log.v(Constants.TAG, "download completed for " + mInfo.mUri);
}
- finalStatus = Downloads.STATUS_SUCCESS;
+ finalStatus = Downloads.Impl.STATUS_SUCCESS;
}
break;
}
@@ -638,7 +639,7 @@ http_request_loop:
if (Config.LOGD) {
Log.d(Constants.TAG, "FileNotFoundException for " + filename + " : " + ex);
}
- finalStatus = Downloads.STATUS_FILE_ERROR;
+ finalStatus = Downloads.Impl.STATUS_FILE_ERROR;
// falls through to the code that reports an error
} catch (RuntimeException ex) { //sometimes the socket code throws unchecked exceptions
if (Constants.LOGV) {
@@ -646,7 +647,7 @@ http_request_loop:
} else if (Config.LOGD) {
Log.d(Constants.TAG, "Exception for id " + mInfo.mId, ex);
}
- finalStatus = Downloads.STATUS_UNKNOWN_ERROR;
+ finalStatus = Downloads.Impl.STATUS_UNKNOWN_ERROR;
// falls through to the code that reports an error
} finally {
mInfo.mHasActiveThread = false;
@@ -671,10 +672,10 @@ http_request_loop:
}
if (filename != null) {
// if the download wasn't successful, delete the file
- if (Downloads.isStatusError(finalStatus)) {
+ if (Downloads.Impl.isStatusError(finalStatus)) {
new File(filename).delete();
filename = null;
- } else if (Downloads.isStatusSuccess(finalStatus) &&
+ } else if (Downloads.Impl.isStatusSuccess(finalStatus) &&
DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING
.equalsIgnoreCase(mimeType)) {
// transfer the file to the DRM content provider
@@ -682,14 +683,14 @@ http_request_loop:
Intent item = DrmStore.addDrmFile(mContext.getContentResolver(), file, null);
if (item == null) {
Log.w(Constants.TAG, "unable to add file " + filename + " to DrmProvider");
- finalStatus = Downloads.STATUS_UNKNOWN_ERROR;
+ finalStatus = Downloads.Impl.STATUS_UNKNOWN_ERROR;
} else {
filename = item.getDataString();
mimeType = item.getType();
}
file.delete();
- } else if (Downloads.isStatusSuccess(finalStatus)) {
+ } else if (Downloads.Impl.isStatusSuccess(finalStatus)) {
// make sure the file is readable
FileUtils.setPermissions(filename, 0644, -1, -1);
@@ -732,7 +733,7 @@ http_request_loop:
String filename, String uri, String mimeType) {
notifyThroughDatabase(
status, countRetry, retryAfter, redirectCount, gotData, filename, uri, mimeType);
- if (Downloads.isStatusCompleted(status)) {
+ if (Downloads.Impl.isStatusCompleted(status)) {
notifyThroughIntent();
}
}
@@ -741,13 +742,13 @@ http_request_loop:
int status, boolean countRetry, int retryAfter, int redirectCount, boolean gotData,
String filename, String uri, String mimeType) {
ContentValues values = new ContentValues();
- values.put(Downloads.COLUMN_STATUS, status);
- values.put(Downloads._DATA, filename);
+ values.put(Downloads.Impl.COLUMN_STATUS, status);
+ values.put(Downloads.Impl._DATA, filename);
if (uri != null) {
- values.put(Downloads.COLUMN_URI, uri);
+ values.put(Downloads.Impl.COLUMN_URI, uri);
}
- values.put(Downloads.COLUMN_MIME_TYPE, mimeType);
- values.put(Downloads.COLUMN_LAST_MODIFICATION, System.currentTimeMillis());
+ values.put(Downloads.Impl.COLUMN_MIME_TYPE, mimeType);
+ values.put(Downloads.Impl.COLUMN_LAST_MODIFICATION, System.currentTimeMillis());
values.put(Constants.RETRY_AFTER_X_REDIRECT_COUNT, retryAfter + (redirectCount << 28));
if (!countRetry) {
values.put(Constants.FAILED_CONNECTIONS, 0);
@@ -757,8 +758,8 @@ http_request_loop:
values.put(Constants.FAILED_CONNECTIONS, mInfo.mNumFailed + 1);
}
- mContext.getContentResolver().update(
- ContentUris.withAppendedId(Downloads.CONTENT_URI, mInfo.mId), values, null, null);
+ mContext.getContentResolver().update(ContentUris.withAppendedId(
+ Downloads.Impl.CONTENT_URI, mInfo.mId), values, null, null);
}
/**
@@ -766,7 +767,7 @@ http_request_loop:
* download completed even if it's not actively watching the cursor.
*/
private void notifyThroughIntent() {
- Uri uri = Uri.parse(Downloads.CONTENT_URI + "/" + mInfo.mId);
+ Uri uri = Uri.parse(Downloads.Impl.CONTENT_URI + "/" + mInfo.mId);
mInfo.sendIntentIfRequested(uri, mContext);
}
diff --git a/src/com/android/providers/downloads/Helpers.java b/src/com/android/providers/downloads/Helpers.java
index d8f262c7..1e07d421 100644
--- a/src/com/android/providers/downloads/Helpers.java
+++ b/src/com/android/providers/downloads/Helpers.java
@@ -91,26 +91,26 @@ public class Helpers {
/*
* Don't download files that we won't be able to handle
*/
- if (destination == Downloads.DESTINATION_EXTERNAL
- || destination == Downloads.DESTINATION_CACHE_PARTITION_PURGEABLE) {
+ if (destination == Downloads.Impl.DESTINATION_EXTERNAL
+ || destination == Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE) {
if (mimeType == null) {
if (Config.LOGD) {
Log.d(Constants.TAG, "external download with no mime type not allowed");
}
- return new DownloadFileInfo(null, null, Downloads.STATUS_NOT_ACCEPTABLE);
+ return new DownloadFileInfo(null, null, Downloads.Impl.STATUS_NOT_ACCEPTABLE);
}
if (!DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING.equalsIgnoreCase(mimeType)) {
// Check to see if we are allowed to download this file. Only files
// that can be handled by the platform can be downloaded.
// special case DRM files, which we should always allow downloading.
Intent intent = new Intent(Intent.ACTION_VIEW);
-
+
// We can provide data as either content: or file: URIs,
// so allow both. (I think it would be nice if we just did
// everything as content: URIs)
// Actually, right now the download manager's UId restrictions
// prevent use from using content: so it's got to be file: or
- // nothing
+ // nothing
PackageManager pm = context.getPackageManager();
intent.setDataAndType(Uri.fromParts("file", "", null), mimeType);
@@ -121,7 +121,7 @@ public class Helpers {
if (Config.LOGD) {
Log.d(Constants.TAG, "no handler found for type " + mimeType);
}
- return new DownloadFileInfo(null, null, Downloads.STATUS_NOT_ACCEPTABLE);
+ return new DownloadFileInfo(null, null, Downloads.Impl.STATUS_NOT_ACCEPTABLE);
}
}
}
@@ -148,10 +148,11 @@ public class Helpers {
StatFs stat = null;
// DRM messages should be temporarily stored internally and then passed to
// the DRM content provider
- if (destination == Downloads.DESTINATION_CACHE_PARTITION
- || destination == Downloads.DESTINATION_CACHE_PARTITION_PURGEABLE
- || destination == Downloads.DESTINATION_CACHE_PARTITION_NOROAMING
+ if (destination == Downloads.Impl.DESTINATION_CACHE_PARTITION
+ || destination == Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE
+ || destination == Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING
|| DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING.equalsIgnoreCase(mimeType)) {
+ // Saving to internal storage.
base = Environment.getDownloadCacheDirectory();
stat = new StatFs(base.getPath());
@@ -160,52 +161,58 @@ public class Helpers {
* Put a bit of margin (in case creating the file grows the system by a few blocks).
*/
int blockSize = stat.getBlockSize();
- for (;;) {
- int availableBlocks = stat.getAvailableBlocks();
- if (blockSize * ((long) availableBlocks - 4) >= contentLength) {
- break;
- }
- if (!discardPurgeableFiles(context,
- contentLength - blockSize * ((long) availableBlocks - 4))) {
+ long bytesAvailable = blockSize * ((long) stat.getAvailableBlocks() - 4);
+ while (bytesAvailable < contentLength) {
+ // Insufficient space; try discarding purgeable files.
+ if (!discardPurgeableFiles(context, contentLength - bytesAvailable)) {
+ // No files to purge, give up.
if (Config.LOGD) {
Log.d(Constants.TAG,
"download aborted - not enough free space in internal storage");
}
- return new DownloadFileInfo(null, null, Downloads.STATUS_FILE_ERROR);
- }
- stat.restat(base.getPath());
- }
-
- } else {
- if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- String root = Environment.getExternalStorageDirectory().getPath();
- base = new File(root + Constants.DEFAULT_DL_SUBDIR);
- if (!base.isDirectory() && !base.mkdir()) {
- if (Config.LOGD) {
- Log.d(Constants.TAG, "download aborted - can't create base directory "
- + base.getPath());
- }
- return new DownloadFileInfo(null, null, Downloads.STATUS_FILE_ERROR);
- }
- stat = new StatFs(base.getPath());
- } else {
- if (Config.LOGD) {
- Log.d(Constants.TAG, "download aborted - no external storage");
+ return new DownloadFileInfo(null, null,
+ Downloads.Impl.STATUS_INSUFFICIENT_SPACE_ERROR);
+ } else {
+ // Recalculate available space and try again.
+ stat.restat(base.getPath());
+ bytesAvailable = blockSize * ((long) stat.getAvailableBlocks() - 4);
}
- return new DownloadFileInfo(null, null, Downloads.STATUS_FILE_ERROR);
}
+ } else if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+ // Saving to external storage (SD card).
+ String root = Environment.getExternalStorageDirectory().getPath();
+ stat = new StatFs(root);
/*
* Check whether there's enough space on the target filesystem to save the file.
* Put a bit of margin (in case creating the file grows the system by a few blocks).
*/
if (stat.getBlockSize() * ((long) stat.getAvailableBlocks() - 4) < contentLength) {
+ // Insufficient space.
if (Config.LOGD) {
Log.d(Constants.TAG, "download aborted - not enough free space");
}
- return new DownloadFileInfo(null, null, Downloads.STATUS_FILE_ERROR);
+ return new DownloadFileInfo(null, null,
+ Downloads.Impl.STATUS_INSUFFICIENT_SPACE_ERROR);
}
+ base = new File(root + 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.
+ if (Config.LOGD) {
+ Log.d(Constants.TAG, "download aborted - can't create base directory "
+ + base.getPath());
+ }
+ return new DownloadFileInfo(null, null, Downloads.Impl.STATUS_FILE_ERROR);
+ }
+ } else {
+ // No SD card found.
+ if (Config.LOGD) {
+ Log.d(Constants.TAG, "download aborted - no external storage");
+ }
+ return new DownloadFileInfo(null, null,
+ Downloads.Impl.STATUS_DEVICE_NOT_FOUND_ERROR);
}
boolean recoveryDir = Constants.RECOVERY_DIRECTORY.equalsIgnoreCase(filename + extension);
@@ -224,7 +231,7 @@ public class Helpers {
if (fullFilename != null) {
return new DownloadFileInfo(fullFilename, new FileOutputStream(fullFilename), 0);
} else {
- return new DownloadFileInfo(null, null, Downloads.STATUS_FILE_ERROR);
+ return new DownloadFileInfo(null, null, Downloads.Impl.STATUS_FILE_ERROR);
}
}
@@ -380,9 +387,9 @@ public class Helpers {
String fullFilename = filename + extension;
if (!new File(fullFilename).exists()
&& (!recoveryDir ||
- (destination != Downloads.DESTINATION_CACHE_PARTITION &&
- destination != Downloads.DESTINATION_CACHE_PARTITION_PURGEABLE &&
- destination != Downloads.DESTINATION_CACHE_PARTITION_NOROAMING))) {
+ (destination != Downloads.Impl.DESTINATION_CACHE_PARTITION &&
+ destination != Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE &&
+ destination != Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING))) {
return fullFilename;
}
filename = filename + Constants.FILENAME_SEQUENCE_SEPARATOR;
@@ -423,14 +430,14 @@ public class Helpers {
*/
public static final boolean discardPurgeableFiles(Context context, long targetBytes) {
Cursor cursor = context.getContentResolver().query(
- Downloads.CONTENT_URI,
+ Downloads.Impl.CONTENT_URI,
null,
"( " +
- Downloads.COLUMN_STATUS + " = '" + Downloads.STATUS_SUCCESS + "' AND " +
- Downloads.COLUMN_DESTINATION +
- " = '" + Downloads.DESTINATION_CACHE_PARTITION_PURGEABLE + "' )",
+ Downloads.Impl.COLUMN_STATUS + " = '" + Downloads.Impl.STATUS_SUCCESS + "' AND " +
+ Downloads.Impl.COLUMN_DESTINATION +
+ " = '" + Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE + "' )",
null,
- Downloads.COLUMN_LAST_MODIFICATION);
+ Downloads.Impl.COLUMN_LAST_MODIFICATION);
if (cursor == null) {
return false;
}
@@ -438,16 +445,16 @@ public class Helpers {
try {
cursor.moveToFirst();
while (!cursor.isAfterLast() && totalFreed < targetBytes) {
- File file = new File(cursor.getString(cursor.getColumnIndex(Downloads._DATA)));
+ File file = new File(cursor.getString(cursor.getColumnIndex(Downloads.Impl._DATA)));
if (Constants.LOGVV) {
Log.v(Constants.TAG, "purging " + file.getAbsolutePath() + " for " +
file.length() + " bytes");
}
totalFreed += file.length();
file.delete();
- long id = cursor.getLong(cursor.getColumnIndex(Downloads._ID));
+ long id = cursor.getLong(cursor.getColumnIndex(Downloads.Impl._ID));
context.getContentResolver().delete(
- ContentUris.withAppendedId(Downloads.CONTENT_URI, id), null, null);
+ ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, id), null, null);
cursor.moveToNext();
}
} finally {
diff --git a/tests/permission/src/com/android/providers/downloads/permission/tests/DownloadProviderPermissionsTest.java b/tests/permission/src/com/android/providers/downloads/permission/tests/DownloadProviderPermissionsTest.java
index b16c2650..ecdce93c 100644
--- a/tests/permission/src/com/android/providers/downloads/permission/tests/DownloadProviderPermissionsTest.java
+++ b/tests/permission/src/com/android/providers/downloads/permission/tests/DownloadProviderPermissionsTest.java
@@ -72,7 +72,7 @@ public class DownloadProviderPermissionsTest extends AndroidTestCase {
@MediumTest
public void testReadDownloadProvider() throws IOException {
try {
- mContentResolver.query(Downloads.CONTENT_URI, null, null, null, null);
+ mContentResolver.query(Downloads.Impl.CONTENT_URI, null, null, null, null);
fail("read from provider did not throw SecurityException as expected.");
} catch (SecurityException e) {
// expected
@@ -88,8 +88,8 @@ public class DownloadProviderPermissionsTest extends AndroidTestCase {
public void testWriteDownloadProvider() throws IOException {
try {
ContentValues values = new ContentValues();
- values.put(Downloads.COLUMN_URI, "foo");
- mContentResolver.insert(Downloads.CONTENT_URI, values);
+ values.put(Downloads.Impl.COLUMN_URI, "foo");
+ mContentResolver.insert(Downloads.Impl.CONTENT_URI, values);
fail("write to provider did not throw SecurityException as expected.");
} catch (SecurityException e) {
// expected