Loading core/java/android/view/KeyboardShortcutInfo.java +12 −3 Original line number Diff line number Diff line Loading @@ -28,8 +28,8 @@ import android.os.Parcelable; * Information about a Keyboard Shortcut. */ public final class KeyboardShortcutInfo implements Parcelable { private final CharSequence mLabel; private final Icon mIcon; @Nullable private final CharSequence mLabel; @Nullable private Icon mIcon; private final char mBaseCharacter; private final int mKeycode; private final int mModifiers; Loading Loading @@ -115,6 +115,15 @@ public final class KeyboardShortcutInfo implements Parcelable { return mIcon; } /** * Removes an icon that was previously set. * * @hide */ public void clearIcon() { mIcon = null; } /** * Returns the base keycode that, combined with the modifiers, triggers this shortcut. If the * base character was set instead, returns {@link KeyEvent#KEYCODE_UNKNOWN}. Valid keycodes are Loading media/java/android/media/RingtoneManager.java +6 −2 Original line number Diff line number Diff line Loading @@ -921,9 +921,13 @@ public class RingtoneManager { + " ignored: failure to find mimeType (no access from this context?)"); return; } if (!(mimeType.startsWith("audio/") || mimeType.equals("application/ogg"))) { if (!(mimeType.startsWith("audio/") || mimeType.equals("application/ogg") || mimeType.equals("application/x-flac") // also check for video ringtones || mimeType.startsWith("video/") || mimeType.equals("application/mp4"))) { Log.e(TAG, "setActualDefaultRingtoneUri for URI:" + ringtoneUri + " ignored: associated mimeType:" + mimeType + " is not an audio type"); + " ignored: associated MIME type:" + mimeType + " is not a recognized audio or video type"); return; } } Loading packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java +68 −11 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ package com.android.externalstorage; import static java.util.regex.Pattern.CASE_INSENSITIVE; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.usage.StorageStatsManager; Loading Loading @@ -61,12 +59,15 @@ import java.io.FileDescriptor; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Objects; import java.util.UUID; import java.util.regex.Pattern; import java.util.stream.Collectors; /** * Presents content of the shared (a.k.a. "external") storage. Loading @@ -89,12 +90,9 @@ public class ExternalStorageProvider extends FileSystemProvider { private static final Uri BASE_URI = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(AUTHORITY).build(); /** * Regex for detecting {@code /Android/data/}, {@code /Android/obb/} and * {@code /Android/sandbox/} along with all their subdirectories and content. */ private static final Pattern PATTERN_RESTRICTED_ANDROID_SUBTREES = Pattern.compile("^Android/(?:data|obb|sandbox)(?:/.+)?", CASE_INSENSITIVE); private static final String PRIMARY_EMULATED_STORAGE_PATH = "/storage/emulated/"; private static final String STORAGE_PATH = "/storage/"; private static final String[] DEFAULT_ROOT_PROJECTION = new String[] { Root.COLUMN_ROOT_ID, Root.COLUMN_FLAGS, Root.COLUMN_ICON, Root.COLUMN_TITLE, Loading Loading @@ -309,10 +307,69 @@ public class ExternalStorageProvider extends FileSystemProvider { return false; } final String path = getPathFromDocId(documentId); return PATTERN_RESTRICTED_ANDROID_SUBTREES.matcher(path).matches(); try { final RootInfo root = getRootFromDocId(documentId); final String canonicalPath = getPathFromDocId(documentId); return isRestrictedPath(root.rootId, canonicalPath); } catch (Exception e) { return true; } } /** * Based on the given root id and path, we restrict path access if file is Android/data or * Android/obb or Android/sandbox or one of their subdirectories. * * @param canonicalPath of the file * @return true if path is restricted */ private boolean isRestrictedPath(String rootId, String canonicalPath) { if (rootId == null || canonicalPath == null) { return true; } final String rootPath; if (rootId.equalsIgnoreCase(ROOT_ID_PRIMARY_EMULATED)) { // Creates "/storage/emulated/<user-id>" rootPath = PRIMARY_EMULATED_STORAGE_PATH + UserHandle.myUserId(); } else { // Creates "/storage/<volume-uuid>" rootPath = STORAGE_PATH + rootId; } List<java.nio.file.Path> restrictedPathList = Arrays.asList( Paths.get(rootPath, "Android", "data"), Paths.get(rootPath, "Android", "obb"), Paths.get(rootPath, "Android", "sandbox")); // We need to identify restricted parent paths which actually exist on the device List<java.nio.file.Path> validRestrictedPathsToCheck = restrictedPathList.stream().filter( Files::exists).collect(Collectors.toList()); boolean isRestricted = false; java.nio.file.Path filePathToCheck = Paths.get(rootPath, canonicalPath); try { while (filePathToCheck != null) { for (java.nio.file.Path restrictedPath : validRestrictedPathsToCheck) { if (Files.isSameFile(restrictedPath, filePathToCheck)) { isRestricted = true; Log.v(TAG, "Restricting access for path: " + filePathToCheck); break; } } if (isRestricted) { break; } filePathToCheck = filePathToCheck.getParent(); } } catch (Exception e) { Log.w(TAG, "Error in checking file equality check.", e); isRestricted = true; } return isRestricted; } /** * Check that the directory is the root of storage or blocked file from tree. * <p> Loading packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +7 −4 Original line number Diff line number Diff line Loading @@ -1972,7 +1972,7 @@ public class SettingsProvider extends ContentProvider { File cacheFile = getCacheFile(name, callingUserId); if (cacheFile != null) { if (!isValidAudioUri(name, value)) { if (!isValidMediaUri(name, value)) { return false; } // Invalidate any relevant cache files Loading Loading @@ -2031,7 +2031,7 @@ public class SettingsProvider extends ContentProvider { return true; } private boolean isValidAudioUri(String name, String uri) { private boolean isValidMediaUri(String name, String uri) { if (uri != null) { Uri audioUri = Uri.parse(uri); if (Settings.AUTHORITY.equals( Loading @@ -2049,10 +2049,13 @@ public class SettingsProvider extends ContentProvider { return false; } if (!(mimeType.startsWith("audio/") || mimeType.equals("application/ogg") || mimeType.equals("application/x-flac"))) { || mimeType.equals("application/x-flac") // also check for video ringtones || mimeType.startsWith("video/") || mimeType.equals("application/mp4"))) { Slog.e(LOG_TAG, "mutateSystemSetting for setting: " + name + " URI: " + audioUri + " ignored: associated mimeType: " + mimeType + " is not an audio type"); + " ignored: associated MIME type: " + mimeType + " is not a recognized audio or video type"); return false; } } Loading packages/SystemUI/res/values/lineage_config.xml +27 −29 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2018-2022 The LineageOS Project Copyright (C) 2018-2024 The LineageOS Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. Loading @@ -23,37 +23,35 @@ <!-- Array of brightness-alpha LUT for framework dimming --> <string-array name="config_udfpsDimmingBrightnessAlphaArray" translatable="false"> <!-- Example: <item>0,255</item> <item>1,234</item> <item>3,227</item> <item>8,208</item> <item>16,192</item> <item>27,176</item> <item>41,160</item> <item>61,144</item> <item>80,128</item> <item>104,112</item> <item>130,96</item> <item>158,80</item> <item>188,64</item> <item>221,48</item> <item>250,36</item> <item>255,33</item> --> <item>1,248</item> <item>2,242</item> <item>3,238</item> <item>4,236</item> <item>6,236</item> <item>10,234</item> <item>20,228</item> <item>30,222</item> <item>45,217</item> <item>70,209</item> <item>100,200</item> <item>150,191</item> <item>227,178</item> <item>300,167</item> <item>400,154</item> <item>500,143</item> <item>600,133</item> <item>800,117</item> <item>1023,109</item> <item>1130,95</item> <item>1211,89</item> <item>1394,79</item> <item>1598,69</item> <item>1817,53</item> <item>2047,46</item> <item>4095,0</item> </string-array> <!-- Brightness range min for UDFPS dimming --> <integer name="config_udfpsDimmingBrightnessMin">0</integer> <!-- Brightness range max for UDFPS dimming --> <integer name="config_udfpsDimmingBrightnessMax">0</integer> <!-- The amount of delay to add when disabling the dimming. This is used to prevent flickers due to the dimming being disabled before the screen has had chance to switch out of HBM mode --> <integer name="config_udfpsDimmingDisableDelay">0</integer> <!-- Doze: does the double tap sensor need a proximity check? --> <bool name="doze_double_tap_proximity_check">false</bool> Loading Loading
core/java/android/view/KeyboardShortcutInfo.java +12 −3 Original line number Diff line number Diff line Loading @@ -28,8 +28,8 @@ import android.os.Parcelable; * Information about a Keyboard Shortcut. */ public final class KeyboardShortcutInfo implements Parcelable { private final CharSequence mLabel; private final Icon mIcon; @Nullable private final CharSequence mLabel; @Nullable private Icon mIcon; private final char mBaseCharacter; private final int mKeycode; private final int mModifiers; Loading Loading @@ -115,6 +115,15 @@ public final class KeyboardShortcutInfo implements Parcelable { return mIcon; } /** * Removes an icon that was previously set. * * @hide */ public void clearIcon() { mIcon = null; } /** * Returns the base keycode that, combined with the modifiers, triggers this shortcut. If the * base character was set instead, returns {@link KeyEvent#KEYCODE_UNKNOWN}. Valid keycodes are Loading
media/java/android/media/RingtoneManager.java +6 −2 Original line number Diff line number Diff line Loading @@ -921,9 +921,13 @@ public class RingtoneManager { + " ignored: failure to find mimeType (no access from this context?)"); return; } if (!(mimeType.startsWith("audio/") || mimeType.equals("application/ogg"))) { if (!(mimeType.startsWith("audio/") || mimeType.equals("application/ogg") || mimeType.equals("application/x-flac") // also check for video ringtones || mimeType.startsWith("video/") || mimeType.equals("application/mp4"))) { Log.e(TAG, "setActualDefaultRingtoneUri for URI:" + ringtoneUri + " ignored: associated mimeType:" + mimeType + " is not an audio type"); + " ignored: associated MIME type:" + mimeType + " is not a recognized audio or video type"); return; } } Loading
packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java +68 −11 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ package com.android.externalstorage; import static java.util.regex.Pattern.CASE_INSENSITIVE; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.usage.StorageStatsManager; Loading Loading @@ -61,12 +59,15 @@ import java.io.FileDescriptor; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Objects; import java.util.UUID; import java.util.regex.Pattern; import java.util.stream.Collectors; /** * Presents content of the shared (a.k.a. "external") storage. Loading @@ -89,12 +90,9 @@ public class ExternalStorageProvider extends FileSystemProvider { private static final Uri BASE_URI = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(AUTHORITY).build(); /** * Regex for detecting {@code /Android/data/}, {@code /Android/obb/} and * {@code /Android/sandbox/} along with all their subdirectories and content. */ private static final Pattern PATTERN_RESTRICTED_ANDROID_SUBTREES = Pattern.compile("^Android/(?:data|obb|sandbox)(?:/.+)?", CASE_INSENSITIVE); private static final String PRIMARY_EMULATED_STORAGE_PATH = "/storage/emulated/"; private static final String STORAGE_PATH = "/storage/"; private static final String[] DEFAULT_ROOT_PROJECTION = new String[] { Root.COLUMN_ROOT_ID, Root.COLUMN_FLAGS, Root.COLUMN_ICON, Root.COLUMN_TITLE, Loading Loading @@ -309,10 +307,69 @@ public class ExternalStorageProvider extends FileSystemProvider { return false; } final String path = getPathFromDocId(documentId); return PATTERN_RESTRICTED_ANDROID_SUBTREES.matcher(path).matches(); try { final RootInfo root = getRootFromDocId(documentId); final String canonicalPath = getPathFromDocId(documentId); return isRestrictedPath(root.rootId, canonicalPath); } catch (Exception e) { return true; } } /** * Based on the given root id and path, we restrict path access if file is Android/data or * Android/obb or Android/sandbox or one of their subdirectories. * * @param canonicalPath of the file * @return true if path is restricted */ private boolean isRestrictedPath(String rootId, String canonicalPath) { if (rootId == null || canonicalPath == null) { return true; } final String rootPath; if (rootId.equalsIgnoreCase(ROOT_ID_PRIMARY_EMULATED)) { // Creates "/storage/emulated/<user-id>" rootPath = PRIMARY_EMULATED_STORAGE_PATH + UserHandle.myUserId(); } else { // Creates "/storage/<volume-uuid>" rootPath = STORAGE_PATH + rootId; } List<java.nio.file.Path> restrictedPathList = Arrays.asList( Paths.get(rootPath, "Android", "data"), Paths.get(rootPath, "Android", "obb"), Paths.get(rootPath, "Android", "sandbox")); // We need to identify restricted parent paths which actually exist on the device List<java.nio.file.Path> validRestrictedPathsToCheck = restrictedPathList.stream().filter( Files::exists).collect(Collectors.toList()); boolean isRestricted = false; java.nio.file.Path filePathToCheck = Paths.get(rootPath, canonicalPath); try { while (filePathToCheck != null) { for (java.nio.file.Path restrictedPath : validRestrictedPathsToCheck) { if (Files.isSameFile(restrictedPath, filePathToCheck)) { isRestricted = true; Log.v(TAG, "Restricting access for path: " + filePathToCheck); break; } } if (isRestricted) { break; } filePathToCheck = filePathToCheck.getParent(); } } catch (Exception e) { Log.w(TAG, "Error in checking file equality check.", e); isRestricted = true; } return isRestricted; } /** * Check that the directory is the root of storage or blocked file from tree. * <p> Loading
packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +7 −4 Original line number Diff line number Diff line Loading @@ -1972,7 +1972,7 @@ public class SettingsProvider extends ContentProvider { File cacheFile = getCacheFile(name, callingUserId); if (cacheFile != null) { if (!isValidAudioUri(name, value)) { if (!isValidMediaUri(name, value)) { return false; } // Invalidate any relevant cache files Loading Loading @@ -2031,7 +2031,7 @@ public class SettingsProvider extends ContentProvider { return true; } private boolean isValidAudioUri(String name, String uri) { private boolean isValidMediaUri(String name, String uri) { if (uri != null) { Uri audioUri = Uri.parse(uri); if (Settings.AUTHORITY.equals( Loading @@ -2049,10 +2049,13 @@ public class SettingsProvider extends ContentProvider { return false; } if (!(mimeType.startsWith("audio/") || mimeType.equals("application/ogg") || mimeType.equals("application/x-flac"))) { || mimeType.equals("application/x-flac") // also check for video ringtones || mimeType.startsWith("video/") || mimeType.equals("application/mp4"))) { Slog.e(LOG_TAG, "mutateSystemSetting for setting: " + name + " URI: " + audioUri + " ignored: associated mimeType: " + mimeType + " is not an audio type"); + " ignored: associated MIME type: " + mimeType + " is not a recognized audio or video type"); return false; } } Loading
packages/SystemUI/res/values/lineage_config.xml +27 −29 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2018-2022 The LineageOS Project Copyright (C) 2018-2024 The LineageOS Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. Loading @@ -23,37 +23,35 @@ <!-- Array of brightness-alpha LUT for framework dimming --> <string-array name="config_udfpsDimmingBrightnessAlphaArray" translatable="false"> <!-- Example: <item>0,255</item> <item>1,234</item> <item>3,227</item> <item>8,208</item> <item>16,192</item> <item>27,176</item> <item>41,160</item> <item>61,144</item> <item>80,128</item> <item>104,112</item> <item>130,96</item> <item>158,80</item> <item>188,64</item> <item>221,48</item> <item>250,36</item> <item>255,33</item> --> <item>1,248</item> <item>2,242</item> <item>3,238</item> <item>4,236</item> <item>6,236</item> <item>10,234</item> <item>20,228</item> <item>30,222</item> <item>45,217</item> <item>70,209</item> <item>100,200</item> <item>150,191</item> <item>227,178</item> <item>300,167</item> <item>400,154</item> <item>500,143</item> <item>600,133</item> <item>800,117</item> <item>1023,109</item> <item>1130,95</item> <item>1211,89</item> <item>1394,79</item> <item>1598,69</item> <item>1817,53</item> <item>2047,46</item> <item>4095,0</item> </string-array> <!-- Brightness range min for UDFPS dimming --> <integer name="config_udfpsDimmingBrightnessMin">0</integer> <!-- Brightness range max for UDFPS dimming --> <integer name="config_udfpsDimmingBrightnessMax">0</integer> <!-- The amount of delay to add when disabling the dimming. This is used to prevent flickers due to the dimming being disabled before the screen has had chance to switch out of HBM mode --> <integer name="config_udfpsDimmingDisableDelay">0</integer> <!-- Doze: does the double tap sensor need a proximity check? --> <bool name="doze_double_tap_proximity_check">false</bool> Loading