mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
Debug: Add devices page
This commit is contained in:
+27
@@ -7,6 +7,7 @@ import androidx.preference.ListPreference
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceCategory
|
||||
import androidx.preference.PreferenceGroup
|
||||
import androidx.preference.SwitchPreferenceCompat
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication
|
||||
import nodomain.freeyourgadget.gadgetbridge.R
|
||||
@@ -116,6 +117,32 @@ abstract class AbstractDebugFragment : AbstractPreferenceFragment() {
|
||||
preferenceScreen?.addPreference(pref)
|
||||
}
|
||||
|
||||
protected fun addDynamicCheckbox(
|
||||
group: PreferenceGroup? = preferenceScreen,
|
||||
title: String,
|
||||
summary: String = "",
|
||||
icon: Int = 0,
|
||||
checked: Boolean,
|
||||
): Preference {
|
||||
val pref = SwitchPreferenceCompat(requireContext())
|
||||
pref.setKey("${PREF_DYNAMIC_PREFIX}_${UUID.randomUUID()}")
|
||||
pref.layoutResource = R.layout.preference_checkbox
|
||||
pref.isPersistent = false
|
||||
pref.isSelectable = false
|
||||
pref.title = title
|
||||
pref.summary = summary
|
||||
if (icon != 0) {
|
||||
pref.setIcon(icon)
|
||||
} else if (!title.isEmpty()) {
|
||||
pref.isIconSpaceReserved = false
|
||||
}
|
||||
pref.isChecked = checked
|
||||
|
||||
group?.addPreference(pref)
|
||||
|
||||
return pref
|
||||
}
|
||||
|
||||
protected fun goTo(fragment: AbstractDebugFragment) {
|
||||
requireActivity().supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.settings_container, fragment)
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.debug
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceCategory
|
||||
import nodomain.freeyourgadget.gadgetbridge.R
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
class DeviceDebugFragment : AbstractDebugFragment() {
|
||||
private lateinit var gbDevice: GBDevice
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
setPreferencesFromResource(R.xml.debug_preferences_device, rootKey)
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
gbDevice = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
|
||||
arguments?.getParcelable(GBDevice.EXTRA_DEVICE, GBDevice::class.java)!!
|
||||
} else {
|
||||
arguments?.getParcelable<GBDevice>(GBDevice.EXTRA_DEVICE)!!
|
||||
}
|
||||
|
||||
preferenceScreen?.title = gbDevice.aliasOrName
|
||||
|
||||
findPreference<Preference>(PREF_DEBUG_DEVICE_NAME)?.summary = gbDevice.name ?: "<null>"
|
||||
findPreference<Preference>(PREF_DEBUG_DEVICE_ALIAS)?.summary = gbDevice.alias ?: getString(R.string.not_set)
|
||||
findPreference<Preference>(PREF_DEBUG_DEVICE_MAC_ADDRESS)?.summary = gbDevice.address
|
||||
findPreference<Preference>(PREF_DEBUG_DEVICE_TYPE)?.summary = gbDevice.type.name
|
||||
|
||||
val headerDetails = findPreference<PreferenceCategory>(PREF_HEADER_DETAILS)
|
||||
for (detail in gbDevice.deviceInfos) {
|
||||
addDynamicPref(headerDetails, detail.name.replace(": *$".toRegex(), ""), detail.details)
|
||||
}
|
||||
|
||||
val headerCoordinator = findPreference<PreferenceCategory>(PREF_HEADER_COORDINATOR)
|
||||
val coordinator = gbDevice.deviceCoordinator
|
||||
|
||||
// Use reflection to find all supports* methods that return boolean
|
||||
val coordinatorClass = coordinator.javaClass
|
||||
val methods = coordinatorClass.methods
|
||||
.filter { it.name.startsWith("supports") }
|
||||
.filter { it.returnType == Boolean::class.javaPrimitiveType || it.returnType == Boolean::class.java }
|
||||
.filter { it.parameterCount == 0 || (it.parameterCount == 1 && it.parameterTypes[0] == GBDevice::class.java) }
|
||||
.sortedBy { it.name }
|
||||
|
||||
for (method in methods) {
|
||||
try {
|
||||
val result = if (method.parameterCount == 0) {
|
||||
method.invoke(coordinator) as Boolean
|
||||
} else {
|
||||
method.invoke(coordinator, gbDevice) as Boolean
|
||||
}
|
||||
addDynamicCheckbox(headerCoordinator, method.name, checked = result)
|
||||
} catch (e: Exception) {
|
||||
LOG.error("Error invoking method ${method.name}", e)
|
||||
addDynamicPref(headerCoordinator, method.name, "Error: ${e.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LOG: Logger = LoggerFactory.getLogger(DeviceDebugFragment::class.java)
|
||||
|
||||
private const val PREF_DEBUG_DEVICE_NAME = "pref_debug_device_name"
|
||||
private const val PREF_DEBUG_DEVICE_ALIAS = "pref_debug_device_alias"
|
||||
private const val PREF_DEBUG_DEVICE_MAC_ADDRESS = "pref_debug_device_mac_address"
|
||||
private const val PREF_DEBUG_DEVICE_TYPE = "pref_debug_device_type"
|
||||
private const val PREF_HEADER_DETAILS = "pref_header_details"
|
||||
private const val PREF_HEADER_COORDINATOR = "pref_header_coordinator"
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.debug
|
||||
|
||||
import android.os.Bundle
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication
|
||||
import nodomain.freeyourgadget.gadgetbridge.R
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice
|
||||
|
||||
class DeviceListDebugFragment : AbstractDebugFragment() {
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
setPreferencesFromResource(R.xml.debug_preferences_empty, rootKey)
|
||||
preferenceScreen?.title = getString(R.string.bottom_nav_devices)
|
||||
reloadDevices()
|
||||
}
|
||||
|
||||
private fun reloadDevices() {
|
||||
removeDynamicPrefs(preferenceScreen)
|
||||
|
||||
val devices = GBApplication.app().deviceManager.devices
|
||||
|
||||
if (!devices.isEmpty()) {
|
||||
for (device in devices) {
|
||||
addDynamicPref(
|
||||
preferenceScreen,
|
||||
device.aliasOrName,
|
||||
device.address,
|
||||
device.deviceCoordinator.defaultIconResource
|
||||
) {
|
||||
goTo(
|
||||
DeviceDebugFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
putParcelable(GBDevice.EXTRA_DEVICE, device)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
addDynamicPref(preferenceScreen, "", "No devices")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960">
|
||||
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M280,840v-720,720ZM480,240q17,0 28.5,-11.5T520,200q0,-17 -11.5,-28.5T480,160q-17,0 -28.5,11.5T440,200q0,17 11.5,28.5T480,240ZM538,920L280,920q-33,0 -56.5,-23.5T200,840v-720q0,-33 23.5,-56.5T280,40h400q33,0 56.5,23.5T760,120v240h-80v-240L280,120v720h215q7,9 15,17l16,16 12,47ZM620,920 L597,828q-36,-26 -56.5,-64.5T520,680q0,-45 20.5,-83.5T597,532l23,-92h160l23,92q36,26 56.5,64.5T880,680q0,45 -20.5,83.5T803,828l-23,92L620,920ZM700,780q42,0 71,-29t29,-71q0,-42 -29,-71t-71,-29q-42,0 -71,29t-29,71q0,42 29,71t71,29Z" />
|
||||
</vector>
|
||||
@@ -1200,6 +1200,7 @@
|
||||
<string name="prefs_always_on_display_style">Style</string>
|
||||
<string name="prefs_always_on_display_summary">Keep the band\'s display always on</string>
|
||||
<string name="prefs_device_name">Device name</string>
|
||||
<string name="prefs_device_alias">Device alias</string>
|
||||
<string name="prefs_password">Password</string>
|
||||
<string name="prefs_password_summary">Lock the band with a password when removed from the wrist</string>
|
||||
<string name="prefs_password_enabled">Password Enabled</string>
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<Preference
|
||||
android:key="pref_debug_device_name"
|
||||
android:persistent="false"
|
||||
android:title="@string/prefs_device_name"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<Preference
|
||||
android:key="pref_debug_device_alias"
|
||||
android:persistent="false"
|
||||
android:title="@string/prefs_device_alias"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<Preference
|
||||
android:key="pref_debug_device_mac_address"
|
||||
android:persistent="false"
|
||||
android:title="@string/device_mac_address"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<Preference
|
||||
android:key="pref_debug_device_type"
|
||||
android:persistent="false"
|
||||
android:title="@string/watchface_dialog_widget_type"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="pref_header_details"
|
||||
android:title="Details"
|
||||
app:iconSpaceReserved="false">
|
||||
|
||||
<!-- to be filled up dynamically -->
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="pref_header_coordinator"
|
||||
android:title="Coordinator"
|
||||
app:iconSpaceReserved="false">
|
||||
|
||||
<!-- to be filled up dynamically -->
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</androidx.preference.PreferenceScreen>
|
||||
@@ -74,6 +74,13 @@
|
||||
android:persistent="false"
|
||||
android:title="@string/menuitem_settings" />
|
||||
|
||||
<Preference
|
||||
android:fragment="nodomain.freeyourgadget.gadgetbridge.activities.debug.DeviceListDebugFragment"
|
||||
android:icon="@drawable/ic_devices_wearables"
|
||||
android:key="pref_debug_devices"
|
||||
android:persistent="false"
|
||||
android:title="@string/bottom_nav_devices" />
|
||||
|
||||
<Preference
|
||||
android:fragment="nodomain.freeyourgadget.gadgetbridge.activities.debug.CompanionDebugFragment"
|
||||
android:icon="@drawable/ic_devices_other"
|
||||
|
||||
Reference in New Issue
Block a user