summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/compose/gallery/AndroidManifest.xml3
-rw-r--r--packages/SystemUI/compose/gallery/app/AndroidManifest.xml4
-rw-r--r--packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/ConfigurationControls.kt114
3 files changed, 118 insertions, 3 deletions
diff --git a/packages/SystemUI/compose/gallery/AndroidManifest.xml b/packages/SystemUI/compose/gallery/AndroidManifest.xml
index 562e1cc3339a..4fcce0bf6968 100644
--- a/packages/SystemUI/compose/gallery/AndroidManifest.xml
+++ b/packages/SystemUI/compose/gallery/AndroidManifest.xml
@@ -17,5 +17,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.systemui.compose.gallery">
-
+ <!-- To emulate a display size and density. -->
+ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
</manifest>
diff --git a/packages/SystemUI/compose/gallery/app/AndroidManifest.xml b/packages/SystemUI/compose/gallery/app/AndroidManifest.xml
index 81132632079a..e7d496c2cb35 100644
--- a/packages/SystemUI/compose/gallery/app/AndroidManifest.xml
+++ b/packages/SystemUI/compose/gallery/app/AndroidManifest.xml
@@ -16,7 +16,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.systemui.compose.gallery">
+ package="com.android.systemui.compose.gallery.app">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
@@ -25,7 +25,7 @@
android:supportsRtl="true"
android:theme="@style/Theme.SystemUIGallery">
<activity
- android:name=".GalleryActivity"
+ android:name="com.android.systemui.compose.gallery.GalleryActivity"
android:exported="true"
android:label="@string/app_name">
<intent-filter>
diff --git a/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/ConfigurationControls.kt b/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/ConfigurationControls.kt
index 65ea88a8eede..06bdad8a6735 100644
--- a/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/ConfigurationControls.kt
+++ b/packages/SystemUI/compose/gallery/src/com/android/systemui/compose/gallery/ConfigurationControls.kt
@@ -1,5 +1,10 @@
package com.android.systemui.compose.gallery
+import android.graphics.Point
+import android.os.UserHandle
+import android.view.Display
+import android.view.WindowManagerGlobal
+import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyRow
@@ -9,14 +14,25 @@ import androidx.compose.material.icons.filled.BrightnessLow
import androidx.compose.material.icons.filled.FormatSize
import androidx.compose.material.icons.filled.FormatTextdirectionLToR
import androidx.compose.material.icons.filled.FormatTextdirectionRToL
+import androidx.compose.material.icons.filled.Smartphone
+import androidx.compose.material.icons.filled.Tablet
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
+import kotlin.math.max
+import kotlin.math.min
enum class FontScale(val scale: Float) {
Small(0.85f),
@@ -35,6 +51,39 @@ fun ConfigurationControls(
onChangeLayoutDirection: () -> Unit,
onChangeFontScale: () -> Unit,
) {
+ // The display we are emulating, if any.
+ var emulatedDisplayName by rememberSaveable { mutableStateOf<String?>(null) }
+ val emulatedDisplay =
+ emulatedDisplayName?.let { name -> EmulatedDisplays.firstOrNull { it.name == name } }
+
+ LaunchedEffect(emulatedDisplay) {
+ val wm = WindowManagerGlobal.getWindowManagerService()
+
+ val defaultDisplayId = Display.DEFAULT_DISPLAY
+ if (emulatedDisplay == null) {
+ wm.clearForcedDisplayDensityForUser(defaultDisplayId, UserHandle.myUserId())
+ wm.clearForcedDisplaySize(defaultDisplayId)
+ } else {
+ val density = emulatedDisplay.densityDpi
+
+ // Emulate the display and make sure that we use the maximum available space possible.
+ val initialSize = Point()
+ wm.getInitialDisplaySize(defaultDisplayId, initialSize)
+ val width = emulatedDisplay.width
+ val height = emulatedDisplay.height
+ val minOfSize = min(width, height)
+ val maxOfSize = max(width, height)
+ if (initialSize.x < initialSize.y) {
+ wm.setForcedDisplaySize(defaultDisplayId, minOfSize, maxOfSize)
+ } else {
+ wm.setForcedDisplaySize(defaultDisplayId, maxOfSize, minOfSize)
+ }
+ wm.setForcedDisplayDensityForUser(defaultDisplayId, density, UserHandle.myUserId())
+ }
+ }
+
+ // TODO(b/231131244): Fork FlowRow from Accompanist and use that instead to make sure that users
+ // don't miss any available configuration.
LazyRow {
// Dark/light theme.
item {
@@ -82,5 +131,70 @@ fun ConfigurationControls(
}
}
}
+
+ // Display emulation.
+ EmulatedDisplays.forEach { display ->
+ item {
+ DisplayButton(
+ display,
+ emulatedDisplay == display,
+ { emulatedDisplayName = it?.name },
+ )
+ }
+ }
+ }
+}
+
+@Composable
+private fun DisplayButton(
+ display: EmulatedDisplay,
+ selected: Boolean,
+ onChangeEmulatedDisplay: (EmulatedDisplay?) -> Unit,
+) {
+ val onClick = {
+ if (selected) {
+ onChangeEmulatedDisplay(null)
+ } else {
+ onChangeEmulatedDisplay(display)
+ }
+ }
+
+ val content: @Composable RowScope.() -> Unit = {
+ Icon(display.icon, null)
+ Spacer(Modifier.width(8.dp))
+ Text(display.name)
+ }
+
+ if (selected) {
+ Button(onClick, contentPadding = ButtonDefaults.TextButtonContentPadding, content = content)
+ } else {
+ TextButton(onClick, content = content)
}
}
+
+/** The displays that can be emulated from this Gallery app. */
+private val EmulatedDisplays =
+ listOf(
+ EmulatedDisplay(
+ "Phone",
+ Icons.Default.Smartphone,
+ width = 1440,
+ height = 3120,
+ densityDpi = 560,
+ ),
+ EmulatedDisplay(
+ "Tablet",
+ Icons.Default.Tablet,
+ width = 2560,
+ height = 1600,
+ densityDpi = 320,
+ ),
+ )
+
+private data class EmulatedDisplay(
+ val name: String,
+ val icon: ImageVector,
+ val width: Int,
+ val height: Int,
+ val densityDpi: Int,
+)