summaryrefslogtreecommitdiffstats
path: root/src/com/android/providers/downloads/DownloadService.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/providers/downloads/DownloadService.java')
-rw-r--r--src/com/android/providers/downloads/DownloadService.java121
1 files changed, 77 insertions, 44 deletions
diff --git a/src/com/android/providers/downloads/DownloadService.java b/src/com/android/providers/downloads/DownloadService.java
index 169ef970..f93c5c2e 100644
--- a/src/com/android/providers/downloads/DownloadService.java
+++ b/src/com/android/providers/downloads/DownloadService.java
@@ -28,6 +28,7 @@ import android.content.Intent;
import android.content.ServiceConnection;
import android.database.ContentObserver;
import android.database.Cursor;
+import android.database.sqlite.SQLiteException;
import android.media.IMediaScannerListener;
import android.media.IMediaScannerService;
import android.net.Uri;
@@ -44,7 +45,6 @@ import com.google.android.collect.Maps;
import com.google.common.annotations.VisibleForTesting;
import java.io.File;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
@@ -114,6 +114,7 @@ public class DownloadService extends Service {
* Receives notification when the data in the observed content
* provider changes.
*/
+ @Override
public void onChange(final boolean selfChange) {
if (Constants.LOGVV) {
Log.v(Constants.TAG, "Service ContentObserver received notification");
@@ -188,6 +189,7 @@ public class DownloadService extends Service {
*
* @throws UnsupportedOperationException
*/
+ @Override
public IBinder onBind(Intent i) {
throw new UnsupportedOperationException("Cannot bind to Download Manager Service");
}
@@ -195,6 +197,7 @@ public class DownloadService extends Service {
/**
* Initializes the service when it is first created
*/
+ @Override
public void onCreate() {
super.onCreate();
if (Constants.LOGVV) {
@@ -232,6 +235,7 @@ public class DownloadService extends Service {
/**
* Cleans up when the service is destroyed
*/
+ @Override
public void onDestroy() {
getContentResolver().unregisterContentObserver(mObserver);
if (Constants.LOGVV) {
@@ -258,6 +262,7 @@ public class DownloadService extends Service {
super("Download Service");
}
+ @Override
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
@@ -363,24 +368,23 @@ public class DownloadService extends Service {
if (info.shouldScanFile()) {
// initiate rescan of the file to - which will populate
// mediaProviderUri column in this row
- if (!scanFile(info, true, false)) {
+ if (!scanFile(info, false, true)) {
throw new IllegalStateException("scanFile failed!");
}
- } else {
- // this file should NOT be scanned. delete the file.
- Helpers.deleteFile(getContentResolver(), info.mId, info.mFileName,
- info.mMimeType);
+ continue;
}
} else {
// yes it has mediaProviderUri column already filled in.
- // delete it from MediaProvider database and then from downloads table
- // in DownProvider database (the order of deletion is important).
+ // delete it from MediaProvider database.
getContentResolver().delete(Uri.parse(info.mMediaProviderUri), null,
null);
- getContentResolver().delete(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI,
- Downloads.Impl._ID + " = ? ",
- new String[]{String.valueOf(info.mId)});
}
+ // delete the file
+ deleteFileIfExists(info.mFileName);
+ // delete from the downloads db
+ getContentResolver().delete(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI,
+ Downloads.Impl._ID + " = ? ",
+ new String[]{String.valueOf(info.mId)});
}
}
}
@@ -463,29 +467,41 @@ 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.Impl.ALL_DOWNLOADS_CONTENT_URI,
- new String[] { Downloads.Impl._ID },
- Downloads.Impl.COLUMN_STATUS + " >= '200'", null,
- Downloads.Impl.COLUMN_LAST_MODIFICATION);
- if (cursor == null) {
- // This isn't good - if we can't do basic queries in our database, nothing's gonna work
- Log.e(Constants.TAG, "null cursor in trimDatabase");
- return;
- }
- if (cursor.moveToFirst()) {
- int numDelete = cursor.getCount() - Constants.MAX_DOWNLOADS;
- int columnId = cursor.getColumnIndexOrThrow(Downloads.Impl._ID);
- while (numDelete > 0) {
- Uri downloadUri = ContentUris.withAppendedId(
- Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, cursor.getLong(columnId));
- getContentResolver().delete(downloadUri, null, null);
- if (!cursor.moveToNext()) {
- break;
+ Cursor cursor = null;
+ try {
+ cursor = getContentResolver().query(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI,
+ new String[] { Downloads.Impl._ID },
+ Downloads.Impl.COLUMN_STATUS + " >= '200'", null,
+ Downloads.Impl.COLUMN_LAST_MODIFICATION);
+ if (cursor == null) {
+ // This isn't good - if we can't do basic queries in our database, nothing's gonna work
+ Log.e(Constants.TAG, "null cursor in trimDatabase");
+ return;
+ }
+ if (cursor.moveToFirst()) {
+ int numDelete = cursor.getCount() - Constants.MAX_DOWNLOADS;
+ int columnId = cursor.getColumnIndexOrThrow(Downloads.Impl._ID);
+ while (numDelete > 0) {
+ Uri downloadUri = ContentUris.withAppendedId(
+ Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, cursor.getLong(columnId));
+ getContentResolver().delete(downloadUri, null, null);
+ if (!cursor.moveToNext()) {
+ break;
+ }
+ numDelete--;
}
- numDelete--;
+ }
+ } catch (SQLiteException e) {
+ // trimming the database raised an exception. alright, ignore the exception
+ // and return silently. trimming database is not exactly a critical operation
+ // and there is no need to propagate the exception.
+ Log.w(Constants.TAG, "trimDatabase failed with exception: " + e.getMessage());
+ return;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
}
}
- cursor.close();
}
/**
@@ -580,22 +596,28 @@ public class DownloadService extends Service {
mMediaScannerService.requestScanFile(info.mFileName, info.mMimeType,
new IMediaScannerListener.Stub() {
public void scanCompleted(String path, Uri uri) {
- if (uri != null && updateDatabase) {
- // file is scanned and mediaprovider returned uri. store it in downloads
- // table (i.e., update this downloaded file's row)
+ if (updateDatabase) {
+ // Mark this as 'scanned' in the database
+ // so that it is NOT subject to re-scanning by MediaScanner
+ // next time this database row row is encountered
ContentValues values = new ContentValues();
values.put(Constants.MEDIA_SCANNED, 1);
- values.put(Downloads.Impl.COLUMN_MEDIAPROVIDER_URI,
- uri.toString());
+ if (uri != null) {
+ values.put(Downloads.Impl.COLUMN_MEDIAPROVIDER_URI,
+ uri.toString());
+ }
getContentResolver().update(key, values, null, null);
- } else if (uri == null && deleteFile) {
- // callback returned NO uri..that means this file doesn't
- // exist in MediaProvider. but it still needs to be deleted
- // TODO don't scan files that are not scannable by MediaScanner.
- // create a public method in MediaFile.java to return false
- // if the given file's mimetype is not any of the types
- // the mediaprovider is interested in.
- Helpers.deleteFile(resolver, id, path, mimeType);
+ } else if (deleteFile) {
+ if (uri != null) {
+ // use the Uri returned to delete it from the MediaProvider
+ getContentResolver().delete(uri, null, null);
+ }
+ // delete the file and delete its row from the downloads db
+ deleteFileIfExists(path);
+ getContentResolver().delete(
+ Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI,
+ Downloads.Impl._ID + " = ? ",
+ new String[]{String.valueOf(id)});
}
}
});
@@ -606,4 +628,15 @@ public class DownloadService extends Service {
}
}
}
+
+ private void deleteFileIfExists(String path) {
+ try {
+ if (!TextUtils.isEmpty(path)) {
+ File file = new File(path);
+ file.delete();
+ }
+ } catch (Exception e) {
+ Log.w(Constants.TAG, "file: '" + path + "' couldn't be deleted", e);
+ }
+ }
}