From 2641422e5020704dd2d229d81029b51810267e66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Mar=C3=A1z?= Date: Thu, 5 Oct 2023 15:57:33 +0200 Subject: [PATCH] Add NFC state sensor (#3905) * Add first draft for NFC sensor * Rename NfcSensorManager.nfcSensor to nfcStateSensor * Move NfcSensorManager to the common module * Add BroadcastReceiver subscription to NfcAdapter.ACTION_ADAPTER_STATE_CHANGED in both the app and wear modules * Remove TODO comments * Change updateType to INTENT * Convert simple methods to expression body * Change mdi:nfc to mdi:nfc-variant * Fix docs URL * Reword NFC sensor manager according to the PR suggestions --- .../android/HomeAssistantApplication.kt | 7 +++ .../android/sensors/SensorReceiver.kt | 6 ++- .../common/sensors/NfcSensorManager.kt | 51 +++++++++++++++++++ common/src/main/res/values/strings.xml | 3 ++ .../android/HomeAssistantApplication.kt | 7 +++ .../android/sensors/SensorReceiver.kt | 6 ++- 6 files changed, 78 insertions(+), 2 deletions(-) create mode 100755 common/src/main/java/io/homeassistant/companion/android/common/sensors/NfcSensorManager.kt diff --git a/app/src/main/java/io/homeassistant/companion/android/HomeAssistantApplication.kt b/app/src/main/java/io/homeassistant/companion/android/HomeAssistantApplication.kt index d6be6cfba71..680e7faee5c 100644 --- a/app/src/main/java/io/homeassistant/companion/android/HomeAssistantApplication.kt +++ b/app/src/main/java/io/homeassistant/companion/android/HomeAssistantApplication.kt @@ -7,6 +7,7 @@ import android.content.Intent import android.content.IntentFilter import android.media.AudioManager import android.net.wifi.WifiManager +import android.nfc.NfcAdapter import android.os.Build import android.os.PowerManager import android.telephony.TelephonyManager @@ -141,6 +142,12 @@ open class HomeAssistantApplication : Application() { IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED) ) + // Listen for NFC state changes + registerReceiver( + sensorReceiver, + IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED) + ) + // Listen to changes to the audio input/output on the device registerReceiver( sensorReceiver, diff --git a/app/src/main/java/io/homeassistant/companion/android/sensors/SensorReceiver.kt b/app/src/main/java/io/homeassistant/companion/android/sensors/SensorReceiver.kt index 95357fdaa8c..79091df714b 100644 --- a/app/src/main/java/io/homeassistant/companion/android/sensors/SensorReceiver.kt +++ b/app/src/main/java/io/homeassistant/companion/android/sensors/SensorReceiver.kt @@ -8,6 +8,7 @@ import android.content.Context import android.content.Intent import android.media.AudioManager import android.net.wifi.WifiManager +import android.nfc.NfcAdapter import android.os.PowerManager import dagger.hilt.android.AndroidEntryPoint import io.homeassistant.companion.android.BuildConfig @@ -24,6 +25,7 @@ import io.homeassistant.companion.android.common.sensors.LightSensorManager import io.homeassistant.companion.android.common.sensors.MobileDataManager import io.homeassistant.companion.android.common.sensors.NetworkSensorManager import io.homeassistant.companion.android.common.sensors.NextAlarmManager +import io.homeassistant.companion.android.common.sensors.NfcSensorManager import io.homeassistant.companion.android.common.sensors.PhoneStateSensorManager import io.homeassistant.companion.android.common.sensors.PowerSensorManager import io.homeassistant.companion.android.common.sensors.PressureSensorManager @@ -72,6 +74,7 @@ class SensorReceiver : SensorReceiverBase() { LocationSensorManager(), MobileDataManager(), NetworkSensorManager(), + NfcSensorManager(), NextAlarmManager(), NotificationSensorManager(), PhoneStateSensorManager(), @@ -113,7 +116,8 @@ class SensorReceiver : SensorReceiverBase() { AudioManager.RINGER_MODE_CHANGED_ACTION to AudioSensorManager.audioSensor.id, Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE to DevicePolicyManager.isWorkProfile.id, Intent.ACTION_MANAGED_PROFILE_AVAILABLE to DevicePolicyManager.isWorkProfile.id, - WifiManager.WIFI_STATE_CHANGED_ACTION to NetworkSensorManager.wifiState.id + WifiManager.WIFI_STATE_CHANGED_ACTION to NetworkSensorManager.wifiState.id, + NfcAdapter.ACTION_ADAPTER_STATE_CHANGED to NfcSensorManager.nfcStateSensor.id ) override fun getSensorSettingsIntent( diff --git a/common/src/main/java/io/homeassistant/companion/android/common/sensors/NfcSensorManager.kt b/common/src/main/java/io/homeassistant/companion/android/common/sensors/NfcSensorManager.kt new file mode 100755 index 00000000000..a9738b62e52 --- /dev/null +++ b/common/src/main/java/io/homeassistant/companion/android/common/sensors/NfcSensorManager.kt @@ -0,0 +1,51 @@ +package io.homeassistant.companion.android.common.sensors + +import android.content.Context +import android.nfc.NfcAdapter +import io.homeassistant.companion.android.common.R as commonR + +class NfcSensorManager : SensorManager { + companion object { + private const val TAG = "NfcSensor" + + val nfcStateSensor = SensorManager.BasicSensor( + "nfc_state", + "binary_sensor", + commonR.string.basic_sensor_name_nfc_state, + commonR.string.sensor_description_nfc_state, + "mdi:nfc-variant", + entityCategory = SensorManager.ENTITY_CATEGORY_DIAGNOSTIC, + updateType = SensorManager.BasicSensor.UpdateType.INTENT + ) + } + + override fun docsLink() = "https://companion.home-assistant.io/docs/core/sensors#nfc-state-sensor" + override val name = commonR.string.sensor_name_nfc + + override suspend fun getAvailableSensors(context: Context) = listOf(nfcStateSensor) + + override fun requiredPermissions(sensorId: String) = emptyArray() + + override fun requestSensorUpdate(context: Context) = updateNfcState(context) + + override fun hasSensor(context: Context): Boolean { + return NfcAdapter.getDefaultAdapter(context) != null + } + + private fun updateNfcState(context: Context) { + if (!isEnabled(context, nfcStateSensor)) { + return + } + + val nfcAdapter = NfcAdapter.getDefaultAdapter(context) + val nfcEnabled = nfcAdapter?.isEnabled == true + + onSensorUpdated( + context, + nfcStateSensor, + nfcEnabled, + nfcStateSensor.statelessIcon, + emptyMap() + ) + } +} diff --git a/common/src/main/res/values/strings.xml b/common/src/main/res/values/strings.xml index 874635ccb35..f9baf517015 100644 --- a/common/src/main/res/values/strings.xml +++ b/common/src/main/res/values/strings.xml @@ -96,6 +96,7 @@ Mobile data Mobile Rx GB Mobile Tx GB + NFC state Phone state Power save Public IP address @@ -611,6 +612,7 @@ Total Tx GB on cellular data since last device reboot Whether music is actively playing on the device The date and time of the next scheduled alarm, any app or manufacturer can override the default behavior. The package attribute will tell you which app set the next scheduled alarm. The setting below will create an Allow List so you can specify what packages you want the alarm event from. This will ignore alarm events for packages not selected and the state will not update until the next scheduled alarm matches one of the selected packages. + Whether NFC is enabled on the device No description Whether the phone is ringing or in a call, no other caller information is stored Whether the device is in Power Save mode @@ -1124,6 +1126,7 @@ The total number of calories over a day (including both BMR and active calories), where the previous day ends and a new day begins at 12:00 AM local time. Daily steps The total step count over a day, where the previous day ends and a new day begins at 12:00 AM local time. + NFC sensor Sync Thread credentials Syncing… An unexpected error occurred while syncing diff --git a/wear/src/main/java/io/homeassistant/companion/android/HomeAssistantApplication.kt b/wear/src/main/java/io/homeassistant/companion/android/HomeAssistantApplication.kt index 35cd3efbd42..2d0297475ee 100644 --- a/wear/src/main/java/io/homeassistant/companion/android/HomeAssistantApplication.kt +++ b/wear/src/main/java/io/homeassistant/companion/android/HomeAssistantApplication.kt @@ -7,6 +7,7 @@ import android.content.Intent import android.content.IntentFilter import android.media.AudioManager import android.net.wifi.WifiManager +import android.nfc.NfcAdapter import android.os.Build import android.os.PowerManager import dagger.hilt.android.HiltAndroidApp @@ -100,6 +101,12 @@ open class HomeAssistantApplication : Application() { IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED) ) + // Listen for NFC state changes + registerReceiver( + sensorReceiver, + IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED) + ) + // Update complications when the screen is on val complicationReceiver = ComplicationReceiver() diff --git a/wear/src/main/java/io/homeassistant/companion/android/sensors/SensorReceiver.kt b/wear/src/main/java/io/homeassistant/companion/android/sensors/SensorReceiver.kt index 0f22282656b..33db86a7a72 100644 --- a/wear/src/main/java/io/homeassistant/companion/android/sensors/SensorReceiver.kt +++ b/wear/src/main/java/io/homeassistant/companion/android/sensors/SensorReceiver.kt @@ -8,6 +8,7 @@ import android.content.Context import android.content.Intent import android.media.AudioManager import android.net.wifi.WifiManager +import android.nfc.NfcAdapter import android.os.Build import android.os.PowerManager import androidx.core.app.TaskStackBuilder @@ -27,6 +28,7 @@ import io.homeassistant.companion.android.common.sensors.LightSensorManager import io.homeassistant.companion.android.common.sensors.MobileDataManager import io.homeassistant.companion.android.common.sensors.NetworkSensorManager import io.homeassistant.companion.android.common.sensors.NextAlarmManager +import io.homeassistant.companion.android.common.sensors.NfcSensorManager import io.homeassistant.companion.android.common.sensors.PhoneStateSensorManager import io.homeassistant.companion.android.common.sensors.PowerSensorManager import io.homeassistant.companion.android.common.sensors.PressureSensorManager @@ -71,6 +73,7 @@ class SensorReceiver : SensorReceiverBase() { MobileDataManager(), NetworkSensorManager(), NextAlarmManager(), + NfcSensorManager(), OnBodySensorManager(), PhoneStateSensorManager(), PowerSensorManager(), @@ -116,7 +119,8 @@ class SensorReceiver : SensorReceiverBase() { "com.google.android.clockwork.actions.WET_MODE_ENDED" to WetModeSensorManager.wetModeSensor.id, "android.bluetooth.device.action.ACL_CONNECTED" to BluetoothSensorManager.bluetoothConnection.id, "android.bluetooth.device.action.ACL_DISCONNECTED" to BluetoothSensorManager.bluetoothConnection.id, - BluetoothAdapter.ACTION_STATE_CHANGED to BluetoothSensorManager.bluetoothState.id + BluetoothAdapter.ACTION_STATE_CHANGED to BluetoothSensorManager.bluetoothState.id, + NfcAdapter.ACTION_ADAPTER_STATE_CHANGED to NfcSensorManager.nfcStateSensor.id ) override fun getSensorSettingsIntent(