Merge "Default ringtone cannot be previewed as alarm stream type."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index c7e479c..25265d9 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="512">
         
     <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 c73871d..5dc21de 100644
--- a/src/com/android/providers/media/MediaProvider.java
+++ b/src/com/android/providers/media/MediaProvider.java
@@ -91,7 +91,6 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PrintWriter;
-import java.text.Collator;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -1751,6 +1750,15 @@
             updateBucketNames(db);
         }
 
+        if (fromVersion < 512) {
+            // remove primary key constraint because column time is not necessarily unique
+            db.execSQL("CREATE TABLE IF NOT EXISTS log_tmp (time DATETIME, message TEXT);");
+            db.execSQL("DELETE FROM log_tmp;");
+            db.execSQL("INSERT INTO log_tmp SELECT time, message FROM log;");
+            db.execSQL("DROP TABLE log;");
+            db.execSQL("ALTER TABLE log_tmp RENAME TO log;");
+        }
+
         sanityCheck(db, fromVersion);
         long elapsedSeconds = (SystemClock.currentTimeMicro() - startTime) / 1000000;
         logToDb(db, "Database upgraded from version " + fromVersion + " to " + toVersion
@@ -1765,7 +1773,7 @@
                 new String[] { message });
         // delete all but the last 500 rows
         db.execSQL("DELETE FROM log WHERE rowid IN" +
-                " (SELECT rowid FROM log ORDER BY time DESC LIMIT 500,-1);");
+                " (SELECT rowid FROM log ORDER BY rowid DESC LIMIT 500,-1);");
     }
 
     /**
@@ -2098,8 +2106,6 @@
             if (!TextUtils.isEmpty(filter)) {
                 String [] searchWords = filter.split(" ");
                 keywords = new String[searchWords.length];
-                Collator col = Collator.getInstance();
-                col.setStrength(Collator.PRIMARY);
                 for (int i = 0; i < searchWords.length; i++) {
                     String key = MediaStore.Audio.keyFor(searchWords[i]);
                     key = key.replace("\\", "\\\\");
@@ -2476,8 +2482,6 @@
         String [] searchWords = mSearchString.length() > 0 ?
                 mSearchString.split(" ") : new String[0];
         String [] wildcardWords = new String[searchWords.length];
-        Collator col = Collator.getInstance();
-        col.setStrength(Collator.PRIMARY);
         int len = searchWords.length;
         for (int i = 0; i < len; i++) {
             // Because we match on individual words here, we need to remove words
@@ -4211,8 +4215,8 @@
             return 0;
         }
         db.beginTransaction();
+        int numlines = 0;
         try {
-            int numlines = 0;
             helper.mNumUpdates += 3;
             Cursor c = db.query("audio_playlists_map",
                     new String [] {"play_order" },
@@ -4250,13 +4254,17 @@
             db.execSQL("UPDATE audio_playlists_map SET play_order=" + to_play_order +
                     " WHERE play_order=-1 AND playlist_id=" + playlist);
             db.setTransactionSuccessful();
-            Uri uri = MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI
-                    .buildUpon().appendEncodedPath(String.valueOf(playlist)).build();
-            getContext().getContentResolver().notifyChange(uri, null);
-            return numlines;
         } finally {
             db.endTransaction();
         }
+
+        Uri uri = MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI
+                .buildUpon().appendEncodedPath(String.valueOf(playlist)).build();
+        // notifyChange() must be called after the database transaction is ended
+        // or the listeners will read the old data in the callback
+        getContext().getContentResolver().notifyChange(uri, null);
+
+        return numlines;
     }
 
     private static final String[] openFileColumns = new String[] {
@@ -5353,7 +5361,7 @@
             }
             if (dumpDbLog) {
                 c = db.query("log", new String[] {"time", "message"},
-                        null, null, null, null, "time");
+                        null, null, null, null, "rowid");
                 try {
                     if (c != null) {
                         while (c.moveToNext()) {