Don't copy ringtones when profile sync goes off
Experimentally, it makes more sense to more people to have the parent
setting as an overlay not a concrete thing.
Test: make cts -j30 && cts-tradefed run cts --module CtsDevicePolicyManagerTestCases --test 'com.android.cts.devicepolicy.ManagedProfileTest#testRingtoneSyncAutoDisableRingtone' </dev/null 2>&1
Bug: 34730524
Change-Id: I5f804713def9e54921b90e4f5cea742ba8aaa685
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index c9b1c9c..143b98c 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4635,7 +4635,7 @@
return setLocationModeForUser(resolver, Integer.parseInt(value), userHandle);
}
if (MOVED_TO_GLOBAL.contains(name)) {
- Log.w(TAG, "Setting " + name + " has moved from android.provider.Settings.System"
+ Log.w(TAG, "Setting " + name + " has moved from android.provider.Settings.Secure"
+ " to android.provider.Settings.Global");
return Global.putStringForUser(resolver, name, value,
tag, makeDefault, userHandle);
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index fa4796a..5855984 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -192,7 +192,7 @@
oneway void releasePlayer(in int piid);
- void disableRingtoneSync();
+ void disableRingtoneSync(in int userId);
int getFocusRampTimeMs(in int focusGain, in AudioAttributes attr);
diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index 8a1027b..e774c71 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -103,10 +103,6 @@
*/
public static final int TYPE_ALL = TYPE_RINGTONE | TYPE_NOTIFICATION | TYPE_ALARM;
- private static final int[] RINGTONE_TYPES = {
- TYPE_RINGTONE, TYPE_NOTIFICATION, TYPE_ALARM
- };
-
// </attr>
/**
@@ -773,30 +769,17 @@
}
/**
- * Disables Settings.System.SYNC_PARENT_SOUNDS, copying the parent's ringtones to the current
- * profile
+ * Disables Settings.System.SYNC_PARENT_SOUNDS.
*
* @hide
*/
- @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
public static void disableSyncFromParent(Context userContext) {
- // Must disable sync first so that ringtone copy below doesn't get redirected to parent
- Settings.Secure.putIntForUser(userContext.getContentResolver(),
- Settings.Secure.SYNC_PARENT_SOUNDS, 0 /* false */, userContext.getUserId());
-
- // Copy ringtones from parent profile
- UserManager um = UserManager.get(userContext);
- UserInfo parentInfo = um.getProfileParent(userContext.getUserId());
- if (parentInfo != null) {
- final Context targetContext = createPackageContextAsUser(userContext, parentInfo.id);
- if (targetContext != null) {
- for (int ringtoneType : RINGTONE_TYPES) {
- Uri ringtoneUri = getActualDefaultRingtoneUri(targetContext, ringtoneType);
- // Add user id of parent so that custom ringtones can be read and played
- RingtoneManager.setActualDefaultRingtoneUri(userContext, ringtoneType,
- maybeAddUserId(ringtoneUri, parentInfo.id));
- }
- }
+ IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
+ IAudioService audioService = IAudioService.Stub.asInterface(b);
+ try {
+ audioService.disableRingtoneSync(userContext.getUserId());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to disable ringtone sync.");
}
}
@@ -851,22 +834,15 @@
* @see #getActualDefaultRingtoneUri(Context, int)
*/
public static void setActualDefaultRingtoneUri(Context context, int type, Uri ringtoneUri) {
- final ContentResolver resolver = context.getContentResolver();
-
- if (Settings.Secure.getString(resolver, Settings.Secure.SYNC_PARENT_SOUNDS).equals("1")) {
- // Sync is enabled, so we need to disable it
- IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
- IAudioService audioService = IAudioService.Stub.asInterface(b);
- try {
- audioService.disableRingtoneSync();
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to disable ringtone sync.");
- return;
- }
- }
-
String setting = getSettingForType(type);
if (setting == null) return;
+
+ final ContentResolver resolver = context.getContentResolver();
+ if (Settings.Secure.getIntForUser(resolver, Settings.Secure.SYNC_PARENT_SOUNDS, 0,
+ context.getUserId()) == 1) {
+ // Parent sound override is enabled. Disable it using the audio service.
+ disableSyncFromParent(context);
+ }
if(!isInternalRingtoneUri(ringtoneUri)) {
ringtoneUri = ContentProvider.maybeAddUserId(ringtoneUri, context.getUserId());
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 85c153c..225b955 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -86,6 +86,7 @@
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
@@ -2615,6 +2616,8 @@
if (isSecureSettingsKey(key)) {
maybeNotifyProfiles(getTypeFromKey(key), userId, uri, name,
sSecureCloneToManagedSettings);
+ maybeNotifyProfiles(SETTINGS_TYPE_SYSTEM, userId, uri, name,
+ sSystemCloneFromParentOnDependency.values());
} else if (isSystemSettingsKey(key)) {
maybeNotifyProfiles(getTypeFromKey(key), userId, uri, name,
sSystemCloneToManagedSettings);
@@ -2624,7 +2627,7 @@
}
private void maybeNotifyProfiles(int type, int userId, Uri uri, String name,
- Set<String> keysCloned) {
+ Collection<String> keysCloned) {
if (keysCloned.contains(name)) {
for (int profileId : mUserManager.getProfileIdsWithDisabled(userId)) {
// the notification for userId has already been sent.
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 5b3495f..79b99a3 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -6518,35 +6518,22 @@
return mRecordMonitor.getActiveRecordingConfigurations();
}
- public void disableRingtoneSync() {
+ public void disableRingtoneSync(final int userId) {
final int callingUserId = UserHandle.getCallingUserId();
+ if (callingUserId != userId) {
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL,
+ "disable sound settings syncing for another profile");
+ }
final long token = Binder.clearCallingIdentity();
try {
- UserManager userManager = UserManager.get(mContext);
-
- // Disable the sync setting
- Settings.Secure.putIntForUser(mContentResolver,
- Settings.Secure.SYNC_PARENT_SOUNDS, 0 /* false */, callingUserId);
-
- UserInfo parentInfo = userManager.getProfileParent(callingUserId);
- if (parentInfo != null && parentInfo.id != callingUserId) {
- // This is a managed profile, so we clone the ringtones from the parent profile
- cloneRingtoneSetting(callingUserId, parentInfo.id, Settings.System.RINGTONE);
- cloneRingtoneSetting(callingUserId, parentInfo.id,
- Settings.System.NOTIFICATION_SOUND);
- cloneRingtoneSetting(callingUserId, parentInfo.id, Settings.System.ALARM_ALERT);
- }
+ // Disable the sync setting so the profile uses its own sound settings.
+ Settings.Secure.putIntForUser(mContentResolver, Settings.Secure.SYNC_PARENT_SOUNDS,
+ 0 /* false */, userId);
} finally {
Binder.restoreCallingIdentity(token);
}
}
- private void cloneRingtoneSetting(int userId, int parentId, String ringtoneSetting) {
- String parentSetting = Settings.System.getStringForUser(mContentResolver, ringtoneSetting,
- parentId);
- Settings.System.putStringForUser(mContentResolver, ringtoneSetting, parentSetting, userId);
- }
-
//======================
// Audio playback notification
//======================