Add help button on the top right corner of more settings page

BUG: 343317785
Test: atest DeviceDetailsFragmentFormatterTest
Flag: com.android.settings.flags.enable_bluetooth_device_details_polish
Change-Id: I3053c0495d4c3cfefcd4f77c9114c4c8c8fe08ca
This commit is contained in:
Haijie Hong
2024-08-21 20:47:55 +08:00
parent 8cd5a449dd
commit ae26d5d17e
8 changed files with 224 additions and 28 deletions

View File

@@ -18,14 +18,17 @@ package com.android.settings.bluetooth.ui.view
import android.bluetooth.BluetoothAdapter
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.media.AudioManager
import android.net.Uri
import androidx.fragment.app.FragmentActivity
import androidx.preference.Preference
import androidx.preference.PreferenceManager
import androidx.preference.PreferenceScreen
import androidx.test.core.app.ApplicationProvider
import com.android.settings.bluetooth.domain.interactor.SpatialAudioInteractor
import com.android.settings.bluetooth.ui.model.DeviceSettingPreferenceModel
import com.android.settings.bluetooth.ui.model.FragmentTypeModel
import com.android.settings.dashboard.DashboardFragment
import com.android.settings.testutils.FakeFeatureFactory
@@ -39,8 +42,12 @@ 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.delay
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Rule
@@ -49,13 +56,17 @@ 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
import org.robolectric.Robolectric
import org.robolectric.RobolectricTestRunner
import org.robolectric.Shadows
import org.robolectric.shadows.ShadowLooper
import org.robolectric.shadows.ShadowLooper.shadowMainLooper
@RunWith(RobolectricTestRunner::class)
class DeviceDetailsFragmentFormatterTest {
@get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
@@ -68,6 +79,7 @@ class DeviceDetailsFragmentFormatterTest {
private lateinit var fragment: TestFragment
private lateinit var underTest: DeviceDetailsFragmentFormatter
private lateinit var featureFactory: FakeFeatureFactory
private lateinit var fragmentActivity: FragmentActivity
private val testScope = TestScope()
@Before
@@ -79,10 +91,10 @@ class DeviceDetailsFragmentFormatterTest {
eq(context), eq(bluetoothAdapter), any()))
.thenReturn(repository)
`when`(
featureFactory.bluetoothFeatureProvider.getSpatialAudioInteractor(
eq(context), any(AudioManager::class.java), any()))
featureFactory.bluetoothFeatureProvider.getSpatialAudioInteractor(
eq(context), any(AudioManager::class.java), any()))
.thenReturn(spatialAudioInteractor)
val fragmentActivity = Robolectric.setupActivity(FragmentActivity::class.java)
fragmentActivity = Robolectric.setupActivity(FragmentActivity::class.java)
assertThat(fragmentActivity.applicationContext).isNotNull()
fragment = TestFragment(context)
fragmentActivity.supportFragmentManager.beginTransaction().add(fragment, null).commit()
@@ -95,7 +107,12 @@ class DeviceDetailsFragmentFormatterTest {
}
underTest =
DeviceDetailsFragmentFormatterImpl(context, fragment, bluetoothAdapter, cachedDevice)
DeviceDetailsFragmentFormatterImpl(
context,
fragment,
bluetoothAdapter,
cachedDevice,
testScope.testScheduler)
}
@Test
@@ -111,9 +128,11 @@ class DeviceDetailsFragmentFormatterTest {
DeviceSettingConfigItemModel.BuiltinItem(
DeviceSettingId.DEVICE_SETTING_ID_ACTION_BUTTONS, "action_buttons"),
),
listOf()))
listOf(),
null))
val keys = underTest.getVisiblePreferenceKeys(FragmentTypeModel.DeviceDetailsMainFragment)
val keys =
underTest.getVisiblePreferenceKeys(FragmentTypeModel.DeviceDetailsMainFragment)
assertThat(keys).containsExactly("bluetooth_device_header", "action_buttons")
}
@@ -124,12 +143,47 @@ class DeviceDetailsFragmentFormatterTest {
testScope.runTest {
`when`(repository.getDeviceSettingsConfig(cachedDevice)).thenReturn(null)
val keys = underTest.getVisiblePreferenceKeys(FragmentTypeModel.DeviceDetailsMainFragment)
val keys =
underTest.getVisiblePreferenceKeys(FragmentTypeModel.DeviceDetailsMainFragment)
assertThat(keys).isNull()
}
}
@Test
fun getMenuItem_returnItem() {
testScope.runTest {
`when`(repository.getDeviceSettingsConfig(cachedDevice))
.thenReturn(
DeviceSettingConfigModel(
listOf(), listOf(), DeviceSettingConfigItemModel.AppProvidedItem(12345)))
val intent = Intent().apply {
setAction(Intent.ACTION_VIEW)
setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
`when`(repository.getDeviceSetting(cachedDevice, 12345))
.thenReturn(
flowOf(
DeviceSettingModel.HelpPreference(
cachedDevice = cachedDevice,
id = 12345,
intent = intent,
)))
var helpPreference: DeviceSettingPreferenceModel.HelpPreference? = null
underTest.getMenuItem(FragmentTypeModel.DeviceDetailsMoreSettingsFragment).onEach {
helpPreference = it
}.launchIn(testScope.backgroundScope)
delay(100)
runCurrent()
helpPreference!!.onClick()
ShadowLooper.idleMainLooper()
val shadowActivity = Shadows.shadowOf(fragmentActivity)
assertThat(shadowActivity.nextStartedActivity).isSameInstanceAs(intent)
}
}
@Test
fun updateLayout_configIsNull_notChange() {
testScope.runTest {
@@ -156,7 +210,8 @@ class DeviceDetailsFragmentFormatterTest {
DeviceSettingId.DEVICE_SETTING_ID_KEYBOARD_SETTINGS,
"keyboard_settings"),
),
listOf()))
listOf(),
null))
underTest.updateLayout(FragmentTypeModel.DeviceDetailsMainFragment)
@@ -181,7 +236,8 @@ class DeviceDetailsFragmentFormatterTest {
DeviceSettingId.DEVICE_SETTING_ID_KEYBOARD_SETTINGS,
"keyboard_settings"),
),
listOf()))
listOf(),
null))
`when`(repository.getDeviceSetting(cachedDevice, DeviceSettingId.DEVICE_SETTING_ID_ANC))
.thenReturn(
flowOf(
@@ -192,15 +248,9 @@ class DeviceDetailsFragmentFormatterTest {
toggles =
listOf(
ToggleModel(
"", DeviceSettingIcon.BitmapIcon(
Bitmap.createBitmap(
1,
1,
Bitmap.Config.ARGB_8888
)
)
)
),
"",
DeviceSettingIcon.BitmapIcon(
Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)))),
isActive = true,
state = DeviceSettingStateModel.MultiTogglePreferenceState(0),
isAllowedChangingState = true,

