diff options
-rw-r--r-- | src/com/android/providers/downloads/DownloadInfo.java | 9 | ||||
-rw-r--r-- | src/com/android/providers/downloads/DownloadProvider.java | 65 | ||||
-rw-r--r-- | src/com/android/providers/downloads/DownloadService.java | 2 | ||||
-rw-r--r-- | src/com/android/providers/downloads/DownloadThread.java | 14 | ||||
-rw-r--r-- | ui/AndroidManifest.xml | 6 | ||||
-rw-r--r-- | ui/res/values-ko/strings.xml | 4 | ||||
-rw-r--r-- | ui/src/com/android/providers/downloads/ui/DownloadList.java | 6 |
7 files changed, 80 insertions, 26 deletions
diff --git a/src/com/android/providers/downloads/DownloadInfo.java b/src/com/android/providers/downloads/DownloadInfo.java index f375b3f1..0ff51260 100644 --- a/src/com/android/providers/downloads/DownloadInfo.java +++ b/src/com/android/providers/downloads/DownloadInfo.java @@ -80,7 +80,7 @@ public class DownloadInfo { info.mTotalBytes = getLong(Downloads.Impl.COLUMN_TOTAL_BYTES); info.mCurrentBytes = getLong(Downloads.Impl.COLUMN_CURRENT_BYTES); info.mETag = getString(Constants.ETAG); - info.mMediaScanned = getInt(Constants.MEDIA_SCANNED) == 1; + info.mMediaScanned = getInt(Constants.MEDIA_SCANNED); info.mDeleted = getInt(Downloads.Impl.COLUMN_DELETED) == 1; info.mMediaProviderUri = getString(Downloads.Impl.COLUMN_MEDIAPROVIDER_URI); info.mIsPublicApi = getInt(Downloads.Impl.COLUMN_IS_PUBLIC_API) != 0; @@ -204,7 +204,7 @@ public class DownloadInfo { public long mTotalBytes; public long mCurrentBytes; public String mETag; - public boolean mMediaScanned; + public int mMediaScanned; public boolean mDeleted; public String mMediaProviderUri; public boolean mIsPublicApi; @@ -522,9 +522,10 @@ public class DownloadInfo { * Returns whether a file should be scanned */ boolean shouldScanFile() { - return !mMediaScanned + return (mMediaScanned == 0) && (mDestination == Downloads.Impl.DESTINATION_EXTERNAL || - mDestination == Downloads.Impl.DESTINATION_FILE_URI) + mDestination == Downloads.Impl.DESTINATION_FILE_URI || + mDestination == Downloads.Impl.DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD) && Downloads.Impl.isStatusSuccess(mStatus) && !DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING.equalsIgnoreCase(mMimeType); } diff --git a/src/com/android/providers/downloads/DownloadProvider.java b/src/com/android/providers/downloads/DownloadProvider.java index 94b10d53..208d7856 100644 --- a/src/com/android/providers/downloads/DownloadProvider.java +++ b/src/com/android/providers/downloads/DownloadProvider.java @@ -480,25 +480,26 @@ public final class DownloadProvider extends ContentProvider { throw new IllegalArgumentException("Unknown/Invalid URI " + uri); } + // copy some of the input values as it ContentValues filteredValues = new ContentValues(); - 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); - copyBoolean(Downloads.Impl.COLUMN_IS_PUBLIC_API, values, filteredValues); + boolean isPublicApi = values.getAsBoolean(Downloads.Impl.COLUMN_IS_PUBLIC_API) == Boolean.TRUE; + // validate the destination column Integer dest = values.getAsInteger(Downloads.Impl.COLUMN_DESTINATION); if (dest != null) { if (getContext().checkCallingPermission(Downloads.Impl.PERMISSION_ACCESS_ADVANCED) != PackageManager.PERMISSION_GRANTED - && dest != Downloads.Impl.DESTINATION_EXTERNAL - && dest != Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE - && dest != Downloads.Impl.DESTINATION_FILE_URI) { + && (dest == Downloads.Impl.DESTINATION_CACHE_PARTITION + || dest == Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING + || dest == Downloads.Impl.DESTINATION_SYSTEMCACHE_PARTITION)) { throw new SecurityException("setting destination to : " + dest + " not allowed, unless PERMISSION_ACCESS_ADVANCED is granted"); } @@ -526,6 +527,8 @@ public final class DownloadProvider extends ContentProvider { } filteredValues.put(Downloads.Impl.COLUMN_DESTINATION, dest); } + + // validate the visibility column Integer vis = values.getAsInteger(Downloads.Impl.COLUMN_VISIBILITY); if (vis == null) { if (dest == Downloads.Impl.DESTINATION_EXTERNAL) { @@ -538,11 +541,34 @@ public final class DownloadProvider extends ContentProvider { } else { filteredValues.put(Downloads.Impl.COLUMN_VISIBILITY, vis); } + // copy the control column as is copyInteger(Downloads.Impl.COLUMN_CONTROL, values, filteredValues); - filteredValues.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_PENDING); + + /* + * requests coming from + * DownloadManager.completedDownload(String, String, String, boolean, String, + * String, long) need special treatment + */ + if (values.getAsInteger(Downloads.Impl.COLUMN_DESTINATION) == + Downloads.Impl.DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD) { + // these requests always are marked as 'completed' + filteredValues.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_SUCCESS); + filteredValues.put(Downloads.Impl.COLUMN_TOTAL_BYTES, + values.getAsLong(Downloads.Impl.COLUMN_TOTAL_BYTES)); + filteredValues.put(Downloads.Impl.COLUMN_CURRENT_BYTES, 0); + copyInteger(Downloads.Impl.COLUMN_MEDIA_SCANNED, values, filteredValues); + copyString(Downloads.Impl._DATA, values, filteredValues); + } else { + filteredValues.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_PENDING); + filteredValues.put(Downloads.Impl.COLUMN_TOTAL_BYTES, -1); + filteredValues.put(Downloads.Impl.COLUMN_CURRENT_BYTES, 0); + } + + // set lastupdate to current time filteredValues.put(Downloads.Impl.COLUMN_LAST_MODIFICATION, mSystemFacade.currentTimeMillis()); + // use packagename of the caller to set the notification columns String pckg = values.getAsString(Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE); String clazz = values.getAsString(Downloads.Impl.COLUMN_NOTIFICATION_CLASS); if (pckg != null && (clazz != null || isPublicApi)) { @@ -558,10 +584,14 @@ public final class DownloadProvider extends ContentProvider { /* ignored for now */ } } + + // copy some more columns as is 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); + + // UID, PID columns if (getContext().checkCallingPermission(Downloads.Impl.PERMISSION_ACCESS_ADVANCED) == PackageManager.PERMISSION_GRANTED) { copyInteger(Downloads.Impl.COLUMN_OTHER_UID, values, filteredValues); @@ -570,11 +600,12 @@ public final class DownloadProvider extends ContentProvider { if (Binder.getCallingUid() == 0) { copyInteger(Constants.UID, values, filteredValues); } + + // copy some more columns as is copyStringWithDefault(Downloads.Impl.COLUMN_TITLE, values, filteredValues, ""); copyStringWithDefault(Downloads.Impl.COLUMN_DESCRIPTION, values, filteredValues, ""); - filteredValues.put(Downloads.Impl.COLUMN_TOTAL_BYTES, -1); - filteredValues.put(Downloads.Impl.COLUMN_CURRENT_BYTES, 0); + // is_visible_in_downloads_ui column if (values.containsKey(Downloads.Impl.COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI)) { copyBoolean(Downloads.Impl.COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI, values, filteredValues); } else { @@ -583,6 +614,7 @@ public final class DownloadProvider extends ContentProvider { filteredValues.put(Downloads.Impl.COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI, isExternal); } + // public api requests and networktypes/roaming columns if (isPublicApi) { copyInteger(Downloads.Impl.COLUMN_ALLOWED_NETWORK_TYPES, values, filteredValues); copyBoolean(Downloads.Impl.COLUMN_ALLOW_ROAMING, values, filteredValues); @@ -666,9 +698,22 @@ public final class DownloadProvider extends ContentProvider { // check columns whose values are restricted enforceAllowedValues(values, Downloads.Impl.COLUMN_IS_PUBLIC_API, Boolean.TRUE); + + // validate the destination column + if (values.getAsInteger(Downloads.Impl.COLUMN_DESTINATION) == + Downloads.Impl.DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD) { + /* this row is inserted by + * DownloadManager.completedDownload(String, String, String, boolean, String, + * String, long) + */ + values.remove(Downloads.Impl.COLUMN_TOTAL_BYTES); + values.remove(Downloads.Impl._DATA); + values.remove(Downloads.Impl.COLUMN_STATUS); + } enforceAllowedValues(values, Downloads.Impl.COLUMN_DESTINATION, Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE, - Downloads.Impl.DESTINATION_FILE_URI); + Downloads.Impl.DESTINATION_FILE_URI, + Downloads.Impl.DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD); if (getContext().checkCallingOrSelfPermission(Downloads.Impl.PERMISSION_NO_NOTIFICATION) == PackageManager.PERMISSION_GRANTED) { @@ -1091,7 +1136,7 @@ public final class DownloadProvider extends ContentProvider { throw new FileNotFoundException("No filename found."); } if (!Helpers.isFilenameValid(path, mDownloadsDataDir)) { - throw new FileNotFoundException("Invalid filename."); + throw new FileNotFoundException("Invalid filename: " + path); } if (!"r".equals(mode)) { throw new FileNotFoundException("Bad mode for " + uri + ": " + mode); diff --git a/src/com/android/providers/downloads/DownloadService.java b/src/com/android/providers/downloads/DownloadService.java index bc4083c7..d06c8803 100644 --- a/src/com/android/providers/downloads/DownloadService.java +++ b/src/com/android/providers/downloads/DownloadService.java @@ -502,8 +502,6 @@ public class DownloadService extends Service { } try { final Uri key = info.getAllDownloadsUri(); - final String mimeType = info.mMimeType; - final ContentResolver resolver = getContentResolver(); final long id = info.mId; mMediaScannerService.requestScanFile(info.mFileName, info.mMimeType, new IMediaScannerListener.Stub() { diff --git a/src/com/android/providers/downloads/DownloadThread.java b/src/com/android/providers/downloads/DownloadThread.java index 2d9eb171..960765dd 100644 --- a/src/com/android/providers/downloads/DownloadThread.java +++ b/src/com/android/providers/downloads/DownloadThread.java @@ -213,7 +213,7 @@ public class DownloadThread extends Thread { addRequestHeaders(innerState, request); // check just before sending the request to avoid using an invalid connection at all - checkConnectivity(state); + checkConnectivity(); HttpResponse response = sendRequest(state, client, request); handleExceptionalStatus(state, innerState, response); @@ -230,7 +230,7 @@ public class DownloadThread extends Thread { /** * Check if current connectivity is valid for this request. */ - private void checkConnectivity(State state) throws StopRequestException { + private void checkConnectivity() throws StopRequestException { int networkUsable = mInfo.checkCanUseNetwork(); if (networkUsable != DownloadInfo.NETWORK_OK) { int status = Downloads.Impl.STATUS_WAITING_FOR_NETWORK; @@ -548,7 +548,7 @@ public class DownloadThread extends Thread { updateDatabaseFromHeaders(state, innerState); // check connectivity again now that we know the total size - checkConnectivity(state); + checkConnectivity(); } /** @@ -763,8 +763,12 @@ public class DownloadThread extends Thread { } private int getFinalStatusForHttpError(State state) { - if (!Helpers.isNetworkAvailable(mSystemFacade)) { - return Downloads.Impl.STATUS_WAITING_FOR_NETWORK; + int networkUsable = mInfo.checkCanUseNetwork(); + if (networkUsable != DownloadInfo.NETWORK_OK) { + return (networkUsable == DownloadInfo.NETWORK_UNUSABLE_DUE_TO_SIZE || + networkUsable == DownloadInfo.NETWORK_RECOMMENDED_UNUSABLE_DUE_TO_SIZE) + ? Downloads.Impl.STATUS_QUEUED_FOR_WIFI + : Downloads.Impl.STATUS_WAITING_FOR_NETWORK; } else if (mInfo.mNumFailed < Constants.MAX_RETRIES) { state.mCountRetry = true; return Downloads.Impl.STATUS_WAITING_TO_RETRY; diff --git a/ui/AndroidManifest.xml b/ui/AndroidManifest.xml index 596f6499..1b4af384 100644 --- a/ui/AndroidManifest.xml +++ b/ui/AndroidManifest.xml @@ -8,10 +8,10 @@ <application android:process="android.process.media" android:label="@string/app_label" - android:icon="@mipmap/ic_launcher_download"> + android:icon="@mipmap/ic_launcher_download" + android:hardwareAccelerated="true"> <activity android:name=".DownloadList" - android:launchMode="singleTop" - android:hardwareAccelerated="true"> + android:launchMode="singleTop"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> diff --git a/ui/res/values-ko/strings.xml b/ui/res/values-ko/strings.xml index 7a8c3575..5f632dc7 100644 --- a/ui/res/values-ko/strings.xml +++ b/ui/res/values-ko/strings.xml @@ -20,8 +20,8 @@ <string name="download_title" msgid="2470985874255839247">"다운로드"</string> <string name="no_downloads" msgid="1029667411186146836">"다운로드 항목이 없습니다."</string> <string name="missing_title" msgid="830115697868833773">"<알 수 없음>"</string> - <string name="download_menu_sort_by_size" msgid="2276438658769422878">"크기순 정렬"</string> - <string name="download_menu_sort_by_date" msgid="4300882048968609945">"시간순 정렬"</string> + <string name="download_menu_sort_by_size" msgid="2276438658769422878">"크기별 정렬"</string> + <string name="download_menu_sort_by_date" msgid="4300882048968609945">"시간별 정렬"</string> <string name="download_queued" msgid="104973307780629904">"대기 중"</string> <string name="download_running" msgid="4656462962155580641">"진행 중"</string> <string name="download_success" msgid="7006048006543495236">"완료"</string> diff --git a/ui/src/com/android/providers/downloads/ui/DownloadList.java b/ui/src/com/android/providers/downloads/ui/DownloadList.java index 133b0bfe..23d0d8fe 100644 --- a/ui/src/com/android/providers/downloads/ui/DownloadList.java +++ b/ui/src/com/android/providers/downloads/ui/DownloadList.java @@ -159,6 +159,12 @@ public class DownloadList extends Activity ensureSomeGroupIsExpanded(); } + // did the caller want to display the data sorted by size? + Bundle extras = getIntent().getExtras(); + if (extras != null && + extras.getBoolean(DownloadManager.INTENT_EXTRAS_SORT_BY_SIZE, false)) { + mIsSortedBySize = true; + } chooseListToShow(); } |