summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorMarco Nelissen <marcone@google.com>2015-11-05 16:44:52 -0800
committerMarco Nelissen <marcone@google.com>2016-01-12 17:12:36 +0000
commit7d9fab680ee5309c6413e5547669582d3635e90b (patch)
tree8725a8a2693d727e2ce361e552838627ba5c5c86 /media
parenta73abeaf4b7b158664c34124d8df39ad843f7451 (diff)
downloadframeworks_base-7d9fab680ee5309c6413e5547669582d3635e90b.zip
frameworks_base-7d9fab680ee5309c6413e5547669582d3635e90b.tar.gz
frameworks_base-7d9fab680ee5309c6413e5547669582d3635e90b.tar.bz2
Fix race condition when setting default ringtones
If the device was powered off during first boot, after media scanner inserted some entries but before the default ringtone settings were set (or committed to disk), the default settings would not be set on subsequent boots. Bug: 18625739 Bug: 22349910 Bug: 25633323 Change-Id: I8ff5d3c4f842297d0675e1f5cbe17c0709a14158
Diffstat (limited to 'media')
-rw-r--r--media/java/android/media/MediaScanner.java95
1 files changed, 65 insertions, 30 deletions
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 9ea6722..4c8085f 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -20,6 +20,7 @@ import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
+import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
@@ -41,6 +42,7 @@ import android.provider.MediaStore.Files.FileColumns;
import android.provider.MediaStore.Images;
import android.provider.MediaStore.Video;
import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
import android.sax.Element;
import android.sax.ElementListener;
import android.sax.RootElement;
@@ -324,8 +326,6 @@ public class MediaScanner
// used when scanning the image database so we know whether we have to prune
// old thumbnail files
private int mOriginalCount;
- /** Whether the database had any entries in it before the scan started */
- private boolean mWasEmptyPriorToScan = false;
/** Whether the scanner has set a default sound for the ringer ringtone. */
private boolean mDefaultRingtoneSet;
/** Whether the scanner has set a default sound for the notification ringtone. */
@@ -529,12 +529,29 @@ public class MediaScanner
FileEntry entry = beginFile(path, mimeType, lastModified,
fileSize, isDirectory, noMedia);
+ if (entry == null) {
+ return null;
+ }
+
// if this file was just inserted via mtp, set the rowid to zero
// (even though it already exists in the database), to trigger
// the correct code path for updating its entry
if (mMtpObjectHandle != 0) {
entry.mRowId = 0;
}
+
+ if (entry.mPath != null &&
+ ((!mDefaultNotificationSet &&
+ doesPathHaveFilename(entry.mPath, mDefaultNotificationFilename))
+ || (!mDefaultRingtoneSet &&
+ doesPathHaveFilename(entry.mPath, mDefaultRingtoneFilename))
+ || (!mDefaultAlarmSet &&
+ doesPathHaveFilename(entry.mPath, mDefaultAlarmAlertFilename)))) {
+ Log.w(TAG, "forcing rescan of " + entry.mPath +
+ "since ringtone setting didn't finish");
+ scanAlways = true;
+ }
+
// rescan for metadata if file was modified since last scan
if (entry != null && (entry.mLastModifiedChanged || scanAlways)) {
if (noMedia) {
@@ -914,6 +931,26 @@ public class MediaScanner
}
Uri result = null;
boolean needToSetSettings = false;
+ // Setting a flag in order not to use bulk insert for the file related with
+ // notifications, ringtones, and alarms, because the rowId of the inserted file is
+ // needed.
+ if (notifications && !mDefaultNotificationSet) {
+ if (TextUtils.isEmpty(mDefaultNotificationFilename) ||
+ doesPathHaveFilename(entry.mPath, mDefaultNotificationFilename)) {
+ needToSetSettings = true;
+ }
+ } else if (ringtones && !mDefaultRingtoneSet) {
+ if (TextUtils.isEmpty(mDefaultRingtoneFilename) ||
+ doesPathHaveFilename(entry.mPath, mDefaultRingtoneFilename)) {
+ needToSetSettings = true;
+ }
+ } else if (alarms && !mDefaultAlarmSet) {
+ if (TextUtils.isEmpty(mDefaultAlarmAlertFilename) ||
+ doesPathHaveFilename(entry.mPath, mDefaultAlarmAlertFilename)) {
+ needToSetSettings = true;
+ }
+ }
+
if (rowId == 0) {
if (mMtpObjectHandle != 0) {
values.put(MediaStore.MediaColumns.MEDIA_SCANNER_NEW_OBJECT_ID, mMtpObjectHandle);
@@ -925,28 +962,6 @@ public class MediaScanner
}
values.put(Files.FileColumns.FORMAT, format);
}
- // Setting a flag in order not to use bulk insert for the file related with
- // notifications, ringtones, and alarms, because the rowId of the inserted file is
- // needed.
- if (mWasEmptyPriorToScan) {
- if (notifications && !mDefaultNotificationSet) {
- if (TextUtils.isEmpty(mDefaultNotificationFilename) ||
- doesPathHaveFilename(entry.mPath, mDefaultNotificationFilename)) {
- needToSetSettings = true;
- }
- } else if (ringtones && !mDefaultRingtoneSet) {
- if (TextUtils.isEmpty(mDefaultRingtoneFilename) ||
- doesPathHaveFilename(entry.mPath, mDefaultRingtoneFilename)) {
- needToSetSettings = true;
- }
- } else if (alarms && !mDefaultAlarmSet) {
- if (TextUtils.isEmpty(mDefaultAlarmAlertFilename) ||
- doesPathHaveFilename(entry.mPath, mDefaultAlarmAlertFilename)) {
- needToSetSettings = true;
- }
- }
- }
-
// New file, insert it.
// Directories need to be inserted before the files they contain, so they
// get priority when bulk inserting.
@@ -1016,14 +1031,18 @@ public class MediaScanner
private void setSettingIfNotSet(String settingName, Uri uri, long rowId) {
- String existingSettingValue = Settings.System.getString(mContext.getContentResolver(),
- settingName);
+ if(wasSettingAlreadySet(settingName)) {
+ return;
+ }
+ ContentResolver cr = mContext.getContentResolver();
+ String existingSettingValue = Settings.System.getString(cr, settingName);
if (TextUtils.isEmpty(existingSettingValue)) {
// Set the setting to the given URI
- Settings.System.putString(mContext.getContentResolver(), settingName,
+ Settings.System.putString(cr, settingName,
ContentUris.withAppendedId(uri, rowId).toString());
}
+ Settings.System.putInt(cr, settingSetIndicatorName(settingName), 1);
}
private int getFileTypeFromDrm(String path) {
@@ -1050,6 +1069,20 @@ public class MediaScanner
}; // end of anonymous MediaScannerClient instance
+ private String settingSetIndicatorName(String base) {
+ return base + "_set";
+ }
+
+ private boolean wasSettingAlreadySet(String name) {
+ ContentResolver cr = mContext.getContentResolver();
+ String indicatorName = settingSetIndicatorName(name);
+ try {
+ return Settings.System.getInt(cr, indicatorName) != 0;
+ } catch (SettingNotFoundException e) {
+ return false;
+ }
+ }
+
private void prescan(String filePath, boolean prescanFiles) throws RemoteException {
Cursor c = null;
String where = null;
@@ -1071,6 +1104,10 @@ public class MediaScanner
selectionArgs = new String[] { "" };
}
+ mDefaultRingtoneSet = wasSettingAlreadySet(Settings.System.RINGTONE);
+ mDefaultNotificationSet = wasSettingAlreadySet(Settings.System.NOTIFICATION_SOUND);
+ mDefaultAlarmSet = wasSettingAlreadySet(Settings.System.ALARM_ALERT);
+
// Tell the provider to not delete the file.
// If the file is truly gone the delete is unnecessary, and we want to avoid
// accidentally deleting files that are really there (this may happen if the
@@ -1089,7 +1126,6 @@ public class MediaScanner
// with CursorWindow positioning.
long lastId = Long.MIN_VALUE;
Uri limitUri = mFilesUri.buildUpon().appendQueryParameter("limit", "1000").build();
- mWasEmptyPriorToScan = true;
while (true) {
selectionArgs[0] = "" + lastId;
@@ -1108,7 +1144,6 @@ public class MediaScanner
if (num == 0) {
break;
}
- mWasEmptyPriorToScan = false;
while (c.moveToNext()) {
long rowId = c.getLong(FILES_PRESCAN_ID_COLUMN_INDEX);
String path = c.getString(FILES_PRESCAN_PATH_COLUMN_INDEX);
@@ -1260,7 +1295,7 @@ public class MediaScanner
}
}
- private void postscan(String[] directories) throws RemoteException {
+ private void postscan(final String[] directories) throws RemoteException {
// handle playlists last, after we know what media files are on the storage.
if (mProcessPlaylists) {