Move default ringtone configuration to framework.

This ensures that partners have a place to customize the default
ringtone configuration, such as adding support for per-SIM ringtones
which aren't officially supported by Android yet.

Bug: 141596983, 141518853, 141594113, 141595768, 141809410
Test: atest --test-mapping packages/providers/MediaProvider
Change-Id: Ibe5b41c09ca40caadfcbb81162b996173fe8509b
This commit is contained in:
Jeff Sharkey
2019-10-17 17:16:36 -06:00
parent 5a1d791ebf
commit 72f1fffe8b
2 changed files with 65 additions and 0 deletions

View File

@@ -3648,6 +3648,10 @@ package android.media {
method public void stop();
}
public class RingtoneManager {
method @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS) public static void ensureDefaultRingtones(@NonNull android.content.Context);
}
}
package android.media.audiopolicy {

View File

@@ -22,6 +22,7 @@ import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.annotation.WorkerThread;
import android.app.Activity;
@@ -40,9 +41,11 @@ import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.MediaStore;
import android.provider.MediaStore.MediaColumns;
import android.provider.Settings;
import android.provider.Settings.System;
import android.util.Log;
@@ -1097,4 +1100,62 @@ public class RingtoneManager {
return null;
}
}
/**
* Ensure that ringtones have been set at least once on this device. This
* should be called after the device has finished scanned all media on
* {@link MediaStore#VOLUME_INTERNAL}, so that default ringtones can be
* configured.
*
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.WRITE_SETTINGS)
public static void ensureDefaultRingtones(@NonNull Context context) {
for (int type : new int[] {
TYPE_RINGTONE,
TYPE_NOTIFICATION,
TYPE_ALARM,
}) {
// Skip if we've already defined it at least once, so we don't
// overwrite the user changing to null
final String setting = getDefaultRingtoneSetting(type);
if (Settings.System.getInt(context.getContentResolver(), setting, 0) != 0) {
continue;
}
// Try finding the scanned ringtone
final String filename = getDefaultRingtoneFilename(type);
final Uri baseUri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI;
try (Cursor cursor = context.getContentResolver().query(baseUri,
new String[] { MediaColumns._ID },
MediaColumns.DISPLAY_NAME + "=?",
new String[] { filename }, null)) {
if (cursor.moveToFirst()) {
final Uri ringtoneUri = context.getContentResolver().canonicalizeOrElse(
ContentUris.withAppendedId(baseUri, cursor.getLong(0)));
RingtoneManager.setActualDefaultRingtoneUri(context, type, ringtoneUri);
Settings.System.putInt(context.getContentResolver(), setting, 1);
}
}
}
}
private static String getDefaultRingtoneSetting(int type) {
switch (type) {
case TYPE_RINGTONE: return "ringtone_set";
case TYPE_NOTIFICATION: return "notification_sound_set";
case TYPE_ALARM: return "alarm_alert_set";
default: throw new IllegalArgumentException();
}
}
private static String getDefaultRingtoneFilename(int type) {
switch (type) {
case TYPE_RINGTONE: return SystemProperties.get("ro.config.ringtone");
case TYPE_NOTIFICATION: return SystemProperties.get("ro.config.notification_sound");
case TYPE_ALARM: return SystemProperties.get("ro.config.alarm_alert");
default: throw new IllegalArgumentException();
}
}
}