diff --git a/SECURITY.md b/SECURITY.md index 807537150f0..7d8f728d1d2 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,7 +1,8 @@ # Security Policy ## Supported Versions -Important note: Lawnchair v2 (Play Store version) is **unsupported**. Use the newer alphas instead. See [this FAQ page](https://lawnchair.app/faq#do-you-still-support-the-play-store-version) for additional information. +> [!NOTE] +> Lawnchair v2 (Play Store version) is **unsupported**. Use the newer alphas instead. See [this FAQ page](https://lawnchair.app/faq#do-you-still-support-the-play-store-version) for additional information. The latest version of Lawnchair is the only supported version. | Version | Supported | @@ -17,6 +18,6 @@ The latest version of Lawnchair is the only supported version. ## Reporting Security issues We appreciate your efforts to responsibly disclose your findings and will make every effort to acknowledge your contributions. -To report an issue, please contact a developer (can be found in the about page of the app) in Telegram or Discord and state your security vunerability starting with the words "SECURITY". +To report an issue, please contact a developer (can be found in the about page of the app) in Telegram or Discord and state your security vulnerability starting with the words "SECURITY". We'll endeavour to respond quickly, and will keep you updated throughout the process. diff --git a/lawnchair/src/app/lawnchair/backup/ui/CreateBackupScreen.kt b/lawnchair/src/app/lawnchair/backup/ui/CreateBackupScreen.kt index 60af753d6fb..5e5572cc27b 100644 --- a/lawnchair/src/app/lawnchair/backup/ui/CreateBackupScreen.kt +++ b/lawnchair/src/app/lawnchair/backup/ui/CreateBackupScreen.kt @@ -5,6 +5,7 @@ import android.app.Activity import android.app.WallpaperManager import android.content.Intent import android.content.res.Configuration +import android.os.Build import android.provider.DocumentsContract import android.util.Log import android.widget.Toast @@ -39,6 +40,7 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavGraphBuilder import app.lawnchair.backup.LawnchairBackup +import app.lawnchair.preferences.PreferenceManager import app.lawnchair.ui.preferences.LocalNavController import app.lawnchair.ui.preferences.components.DummyLauncherBox import app.lawnchair.ui.preferences.components.WallpaperPreview @@ -47,6 +49,8 @@ import app.lawnchair.ui.preferences.components.layout.PreferenceGroup import app.lawnchair.ui.preferences.components.layout.PreferenceLayout import app.lawnchair.ui.preferences.preferenceGraph import app.lawnchair.util.BackHandler +import app.lawnchair.util.checkAndRequestFilesPermission +import app.lawnchair.util.filesAndStorageGranted import app.lawnchair.util.hasFlag import app.lawnchair.util.removeFlag import com.android.launcher3.R @@ -73,8 +77,14 @@ fun CreateBackupScreen( val context = LocalContext.current val hasLiveWallpaper = remember { WallpaperManager.getInstance(context).wallpaperInfo != null } - val permissionState = rememberPermissionState(Manifest.permission.READ_EXTERNAL_STORAGE) - val hasStoragePermission = permissionState.status.isGranted + val permissionState = rememberPermissionState( + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + Manifest.permission.MANAGE_EXTERNAL_STORAGE + } else { + Manifest.permission.READ_EXTERNAL_STORAGE + }, + ) + val hasStoragePermission = permissionState.status.isGranted || filesAndStorageGranted(context) val scope = rememberCoroutineScope() var creatingBackup by remember { mutableStateOf(false) } @@ -155,7 +165,7 @@ fun CreateBackupScreen( flags = contents, setFlags = { if (it.hasFlag(LawnchairBackup.INCLUDE_WALLPAPER) && !hasStoragePermission) { - permissionState.launchPermissionRequest() + checkAndRequestFilesPermission(context, PreferenceManager.getInstance(context)) } else { viewModel.setBackupContents(it) } diff --git a/lawnchair/src/app/lawnchair/ui/preferences/components/WallpaperPreview.kt b/lawnchair/src/app/lawnchair/ui/preferences/components/WallpaperPreview.kt index 60d99623106..67a8ce2391b 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/components/WallpaperPreview.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/components/WallpaperPreview.kt @@ -4,6 +4,7 @@ import android.annotation.SuppressLint import android.app.WallpaperManager import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable +import android.os.Build import android.util.Size import androidx.compose.foundation.Image import androidx.compose.runtime.Composable @@ -15,6 +16,9 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.core.graphics.drawable.toBitmap +import app.lawnchair.preferences.PreferenceManager +import app.lawnchair.util.checkAndRequestFilesPermission +import app.lawnchair.util.filesAndStorageGranted import app.lawnchair.util.scaleDownToDisplaySize import com.google.accompanist.drawablepainter.rememberDrawablePainter import com.google.accompanist.permissions.ExperimentalPermissionsApi @@ -43,11 +47,17 @@ fun wallpaperDrawable(): Drawable? { val context = LocalContext.current val wallpaperManager = remember { WallpaperManager.getInstance(context) } val wallpaperInfo = wallpaperManager.wallpaperInfo - val permissionState = rememberPermissionState(android.Manifest.permission.READ_EXTERNAL_STORAGE) + val permissionState = rememberPermissionState( + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + android.Manifest.permission.MANAGE_EXTERNAL_STORAGE + } else { + android.Manifest.permission.READ_EXTERNAL_STORAGE + }, + ) val wallpaperDrawable by produceState(initialValue = null) { value = when { wallpaperInfo != null -> wallpaperInfo.loadThumbnail(context.packageManager) - permissionState.status.isGranted -> { + filesAndStorageGranted(context) -> { withContext(Dispatchers.IO) { wallpaperManager.drawable?.let { val size = Size(it.intrinsicWidth, it.intrinsicHeight).scaleDownToDisplaySize(context) @@ -62,7 +72,7 @@ fun wallpaperDrawable(): Drawable? { if (!permissionState.status.isGranted) { SideEffect { - permissionState.launchPermissionRequest() + checkAndRequestFilesPermission(context, PreferenceManager.getInstance(context)) } } diff --git a/lawnchair/src/app/lawnchair/ui/preferences/destinations/GeneralPreferences.kt b/lawnchair/src/app/lawnchair/ui/preferences/destinations/GeneralPreferences.kt index de0d42eb06e..a1d01cd5f46 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/destinations/GeneralPreferences.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/destinations/GeneralPreferences.kt @@ -96,11 +96,11 @@ fun GeneralPreferences() { PreferenceLayout(label = stringResource(id = R.string.general_label)) { PreferenceGroup { -// SwitchPreference( -// adapter = prefs.allowRotation.getAdapter(), -// label = stringResource(id = R.string.home_screen_rotation_label), -// description = stringResource(id = R.string.home_screen_rotaton_description), -// ) + SwitchPreference( + adapter = prefs.allowRotation.getAdapter(), + label = stringResource(id = R.string.home_screen_rotation_label), + description = stringResource(id = R.string.home_screen_rotaton_description), + ) val enableFontSelection = prefs2.enableFontSelection.asState().value if (enableFontSelection) { FontPreference( diff --git a/quickstep/res/values-night/colors.xml b/quickstep/res/values-night/colors.xml index 23ece7b2f58..623a1655edc 100644 --- a/quickstep/res/values-night/colors.xml +++ b/quickstep/res/values-night/colors.xml @@ -27,5 +27,5 @@ ?attr/colorAccentPrimary ?attr/materialColorPrimaryFixedDim - ?attr/materialColorOnPrimaryFixed - \ No newline at end of file + @color/material_color_on_primary_fixed + diff --git a/quickstep/res/values/colors.xml b/quickstep/res/values/colors.xml index f799d72b158..9ca66bb8d3a 100644 --- a/quickstep/res/values/colors.xml +++ b/quickstep/res/values/colors.xml @@ -95,5 +95,5 @@ ?attr/colorAccentPrimary ?attr/materialColorPrimaryFixedDim - ?attr/materialColorOnPrimaryFixed - \ No newline at end of file + @color/material_color_on_primary_fixed + diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 0c916d1284e..a81b25f3374 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -331,15 +331,17 @@ public static void mapRectInSelfToDescendant(View descendant, View root, Rect re public static void mapCoordInSelfToDescendant(View descendant, View root, float[] coord) { sMatrix.reset(); View v = descendant; - while (v != root) { + if (v != null) { + while (v != root) { + sMatrix.postTranslate(-v.getScrollX(), -v.getScrollY()); + sMatrix.postConcat(v.getMatrix()); + sMatrix.postTranslate(v.getLeft(), v.getTop()); + v = (View) v.getParent(); + } sMatrix.postTranslate(-v.getScrollX(), -v.getScrollY()); - sMatrix.postConcat(v.getMatrix()); - sMatrix.postTranslate(v.getLeft(), v.getTop()); - v = (View) v.getParent(); + sMatrix.invert(sInverseMatrix); + sInverseMatrix.mapPoints(coord); } - sMatrix.postTranslate(-v.getScrollX(), -v.getScrollY()); - sMatrix.invert(sInverseMatrix); - sInverseMatrix.mapPoints(coord); } /** diff --git a/src/com/android/launcher3/allapps/WorkProfileManager.java b/src/com/android/launcher3/allapps/WorkProfileManager.java index c4e03cc7744..958680962dc 100644 --- a/src/com/android/launcher3/allapps/WorkProfileManager.java +++ b/src/com/android/launcher3/allapps/WorkProfileManager.java @@ -166,8 +166,7 @@ private void updateCurrentState(@WorkProfileState int currentState) { */ public boolean attachWorkModeSwitch() { if (!mAllApps.getAppsStore().hasModelFlag( - FLAG_HAS_SHORTCUT_PERMISSION | FLAG_QUIET_MODE_CHANGE_PERMISSION) - || !Utilities.ATLEAST_Q) { + FLAG_HAS_SHORTCUT_PERMISSION | FLAG_QUIET_MODE_CHANGE_PERMISSION)) { Log.e(TAG, "unable to attach work mode switch; Missing required permissions"); return false; } diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index e4df413489f..c83ac67a910 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -433,8 +433,10 @@ public void mapCoordInSelfToDescendant(View descendant, float[] coord) { public void mapCoordInSelfToDescendant(View descendant, int[] coord) { mTmpXY[0] = coord[0]; mTmpXY[1] = coord[1]; - Utilities.mapCoordInSelfToDescendant(descendant, this, mTmpXY); - Utilities.roundArray(mTmpXY, coord); + if (descendant != null) { + Utilities.mapCoordInSelfToDescendant(descendant, this, mTmpXY); + Utilities.roundArray(mTmpXY, coord); + } } public void getViewRectRelativeToSelf(View v, Rect r) {