Merge "Remove unused android.net.Downloads."
This commit is contained in:
@@ -1,644 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentUris;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.BaseColumns;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* The Download Manager
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class Downloads {
|
||||
|
||||
|
||||
/**
|
||||
* Download status codes
|
||||
*/
|
||||
|
||||
/**
|
||||
* This download hasn't started yet
|
||||
*/
|
||||
public static final int STATUS_PENDING = 190;
|
||||
|
||||
/**
|
||||
* This download has started
|
||||
*/
|
||||
public static final int STATUS_RUNNING = 192;
|
||||
|
||||
/**
|
||||
* This download has successfully completed.
|
||||
* Warning: there might be other status values that indicate success
|
||||
* in the future.
|
||||
* Use isSucccess() to capture the entire category.
|
||||
*/
|
||||
public static final int STATUS_SUCCESS = 200;
|
||||
|
||||
/**
|
||||
* This download can't be performed because the content type cannot be
|
||||
* handled.
|
||||
*/
|
||||
public static final int STATUS_NOT_ACCEPTABLE = 406;
|
||||
|
||||
/**
|
||||
* This download has completed with an error.
|
||||
* Warning: there will be other status values that indicate errors in
|
||||
* the future. Use isStatusError() to capture the entire category.
|
||||
*/
|
||||
public static final int STATUS_UNKNOWN_ERROR = 491;
|
||||
|
||||
/**
|
||||
* This download couldn't be completed because of an HTTP
|
||||
* redirect response that the download manager couldn't
|
||||
* handle.
|
||||
*/
|
||||
public static final int STATUS_UNHANDLED_REDIRECT = 493;
|
||||
|
||||
/**
|
||||
* This download couldn't be completed due to insufficient storage
|
||||
* space. Typically, this is because the SD card is full.
|
||||
*/
|
||||
public static final int STATUS_INSUFFICIENT_SPACE_ERROR = 498;
|
||||
|
||||
/**
|
||||
* This download couldn't be completed because no external storage
|
||||
* device was found. Typically, this is because the SD card is not
|
||||
* mounted.
|
||||
*/
|
||||
public static final int STATUS_DEVICE_NOT_FOUND_ERROR = 499;
|
||||
|
||||
/**
|
||||
* Returns whether the status is a success (i.e. 2xx).
|
||||
*/
|
||||
public static boolean isStatusSuccess(int status) {
|
||||
return (status >= 200 && status < 300);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the status is an error (i.e. 4xx or 5xx).
|
||||
*/
|
||||
public static boolean isStatusError(int status) {
|
||||
return (status >= 400 && status < 600);
|
||||
}
|
||||
|
||||
/**
|
||||
* Download destinations
|
||||
*/
|
||||
|
||||
/**
|
||||
* This download will be saved to the external storage. This is the
|
||||
* default behavior, and should be used for any file that the user
|
||||
* can freely access, copy, delete. Even with that destination,
|
||||
* unencrypted DRM files are saved in secure internal storage.
|
||||
* Downloads to the external destination only write files for which
|
||||
* there is a registered handler. The resulting files are accessible
|
||||
* by filename to all applications.
|
||||
*/
|
||||
public static final int DOWNLOAD_DESTINATION_EXTERNAL = 1;
|
||||
|
||||
/**
|
||||
* This download will be saved to the download manager's private
|
||||
* partition. This is the behavior used by applications that want to
|
||||
* download private files that are used and deleted soon after they
|
||||
* get downloaded. All file types are allowed, and only the initiating
|
||||
* application can access the file (indirectly through a content
|
||||
* provider). This requires the
|
||||
* android.permission.ACCESS_DOWNLOAD_MANAGER_ADVANCED permission.
|
||||
*/
|
||||
public static final int DOWNLOAD_DESTINATION_CACHE = 2;
|
||||
|
||||
/**
|
||||
* This download will be saved to the download manager's private
|
||||
* partition and will be purged as necessary to make space. This is
|
||||
* for private files (similar to CACHE_PARTITION) that aren't deleted
|
||||
* immediately after they are used, and are kept around by the download
|
||||
* manager as long as space is available.
|
||||
*/
|
||||
public static final int DOWNLOAD_DESTINATION_CACHE_PURGEABLE = 3;
|
||||
|
||||
|
||||
/**
|
||||
* An invalid download id
|
||||
*/
|
||||
public static final long DOWNLOAD_ID_INVALID = -1;
|
||||
|
||||
|
||||
/**
|
||||
* Broadcast Action: this is sent by the download manager to the app
|
||||
* that had initiated a download when that download completes. The
|
||||
* download's content: uri is specified in the intent's data.
|
||||
*/
|
||||
public static final String ACTION_DOWNLOAD_COMPLETED =
|
||||
"android.intent.action.DOWNLOAD_COMPLETED";
|
||||
|
||||
/**
|
||||
* If extras are specified when requesting a download they will be provided in the intent that
|
||||
* is sent to the specified class and package when a download has finished.
|
||||
* <P>Type: TEXT</P>
|
||||
* <P>Owner can Init</P>
|
||||
*/
|
||||
public static final String COLUMN_NOTIFICATION_EXTRAS = "notificationextras";
|
||||
|
||||
|
||||
/**
|
||||
* Status class for a download
|
||||
*/
|
||||
public static final class StatusInfo {
|
||||
public boolean completed = false;
|
||||
/** The filename of the active download. */
|
||||
public String filename = null;
|
||||
/** An opaque id for the download */
|
||||
public long id = DOWNLOAD_ID_INVALID;
|
||||
/** An opaque status code for the download */
|
||||
public int statusCode = -1;
|
||||
/** Approximate number of bytes downloaded so far, for debugging purposes. */
|
||||
public long bytesSoFar = -1;
|
||||
|
||||
/**
|
||||
* Returns whether the download is completed
|
||||
* @return a boolean whether the download is complete.
|
||||
*/
|
||||
public boolean isComplete() {
|
||||
return android.provider.Downloads.Impl.isStatusCompleted(statusCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the download is successful
|
||||
* @return a boolean whether the download is successful.
|
||||
*/
|
||||
public boolean isSuccessful() {
|
||||
return android.provider.Downloads.Impl.isStatusSuccess(statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to access initiate and query download by server uri
|
||||
*/
|
||||
public static final class ByUri extends DownloadBase {
|
||||
/** @hide */
|
||||
private ByUri() {}
|
||||
|
||||
/**
|
||||
* Query where clause by app data.
|
||||
* @hide
|
||||
*/
|
||||
private static final String QUERY_WHERE_APP_DATA_CLAUSE =
|
||||
android.provider.Downloads.Impl.COLUMN_APP_DATA + "=?";
|
||||
|
||||
/**
|
||||
* Gets a Cursor pointing to the download(s) of the current system update.
|
||||
* @hide
|
||||
*/
|
||||
private static final Cursor getCurrentOtaDownloads(Context context, String url) {
|
||||
return context.getContentResolver().query(
|
||||
android.provider.Downloads.Impl.CONTENT_URI,
|
||||
DOWNLOADS_PROJECTION,
|
||||
QUERY_WHERE_APP_DATA_CLAUSE,
|
||||
new String[] {url},
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a StatusInfo with the result of trying to download the
|
||||
* given URL. Returns null if no attempts have been made.
|
||||
*/
|
||||
public static final StatusInfo getStatus(
|
||||
Context context,
|
||||
String url,
|
||||
long redownload_threshold) {
|
||||
StatusInfo result = null;
|
||||
boolean hasFailedDownload = false;
|
||||
long failedDownloadModificationTime = 0;
|
||||
Cursor c = getCurrentOtaDownloads(context, url);
|
||||
try {
|
||||
while (c != null && c.moveToNext()) {
|
||||
if (result == null) {
|
||||
result = new StatusInfo();
|
||||
}
|
||||
int status = getStatusOfDownload(c, redownload_threshold);
|
||||
if (status == STATUS_DOWNLOADING_UPDATE ||
|
||||
status == STATUS_DOWNLOADED_UPDATE) {
|
||||
result.completed = (status == STATUS_DOWNLOADED_UPDATE);
|
||||
result.filename = c.getString(DOWNLOADS_COLUMN_FILENAME);
|
||||
result.id = c.getLong(DOWNLOADS_COLUMN_ID);
|
||||
result.statusCode = c.getInt(DOWNLOADS_COLUMN_STATUS);
|
||||
result.bytesSoFar = c.getLong(DOWNLOADS_COLUMN_CURRENT_BYTES);
|
||||
return result;
|
||||
}
|
||||
|
||||
long modTime = c.getLong(DOWNLOADS_COLUMN_LAST_MODIFICATION);
|
||||
if (hasFailedDownload &&
|
||||
modTime < failedDownloadModificationTime) {
|
||||
// older than the one already in result; skip it.
|
||||
continue;
|
||||
}
|
||||
|
||||
hasFailedDownload = true;
|
||||
failedDownloadModificationTime = modTime;
|
||||
result.statusCode = c.getInt(DOWNLOADS_COLUMN_STATUS);
|
||||
result.bytesSoFar = c.getLong(DOWNLOADS_COLUMN_CURRENT_BYTES);
|
||||
}
|
||||
} finally {
|
||||
if (c != null) {
|
||||
c.close();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query where clause for general querying.
|
||||
*/
|
||||
private static final String QUERY_WHERE_CLAUSE =
|
||||
android.provider.Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE + "=? AND " +
|
||||
android.provider.Downloads.Impl.COLUMN_NOTIFICATION_CLASS + "=?";
|
||||
|
||||
/**
|
||||
* Delete all the downloads for a package/class pair.
|
||||
*/
|
||||
public static final void removeAllDownloadsByPackage(
|
||||
Context context,
|
||||
String notification_package,
|
||||
String notification_class) {
|
||||
context.getContentResolver().delete(
|
||||
android.provider.Downloads.Impl.CONTENT_URI,
|
||||
QUERY_WHERE_CLAUSE,
|
||||
new String[] { notification_package, notification_class });
|
||||
}
|
||||
|
||||
/**
|
||||
* The column for the id in the Cursor returned by
|
||||
* getProgressCursor()
|
||||
*/
|
||||
public static final int getProgressColumnId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The column for the current byte count in the Cursor returned by
|
||||
* getProgressCursor()
|
||||
*/
|
||||
public static final int getProgressColumnCurrentBytes() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* The column for the total byte count in the Cursor returned by
|
||||
* getProgressCursor()
|
||||
*/
|
||||
public static final int getProgressColumnTotalBytes() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
private static final String[] PROJECTION = {
|
||||
BaseColumns._ID,
|
||||
android.provider.Downloads.Impl.COLUMN_CURRENT_BYTES,
|
||||
android.provider.Downloads.Impl.COLUMN_TOTAL_BYTES
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a Cursor representing the progress of the download identified by the ID.
|
||||
*/
|
||||
public static final Cursor getProgressCursor(Context context, long id) {
|
||||
Uri downloadUri = Uri.withAppendedPath(android.provider.Downloads.Impl.CONTENT_URI,
|
||||
String.valueOf(id));
|
||||
return context.getContentResolver().query(downloadUri, PROJECTION, null, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to access downloads by opaque download id
|
||||
*/
|
||||
public static final class ById extends DownloadBase {
|
||||
/** @hide */
|
||||
private ById() {}
|
||||
|
||||
/**
|
||||
* Get the mime tupe of the download specified by the download id
|
||||
*/
|
||||
public static String getMimeTypeForId(Context context, long downloadId) {
|
||||
ContentResolver cr = context.getContentResolver();
|
||||
|
||||
String mimeType = null;
|
||||
Cursor downloadCursor = null;
|
||||
|
||||
try {
|
||||
Uri downloadUri = getDownloadUri(downloadId);
|
||||
|
||||
downloadCursor = cr.query(
|
||||
downloadUri, new String[]{android.provider.Downloads.Impl.COLUMN_MIME_TYPE},
|
||||
null, null, null);
|
||||
if (downloadCursor.moveToNext()) {
|
||||
mimeType = downloadCursor.getString(0);
|
||||
}
|
||||
} finally {
|
||||
if (downloadCursor != null) downloadCursor.close();
|
||||
}
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a download by Id
|
||||
*/
|
||||
public static void deleteDownload(Context context, long downloadId) {
|
||||
ContentResolver cr = context.getContentResolver();
|
||||
|
||||
String mimeType = null;
|
||||
|
||||
Uri downloadUri = getDownloadUri(downloadId);
|
||||
|
||||
cr.delete(downloadUri, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a filedescriptor to a particular download
|
||||
*/
|
||||
public static ParcelFileDescriptor openDownload(
|
||||
Context context, long downloadId, String mode)
|
||||
throws FileNotFoundException
|
||||
{
|
||||
ContentResolver cr = context.getContentResolver();
|
||||
|
||||
String mimeType = null;
|
||||
|
||||
Uri downloadUri = getDownloadUri(downloadId);
|
||||
|
||||
return cr.openFileDescriptor(downloadUri, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a stream to a particular download
|
||||
*/
|
||||
public static InputStream openDownloadStream(Context context, long downloadId)
|
||||
throws FileNotFoundException, IOException
|
||||
{
|
||||
ContentResolver cr = context.getContentResolver();
|
||||
|
||||
String mimeType = null;
|
||||
|
||||
Uri downloadUri = getDownloadUri(downloadId);
|
||||
|
||||
return cr.openInputStream(downloadUri);
|
||||
}
|
||||
|
||||
private static Uri getDownloadUri(long downloadId) {
|
||||
return Uri.parse(android.provider.Downloads.Impl.CONTENT_URI + "/" + downloadId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a StatusInfo with the result of trying to download the
|
||||
* given URL. Returns null if no attempts have been made.
|
||||
*/
|
||||
public static final StatusInfo getStatus(
|
||||
Context context,
|
||||
long downloadId) {
|
||||
StatusInfo result = null;
|
||||
boolean hasFailedDownload = false;
|
||||
long failedDownloadModificationTime = 0;
|
||||
|
||||
Uri downloadUri = getDownloadUri(downloadId);
|
||||
|
||||
ContentResolver cr = context.getContentResolver();
|
||||
|
||||
Cursor c = cr.query(downloadUri, DOWNLOADS_PROJECTION, null /* selection */,
|
||||
null /* selection args */, null /* sort order */);
|
||||
try {
|
||||
if (c == null || !c.moveToNext()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (result == null) {
|
||||
result = new StatusInfo();
|
||||
}
|
||||
int status = getStatusOfDownload(c,0);
|
||||
if (status == STATUS_DOWNLOADING_UPDATE ||
|
||||
status == STATUS_DOWNLOADED_UPDATE) {
|
||||
result.completed = (status == STATUS_DOWNLOADED_UPDATE);
|
||||
result.filename = c.getString(DOWNLOADS_COLUMN_FILENAME);
|
||||
result.id = c.getLong(DOWNLOADS_COLUMN_ID);
|
||||
result.statusCode = c.getInt(DOWNLOADS_COLUMN_STATUS);
|
||||
result.bytesSoFar = c.getLong(DOWNLOADS_COLUMN_CURRENT_BYTES);
|
||||
return result;
|
||||
}
|
||||
|
||||
long modTime = c.getLong(DOWNLOADS_COLUMN_LAST_MODIFICATION);
|
||||
|
||||
result.statusCode = c.getInt(DOWNLOADS_COLUMN_STATUS);
|
||||
result.bytesSoFar = c.getLong(DOWNLOADS_COLUMN_CURRENT_BYTES);
|
||||
} finally {
|
||||
if (c != null) {
|
||||
c.close();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Base class with common functionality for the various download classes
|
||||
*/
|
||||
public static class DownloadBase {
|
||||
/** @hide */
|
||||
DownloadBase() {}
|
||||
|
||||
/**
|
||||
* Initiate a download where the download will be tracked by its URI.
|
||||
*/
|
||||
public static long startDownloadByUri(
|
||||
Context context,
|
||||
String url,
|
||||
String cookieData,
|
||||
boolean showDownload,
|
||||
int downloadDestination,
|
||||
boolean allowRoaming,
|
||||
boolean skipIntegrityCheck,
|
||||
String title,
|
||||
String notification_package,
|
||||
String notification_class,
|
||||
String notification_extras) {
|
||||
ContentResolver cr = context.getContentResolver();
|
||||
|
||||
// Tell download manager to start downloading update.
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(android.provider.Downloads.Impl.COLUMN_URI, url);
|
||||
values.put(android.provider.Downloads.Impl.COLUMN_COOKIE_DATA, cookieData);
|
||||
values.put(android.provider.Downloads.Impl.COLUMN_VISIBILITY,
|
||||
showDownload ? android.provider.Downloads.Impl.VISIBILITY_VISIBLE
|
||||
: android.provider.Downloads.Impl.VISIBILITY_HIDDEN);
|
||||
if (title != null) {
|
||||
values.put(android.provider.Downloads.Impl.COLUMN_TITLE, title);
|
||||
}
|
||||
values.put(android.provider.Downloads.Impl.COLUMN_APP_DATA, url);
|
||||
|
||||
|
||||
// NOTE: destination should be seperated from whether the download
|
||||
// can happen when roaming
|
||||
int destination = android.provider.Downloads.Impl.DESTINATION_EXTERNAL;
|
||||
switch (downloadDestination) {
|
||||
case DOWNLOAD_DESTINATION_EXTERNAL:
|
||||
destination = android.provider.Downloads.Impl.DESTINATION_EXTERNAL;
|
||||
break;
|
||||
case DOWNLOAD_DESTINATION_CACHE:
|
||||
if (allowRoaming) {
|
||||
destination = android.provider.Downloads.Impl.DESTINATION_CACHE_PARTITION;
|
||||
} else {
|
||||
destination =
|
||||
android.provider.Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING;
|
||||
}
|
||||
break;
|
||||
case DOWNLOAD_DESTINATION_CACHE_PURGEABLE:
|
||||
destination =
|
||||
android.provider.Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE;
|
||||
break;
|
||||
}
|
||||
values.put(android.provider.Downloads.Impl.COLUMN_DESTINATION, destination);
|
||||
values.put(android.provider.Downloads.Impl.COLUMN_NO_INTEGRITY,
|
||||
skipIntegrityCheck); // Don't check ETag
|
||||
if (notification_package != null && notification_class != null) {
|
||||
values.put(android.provider.Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE,
|
||||
notification_package);
|
||||
values.put(android.provider.Downloads.Impl.COLUMN_NOTIFICATION_CLASS,
|
||||
notification_class);
|
||||
|
||||
if (notification_extras != null) {
|
||||
values.put(android.provider.Downloads.Impl.COLUMN_NOTIFICATION_EXTRAS,
|
||||
notification_extras);
|
||||
}
|
||||
}
|
||||
|
||||
Uri downloadUri = cr.insert(android.provider.Downloads.Impl.CONTENT_URI, values);
|
||||
|
||||
long downloadId = DOWNLOAD_ID_INVALID;
|
||||
if (downloadUri != null) {
|
||||
downloadId = Long.parseLong(downloadUri.getLastPathSegment());
|
||||
}
|
||||
return downloadId;
|
||||
}
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
private static final int STATUS_INVALID = 0;
|
||||
/** @hide */
|
||||
private static final int STATUS_DOWNLOADING_UPDATE = 3;
|
||||
/** @hide */
|
||||
private static final int STATUS_DOWNLOADED_UPDATE = 4;
|
||||
|
||||
/**
|
||||
* Column projection for the query to the download manager. This must match
|
||||
* with the constants DOWNLOADS_COLUMN_*.
|
||||
* @hide
|
||||
*/
|
||||
private static final String[] DOWNLOADS_PROJECTION = {
|
||||
BaseColumns._ID,
|
||||
android.provider.Downloads.Impl.COLUMN_APP_DATA,
|
||||
android.provider.Downloads.Impl.COLUMN_STATUS,
|
||||
android.provider.Downloads.Impl._DATA,
|
||||
android.provider.Downloads.Impl.COLUMN_LAST_MODIFICATION,
|
||||
android.provider.Downloads.Impl.COLUMN_CURRENT_BYTES,
|
||||
};
|
||||
|
||||
/**
|
||||
* The column index for the ID.
|
||||
* @hide
|
||||
*/
|
||||
private static final int DOWNLOADS_COLUMN_ID = 0;
|
||||
/**
|
||||
* The column index for the URI.
|
||||
* @hide
|
||||
*/
|
||||
private static final int DOWNLOADS_COLUMN_URI = 1;
|
||||
/**
|
||||
* The column index for the status code.
|
||||
* @hide
|
||||
*/
|
||||
private static final int DOWNLOADS_COLUMN_STATUS = 2;
|
||||
/**
|
||||
* The column index for the filename.
|
||||
* @hide
|
||||
*/
|
||||
private static final int DOWNLOADS_COLUMN_FILENAME = 3;
|
||||
/**
|
||||
* The column index for the last modification time.
|
||||
* @hide
|
||||
*/
|
||||
private static final int DOWNLOADS_COLUMN_LAST_MODIFICATION = 4;
|
||||
/**
|
||||
* The column index for the number of bytes downloaded so far.
|
||||
* @hide
|
||||
*/
|
||||
private static final int DOWNLOADS_COLUMN_CURRENT_BYTES = 5;
|
||||
|
||||
/**
|
||||
* Gets the status of a download.
|
||||
*
|
||||
* @param c A Cursor pointing to a download. The URL column is assumed to be valid.
|
||||
* @return The status of the download.
|
||||
* @hide
|
||||
*/
|
||||
private static final int getStatusOfDownload( Cursor c, long redownload_threshold) {
|
||||
int status = c.getInt(DOWNLOADS_COLUMN_STATUS);
|
||||
long realtime = SystemClock.elapsedRealtime();
|
||||
|
||||
// TODO(dougz): special handling of 503, 404? (eg, special
|
||||
// explanatory messages to user)
|
||||
|
||||
if (!android.provider.Downloads.Impl.isStatusCompleted(status)) {
|
||||
// Check if it's stuck
|
||||
long modified = c.getLong(DOWNLOADS_COLUMN_LAST_MODIFICATION);
|
||||
long now = System.currentTimeMillis();
|
||||
if (now < modified || now - modified > redownload_threshold) {
|
||||
return STATUS_INVALID;
|
||||
}
|
||||
|
||||
return STATUS_DOWNLOADING_UPDATE;
|
||||
}
|
||||
|
||||
if (android.provider.Downloads.Impl.isStatusError(status)) {
|
||||
return STATUS_INVALID;
|
||||
}
|
||||
|
||||
String filename = c.getString(DOWNLOADS_COLUMN_FILENAME);
|
||||
if (filename == null) {
|
||||
return STATUS_INVALID;
|
||||
}
|
||||
|
||||
return STATUS_DOWNLOADED_UPDATE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
private Downloads() {}
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
package android.provider;
|
||||
|
||||
import android.app.DownloadManager;
|
||||
import android.content.Context;
|
||||
import android.net.NetworkPolicyManager;
|
||||
import android.net.Uri;
|
||||
|
||||
@@ -742,4 +743,19 @@ public final class Downloads {
|
||||
public static final String INSERT_KEY_PREFIX = "http_header_";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Query where clause for general querying.
|
||||
*/
|
||||
private static final String QUERY_WHERE_CLAUSE = Impl.COLUMN_NOTIFICATION_PACKAGE + "=? AND "
|
||||
+ Impl.COLUMN_NOTIFICATION_CLASS + "=?";
|
||||
|
||||
/**
|
||||
* Delete all the downloads for a package/class pair.
|
||||
*/
|
||||
public static final void removeAllDownloadsByPackage(
|
||||
Context context, String notification_package, String notification_class) {
|
||||
context.getContentResolver().delete(Impl.CONTENT_URI, QUERY_WHERE_CLAUSE,
|
||||
new String[] { notification_package, notification_class });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,13 +20,13 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Downloads;
|
||||
import android.os.Build;
|
||||
import android.os.DropBoxManager;
|
||||
import android.os.FileObserver;
|
||||
import android.os.FileUtils;
|
||||
import android.os.RecoverySystem;
|
||||
import android.os.SystemProperties;
|
||||
import android.provider.Downloads;
|
||||
import android.util.Slog;
|
||||
|
||||
import java.io.File;
|
||||
@@ -78,9 +78,8 @@ public class BootReceiver extends BroadcastReceiver {
|
||||
}.start();
|
||||
}
|
||||
|
||||
private void removeOldUpdatePackages(Context ctx) {
|
||||
Downloads.ByUri.removeAllDownloadsByPackage(
|
||||
ctx, OLD_UPDATER_PACKAGE, OLD_UPDATER_CLASS);
|
||||
private void removeOldUpdatePackages(Context context) {
|
||||
Downloads.removeAllDownloadsByPackage(context, OLD_UPDATER_PACKAGE, OLD_UPDATER_CLASS);
|
||||
}
|
||||
|
||||
private void logBootEvents(Context ctx) throws IOException {
|
||||
|
||||
Reference in New Issue
Block a user