Validate ringtone URIs before setting
Add checks URIs for content from other users. Fail for users that are not profiles of the current user. Test: atest DefaultRingtonePreferenceTest Bug: 299614635 Change-Id: Ib266b285a3a1c6c5265ae2321159e61e08e349f6 Merged-In: Ib266b285a3a1c6c5265ae2321159e61e08e349f6
This commit is contained in:
committed by
Iavor-Valentin Iftime
parent
7b38ca4ff1
commit
1876c44991
@@ -51,16 +51,9 @@ public class DefaultRingtonePreference extends RingtonePreference {
|
||||
return;
|
||||
}
|
||||
|
||||
String mimeType = mUserContext.getContentResolver().getType(ringtoneUri);
|
||||
if (mimeType == null) {
|
||||
if (!isValidRingtoneUri(ringtoneUri)) {
|
||||
Log.e(TAG, "onSaveRingtone for URI:" + ringtoneUri
|
||||
+ " ignored: failure to find mimeType (no access from this context?)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(mimeType.startsWith("audio/") || mimeType.equals("application/ogg"))) {
|
||||
Log.e(TAG, "onSaveRingtone for URI:" + ringtoneUri
|
||||
+ " ignored: associated mimeType:" + mimeType + " is not an audio type");
|
||||
+ " ignored: invalid ringtone Uri");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.settings;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.TypedArray;
|
||||
@@ -23,9 +25,11 @@ import android.media.AudioAttributes;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings.System;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceManager;
|
||||
@@ -239,4 +243,83 @@ public class RingtonePreference extends Preference {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isDefaultRingtone(Uri ringtoneUri) {
|
||||
// null URIs are valid (None/silence)
|
||||
return ringtoneUri == null || RingtoneManager.isDefault(ringtoneUri);
|
||||
}
|
||||
|
||||
protected boolean isValidRingtoneUri(Uri ringtoneUri) {
|
||||
if (isDefaultRingtone(ringtoneUri)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return early for android resource URIs
|
||||
if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(ringtoneUri.getScheme())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String mimeType = mUserContext.getContentResolver().getType(ringtoneUri);
|
||||
if (mimeType == null) {
|
||||
Log.e(TAG, "isValidRingtoneUri for URI:" + ringtoneUri
|
||||
+ " failed: failure to find mimeType (no access from this context?)");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(mimeType.startsWith("audio/") || mimeType.equals("application/ogg")
|
||||
|| mimeType.equals("application/x-flac"))) {
|
||||
Log.e(TAG, "isValidRingtoneUri for URI:" + ringtoneUri
|
||||
+ " failed: associated mimeType:" + mimeType + " is not an audio type");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate userId from URIs: content://{userId}@...
|
||||
final int userIdFromUri = ContentProvider.getUserIdFromUri(ringtoneUri, mUserId);
|
||||
if (userIdFromUri != mUserId) {
|
||||
final UserManager userManager = mUserContext.getSystemService(UserManager.class);
|
||||
|
||||
if (!userManager.isSameProfileGroup(mUserId, userIdFromUri)) {
|
||||
Log.e(TAG,
|
||||
"isValidRingtoneUri for URI:" + ringtoneUri + " failed: user " + userIdFromUri
|
||||
+ " and user " + mUserId + " are not in the same profile group");
|
||||
return false;
|
||||
}
|
||||
|
||||
final int parentUserId;
|
||||
final int profileUserId;
|
||||
if (userManager.isProfile()) {
|
||||
profileUserId = mUserId;
|
||||
parentUserId = userIdFromUri;
|
||||
} else {
|
||||
parentUserId = mUserId;
|
||||
profileUserId = userIdFromUri;
|
||||
}
|
||||
|
||||
final UserHandle parent = userManager.getProfileParent(UserHandle.of(profileUserId));
|
||||
if (parent == null || parent.getIdentifier() != parentUserId) {
|
||||
Log.e(TAG,
|
||||
"isValidRingtoneUri for URI:" + ringtoneUri + " failed: user " + profileUserId
|
||||
+ " is not a profile of user " + parentUserId);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Allow parent <-> managed profile sharing, unless restricted
|
||||
if (userManager.hasUserRestrictionForUser(
|
||||
UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE, UserHandle.of(parentUserId))) {
|
||||
Log.e(TAG,
|
||||
"isValidRingtoneUri for URI:" + ringtoneUri + " failed: user " + parentUserId
|
||||
+ " has restriction: " + UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(userManager.isManagedProfile(profileUserId) || userManager.getUserProperties(
|
||||
UserHandle.of(profileUserId)).isMediaSharedWithParent())) {
|
||||
Log.e(TAG, "isValidRingtoneUri for URI:" + ringtoneUri
|
||||
+ " failed: user " + profileUserId + " is not a cloned or managed profile");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -25,10 +25,13 @@ import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import android.util.Log;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.RingtonePreference;
|
||||
|
||||
public class NotificationSoundPreference extends RingtonePreference {
|
||||
private static final String TAG = "NotificationSoundPreference";
|
||||
|
||||
private Uri mRingtone;
|
||||
|
||||
public NotificationSoundPreference(Context context, AttributeSet attrs) {
|
||||
@@ -50,8 +53,13 @@ public class NotificationSoundPreference extends RingtonePreference {
|
||||
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (data != null) {
|
||||
Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
|
||||
setRingtone(uri);
|
||||
callChangeListener(uri);
|
||||
if (isValidRingtoneUri(uri)) {
|
||||
setRingtone(uri);
|
||||
callChangeListener(uri);
|
||||
} else {
|
||||
Log.e(TAG, "onActivityResult for URI:" + uri
|
||||
+ " ignored: invalid ringtone Uri");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
Reference in New Issue
Block a user