View File

@@ -78,7 +78,11 @@ class BluetoothDeviceDetailsViewModelTest {
underTest =
BluetoothDeviceDetailsViewModel(
application, repository, spatialAudioInteractor, cachedDevice)
application,
repository,
spatialAudioInteractor,
cachedDevice,
testScope.testScheduler)
}
@Test
@@ -87,7 +91,7 @@ class BluetoothDeviceDetailsViewModelTest {
`when`(repository.getDeviceSettingsConfig(cachedDevice))
.thenReturn(
DeviceSettingConfigModel(
listOf(BUILTIN_SETTING_ITEM_1, BUILDIN_SETTING_ITEM_2), listOf()))
listOf(BUILTIN_SETTING_ITEM_1, BUILDIN_SETTING_ITEM_2), listOf(), null))
val keys = underTest.getItems(FragmentTypeModel.DeviceDetailsMainFragment)
@@ -95,6 +99,38 @@ class BluetoothDeviceDetailsViewModelTest {
}
}
@Test
fun getHelpItems_mainPage_returnNull() {
testScope.runTest {
`when`(repository.getDeviceSettingsConfig(cachedDevice))
.thenReturn(
DeviceSettingConfigModel(
listOf(BUILTIN_SETTING_ITEM_1, BUILDIN_SETTING_ITEM_2),
listOf(),
SETTING_ITEM_HELP))
val item = underTest.getHelpItem(FragmentTypeModel.DeviceDetailsMainFragment)
assertThat(item).isNull()
}
}
@Test
fun getHelpItems_moreSettings_returnConfigHelpItem() {
testScope.runTest {
`when`(repository.getDeviceSettingsConfig(cachedDevice))
.thenReturn(
DeviceSettingConfigModel(
listOf(BUILTIN_SETTING_ITEM_1, BUILDIN_SETTING_ITEM_2),
listOf(),
SETTING_ITEM_HELP))
val item = underTest.getHelpItem(FragmentTypeModel.DeviceDetailsMoreSettingsFragment)
assertThat(item).isSameInstanceAs(SETTING_ITEM_HELP)
}
}
@Test
fun getDeviceSetting_returnRepositoryResponse() {
testScope.runTest {
@@ -107,7 +143,8 @@ class BluetoothDeviceDetailsViewModelTest {
BUILTIN_SETTING_ITEM_1,
buildRemoteSettingItem(remoteSettingId1),
),
listOf()))
listOf(),
null))
`when`(repository.getDeviceSetting(cachedDevice, remoteSettingId1))
.thenReturn(flowOf(pref))
@@ -137,7 +174,8 @@ class BluetoothDeviceDetailsViewModelTest {
buildRemoteSettingItem(
DeviceSettingId.DEVICE_SETTING_ID_SPATIAL_AUDIO_MULTI_TOGGLE),
),
listOf()))
listOf(),
null))
`when`(spatialAudioInteractor.getDeviceSetting(cachedDevice)).thenReturn(flowOf(pref))
var deviceSettingPreference: DeviceSettingPreferenceModel? = null
@@ -159,7 +197,7 @@ class BluetoothDeviceDetailsViewModelTest {
`when`(repository.getDeviceSettingsConfig(cachedDevice))
.thenReturn(
DeviceSettingConfigModel(
listOf(BUILTIN_SETTING_ITEM_1, BUILDIN_SETTING_ITEM_2), listOf()))
listOf(BUILTIN_SETTING_ITEM_1, BUILDIN_SETTING_ITEM_2), listOf(), null))
val layout = underTest.getLayout(FragmentTypeModel.DeviceDetailsMainFragment)!!
@@ -186,7 +224,8 @@ class BluetoothDeviceDetailsViewModelTest {
buildRemoteSettingItem(remoteSettingId2),
buildRemoteSettingItem(remoteSettingId3),
),
listOf()))
listOf(),
null))
`when`(repository.getDeviceSetting(cachedDevice, remoteSettingId1))
.thenReturn(flowOf(buildMultiTogglePreference(remoteSettingId1)))
`when`(repository.getDeviceSetting(cachedDevice, remoteSettingId2))
@@ -248,5 +287,6 @@ class BluetoothDeviceDetailsViewModelTest {
val BUILDIN_SETTING_ITEM_2 =
DeviceSettingConfigItemModel.BuiltinItem(
DeviceSettingId.DEVICE_SETTING_ID_ACTION_BUTTONS, "action_buttons")
val SETTING_ITEM_HELP = DeviceSettingConfigItemModel.AppProvidedItem(12345)
}
}