am edfa644d: Merge "Notify change of movePlaylistEntry after transaction ends"
# By Oscar Rydhé
# Via Gerrit Code Review (1) and Henrik Baard (1)
* commit 'edfa644dd785f91949b3cb865e28037bf0acae14':
Notify change of movePlaylistEntry after transaction ends
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index c7e479c..52daa72 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2,7 +2,7 @@
package="com.android.providers.media"
android:sharedUserId="android.media"
android:sharedUserLabel="@string/uid_label"
- android:versionCode="511">
+ android:versionCode="600">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
diff --git a/src/com/android/providers/media/MediaProvider.java b/src/com/android/providers/media/MediaProvider.java
index 2d1ddc5..42f0cee 100644
--- a/src/com/android/providers/media/MediaProvider.java
+++ b/src/com/android/providers/media/MediaProvider.java
@@ -567,8 +567,6 @@
iFilter.addDataScheme("file");
context.registerReceiver(mUnmountReceiver, iFilter);
- mCaseInsensitivePaths = true;
-
StorageManager storageManager =
(StorageManager)context.getSystemService(Context.STORAGE_SERVICE);
mExternalStoragePaths = storageManager.getVolumePaths();
@@ -1575,6 +1573,8 @@
+ FileColumns.MEDIA_TYPE_IMAGE + ";");
}
+ // Honeycomb went up to version 307, ICS started at 401
+
// Database version 401 did not add storage_id to the internal database.
// We need it there too, so add it in version 402
if (fromVersion < 401 || (fromVersion == 401 && internal)) {
@@ -1644,6 +1644,8 @@
db.execSQL("DELETE FROM audio_genres");
}
+ // ICS went out with database version 409, JB started at 500
+
if (fromVersion < 500) {
// we're now deleting the file in mediaprovider code, rather than via a trigger
db.execSQL("DROP TRIGGER IF EXISTS videothumbnails_cleanup;");
@@ -1751,6 +1753,60 @@
updateBucketNames(db);
}
+ // JB 4.2 went out with database version 511, starting next release with 600
+
+ if (fromVersion < 600) {
+ // modify _data column to be unique and collate nocase. Because this drops the original
+ // table and replaces it with a new one by the same name, we need to also recreate all
+ // indices and triggers that refer to the files table.
+ // Views don't need to be recreated.
+
+ db.execSQL("CREATE TABLE files2 (_id INTEGER PRIMARY KEY AUTOINCREMENT," +
+ "_data TEXT UNIQUE" +
+ // the internal filesystem is case-sensitive
+ (internal ? "," : " COLLATE NOCASE,") +
+ "_size INTEGER,format INTEGER,parent INTEGER,date_added INTEGER," +
+ "date_modified INTEGER,mime_type TEXT,title TEXT,description TEXT," +
+ "_display_name TEXT,picasa_id TEXT,orientation INTEGER,latitude DOUBLE," +
+ "longitude DOUBLE,datetaken INTEGER,mini_thumb_magic INTEGER,bucket_id TEXT," +
+ "bucket_display_name TEXT,isprivate INTEGER,title_key TEXT,artist_id INTEGER," +
+ "album_id INTEGER,composer TEXT,track INTEGER,year INTEGER CHECK(year!=0)," +
+ "is_ringtone INTEGER,is_music INTEGER,is_alarm INTEGER," +
+ "is_notification INTEGER,is_podcast INTEGER,album_artist TEXT," +
+ "duration INTEGER,bookmark INTEGER,artist TEXT,album TEXT,resolution TEXT," +
+ "tags TEXT,category TEXT,language TEXT,mini_thumb_data TEXT,name TEXT," +
+ "media_type INTEGER,old_id INTEGER,storage_id INTEGER,is_drm INTEGER," +
+ "width INTEGER, height INTEGER);");
+
+ // copy data from old table, squashing entries with duplicate _data
+ db.execSQL("INSERT OR REPLACE INTO files2 SELECT * FROM files;");
+ db.execSQL("DROP TABLE files;");
+ db.execSQL("ALTER TABLE files2 RENAME TO files;");
+
+ // recreate indices and triggers
+ db.execSQL("CREATE INDEX album_id_idx ON files(album_id);");
+ db.execSQL("CREATE INDEX artist_id_idx ON files(artist_id);");
+ db.execSQL("CREATE INDEX bucket_index on files(bucket_id,media_type," +
+ "datetaken, _id);");
+ db.execSQL("CREATE INDEX bucket_name on files(bucket_id,media_type," +
+ "bucket_display_name);");
+ db.execSQL("CREATE INDEX format_index ON files(format);");
+ db.execSQL("CREATE INDEX media_type_index ON files(media_type);");
+ db.execSQL("CREATE INDEX parent_index ON files(parent);");
+ db.execSQL("CREATE INDEX path_index ON files(_data);");
+ db.execSQL("CREATE INDEX sort_index ON files(datetaken ASC, _id ASC);");
+ db.execSQL("CREATE INDEX title_idx ON files(title);");
+ db.execSQL("CREATE INDEX titlekey_index ON files(title_key);");
+ if (!internal) {
+ db.execSQL("CREATE TRIGGER audio_playlists_cleanup DELETE ON files" +
+ " WHEN old.media_type=4" +
+ " BEGIN DELETE FROM audio_playlists_map WHERE playlist_id = old._id;" +
+ "SELECT _DELETE_FILE(old._data);END;");
+ db.execSQL("CREATE TRIGGER files_cleanup DELETE ON files" +
+ " BEGIN SELECT _OBJECT_REMOVED(old._id);END;");
+ }
+ }
+
sanityCheck(db, fromVersion);
long elapsedSeconds = (SystemClock.currentTimeMicro() - startTime) / 1000000;
logToDb(db, "Database upgraded from version " + fromVersion + " to " + toVersion
@@ -1761,7 +1817,8 @@
* Write a persistent diagnostic message to the log table.
*/
static void logToDb(SQLiteDatabase db, String message) {
- db.execSQL("INSERT INTO log (time,message) VALUES (strftime('%Y-%m-%d %H:%M:%f','now'),?);",
+ db.execSQL("INSERT OR REPLACE" +
+ " INTO log (time,message) VALUES (strftime('%Y-%m-%d %H:%M:%f','now'),?);",
new String[] { message });
// delete all but the last 500 rows
db.execSQL("DELETE FROM log WHERE rowid IN" +
@@ -2442,7 +2499,10 @@
combine(prependArgs, selectionArgs), groupBy, null, sort, limit);
if (c != null) {
- c.setNotificationUri(getContext().getContentResolver(), uri);
+ String nonotify = uri.getQueryParameter("nonotify");
+ if (nonotify == null || !nonotify.equals("1")) {
+ c.setNotificationUri(getContext().getContentResolver(), uri);
+ }
}
return c;
@@ -2587,9 +2647,7 @@
values = initialValues;
}
- if (!ensureFileExists(file)) {
- throw new IllegalStateException("Unable to create new file: " + file);
- }
+ // we used to create the file here, but now defer this until openFile() is called
return values;
}
@@ -2758,17 +2816,7 @@
return cid;
}
- // Use "LIKE" instead of "=" on case insensitive file systems so we do a
- // case insensitive match when looking for parent directory.
- // TODO: investigate whether a "nocase" constraint on the column and
- // using "=" would give the same result faster.
- String selection = (mCaseInsensitivePaths ? MediaStore.MediaColumns.DATA + " LIKE ?1"
- // The like above makes it use the index.
- // The comparison below makes it correct when the path has wildcard chars
- + " AND lower(_data)=lower(?1)"
- // search only directories.
- + " AND format=" + MtpConstants.FORMAT_ASSOCIATION
- : MediaStore.MediaColumns.DATA + "=?");
+ String selection = MediaStore.MediaColumns.DATA + "=?";
String [] selargs = { parentPath };
helper.mNumQueries++;
Cursor c = db.query("files", sIdOnlyColumn, selection, selargs, null, null, null);
@@ -3004,7 +3052,9 @@
File file = new File(path);
if (file.exists()) {
values.put(FileColumns.DATE_MODIFIED, file.lastModified() / 1000);
- values.put(FileColumns.SIZE, file.length());
+ if (!values.containsKey(FileColumns.SIZE)) {
+ values.put(FileColumns.SIZE, file.length());
+ }
}
}
diff --git a/src/com/android/providers/media/MtpService.java b/src/com/android/providers/media/MtpService.java
index 04033e9..74fd747 100644
--- a/src/com/android/providers/media/MtpService.java
+++ b/src/com/android/providers/media/MtpService.java
@@ -71,13 +71,23 @@
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (Intent.ACTION_USER_PRESENT.equals(action)) {
- synchronized (mBinder) {
- // Unhide the storage units when the user has unlocked the lockscreen
- if (mMtpDisabled) {
- addStorageDevicesLocked();
- mMtpDisabled = false;
- }
- }
+ // If the media scanner is running, it may currently be calling
+ // sendObjectAdded/Removed, which also synchronizes on mBinder
+ // (and in addition to that, all the native MtpServer methods
+ // lock the same Mutex). If it happens to be in an mtp device
+ // write(), it may block for some time, so process this broadcast
+ // in a thread.
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ synchronized (mBinder) {
+ // Unhide the storage units when the user has unlocked the lockscreen
+ if (mMtpDisabled) {
+ addStorageDevicesLocked();
+ mMtpDisabled = false;
+ }
+ }
+ }}, "addStorageDevices").start();
}
}
};
diff --git a/tools/genfiles/genfiles.sh b/tools/genfiles/genfiles.sh
index 32d2352..2a139a5 100755
--- a/tools/genfiles/genfiles.sh
+++ b/tools/genfiles/genfiles.sh
@@ -139,7 +139,7 @@
}
echo mkfiles.sh generated. Now run:
-grep sdcard0\/proto mkfiles.sh |sed 's/cat \/storage\/sdcard0\//adb push /' | sed 's/ > .*/ \/storage\/sdcard0/'|sort -u
+grep sdcard0\/proto mkfiles.sh |sed 's/cat \/storage\/sdcard0\//adb push protos\//' | sed 's/ > .*/ \/storage\/sdcard0\//'|sort -u
echo adb push mkfiles.sh /storage/sdcard0
echo adb shell sh /storage/sdcard0/mkfiles.sh