Snap for 12695596 from d5d59630b5 to 25Q1-release

Change-Id: I83535d61b12d7c3ce38ca3d49440823785278c0f
This commit is contained in:
Android Build Coastguard Worker
2024-11-22 00:17:56 +00:00
16 changed files with 308 additions and 58 deletions

View File

@@ -49,7 +49,7 @@
android:text="@string/reset_esim_title"/>
<TextView
style="?android:attr/textAppearanceSmall"
style="@style/TextAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/reset_esim_desc"/>

View File

@@ -16,7 +16,6 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="input_touchpad_three_finger_tap"
android:persistent="false"
android:title="@string/three_finger_tap_preference_title">
@@ -25,5 +24,4 @@
android:key="input_touchpad_three_finger_tap_preference"
android:title="@string/three_finger_tap_preference_title"/>
</PreferenceScreen>

View File

@@ -17,6 +17,7 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="lockscreen_from_display_settings"
android:title="@string/lockscreen_settings_title">
<PreferenceCategory

View File

@@ -186,7 +186,7 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF
}
/** Returns if catalyst is enabled on current screen. */
protected final boolean isCatalystEnabled() {
public final boolean isCatalystEnabled() {
// TODO(b/379130874): make Catalyst compatible with desktop device, such as user restriction
// check.
Context context = getContext();

View File

@@ -17,6 +17,7 @@
package com.android.settings.bluetooth.ui.view
import android.app.ActivityOptions
import android.app.settings.SettingsEnums
import android.bluetooth.BluetoothAdapter
import android.content.Context
import android.content.Intent
@@ -39,6 +40,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.lifecycleScope
import androidx.preference.Preference
import com.android.settings.R
import com.android.settings.SettingsPreferenceFragment
@@ -50,30 +52,33 @@ import com.android.settings.bluetooth.ui.model.FragmentTypeModel
import com.android.settings.bluetooth.ui.view.DeviceDetailsMoreSettingsFragment.Companion.KEY_DEVICE_ADDRESS
import com.android.settings.bluetooth.ui.viewmodel.BluetoothDeviceDetailsViewModel
import com.android.settings.core.SubSettingLauncher
import com.android.settings.overlay.FeatureFactory
import com.android.settings.spa.preference.ComposePreference
import com.android.settingslib.bluetooth.CachedBluetoothDevice
import com.android.settingslib.bluetooth.devicesettings.shared.model.DeviceSettingActionModel
import com.android.settingslib.bluetooth.devicesettings.shared.model.DeviceSettingConfigItemModel
import com.android.settingslib.bluetooth.devicesettings.shared.model.DeviceSettingIcon
import com.android.settingslib.spa.framework.theme.SettingsDimension
import com.android.settingslib.spa.widget.button.ActionButton
import com.android.settingslib.spa.widget.button.ActionButtons
import com.android.settingslib.spa.widget.preference.Preference as SpaPreference
import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spa.widget.preference.SwitchPreference
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
import com.android.settingslib.spa.widget.preference.TwoTargetSwitchPreference
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
import com.android.settingslib.spa.widget.ui.Footer
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.emitAll
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.runBlocking
/** Handles device details fragment layout according to config. */
@@ -93,6 +98,7 @@ interface DeviceDetailsFragmentFormatter {
): Flow<DeviceSettingPreferenceModel.HelpPreference?>
}
@FlowPreview
@OptIn(ExperimentalCoroutinesApi::class)
class DeviceDetailsFragmentFormatterImpl(
private val context: Context,
@@ -101,6 +107,9 @@ class DeviceDetailsFragmentFormatterImpl(
private val cachedDevice: CachedBluetoothDevice,
private val backgroundCoroutineContext: CoroutineContext,
) : DeviceDetailsFragmentFormatter {
private val metricsFeatureProvider = FeatureFactory.featureFactory.metricsFeatureProvider
private val prefVisibility = mutableMapOf<String, MutableStateFlow<Boolean>>()
private val prefVisibilityJobs = mutableListOf<Job>()
private val viewModel: BluetoothDeviceDetailsViewModel =
ViewModelProvider(
@@ -147,21 +156,33 @@ class DeviceDetailsFragmentFormatterImpl(
prefKeyToSettingId[pref.key]?.let { id -> settingIdToXmlPreferences[id] = pref }
}
fragment.preferenceScreen.removeAll()
for (job in prefVisibilityJobs) {
job.cancel()
}
prefVisibilityJobs.clear()
for (row in items.indices) {
val settingId = items[row].settingId
if (settingIdToXmlPreferences.containsKey(settingId)) {
fragment.preferenceScreen.addPreference(
settingIdToXmlPreferences[settingId]!!.apply { order = row }
settingIdToXmlPreferences[settingId]!!
.apply { order = row }
.also { logItemShown(it.key, it.isVisible) }
)
} else {
val prefKey = getPreferenceKey(settingId)
prefVisibilityJobs.add(
getDevicesSettingForRow(layout, row)
.onEach { logItemShown(prefKey, it.isNotEmpty()) }
.launchIn(fragment.lifecycleScope)
)
val pref =
ComposePreference(context)
.apply {
key = getPreferenceKey(settingId)
key = prefKey
order = row
}
.also { pref -> pref.setContent { buildPreference(layout, row) } }
.also { pref -> pref.setContent { buildPreference(layout, row, prefKey) } }
fragment.preferenceScreen.addPreference(pref)
}
}
@@ -183,24 +204,28 @@ class DeviceDetailsFragmentFormatterImpl(
} ?: emit(null)
}
@Composable
private fun buildPreference(layout: DeviceSettingLayout, row: Int) {
val contents by
remember(row) {
layout.rows[row].columns.flatMapLatest { columns ->
if (columns.isEmpty()) {
flowOf(emptyList<DeviceSettingPreferenceModel>())
} else {
combine(
columns.map { column ->
viewModel.getDeviceSetting(cachedDevice, column.settingId)
}
) {
it.toList()
}
}
private fun getDevicesSettingForRow(
layout: DeviceSettingLayout,
row: Int,
): Flow<List<DeviceSettingPreferenceModel>> =
layout.rows[row].columns.flatMapLatest { columns ->
if (columns.isEmpty()) {
flowOf(emptyList())
} else {
combine(
columns.map { column ->
viewModel.getDeviceSetting(cachedDevice, column.settingId)
}
) {
it.toList().filterNotNull()
}
}
}
@Composable
private fun buildPreference(layout: DeviceSettingLayout, row: Int, prefKey: String) {
val contents by
remember(row) { getDevicesSettingForRow(layout, row) }
.collectAsStateWithLifecycle(initialValue = listOf())
val highlighted by
@@ -226,31 +251,31 @@ class DeviceDetailsFragmentFormatterImpl(
shape = RoundedCornerShape(28.dp),
)
) {}
buildPreferences(settings)
buildPreferences(settings, prefKey)
}
}
}
@Composable
fun buildPreferences(settings: List<DeviceSettingPreferenceModel?>) {
fun buildPreferences(settings: List<DeviceSettingPreferenceModel?>, prefKey: String) {
when (settings.size) {
0 -> {}
1 -> {
when (val setting = settings[0]) {
is DeviceSettingPreferenceModel.PlainPreference -> {
buildPlainPreference(setting)
buildPlainPreference(setting, prefKey)
}
is DeviceSettingPreferenceModel.SwitchPreference -> {
buildSwitchPreference(setting)
buildSwitchPreference(setting, prefKey)
}
is DeviceSettingPreferenceModel.MultiTogglePreference -> {
buildMultiTogglePreference(setting)
buildMultiTogglePreference(setting, prefKey)
}
is DeviceSettingPreferenceModel.FooterPreference -> {
buildFooterPreference(setting)
}
is DeviceSettingPreferenceModel.MoreSettingsPreference -> {
buildMoreSettingsPreference()
buildMoreSettingsPreference(prefKey)
}
is DeviceSettingPreferenceModel.HelpPreference -> {}
null -> {}
@@ -262,20 +287,32 @@ class DeviceDetailsFragmentFormatterImpl(
@Composable
private fun buildMultiTogglePreference(
pref: DeviceSettingPreferenceModel.MultiTogglePreference
pref: DeviceSettingPreferenceModel.MultiTogglePreference,
prefKey: String,
) {
MultiTogglePreference(pref)
MultiTogglePreference(
pref.copy(
onSelectedChange = { newState ->
logItemClick(prefKey, newState)
pref.onSelectedChange(newState)
}
)
)
}
@Composable
private fun buildSwitchPreference(model: DeviceSettingPreferenceModel.SwitchPreference) {
private fun buildSwitchPreference(
model: DeviceSettingPreferenceModel.SwitchPreference,
prefKey: String,
) {
val switchPrefModel =
object : SwitchPreferenceModel {
override val title = model.title
override val summary = { model.summary ?: "" }
override val checked = { model.checked }
override val onCheckedChange = { newChecked: Boolean ->
model.onCheckedChange(newChecked)
override val onCheckedChange = { newState: Boolean ->
logItemClick(prefKey, if (newState) EVENT_SWITCH_ON else EVENT_SWITCH_OFF)
model.onCheckedChange(newState)
}
override val changeable = { !model.disabled }
override val icon: (@Composable () -> Unit)?
@@ -289,8 +326,11 @@ class DeviceDetailsFragmentFormatterImpl(
if (model.action != null) {
TwoTargetSwitchPreference(
switchPrefModel,
primaryOnClick = { triggerAction(model.action) },
primaryEnabled = { !model.disabled }
primaryOnClick = {
logItemClick(prefKey, EVENT_CLICK_PRIMARY)
triggerAction(model.action)
},
primaryEnabled = { !model.disabled },
)
} else {
SwitchPreference(switchPrefModel)
@@ -298,12 +338,16 @@ class DeviceDetailsFragmentFormatterImpl(
}
@Composable
private fun buildPlainPreference(model: DeviceSettingPreferenceModel.PlainPreference) {
private fun buildPlainPreference(
model: DeviceSettingPreferenceModel.PlainPreference,
prefKey: String,
) {
SpaPreference(
object : PreferenceModel {
override val title = model.title
override val summary = { model.summary ?: "" }
override val onClick = {
logItemClick(prefKey, EVENT_CLICK_PRIMARY)
model.action?.let { triggerAction(it) }
Unit
}
@@ -319,7 +363,7 @@ class DeviceDetailsFragmentFormatterImpl(
}
@Composable
fun buildMoreSettingsPreference() {
fun buildMoreSettingsPreference(prefKey: String) {
SpaPreference(
object : PreferenceModel {
override val title =
@@ -328,6 +372,7 @@ class DeviceDetailsFragmentFormatterImpl(
context.getString(R.string.bluetooth_device_more_settings_preference_summary)
}
override val onClick = {
logItemClick(prefKey, EVENT_CLICK_PRIMARY)
SubSettingLauncher(context)
.setDestination(DeviceDetailsMoreSettingsFragment::class.java.name)
.setSourceMetricsCategory(fragment.getMetricsCategory())
@@ -356,6 +401,35 @@ class DeviceDetailsFragmentFormatterImpl(
icon?.let { Icon(it, modifier = Modifier.size(SettingsDimension.itemIconSize)) }
}
private fun logItemClick(preferenceKey: String, value: Int = 0) {
logAction(preferenceKey, SettingsEnums.ACTION_BLUETOOTH_DEVICE_DETAILS_ITEM_CLICKED, value)
}
private fun logItemShown(preferenceKey: String, visible: Boolean) {
if (!visible && !prefVisibility.containsKey(preferenceKey)) {
return
}
prefVisibility
.computeIfAbsent(preferenceKey) {
MutableStateFlow(true).also { visibilityFlow ->
visibilityFlow
.onEach {
logAction(
preferenceKey,
SettingsEnums.ACTION_BLUETOOTH_DEVICE_DETAILS_ITEM_SHOWN,
if (it) EVENT_VISIBLE else EVENT_INVISIBLE,
)
}
.launchIn(fragment.lifecycleScope)
}
}
.value = visible
}
private fun logAction(preferenceKey: String, action: Int, value: Int) {
metricsFeatureProvider.action(SettingsEnums.PAGE_UNKNOWN, action, 0, preferenceKey, value)
}
private fun triggerAction(action: DeviceSettingActionModel) {
when (action) {
is DeviceSettingActionModel.IntentAction -> {
@@ -375,7 +449,12 @@ class DeviceDetailsFragmentFormatterImpl(
private fun getPreferenceKey(settingId: Int) = "DEVICE_SETTING_${settingId}"
companion object {
private companion object {
const val TAG = "DeviceDetailsFormatter"
const val EVENT_SWITCH_OFF = 0
const val EVENT_SWITCH_ON = 1
const val EVENT_CLICK_PRIMARY = 2
const val EVENT_INVISIBLE = 0
const val EVENT_VISIBLE = 1
}
}

View File

@@ -427,6 +427,7 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
private void removeControllersForHybridMode() {
Set<String> keys = getPreferenceKeysInHierarchy();
Iterator<AbstractPreferenceController> iterator = mControllers.iterator();
Lifecycle lifecycle = getSettingsLifecycle();
while (iterator.hasNext()) {
AbstractPreferenceController controller = iterator.next();
String key = controller.getPreferenceKey();
@@ -438,6 +439,9 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
if (controllers != null) {
controllers.remove(controller);
}
if (controller instanceof LifecycleObserver) {
lifecycle.removeObserver((LifecycleObserver) controller);
}
}
}
}

View File

@@ -0,0 +1,116 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.display
import android.content.Context
import android.hardware.display.AmbientDisplayConfiguration
import android.os.SystemProperties
import android.os.UserHandle
import android.os.UserManager
import android.provider.Settings.Secure.DOZE_ALWAYS_ON
import com.android.settings.PreferenceRestrictionMixin
import com.android.settings.R
import com.android.settings.display.AmbientDisplayAlwaysOnPreferenceController.isAodSuppressedByBedtime
import com.android.settingslib.datastore.HandlerExecutor
import com.android.settingslib.datastore.KeyValueStore
import com.android.settingslib.datastore.KeyedObservableDelegate
import com.android.settingslib.datastore.KeyedObserver
import com.android.settingslib.datastore.SettingsSecureStore
import com.android.settingslib.datastore.SettingsStore
import com.android.settingslib.metadata.PreferenceAvailabilityProvider
import com.android.settingslib.metadata.PreferenceLifecycleContext
import com.android.settingslib.metadata.PreferenceLifecycleProvider
import com.android.settingslib.metadata.PreferenceSummaryProvider
import com.android.settingslib.metadata.ReadWritePermit
import com.android.settingslib.metadata.SwitchPreference
// LINT.IfChange
class AmbientDisplayAlwaysOnPreference :
SwitchPreference(KEY, R.string.doze_always_on_title, R.string.doze_always_on_summary),
PreferenceAvailabilityProvider,
PreferenceSummaryProvider,
PreferenceLifecycleProvider,
PreferenceRestrictionMixin {
private var keyMappingObserver: KeyedObserver<String>? = null
override val keywords: Int
get() = R.string.keywords_always_show_time_info
override val restrictionKeys: Array<String>
get() = arrayOf(UserManager.DISALLOW_AMBIENT_DISPLAY)
override fun isEnabled(context: Context) = super<PreferenceRestrictionMixin>.isEnabled(context)
override fun isAvailable(context: Context) =
!SystemProperties.getBoolean(PROP_AWARE_AVAILABLE, false) &&
AmbientDisplayConfiguration(context).alwaysOnAvailableForUser(UserHandle.myUserId())
override fun getSummary(context: Context): CharSequence? =
context.getText(
when {
isAodSuppressedByBedtime(context) -> R.string.aware_summary_when_bedtime_on
else -> R.string.doze_always_on_summary
}
)
override fun storage(context: Context): KeyValueStore = Storage(context)
override fun getReadPermit(context: Context, myUid: Int, callingUid: Int) =
ReadWritePermit.ALLOW
override fun getWritePermit(context: Context, value: Boolean?, myUid: Int, callingUid: Int) =
ReadWritePermit.ALLOW
override fun onCreate(context: PreferenceLifecycleContext) {
val storage = SettingsSecureStore.get(context)
keyMappingObserver =
KeyedObserver<String> { _, reason -> storage.notifyChange(KEY, reason) }
.also { storage.addObserver(DOZE_ALWAYS_ON, it, HandlerExecutor.main) }
}
override fun onDestroy(context: PreferenceLifecycleContext) {
keyMappingObserver?.let {
SettingsSecureStore.get(context).removeObserver(DOZE_ALWAYS_ON, it)
}
}
@Suppress("UNCHECKED_CAST")
class Storage(
private val context: Context,
private val settingsStore: SettingsStore = SettingsSecureStore.get(context),
) : KeyedObservableDelegate<String>(settingsStore), KeyValueStore {
override fun contains(key: String) = settingsStore.contains(DOZE_ALWAYS_ON)
override fun <T : Any> getDefaultValue(key: String, valueType: Class<T>) =
context.resources.getBoolean(com.android.internal.R.bool.config_dozeAlwaysOnEnabled)
as T
override fun <T : Any> getValue(key: String, valueType: Class<T>) =
settingsStore.getValue(DOZE_ALWAYS_ON, valueType) ?: getDefaultValue(key, valueType)
override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) =
settingsStore.setValue(DOZE_ALWAYS_ON, valueType, value)
}
companion object {
const val KEY = "ambient_display_always_on"
private const val PROP_AWARE_AVAILABLE = "ro.vendor.aware_available"
}
}
// LINT.ThenChange(AmbientDisplayAlwaysOnPreferenceController.java)

View File

@@ -29,6 +29,7 @@ import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
// LINT.IfChange
public class AmbientDisplayAlwaysOnPreferenceController extends TogglePreferenceController {
private final int ON = 1;
@@ -130,3 +131,4 @@ public class AmbientDisplayAlwaysOnPreferenceController extends TogglePreference
return powerManager.isAmbientDisplaySuppressedForTokenByApp(AOD_SUPPRESSED_TOKEN, uid);
}
}
// LINT.ThenChange(AmbientDisplayAlwaysOnPreference.kt)

View File

@@ -21,6 +21,7 @@ import com.android.settings.R
import com.android.settings.Settings.DisplaySettingsActivity
import com.android.settings.display.darkmode.DarkModeScreen
import com.android.settings.flags.Flags
import com.android.settings.security.LockScreenPreferenceScreen
import com.android.settings.utils.makeLaunchIntent
import com.android.settingslib.metadata.PreferenceAvailabilityProvider
import com.android.settingslib.metadata.PreferenceIconProvider
@@ -50,12 +51,14 @@ open class DisplayScreen :
override fun fragmentClass() = DisplaySettings::class.java
override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(this) {
+BrightnessLevelPreference()
+AutoBrightnessScreen.KEY
+DarkModeScreen.KEY
+PeakRefreshRateSwitchPreference()
}
override fun getPreferenceHierarchy(context: Context) =
preferenceHierarchy(this) {
+BrightnessLevelPreference()
+AutoBrightnessScreen.KEY
+LockScreenPreferenceScreen.KEY
+DarkModeScreen.KEY
+PeakRefreshRateSwitchPreference()
}
override fun getLaunchIntent(context: Context, metadata: PreferenceMetadata?) =
makeLaunchIntent(context, DisplaySettingsActivity::class.java, metadata?.key)

View File

@@ -47,6 +47,7 @@ public class PointerFillStylePreference extends Preference {
public PointerFillStylePreference(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
setLayoutResource(R.layout.pointer_icon_fill_style_layout);
setSelectable(false);
}
@Override

View File

@@ -38,6 +38,7 @@ public class PointerStrokeStylePreference extends Preference {
public PointerStrokeStylePreference(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
setLayoutResource(R.layout.pointer_icon_stroke_style_layout);
setSelectable(false);
}
@Override

View File

@@ -45,6 +45,7 @@ public class TouchpadThreeFingerTapSelector extends Preference {
super(context, attrs);
setLayoutResource(R.layout.touchpad_three_finger_tap_layout);
mInputManager = context.getSystemService(InputManager.class);
setSelectable(false);
}
@Override

View File

@@ -17,13 +17,19 @@ package com.android.settings.security
import android.content.Context
import com.android.settings.R
import com.android.settings.Settings.LockScreenSettingsActivity
import com.android.settings.display.AmbientDisplayAlwaysOnPreference
import com.android.settings.flags.Flags
import com.android.settings.notification.LockScreenNotificationPreferenceController
import com.android.settings.utils.makeLaunchIntent
import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.metadata.PreferenceSummaryProvider
import com.android.settingslib.metadata.ProvidePreferenceScreen
import com.android.settingslib.metadata.preferenceHierarchy
import com.android.settingslib.preference.PreferenceScreenCreator
@ProvidePreferenceScreen
open class LockScreenPreferenceScreen : PreferenceScreenCreator {
open class LockScreenPreferenceScreen : PreferenceScreenCreator, PreferenceSummaryProvider {
override val key: String
get() = KEY
@@ -33,17 +39,24 @@ open class LockScreenPreferenceScreen : PreferenceScreenCreator {
override val keywords: Int
get() = R.string.keywords_ambient_display_screen
override fun getSummary(context: Context): CharSequence? =
context.getString(LockScreenNotificationPreferenceController.getSummaryResource(context))
override fun isFlagEnabled(context: Context) = Flags.catalystLockscreenFromDisplaySettings()
override fun hasCompleteHierarchy() = false
override fun fragmentClass() = LockscreenDashboardFragment::class.java
override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(this) {
// add hierarchy here
}
override fun getLaunchIntent(context: Context, metadata: PreferenceMetadata?) =
makeLaunchIntent(context, LockScreenSettingsActivity::class.java, metadata?.key)
override fun getPreferenceHierarchy(context: Context) =
preferenceHierarchy(this) {
+AmbientDisplayAlwaysOnPreference()
}
companion object {
const val KEY = "lockscreen_from_display_settings"
}
}
}

View File

@@ -56,8 +56,6 @@ import java.util.List;
public class LockscreenDashboardFragment extends DashboardFragment
implements OwnerInfoPreferenceController.OwnerInfoCallback {
public static final String KEY_AMBIENT_DISPLAY_ALWAYS_ON = "ambient_display_always_on";
private static final String TAG = "LockscreenDashboardFragment";
@VisibleForTesting
@@ -111,7 +109,9 @@ public class LockscreenDashboardFragment extends DashboardFragment
@Override
public void onAttach(Context context) {
super.onAttach(context);
use(AmbientDisplayAlwaysOnPreferenceController.class).setConfig(getConfig(context));
if (!isCatalystEnabled()) {
use(AmbientDisplayAlwaysOnPreferenceController.class).setConfig(getConfig(context));
}
use(AmbientDisplayNotificationsPreferenceController.class).setConfig(getConfig(context));
use(DoubleTapScreenPreferenceController.class).setConfig(getConfig(context));
use(PickupGesturePreferenceController.class).setConfig(getConfig(context));

View File

@@ -16,6 +16,7 @@
package com.android.settings.bluetooth.ui.view
import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothAdapter
import android.content.Context
import android.content.Intent
@@ -39,6 +40,7 @@ import com.android.settingslib.bluetooth.devicesettings.shared.model.DeviceSetti
import com.android.settingslib.bluetooth.devicesettings.shared.model.DeviceSettingStateModel
import com.android.settingslib.bluetooth.devicesettings.shared.model.ToggleModel
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.launchIn
@@ -53,6 +55,7 @@ import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
import org.mockito.Mockito.any
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.junit.MockitoJUnit
import org.mockito.junit.MockitoRule
@@ -62,6 +65,7 @@ import org.robolectric.shadows.ShadowLooper
import org.robolectric.shadows.ShadowLooper.shadowMainLooper
@ExperimentalCoroutinesApi
@RunWith(RobolectricTestRunner::class)
class DeviceDetailsFragmentFormatterTest {
@get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
@@ -70,6 +74,7 @@ class DeviceDetailsFragmentFormatterTest {
@Mock private lateinit var bluetoothAdapter: BluetoothAdapter
@Mock private lateinit var repository: DeviceSettingRepository
private lateinit var context: Context
private lateinit var fragment: TestFragment
private lateinit var underTest: DeviceDetailsFragmentFormatter
private lateinit var featureFactory: FakeFeatureFactory
@@ -78,7 +83,7 @@ class DeviceDetailsFragmentFormatterTest {
@Before
fun setUp() {
val context = ApplicationProvider.getApplicationContext<Context>()
context = ApplicationProvider.getApplicationContext()
featureFactory = FakeFeatureFactory.setupForTest()
`when`(
featureFactory.bluetoothFeatureProvider.getDeviceSettingRepository(
@@ -204,9 +209,22 @@ class DeviceDetailsFragmentFormatterTest {
null))
underTest.updateLayout(FragmentTypeModel.DeviceDetailsMainFragment)
runCurrent()
assertThat(getDisplayedPreferences().mapNotNull { it.key })
.containsExactly("bluetooth_device_header", "keyboard_settings")
verify(featureFactory.metricsFeatureProvider)
.action(
SettingsEnums.PAGE_UNKNOWN,
SettingsEnums.ACTION_BLUETOOTH_DEVICE_DETAILS_ITEM_SHOWN,
0,
"bluetooth_device_header", 1)
verify(featureFactory.metricsFeatureProvider)
.action(
SettingsEnums.PAGE_UNKNOWN,
SettingsEnums.ACTION_BLUETOOTH_DEVICE_DETAILS_ITEM_SHOWN,
0,
"keyboard_settings", 1)
}
}
@@ -249,12 +267,20 @@ class DeviceDetailsFragmentFormatterTest {
updateState = {})))
underTest.updateLayout(FragmentTypeModel.DeviceDetailsMainFragment)
runCurrent()
assertThat(getDisplayedPreferences().mapNotNull { it.key })
.containsExactly(
"bluetooth_device_header",
"DEVICE_SETTING_${DeviceSettingId.DEVICE_SETTING_ID_ANC}",
"keyboard_settings")
verify(featureFactory.metricsFeatureProvider)
.action(
SettingsEnums.PAGE_UNKNOWN,
SettingsEnums.ACTION_BLUETOOTH_DEVICE_DETAILS_ITEM_SHOWN,
0,
"DEVICE_SETTING_${DeviceSettingId.DEVICE_SETTING_ID_ANC}", 1
)
}
}

View File

@@ -23,6 +23,7 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
import android.content.Context;
@@ -88,7 +89,11 @@ public class LockscreenDashboardFragmentTest {
AmbientDisplayAlwaysOnPreferenceController.class);
mTestFragment.onAttach(mContext);
verify(controller).setConfig(any());
if (mTestFragment.isCatalystEnabled()) {
verifyNoInteractions(controller);
} else {
verify(controller).setConfig(any());
}
}
@Test