From 983dbd58e40e0f4100c9758965acbe36c3bdc78f Mon Sep 17 00:00:00 2001 From: RoboMagus <68224306+RoboMagus@users.noreply.github.com> Date: Wed, 19 Oct 2022 20:45:22 +0200 Subject: [PATCH] Add notify command for app-lock (#2868) * Add notify command for app-lock * Add null check for optional parameters * Only allow enabling app_lock by notify command if previously enabled by user * Use constants for app lock command parameters * Add BiometricManager check before turning on app_lock * Remove 'hasLockEverBeenEnabled' in favor of only biometricmanager check. * Improved value checking for app lock command. Made setAppLock function suspending i.s.o. sepearate runBlocking calls. * Show notification if no parameters were updated. * improved parameter value checking * Don't make changes when invalid data is provided * Early check on argument validity for app lock commands * Cleanup app lock command parameter validation --- .../android/notifications/MessagingManager.kt | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/app/src/main/java/io/homeassistant/companion/android/notifications/MessagingManager.kt b/app/src/main/java/io/homeassistant/companion/android/notifications/MessagingManager.kt index 0dabfde63..616801390 100644 --- a/app/src/main/java/io/homeassistant/companion/android/notifications/MessagingManager.kt +++ b/app/src/main/java/io/homeassistant/companion/android/notifications/MessagingManager.kt @@ -35,6 +35,7 @@ import android.view.KeyEvent import android.widget.RemoteViews import android.widget.Toast import androidx.annotation.RequiresApi +import androidx.biometric.BiometricManager import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import androidx.core.app.RemoteInput @@ -165,6 +166,7 @@ class MessagingManager @Inject constructor( const val COMMAND_WEBVIEW = "command_webview" const val COMMAND_KEEP_SCREEN_ON = "keep_screen_on" const val COMMAND_LAUNCH_APP = "command_launch_app" + const val COMMAND_APP_LOCK = "command_app_lock" const val COMMAND_PERSISTENT_CONNECTION = "command_persistent_connection" const val COMMAND_STOP_TTS = "command_stop_tts" const val COMMAND_AUTO_SCREEN_BRIGHTNESS = "command_auto_screen_brightness" @@ -225,6 +227,11 @@ class MessagingManager @Inject constructor( const val BLE_MAJOR = "ble_major" const val BLE_MINOR = "ble_minor" + // App-lock command parameters: + const val APP_LOCK_ENABLED = "app_lock_enabled" + const val APP_LOCK_TIMEOUT = "app_lock_timeout" + const val HOME_BYPASS_ENABLED = "home_bypass_enabled" + // High accuracy commands const val HIGH_ACCURACY_SET_UPDATE_INTERVAL = "high_accuracy_set_update_interval" const val FORCE_ON = "force_on" @@ -246,6 +253,7 @@ class MessagingManager @Inject constructor( COMMAND_MEDIA, COMMAND_UPDATE_SENSORS, COMMAND_LAUNCH_APP, + COMMAND_APP_LOCK, COMMAND_PERSISTENT_CONNECTION, COMMAND_STOP_TTS, COMMAND_AUTO_SCREEN_BRIGHTNESS, @@ -472,6 +480,32 @@ class MessagingManager @Inject constructor( } } } + COMMAND_APP_LOCK -> { + val app_lock_enable_param_present = jsonData[APP_LOCK_ENABLED] != null + val app_lock_timeout_param_present = jsonData[APP_LOCK_TIMEOUT] != null + val home_bypass_param_present = jsonData[APP_LOCK_ENABLED] != null + + val app_lock_enable_value = jsonData[APP_LOCK_ENABLED]?.toLowerCase()?.toBooleanStrictOrNull() + val app_lock_timeout_value = jsonData[APP_LOCK_TIMEOUT]?.toIntOrNull() + val home_bypass_value = jsonData[APP_LOCK_ENABLED]?.toLowerCase()?.toBooleanStrictOrNull() + + val invalid = (!app_lock_enable_param_present && !app_lock_timeout_param_present && !home_bypass_param_present) || + (app_lock_enable_param_present && app_lock_enable_value == null) || + (app_lock_timeout_param_present && (app_lock_timeout_value == null || app_lock_timeout_value < 0)) || + (home_bypass_param_present && home_bypass_value == null) + + if (!invalid) + handleDeviceCommands(jsonData) + else { + mainScope.launch { + Log.d( + TAG, + "Invalid app lock command received, posting notification to device" + ) + sendNotification(jsonData) + } + } + } COMMAND_WEBVIEW -> { handleDeviceCommands(jsonData) } @@ -870,6 +904,11 @@ class MessagingManager @Inject constructor( } else processActivityCommand(data) } + COMMAND_APP_LOCK -> { + mainScope.launch { + setAppLock(data) + } + } COMMAND_WEBVIEW -> { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (!Settings.canDrawOverlays(context)) @@ -2016,6 +2055,28 @@ class MessagingManager @Inject constructor( } } + private suspend fun setAppLock(data: Map) { + val app_lock_enable_value = data[APP_LOCK_ENABLED]?.toLowerCase()?.toBooleanStrictOrNull() + val app_lock_timeout_value = data[APP_LOCK_TIMEOUT]?.toIntOrNull() + val home_bypass_value = data[APP_LOCK_ENABLED]?.toLowerCase()?.toBooleanStrictOrNull() + + val canAuth = (BiometricManager.from(context).canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS) + if (canAuth) { + if (app_lock_enable_value != null) { + authenticationUseCase.setLockEnabled(app_lock_enable_value) + } + if (app_lock_timeout_value != null) { + integrationUseCase.sessionTimeOut(app_lock_timeout_value) + } + if (home_bypass_value != null) { + authenticationUseCase.setLockHomeBypassEnabled(home_bypass_value) + } + } else { + Log.w(TAG, "Not changing App-Lock settings. BiometricManager cannot Authenticate!") + sendNotification(data) + } + } + private fun togglePersistentConnection(mode: String) { when (mode.uppercase()) { WebsocketSetting.NEVER.name -> {