Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 931ee10c authored by Wenhao Shi's avatar Wenhao Shi Committed by Automerger Merge Worker
Browse files

Implemement the media lookup for ringtone restore in SettingsProvider. am: 452ffae8

parents 5ca8d2c5 452ffae8
Loading
Loading
Loading
Loading
+91 −0
Original line number Diff line number Diff line
@@ -46,7 +46,9 @@ import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.BaseColumns;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio.AudioColumns;
import android.provider.MediaStore.MediaColumns;
import android.provider.Settings;
import android.provider.Settings.System;
@@ -507,6 +509,95 @@ public class RingtoneManager {
        return getUriFromCursor(mContext, mCursor);
    }

    /**
     * Gets the valid ringtone uri by a given uri string and ringtone type for the restore purpose.
     *
     * @param contentResolver ContentResolver to execute media query.
     * @param value a canonicalized uri which refers to the ringtone.
     * @param ringtoneType an integer representation of the kind of uri that is being restored, can
     *     be RingtoneManager.TYPE_RINGTONE, RingtoneManager.TYPE_NOTIFICATION, or
     *     RingtoneManager.TYPE_ALARM.
     * @hide
     */
    public static @Nullable Uri getRingtoneUriForRestore(
            @NonNull ContentResolver contentResolver, @Nullable String value, int ringtoneType)
            throws FileNotFoundException, IllegalArgumentException {
        if (value == null) {
            // Return a valid null. It means the null value is intended instead of a failure.
            return null;
        }

        Uri ringtoneUri;
        final Uri canonicalUri = Uri.parse(value);

        // Try to get the media uri via the regular uncanonicalize method first.
        ringtoneUri = contentResolver.uncanonicalize(canonicalUri);
        if (ringtoneUri != null) {
            // Canonicalize it to make the result contain the right metadata of the media asset.
            ringtoneUri = contentResolver.canonicalize(ringtoneUri);
            return ringtoneUri;
        }

        // Query the media by title and ringtone type.
        final String title = canonicalUri.getQueryParameter(AudioColumns.TITLE);
        Uri baseUri = ContentUris.removeId(canonicalUri).buildUpon().clearQuery().build();
        String ringtoneTypeSelection = "";
        switch (ringtoneType) {
            case RingtoneManager.TYPE_RINGTONE:
                ringtoneTypeSelection = MediaStore.Audio.AudioColumns.IS_RINGTONE;
                break;
            case RingtoneManager.TYPE_NOTIFICATION:
                ringtoneTypeSelection = MediaStore.Audio.AudioColumns.IS_NOTIFICATION;
                break;
            case RingtoneManager.TYPE_ALARM:
                ringtoneTypeSelection = MediaStore.Audio.AudioColumns.IS_ALARM;
                break;
            default:
                throw new IllegalArgumentException("Unknown ringtone type: " + ringtoneType);
        }

        final String selection = ringtoneTypeSelection + "=1 AND " + AudioColumns.TITLE + "=?";
        Cursor cursor = null;
        try {
            cursor =
                    contentResolver.query(
                            baseUri,
                            /* projection */ new String[] {BaseColumns._ID},
                            /* selection */ selection,
                            /* selectionArgs */ new String[] {title},
                            /* sortOrder */ null,
                            /* cancellationSignal */ null);

        } catch (IllegalArgumentException e) {
            throw new FileNotFoundException("Volume not found for " + baseUri);
        }
        if (cursor == null) {
            throw new FileNotFoundException("Missing cursor for " + baseUri);
        } else if (cursor.getCount() == 0) {
            FileUtils.closeQuietly(cursor);
            throw new FileNotFoundException("No item found for " + baseUri);
        } else if (cursor.getCount() > 1) {
            // Find more than 1 result.
            // We are not sure which one is the right ringtone file so just abandon this case.
            FileUtils.closeQuietly(cursor);
            throw new FileNotFoundException(
                    "Find multiple ringtone candidates by title+ringtone_type query: count: "
                            + cursor.getCount());
        }
        if (cursor.moveToFirst()) {
            ringtoneUri = ContentUris.withAppendedId(baseUri, cursor.getLong(0));
            FileUtils.closeQuietly(cursor);
        } else {
            FileUtils.closeQuietly(cursor);
            throw new FileNotFoundException("Failed to read row from the result.");
        }

        // Canonicalize it to make the result contain the right metadata of the media asset.
        ringtoneUri = contentResolver.canonicalize(ringtoneUri);
        Log.v(TAG, "Find a valid result: " + ringtoneUri);
        return ringtoneUri;
    }

    private static Uri getUriFromCursor(Context context, Cursor cursor) {
        final Uri uri = ContentUris.withAppendedId(Uri.parse(cursor.getString(URI_COLUMN_INDEX)),
                cursor.getLong(ID_COLUMN_INDEX));
+21 −11
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.LocalePicker;
import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
@@ -332,21 +333,30 @@ public class SettingsHelper {
     * @param value can be a canonicalized uri or "_silent" to indicate a silent (null) ringtone.
     */
    private void setRingtone(String name, String value) {
        // If it's null, don't change the default
        Log.v(TAG, "Set ringtone for name: " + name + " value: " + value);

        // If it's null, don't change the default.
        if (value == null) return;
        final Uri ringtoneUri;
        final int ringtoneType = getRingtoneType(name);
        if (SILENT_RINGTONE.equals(value)) {
            ringtoneUri = null;
        } else {
            Uri canonicalUri = Uri.parse(value);
            ringtoneUri = mContext.getContentResolver().uncanonicalize(canonicalUri);
            if (ringtoneUri == null) {
                // Unrecognized or invalid Uri, don't restore
            // SILENT_RINGTONE is a special constant generated by onBackupValue in the source
            // device.
            RingtoneManager.setActualDefaultRingtoneUri(mContext, ringtoneType, null);
            return;
        }

        Uri ringtoneUri = null;
        try {
            ringtoneUri =
                    RingtoneManager.getRingtoneUriForRestore(
                            mContext.getContentResolver(), value, ringtoneType);
        } catch (FileNotFoundException | IllegalArgumentException e) {
            Log.w(TAG, "Failed to resolve " + value + ": " + e);
            // Unrecognized or invalid Uri, don't restore
            return;
        }
        final int ringtoneType = getRingtoneType(name);

        Log.v(TAG, "setActualDefaultRingtoneUri type: " + ringtoneType + ", uri: " + ringtoneUri);
        RingtoneManager.setActualDefaultRingtoneUri(mContext, ringtoneType, ringtoneUri);
    }

+404 −0

File changed.

Preview size limit exceeded, changes collapsed.