Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4775f41e authored by Haijie Hong's avatar Haijie Hong Committed by Android (Google) Code Review
Browse files

Merge "Add help button on the top right corner of more settings page" into main

parents c23786f3 ae26d5d1
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1868,6 +1868,8 @@
    <string name="bluetooth_device_more_settings_preference_title">More settings</string>
    <!-- Title for more settings summary. [CHAR LIMIT=50] -->
    <string name="bluetooth_device_more_settings_preference_summary">Firmware updates, about, and more</string>
    <!-- Title for bluetooth device tips and support. [CHAR LIMIT=50] -->
    <string name="bluetooth_device_tip_support">Tips &amp; support</string>
    <!-- Title of the item to show device MAC address -->
    <string name="bluetooth_device_mac_address">Device\'s Bluetooth address: <xliff:g id="address">%1$s</xliff:g></string>
    <!-- Title of the items to show multuple devices MAC address [CHAR LIMIT=NONE]-->
+7 −1
Original line number Diff line number Diff line
@@ -101,6 +101,12 @@ open class BluetoothFeatureProviderImpl : BluetoothFeatureProvider {
        bluetoothAdapter: BluetoothAdapter,
        cachedDevice: CachedBluetoothDevice
    ): DeviceDetailsFragmentFormatter {
        return DeviceDetailsFragmentFormatterImpl(context, fragment, bluetoothAdapter, cachedDevice)
        return DeviceDetailsFragmentFormatterImpl(
            context,
            fragment,
            bluetoothAdapter,
            cachedDevice,
            Dispatchers.IO
        )
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -66,4 +66,11 @@ sealed interface DeviceSettingPreferenceModel {
    data class MoreSettingsPreference(
        @DeviceSettingId override val id: Int,
    ) : DeviceSettingPreferenceModel

    /** Models a help button on the top right corner of the fragment. */
    data class HelpPreference(
        @DeviceSettingId override val id: Int,
        val icon: DeviceSettingIcon,
        val onClick: (() -> Unit),
    ) : DeviceSettingPreferenceModel
}
+27 −1
Original line number Diff line number Diff line
@@ -52,10 +52,15 @@ 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.ui.Footer
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
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.map
import kotlinx.coroutines.runBlocking

/** Handles device details fragment layout according to config. */
@@ -65,6 +70,11 @@ interface DeviceDetailsFragmentFormatter {

    /** Updates device details fragment layout. */
    fun updateLayout(fragmentType: FragmentTypeModel)

    /** Gets the menu items of the fragment. */
    fun getMenuItem(
        fragmentType: FragmentTypeModel
    ): Flow<DeviceSettingPreferenceModel.HelpPreference?>
}

@OptIn(ExperimentalCoroutinesApi::class)
@@ -72,7 +82,8 @@ class DeviceDetailsFragmentFormatterImpl(
    private val context: Context,
    private val fragment: SettingsPreferenceFragment,
    bluetoothAdapter: BluetoothAdapter,
    private val cachedDevice: CachedBluetoothDevice
    private val cachedDevice: CachedBluetoothDevice,
    private val backgroundCoroutineContext: CoroutineContext,
) : DeviceDetailsFragmentFormatter {
    private val repository =
        featureFactory.bluetoothFeatureProvider.getDeviceSettingRepository(
@@ -88,6 +99,7 @@ class DeviceDetailsFragmentFormatterImpl(
                    repository,
                    spatialAudioInteractor,
                    cachedDevice,
                    backgroundCoroutineContext,
                ))
            .get(BluetoothDeviceDetailsViewModel::class.java)

@@ -135,6 +147,19 @@ class DeviceDetailsFragmentFormatterImpl(
        fragment.preferenceScreen.addPreference(Preference(context).apply { order = 10000 })
    }

    override fun getMenuItem(
        fragmentType: FragmentTypeModel
    ): Flow<DeviceSettingPreferenceModel.HelpPreference?> = flow {
        val t = viewModel.getHelpItem(fragmentType)

        t?.let { item ->
            emitAll(
                viewModel.getDeviceSetting(cachedDevice, item.settingId).map {
                    it as? DeviceSettingPreferenceModel.HelpPreference
                })
        } ?: emit(null)
    }

    @Composable
    private fun buildPreference(layout: DeviceSettingLayout, row: Int) {
        val contents by
@@ -174,6 +199,7 @@ class DeviceDetailsFragmentFormatterImpl(
                    is DeviceSettingPreferenceModel.MoreSettingsPreference -> {
                        buildMoreSettingsPreference()
                    }
                    is DeviceSettingPreferenceModel.HelpPreference -> {}
                    null -> {}
                }
            }
+44 −0
Original line number Diff line number Diff line
@@ -19,26 +19,65 @@ package com.android.settings.bluetooth.ui.view
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothManager
import android.content.Context
import android.graphics.PorterDuff
import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import androidx.lifecycle.lifecycleScope
import com.android.settings.R
import com.android.settings.bluetooth.BluetoothDetailsProfilesController
import com.android.settings.bluetooth.Utils
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.overlay.FeatureFactory.Companion.featureFactory
import com.android.settingslib.bluetooth.CachedBluetoothDevice
import com.android.settingslib.bluetooth.LocalBluetoothManager
import com.android.settingslib.bluetooth.devicesettings.shared.model.DeviceSettingIcon
import com.android.settingslib.core.AbstractPreferenceController
import com.android.settingslib.core.lifecycle.LifecycleObserver
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch

class DeviceDetailsMoreSettingsFragment : DashboardFragment() {
    private lateinit var formatter: DeviceDetailsFragmentFormatter
    private lateinit var localBluetoothManager: LocalBluetoothManager
    private lateinit var cachedDevice: CachedBluetoothDevice
    private lateinit var helpItem: StateFlow<DeviceSettingPreferenceModel.HelpPreference?>

    // TODO(b/343317785): add metrics category
    override fun getMetricsCategory(): Int = 0

    override fun onPrepareOptionsMenu(menu: Menu) {
        super.onPrepareOptionsMenu(menu)
        lifecycleScope.launch {
            helpItem.filterNotNull().collect { item ->
                val iconRes = item.icon as? DeviceSettingIcon.ResourceIcon ?: return@collect
                val item: MenuItem =
                    menu.add(0, MENU_HELP_ITEM_ID, 0, R.string.bluetooth_device_tip_support)
                item.setIcon(iconRes.resId)
                item.icon?.setColorFilter(
                    resources.getColor(
                        com.android.settingslib.widget.theme.R.color
                            .settingslib_materialColorOnSurface),
                    PorterDuff.Mode.SRC_ATOP)
                item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
            }
        }
    }

    override fun onOptionsItemSelected(menuItem: MenuItem): Boolean {
        if (menuItem.itemId == MENU_HELP_ITEM_ID) {
            helpItem.value?.let { it.onClick() }
            return true
        }
        return super.onOptionsItemSelected(menuItem)
    }

    override fun getPreferenceScreenResId(): Int {
        return R.xml.bluetooth_device_more_settings_fragment
    }
@@ -78,6 +117,10 @@ class DeviceDetailsMoreSettingsFragment : DashboardFragment() {
        formatter =
            featureFactory.bluetoothFeatureProvider.getDeviceDetailsFragmentFormatter(
                requireContext(), this, bluetoothManager.adapter, cachedDevice)
        helpItem =
            formatter
                .getMenuItem(FragmentTypeModel.DeviceDetailsMoreSettingsFragment)
                .stateIn(lifecycleScope, SharingStarted.WhileSubscribed(), initialValue = null)
        return listOf(
            BluetoothDetailsProfilesController(
                context, this, localBluetoothManager, cachedDevice, settingsLifecycle))
@@ -88,5 +131,6 @@ class DeviceDetailsMoreSettingsFragment : DashboardFragment() {
    companion object {
        const val TAG: String = "DeviceMoreSettingsFrg"
        const val KEY_DEVICE_ADDRESS: String = "device_address"
        const val MENU_HELP_ITEM_ID = Menu.FIRST
    }
}
Loading