Show bond loss UI in device details
Bug: 380801155 Test: atest BluetoothDetailsFragmentTest Flag: EXEMPT minor change Change-Id: I458778e1a3adde4ec1ddd8b84b8dc7f1d91621f5
This commit is contained in:
32
res/drawable/bluetooth_details_banner_background.xml
Normal file
32
res/drawable/bluetooth_details_banner_background.xml
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2025 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.
|
||||
-->
|
||||
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="?android:colorControlHighlight">
|
||||
<item
|
||||
android:start="16dp"
|
||||
android:end="16dp"
|
||||
android:top="16dp"
|
||||
android:bottom="16dp">
|
||||
<shape android:shape="rectangle">
|
||||
<solid
|
||||
android:color="@color/settingslib_materialColorSurfaceVariant" />
|
||||
<corners
|
||||
android:radius="28dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
50
res/layout/bluetooth_details_banner.xml
Normal file
50
res/layout/bluetooth_details_banner.xml
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2025 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.
|
||||
-->
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="36dp"
|
||||
android:orientation="vertical"
|
||||
android:background="@drawable/bluetooth_details_banner_background">
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="start|top"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="8dp">
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/settingslib_ic_info_outline_24"
|
||||
android:tint="@color/settingslib_materialColorOnSurfaceVariant"
|
||||
android:importantForAccessibility="no" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bluetooth_details_banner_message"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start"
|
||||
android:textAlignment="viewStart"
|
||||
android:textColor="@color/settingslib_materialColorOnSurfaceVariant"
|
||||
android:hyphenationFrequency="normalFast"
|
||||
android:lineBreakWordStyle="phrase"
|
||||
android:ellipsize="marquee" />
|
||||
|
||||
</LinearLayout>
|
@@ -19,6 +19,13 @@
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/device_details_title">
|
||||
|
||||
<com.android.settingslib.widget.LayoutPreference
|
||||
android:key="bluetooth_details_banner"
|
||||
android:layout="@layout/bluetooth_details_banner"
|
||||
android:selectable="false"
|
||||
settings:allowDividerBelow="true"
|
||||
settings:searchable="false"/>
|
||||
|
||||
<com.android.settingslib.widget.LayoutPreference
|
||||
android:key="bluetooth_device_header"
|
||||
android:layout="@layout/settings_entity_header"
|
||||
|
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2025 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.bluetooth
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.TextView
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.PreferenceScreen
|
||||
import com.android.settings.R
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle
|
||||
import com.android.settingslib.widget.LayoutPreference
|
||||
|
||||
class BluetoothDetailsBannerController(
|
||||
private val context: Context,
|
||||
fragment: PreferenceFragmentCompat,
|
||||
private val cachedDevice: CachedBluetoothDevice,
|
||||
lifecycle: Lifecycle,
|
||||
) : BluetoothDetailsController(context, fragment, cachedDevice, lifecycle) {
|
||||
private lateinit var pref: LayoutPreference
|
||||
|
||||
override fun getPreferenceKey(): String = KEY_BLUETOOTH_DETAILS_BANNER
|
||||
|
||||
override fun init(screen: PreferenceScreen) {
|
||||
pref = screen.findPreference(KEY_BLUETOOTH_DETAILS_BANNER) ?: return
|
||||
}
|
||||
|
||||
override fun refresh() {
|
||||
pref.findViewById<TextView>(R.id.bluetooth_details_banner_message).text =
|
||||
context.getString(R.string.device_details_key_missing_title, cachedDevice.name)
|
||||
}
|
||||
|
||||
override fun isAvailable(): Boolean =
|
||||
BluetoothUtils.getKeyMissingCount(cachedDevice.device)?.let { it > 0 } ?: false
|
||||
|
||||
private companion object {
|
||||
const val KEY_BLUETOOTH_DETAILS_BANNER: String = "bluetooth_details_banner"
|
||||
}
|
||||
}
|
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2025 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.bluetooth
|
||||
|
||||
import android.os.Bundle
|
||||
import android.os.UserManager
|
||||
import android.view.View
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceCategory
|
||||
import androidx.preference.PreferenceGroup
|
||||
import com.android.settings.dashboard.RestrictedDashboardFragment
|
||||
|
||||
/** Base class for bluetooth settings which makes the preference visibility/order configurable. */
|
||||
abstract class BluetoothDetailsConfigurableFragment :
|
||||
RestrictedDashboardFragment(UserManager.DISALLOW_CONFIG_BLUETOOTH) {
|
||||
private var displayOrder: List<String>? = null
|
||||
|
||||
fun setPreferenceDisplayOrder(prefKeyOrder: List<String>?) {
|
||||
if (displayOrder == prefKeyOrder) {
|
||||
return
|
||||
}
|
||||
displayOrder = prefKeyOrder
|
||||
updatePreferenceOrder()
|
||||
}
|
||||
|
||||
private val invisiblePrefCategory: PreferenceGroup by lazy {
|
||||
preferenceScreen.findPreference<PreferenceGroup>(INVISIBLE_CATEGORY)
|
||||
?: run {
|
||||
PreferenceCategory(requireContext())
|
||||
.apply {
|
||||
key = INVISIBLE_CATEGORY
|
||||
isVisible = false
|
||||
isOrderingAsAdded = true
|
||||
}
|
||||
.also { preferenceScreen.addPreference(it) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
updatePreferenceOrder()
|
||||
}
|
||||
|
||||
private fun updatePreferenceOrder() {
|
||||
val order = displayOrder?: return
|
||||
if (preferenceScreen == null) {
|
||||
return
|
||||
}
|
||||
preferenceScreen.isOrderingAsAdded = true
|
||||
val allPrefs =
|
||||
(invisiblePrefCategory.getAndRemoveAll() + preferenceScreen.getAndRemoveAll()).filter {
|
||||
it != invisiblePrefCategory
|
||||
}
|
||||
allPrefs.forEach { it.order = Preference.DEFAULT_ORDER }
|
||||
val visiblePrefs =
|
||||
allPrefs.filter { order.contains(it.key) }.sortedBy { order.indexOf(it.key) }
|
||||
val invisiblePrefs = allPrefs.filter { !order.contains(it.key) }
|
||||
preferenceScreen.addPreferences(visiblePrefs)
|
||||
preferenceScreen.addPreference(invisiblePrefCategory)
|
||||
invisiblePrefCategory.addPreferences(invisiblePrefs)
|
||||
}
|
||||
|
||||
private fun PreferenceGroup.getAndRemoveAll(): List<Preference> {
|
||||
val prefs = mutableListOf<Preference>()
|
||||
for (i in 0..<preferenceCount) {
|
||||
prefs.add(getPreference(i))
|
||||
}
|
||||
removeAll()
|
||||
return prefs
|
||||
}
|
||||
|
||||
private fun PreferenceGroup.addPreferences(prefs: List<Preference>) {
|
||||
for (pref in prefs) {
|
||||
addPreference(pref)
|
||||
}
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val INVISIBLE_CATEGORY = "invisible_profile_category"
|
||||
}
|
||||
}
|
@@ -62,7 +62,6 @@ public class BluetoothDetailsHeaderController extends BluetoothDetailsController
|
||||
final LayoutPreference headerPreference = screen.findPreference(KEY_DEVICE_HEADER);
|
||||
mHeaderController = EntityHeaderController.newInstance(mFragment.getActivity(), mFragment,
|
||||
headerPreference.findViewById(R.id.entity_header));
|
||||
screen.addPreference(headerPreference);
|
||||
}
|
||||
|
||||
protected void setHeaderProperties() {
|
||||
|
@@ -17,7 +17,6 @@
|
||||
package com.android.settings.bluetooth;
|
||||
|
||||
import static android.bluetooth.BluetoothDevice.BOND_NONE;
|
||||
import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.settings.SettingsEnums;
|
||||
@@ -49,7 +48,6 @@ import com.android.settings.R;
|
||||
import com.android.settings.bluetooth.ui.model.FragmentTypeModel;
|
||||
import com.android.settings.bluetooth.ui.view.DeviceDetailsFragmentFormatter;
|
||||
import com.android.settings.connecteddevice.stylus.StylusDevicesController;
|
||||
import com.android.settings.dashboard.RestrictedDashboardFragment;
|
||||
import com.android.settings.flags.Flags;
|
||||
import com.android.settings.inputmethod.KeyboardSettingsPreferenceController;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
@@ -66,7 +64,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment {
|
||||
public class BluetoothDeviceDetailsFragment extends BluetoothDetailsConfigurableFragment {
|
||||
public static final String KEY_DEVICE_ADDRESS = "device_address";
|
||||
private static final String TAG = "BTDeviceDetailsFrg";
|
||||
private static final int METADATA_FAST_PAIR_CUSTOMIZED_FIELDS = 25;
|
||||
@@ -102,6 +100,7 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
|
||||
BluetoothAdapter mBluetoothAdapter;
|
||||
@VisibleForTesting
|
||||
DeviceDetailsFragmentFormatter mFormatter;
|
||||
boolean mIsKeyMissingDevice = false;
|
||||
|
||||
@Nullable
|
||||
InputDevice mInputDevice;
|
||||
@@ -144,7 +143,7 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
|
||||
};
|
||||
|
||||
public BluetoothDeviceDetailsFragment() {
|
||||
super(DISALLOW_CONFIG_BLUETOOTH);
|
||||
super();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -212,6 +211,9 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
Integer keyMissingCount = BluetoothUtils.getKeyMissingCount(mCachedDevice.getDevice());
|
||||
mIsKeyMissingDevice = keyMissingCount != null && keyMissingCount > 0;
|
||||
setPreferenceDisplayOrder(generateDisplayedPreferenceKeys(mIsKeyMissingDevice));
|
||||
getController(
|
||||
AdvancedBluetoothDetailsHeaderController.class,
|
||||
controller -> controller.init(mCachedDevice, this));
|
||||
@@ -342,7 +344,7 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
if (Flags.enableBluetoothDeviceDetailsPolish()) {
|
||||
if (!mIsKeyMissingDevice && Flags.enableBluetoothDeviceDetailsPolish()) {
|
||||
if (mFormatter == null) {
|
||||
List<AbstractPreferenceController> controllers = getPreferenceControllers().stream()
|
||||
.flatMap(List::stream)
|
||||
@@ -412,12 +414,29 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
|
||||
return super.onOptionsItemSelected(menuItem);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private List<String> generateDisplayedPreferenceKeys(boolean bondingLoss) {
|
||||
if (bondingLoss) {
|
||||
return List.of(
|
||||
use(BluetoothDetailsBannerController.class).getPreferenceKey(),
|
||||
use(AdvancedBluetoothDetailsHeaderController.class).getPreferenceKey(),
|
||||
use(BluetoothDetailsHeaderController.class).getPreferenceKey(),
|
||||
use(LeAudioBluetoothDetailsHeaderController.class).getPreferenceKey(),
|
||||
use(BluetoothDetailsButtonsController.class).getPreferenceKey(),
|
||||
use(BluetoothDetailsMacAddressController.class).getPreferenceKey());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
||||
ArrayList<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||
|
||||
if (mCachedDevice != null) {
|
||||
Lifecycle lifecycle = getSettingsLifecycle();
|
||||
controllers.add(
|
||||
new BluetoothDetailsBannerController(
|
||||
context, this, mCachedDevice, lifecycle));
|
||||
controllers.add(new BluetoothDetailsHeaderController(context, this, mCachedDevice,
|
||||
lifecycle));
|
||||
controllers.add(
|
||||
|
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2025 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.bluetooth
|
||||
|
||||
import android.bluetooth.BluetoothDevice
|
||||
import com.android.settings.R
|
||||
import com.android.settings.testutils.FakeFeatureFactory
|
||||
import com.android.settingslib.widget.LayoutPreference
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
import org.mockito.junit.MockitoRule
|
||||
import org.mockito.kotlin.whenever
|
||||
|
||||
class BluetoothDetailsBannerControllerTest : BluetoothDetailsControllerTestBase() {
|
||||
@get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
|
||||
|
||||
private lateinit var controller: BluetoothDetailsBannerController
|
||||
private lateinit var preference: LayoutPreference
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
FakeFeatureFactory.setupForTest()
|
||||
controller =
|
||||
BluetoothDetailsBannerController(mContext, mFragment, mCachedDevice, mLifecycle)
|
||||
preference = LayoutPreference(mContext, R.layout.bluetooth_details_banner)
|
||||
preference.key = controller.getPreferenceKey()
|
||||
mScreen.addPreference(preference)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun iaAvailable_notKeyMissing_false() {
|
||||
setupDevice(makeDefaultDeviceConfig())
|
||||
|
||||
assertThat(controller.isAvailable).isFalse()
|
||||
}
|
||||
|
||||
// TODO(b/379729762): add more tests after BluetoothDevice.getKeyMissingCount is available.
|
||||
}
|
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (C) 2025 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.bluetooth
|
||||
|
||||
import android.content.Context
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.fragment.app.testing.EmptyFragmentActivity
|
||||
import androidx.preference.Preference
|
||||
import androidx.test.core.app.ActivityScenario
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mockito.spy
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
import org.mockito.junit.MockitoRule
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
class BluetoothDetailsFragmentTest {
|
||||
@get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
|
||||
|
||||
private lateinit var activity: FragmentActivity
|
||||
private lateinit var fragment: TestConfigurableFragment
|
||||
private lateinit var context: Context
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
context = spy(ApplicationProvider.getApplicationContext<Context>())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setPreferenceDisplayOrder_null_unchanged() = buildFragment {
|
||||
fragment.preferenceScreen.addPreference(Preference(context).apply { key = "key1" })
|
||||
fragment.preferenceScreen.addPreference(Preference(context).apply { key = "key2" })
|
||||
|
||||
fragment.setPreferenceDisplayOrder(null)
|
||||
|
||||
assertThat(this.displayedKeys).containsExactly("key1", "key2")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setPreferenceDisplayOrder_hideItem() = buildFragment {
|
||||
fragment.preferenceScreen.addPreference(Preference(context).apply { key = "key1" })
|
||||
fragment.preferenceScreen.addPreference(Preference(context).apply { key = "key2" })
|
||||
|
||||
fragment.setPreferenceDisplayOrder(mutableListOf("key2"))
|
||||
|
||||
assertThat(this.displayedKeys).containsExactly("key2")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setPreferenceDisplayOrder_hideAndReShownItem() = buildFragment {
|
||||
fragment.preferenceScreen.addPreference(Preference(context).apply { key = "key1" })
|
||||
fragment.preferenceScreen.addPreference(Preference(context).apply { key = "key2" })
|
||||
|
||||
fragment.setPreferenceDisplayOrder(mutableListOf("key2"))
|
||||
fragment.setPreferenceDisplayOrder(mutableListOf("key2", "key1"))
|
||||
|
||||
assertThat(this.displayedKeys).containsExactly("key2", "key1")
|
||||
}
|
||||
|
||||
private fun buildFragment(r: (() -> Unit)) {
|
||||
ActivityScenario.launch(EmptyFragmentActivity::class.java).use { activityScenario ->
|
||||
activityScenario.onActivity { activity: EmptyFragmentActivity ->
|
||||
this@BluetoothDetailsFragmentTest.activity = activity
|
||||
fragment = TestConfigurableFragment()
|
||||
activity.supportFragmentManager.beginTransaction().add(fragment, null).commitNow()
|
||||
fragment.setPreferenceScreen(
|
||||
fragment.preferenceManager.createPreferenceScreen(context)
|
||||
)
|
||||
r.invoke()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val displayedKeys: List<String>
|
||||
get() {
|
||||
val keys: MutableList<String> = mutableListOf()
|
||||
for (i in 0..<fragment.preferenceScreen.preferenceCount) {
|
||||
if (fragment.preferenceScreen.getPreference(i).isVisible) {
|
||||
keys.add(fragment.preferenceScreen.getPreference(i).key)
|
||||
}
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
class TestConfigurableFragment : BluetoothDetailsConfigurableFragment() {
|
||||
protected override fun getPreferenceScreenResId(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
override fun getLogTag(): String {
|
||||
return "TAG"
|
||||
}
|
||||
|
||||
override fun getMetricsCategory(): Int {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user