Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add permissions requests to wear OS sensors and add network sensors #2956

Merged
merged 8 commits into from
Oct 19, 2022
2 changes: 2 additions & 0 deletions wear/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

<uses-feature android:name="android.hardware.type.watch" />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package io.homeassistant.companion.android
import android.app.Application
import android.content.Intent
import android.content.IntentFilter
import android.net.wifi.WifiManager
import dagger.hilt.android.HiltAndroidApp
import io.homeassistant.companion.android.complications.ComplicationReceiver
import io.homeassistant.companion.android.sensors.SensorReceiver
Expand All @@ -26,6 +27,15 @@ open class HomeAssistantApplication : Application() {
}
)

// This will trigger an update any time the wifi state has changed
registerReceiver(
sensorReceiver,
IntentFilter().apply {
addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION)
addAction(WifiManager.WIFI_STATE_CHANGED_ACTION)
}
)

// Update complications when the screen is on
val complicationReceiver = ComplicationReceiver()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import io.homeassistant.companion.android.data.SimplifiedEntity
import io.homeassistant.companion.android.database.sensor.SensorDao
import io.homeassistant.companion.android.database.wear.FavoritesDao
import io.homeassistant.companion.android.database.wear.getAllFlow
import io.homeassistant.companion.android.sensors.SensorWorker
import io.homeassistant.companion.android.util.RegistriesDataHandler
import kotlinx.coroutines.async
import kotlinx.coroutines.flow.Flow
Expand Down Expand Up @@ -278,6 +279,7 @@ class MainViewModel @Inject constructor(
isEnabled: Boolean
) {
sensorDao.setSensorsEnabled(listOf(basicSensor.id), isEnabled)
SensorWorker.start(getApplication())
}

fun getAreaForEntity(entityId: String): AreaRegistryResponse? =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package io.homeassistant.companion.android.home.views

import android.Manifest
import android.os.Build
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
Expand All @@ -21,13 +25,48 @@ fun SensorUi(
basicSensor: SensorManager.BasicSensor,
onSensorClicked: (String, Boolean) -> Unit,
) {
val perm = manager.checkPermission(LocalContext.current, basicSensor.id)
val checked = sensor?.enabled == true

val backgroundRequest =
rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()) {
onSensorClicked(basicSensor.id, it)
}

val permissionLaunch = rememberLauncherForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { isGranted ->
var allGranted = true
isGranted.forEach {
if (
manager.requiredPermissions(basicSensor.id).contains(Manifest.permission.ACCESS_FINE_LOCATION) &&
manager.requiredPermissions(basicSensor.id).contains(Manifest.permission.ACCESS_BACKGROUND_LOCATION) &&
it.key == Manifest.permission.ACCESS_FINE_LOCATION && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
) {
backgroundRequest.launch(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
dshokouhi marked this conversation as resolved.
Show resolved Hide resolved
return@forEach
}
if (!it.value)
allGranted = false
}
onSensorClicked(basicSensor.id, allGranted)
}

val perm = manager.checkPermission(LocalContext.current, basicSensor.id)
ToggleChip(
checked = (sensor == null && manager.enabledByDefault) ||
(sensor?.enabled == true && perm),
onCheckedChange = { enabled ->
onSensorClicked(basicSensor.id, enabled)
val permissions = manager.requiredPermissions(basicSensor.id)
if (perm || !enabled)
onSensorClicked(basicSensor.id, enabled)
else
permissionLaunch.launch(
if (permissions.size == 1 && permissions[0] == Manifest.permission.ACCESS_BACKGROUND_LOCATION)
permissions
else
permissions.toSet().minus(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
.toTypedArray()
)
},
modifier = Modifier
.fillMaxWidth(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,19 @@ fun SensorsView(
ListHeader(id = commonR.string.sensors)
}
items(sensorManagers.size, { sensorManagers[it].name }) { index ->
sensorManagers.forEach { manager ->
Row {
Chip(
modifier = Modifier
.fillMaxWidth(),
colors = ChipDefaults.secondaryChipColors(),
label = {
Text(
text = stringResource(manager.name)
)
},
onClick = { onClickSensorManager(manager) }
)
}
val manager = sensorManagers[index]
Row {
Chip(
modifier = Modifier
.fillMaxWidth(),
colors = ChipDefaults.secondaryChipColors(),
label = {
Text(
text = stringResource(manager.name)
)
},
onClick = { onClickSensorManager(manager) }
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package io.homeassistant.companion.android.sensors
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.wifi.WifiManager
import dagger.hilt.android.AndroidEntryPoint
import io.homeassistant.companion.android.BuildConfig
import io.homeassistant.companion.android.common.sensors.BatterySensorManager
import io.homeassistant.companion.android.common.sensors.NetworkSensorManager
import io.homeassistant.companion.android.common.sensors.SensorManager
import io.homeassistant.companion.android.common.sensors.SensorReceiverBase

Expand All @@ -24,7 +26,8 @@ class SensorReceiver : SensorReceiverBase() {
companion object {
const val TAG = "SensorReceiver"
val MANAGERS = listOf(
BatterySensorManager()
BatterySensorManager(),
NetworkSensorManager()
)

const val ACTION_REQUEST_SENSORS_UPDATE =
Expand All @@ -33,7 +36,9 @@ class SensorReceiver : SensorReceiverBase() {

// Suppress Lint because we only register for the receiver if the android version matches the intent
@SuppressLint("InlinedApi")
override val skippableActions = mapOf<String, String>()
override val skippableActions = mapOf(
WifiManager.WIFI_STATE_CHANGED_ACTION to NetworkSensorManager.wifiState.id
)

override fun getSensorSettingsIntent(context: Context, id: String): Intent? = null
}