That fuck shit the fascists are using
at master 121 lines 4.2 kB view raw
1package org.tm.archive.util; 2 3import android.annotation.SuppressLint; 4import android.content.ContentResolver; 5import android.content.Context; 6import android.media.Ringtone; 7import android.media.RingtoneManager; 8import android.net.Uri; 9import android.provider.Settings; 10 11import androidx.annotation.NonNull; 12import androidx.annotation.Nullable; 13 14import org.signal.core.util.logging.Log; 15 16import java.lang.reflect.InvocationTargetException; 17import java.lang.reflect.Method; 18 19/** 20 * Some custom ROMs and some Samsung Android 11 devices have quirks around accessing the default ringtone. This attempts to deal 21 * with them with progressively worse approaches. 22 */ 23public final class RingtoneUtil { 24 25 private static final String TAG = Log.tag(RingtoneUtil.class); 26 27 private RingtoneUtil() {} 28 29 public static @Nullable Ringtone getRingtone(@NonNull Context context, @NonNull Uri uri) { 30 Ringtone tone; 31 try { 32 tone = RingtoneManager.getRingtone(context, uri); 33 } catch (SecurityException e) { 34 Log.w(TAG, "Unable to get default ringtone due to permission", e); 35 tone = RingtoneManager.getRingtone(context, RingtoneUtil.getActualDefaultRingtoneUri(context)); 36 } 37 return tone; 38 } 39 40 public static @Nullable Uri getActualDefaultRingtoneUri(@NonNull Context context) { 41 Log.i(TAG, "Attempting to get default ringtone directly via normal way"); 42 try { 43 return RingtoneManager.getActualDefaultRingtoneUri(context, RingtoneManager.TYPE_RINGTONE); 44 } catch (SecurityException e) { 45 Log.w(TAG, "Failed to get ringtone with first fallback approach", e); 46 } 47 48 Log.i(TAG, "Attempting to get default ringtone directly via reflection"); 49 String uriString = getStringForUser(context.getContentResolver(), getUserId(context)); 50 Uri ringtoneUri = uriString != null ? Uri.parse(uriString) : null; 51 52 if (ringtoneUri != null && getUserIdFromAuthority(ringtoneUri.getAuthority(), getUserId(context)) == getUserId(context)) { 53 ringtoneUri = getUriWithoutUserId(ringtoneUri); 54 } 55 56 return ringtoneUri; 57 } 58 59 @SuppressWarnings("JavaReflectionMemberAccess") 60 @SuppressLint("DiscouragedPrivateApi") 61 private static @Nullable String getStringForUser(@NonNull ContentResolver resolver, int userHandle) { 62 try { 63 Method getStringForUser = Settings.System.class.getMethod("getStringForUser", ContentResolver.class, String.class, int.class); 64 return (String) getStringForUser.invoke(Settings.System.class, resolver, Settings.System.RINGTONE, userHandle); 65 } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { 66 Log.w(TAG, "Unable to getStringForUser via reflection", e); 67 } 68 return null; 69 } 70 71 @SuppressWarnings("JavaReflectionMemberAccess") 72 @SuppressLint("DiscouragedPrivateApi") 73 private static int getUserId(@NonNull Context context) { 74 try { 75 Object userId = Context.class.getMethod("getUserId").invoke(context); 76 if (userId instanceof Integer) { 77 return (Integer) userId; 78 } else { 79 Log.w(TAG, "getUserId did not return an integer"); 80 } 81 } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { 82 Log.w(TAG, "Unable to getUserId via reflection", e); 83 } 84 return 0; 85 } 86 87 private static @Nullable Uri getUriWithoutUserId(@Nullable Uri uri) { 88 if (uri == null) { 89 return null; 90 } 91 Uri.Builder builder = uri.buildUpon(); 92 builder.authority(getAuthorityWithoutUserId(uri.getAuthority())); 93 return builder.build(); 94 } 95 96 private static @Nullable String getAuthorityWithoutUserId(@Nullable String auth) { 97 if (auth == null) { 98 return null; 99 } 100 int end = auth.lastIndexOf('@'); 101 return auth.substring(end + 1); 102 } 103 104 private static int getUserIdFromAuthority(@Nullable String authority, int defaultUserId) { 105 if (authority == null) { 106 return defaultUserId; 107 } 108 109 int end = authority.lastIndexOf('@'); 110 if (end == -1) { 111 return defaultUserId; 112 } 113 114 String userIdString = authority.substring(0, end); 115 try { 116 return Integer.parseInt(userIdString); 117 } catch (NumberFormatException e) { 118 return defaultUserId; 119 } 120 } 121}