Skip to content

Commit

Permalink
Rename/reorder reused Matter code
Browse files Browse the repository at this point in the history
 - Change names and order of reused Matter code for Thread importing to prevent potential confusion
  • Loading branch information
jpelgrom committed Jan 11, 2024
1 parent 8a603b0 commit 8f10be3
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 84 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package io.homeassistant.companion.android.matter
package io.homeassistant.companion.android.webview

enum class MatterFrontendCommissioningStatus {
enum class MatterThreadStep {
NOT_STARTED,
REQUESTED,
THREAD_EXPORT_TO_SERVER_MATTER,
THREAD_EXPORT_TO_SERVER_ONLY,
IN_PROGRESS,
MATTER_IN_PROGRESS,
THREAD_SENT,
THREAD_NONE,
ERROR_MATTER,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ import io.homeassistant.companion.android.database.authentication.Authentication
import io.homeassistant.companion.android.databinding.ActivityWebviewBinding
import io.homeassistant.companion.android.databinding.DialogAuthenticationBinding
import io.homeassistant.companion.android.launch.LaunchActivity
import io.homeassistant.companion.android.matter.MatterFrontendCommissioningStatus
import io.homeassistant.companion.android.nfc.WriteNfcTag
import io.homeassistant.companion.android.sensors.SensorReceiver
import io.homeassistant.companion.android.sensors.SensorWorker
Expand Down Expand Up @@ -171,7 +170,7 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
mFilePathCallback = null
}
private val commissionMatterDevice = registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result ->
presenter.onMatterCommissioningIntentResult(this, result)
presenter.onMatterThreadIntentResult(this, result)
}

@Inject
Expand Down Expand Up @@ -631,45 +630,45 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi

lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
presenter.getMatterCommissioningStatusFlow().collect {
Log.d(TAG, "Matter commissioning status changed to $it")
presenter.getMatterThreadStepFlow().collect {
Log.d(TAG, "Matter/Thread step changed to $it")
when (it) {
MatterFrontendCommissioningStatus.THREAD_EXPORT_TO_SERVER_MATTER,
MatterFrontendCommissioningStatus.THREAD_EXPORT_TO_SERVER_ONLY,
MatterFrontendCommissioningStatus.IN_PROGRESS -> {
presenter.getMatterCommissioningIntent()?.let { intentSender ->
MatterThreadStep.THREAD_EXPORT_TO_SERVER_MATTER,
MatterThreadStep.THREAD_EXPORT_TO_SERVER_ONLY,
MatterThreadStep.MATTER_IN_PROGRESS -> {
presenter.getMatterThreadIntent()?.let { intentSender ->
commissionMatterDevice.launch(IntentSenderRequest.Builder(intentSender).build())
}
}
MatterFrontendCommissioningStatus.THREAD_NONE -> {
MatterThreadStep.THREAD_NONE -> {
alertDialog?.cancel()
AlertDialog.Builder(this@WebViewActivity)
.setMessage(commonR.string.thread_export_none)
.setPositiveButton(commonR.string.ok, null)
.show()
presenter.confirmMatterCommissioningError()
presenter.finishMatterThreadFlow()
}
MatterFrontendCommissioningStatus.THREAD_SENT -> {
MatterThreadStep.THREAD_SENT -> {
Toast.makeText(this@WebViewActivity, commonR.string.thread_export_success, Toast.LENGTH_SHORT).show()
alertDialog?.cancel()
presenter.confirmMatterCommissioningError()
presenter.finishMatterThreadFlow()
}
MatterFrontendCommissioningStatus.ERROR_MATTER -> {
MatterThreadStep.ERROR_MATTER -> {
Toast.makeText(this@WebViewActivity, commonR.string.matter_commissioning_unavailable, Toast.LENGTH_SHORT).show()
presenter.confirmMatterCommissioningError()
presenter.finishMatterThreadFlow()
}
MatterFrontendCommissioningStatus.ERROR_THREAD_LOCAL_NETWORK -> {
MatterThreadStep.ERROR_THREAD_LOCAL_NETWORK -> {
alertDialog?.cancel()
AlertDialog.Builder(this@WebViewActivity)
.setMessage(commonR.string.thread_export_not_connected)
.setPositiveButton(commonR.string.ok, null)
.show()
presenter.confirmMatterCommissioningError()
presenter.finishMatterThreadFlow()
}
MatterFrontendCommissioningStatus.ERROR_THREAD_OTHER -> {
MatterThreadStep.ERROR_THREAD_OTHER -> {
Toast.makeText(this@WebViewActivity, commonR.string.thread_export_unavailable, Toast.LENGTH_SHORT).show()
alertDialog?.cancel()
presenter.confirmMatterCommissioningError()
presenter.finishMatterThreadFlow()
}
else -> { } // Do nothing
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package io.homeassistant.companion.android.webview
import android.content.Context
import android.content.IntentSender
import androidx.activity.result.ActivityResult
import io.homeassistant.companion.android.matter.MatterFrontendCommissioningStatus
import kotlinx.coroutines.flow.Flow

interface WebViewPresenter {
Expand Down Expand Up @@ -54,12 +53,12 @@ interface WebViewPresenter {

fun appCanCommissionMatterDevice(): Boolean
fun startCommissioningMatterDevice(context: Context)
fun getMatterCommissioningStatusFlow(): Flow<MatterFrontendCommissioningStatus>
fun getMatterCommissioningIntent(): IntentSender?
fun onMatterCommissioningIntentResult(context: Context, result: ActivityResult)
fun confirmMatterCommissioningError()

/** @return `true` if the app can send this device's preferred Thread credential to the server */
fun appCanExportThreadCredentials(): Boolean
fun exportThreadCredentials(context: Context)
fun getMatterThreadStepFlow(): Flow<MatterThreadStep>
fun getMatterThreadIntent(): IntentSender?
fun onMatterThreadIntentResult(context: Context, result: ActivityResult)
fun finishMatterThreadFlow()
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import io.homeassistant.companion.android.common.data.authentication.SessionStat
import io.homeassistant.companion.android.common.data.prefs.PrefsRepository
import io.homeassistant.companion.android.common.data.servers.ServerManager
import io.homeassistant.companion.android.common.util.DisabledLocationHandler
import io.homeassistant.companion.android.matter.MatterFrontendCommissioningStatus
import io.homeassistant.companion.android.matter.MatterManager
import io.homeassistant.companion.android.thread.ThreadManager
import io.homeassistant.companion.android.util.UrlUtil
Expand Down Expand Up @@ -58,9 +57,9 @@ class WebViewPresenterImpl @Inject constructor(
private var url: URL? = null
private var urlForServer: Int? = null

private val _matterCommissioningStatus = MutableStateFlow(MatterFrontendCommissioningStatus.NOT_STARTED)
private val _matterThreadStep = MutableStateFlow(MatterThreadStep.NOT_STARTED)

private var matterCommissioningIntentSender: IntentSender? = null
private var matterThreadIntentSender: IntentSender? = null

init {
updateActiveServer()
Expand Down Expand Up @@ -343,8 +342,8 @@ class WebViewPresenterImpl @Inject constructor(
override fun appCanCommissionMatterDevice(): Boolean = matterUseCase.appSupportsCommissioning()

override fun startCommissioningMatterDevice(context: Context) {
if (_matterCommissioningStatus.value != MatterFrontendCommissioningStatus.REQUESTED) {
_matterCommissioningStatus.tryEmit(MatterFrontendCommissioningStatus.REQUESTED)
if (_matterThreadStep.value != MatterThreadStep.REQUESTED) {
_matterThreadStep.tryEmit(MatterThreadStep.REQUESTED)

mainScope.launch {
val deviceThreadIntent = try {
Expand All @@ -358,8 +357,8 @@ class WebViewPresenterImpl @Inject constructor(
null
}
if (deviceThreadIntent != null) {
matterCommissioningIntentSender = deviceThreadIntent
_matterCommissioningStatus.tryEmit(MatterFrontendCommissioningStatus.THREAD_EXPORT_TO_SERVER_MATTER)
matterThreadIntentSender = deviceThreadIntent
_matterThreadStep.tryEmit(MatterThreadStep.THREAD_EXPORT_TO_SERVER_MATTER)
} else {
startMatterCommissioningFlow(context)
}
Expand All @@ -372,41 +371,76 @@ class WebViewPresenterImpl @Inject constructor(
context,
{ intentSender ->
Log.d(TAG, "Matter commissioning is ready")
matterCommissioningIntentSender = intentSender
_matterCommissioningStatus.tryEmit(MatterFrontendCommissioningStatus.IN_PROGRESS)
matterThreadIntentSender = intentSender
_matterThreadStep.tryEmit(MatterThreadStep.MATTER_IN_PROGRESS)
},
{ e ->
Log.e(TAG, "Matter commissioning couldn't be prepared", e)
_matterCommissioningStatus.tryEmit(MatterFrontendCommissioningStatus.ERROR_MATTER)
_matterThreadStep.tryEmit(MatterThreadStep.ERROR_MATTER)
}
)
}

override fun getMatterCommissioningStatusFlow(): Flow<MatterFrontendCommissioningStatus> =
_matterCommissioningStatus.asStateFlow()
override fun appCanExportThreadCredentials(): Boolean = threadUseCase.appSupportsThread()

override fun exportThreadCredentials(context: Context) {
if (_matterThreadStep.value != MatterThreadStep.REQUESTED) {
_matterThreadStep.tryEmit(MatterThreadStep.REQUESTED)

mainScope.launch {
try {
val result = threadUseCase.syncPreferredDataset(context, serverId, true, CoroutineScope(coroutineContext + SupervisorJob()))
Log.d(TAG, "Export preferred Thread dataset returned $result")

when (result) {
is ThreadManager.SyncResult.OnlyOnDevice -> {
matterThreadIntentSender = result.exportIntent
_matterThreadStep.tryEmit(MatterThreadStep.THREAD_EXPORT_TO_SERVER_ONLY)
}
is ThreadManager.SyncResult.NoneHaveCredentials,
is ThreadManager.SyncResult.OnlyOnServer -> {
_matterThreadStep.tryEmit(MatterThreadStep.THREAD_NONE)
}
is ThreadManager.SyncResult.NotConnected -> {
_matterThreadStep.tryEmit(MatterThreadStep.ERROR_THREAD_LOCAL_NETWORK)
}
else -> {
_matterThreadStep.tryEmit(MatterThreadStep.ERROR_THREAD_OTHER)
}
}
} catch (e: Exception) {
Log.w(TAG, "Unable to export preferred Thread dataset", e)
_matterThreadStep.tryEmit(MatterThreadStep.ERROR_THREAD_OTHER)
}
}
} // else already waiting for a result, don't send another request
}

override fun getMatterThreadStepFlow(): Flow<MatterThreadStep> =
_matterThreadStep.asStateFlow()

override fun getMatterCommissioningIntent(): IntentSender? {
val intent = matterCommissioningIntentSender
matterCommissioningIntentSender = null
override fun getMatterThreadIntent(): IntentSender? {
val intent = matterThreadIntentSender
matterThreadIntentSender = null
return intent
}

override fun onMatterCommissioningIntentResult(context: Context, result: ActivityResult) {
when (_matterCommissioningStatus.value) {
MatterFrontendCommissioningStatus.THREAD_EXPORT_TO_SERVER_MATTER -> {
override fun onMatterThreadIntentResult(context: Context, result: ActivityResult) {
when (_matterThreadStep.value) {
MatterThreadStep.THREAD_EXPORT_TO_SERVER_MATTER -> {
mainScope.launch {
threadUseCase.sendThreadDatasetExportResult(result, serverId)
startMatterCommissioningFlow(context)
}
}
MatterFrontendCommissioningStatus.THREAD_EXPORT_TO_SERVER_ONLY -> {
MatterThreadStep.THREAD_EXPORT_TO_SERVER_ONLY -> {
mainScope.launch {
val sent = threadUseCase.sendThreadDatasetExportResult(result, serverId)
Log.d(TAG, "Thread ${if (!sent.isNullOrBlank()) "sent credential for $sent" else "did not send credential"}")
if (sent.isNullOrBlank()) {
_matterCommissioningStatus.tryEmit(MatterFrontendCommissioningStatus.THREAD_NONE)
_matterThreadStep.tryEmit(MatterThreadStep.THREAD_NONE)
} else {
_matterCommissioningStatus.tryEmit(MatterFrontendCommissioningStatus.THREAD_SENT)
_matterThreadStep.tryEmit(MatterThreadStep.THREAD_SENT)
}
}
}
Expand All @@ -421,42 +455,7 @@ class WebViewPresenterImpl @Inject constructor(
}
}

override fun confirmMatterCommissioningError() {
_matterCommissioningStatus.tryEmit(MatterFrontendCommissioningStatus.NOT_STARTED)
}

override fun appCanExportThreadCredentials(): Boolean = threadUseCase.appSupportsThread()

override fun exportThreadCredentials(context: Context) {
if (_matterCommissioningStatus.value != MatterFrontendCommissioningStatus.REQUESTED) {
_matterCommissioningStatus.tryEmit(MatterFrontendCommissioningStatus.REQUESTED)

mainScope.launch {
try {
val result = threadUseCase.syncPreferredDataset(context, serverId, true, CoroutineScope(coroutineContext + SupervisorJob()))
Log.d(TAG, "Export preferred Thread dataset returned $result")

when (result) {
is ThreadManager.SyncResult.OnlyOnDevice -> {
matterCommissioningIntentSender = result.exportIntent
_matterCommissioningStatus.tryEmit(MatterFrontendCommissioningStatus.THREAD_EXPORT_TO_SERVER_ONLY)
}
is ThreadManager.SyncResult.NoneHaveCredentials,
is ThreadManager.SyncResult.OnlyOnServer -> {
_matterCommissioningStatus.tryEmit(MatterFrontendCommissioningStatus.THREAD_NONE)
}
is ThreadManager.SyncResult.NotConnected -> {
_matterCommissioningStatus.tryEmit(MatterFrontendCommissioningStatus.ERROR_THREAD_LOCAL_NETWORK)
}
else -> {
_matterCommissioningStatus.tryEmit(MatterFrontendCommissioningStatus.ERROR_THREAD_OTHER)
}
}
} catch (e: Exception) {
Log.w(TAG, "Unable to export preferred Thread dataset", e)
_matterCommissioningStatus.tryEmit(MatterFrontendCommissioningStatus.ERROR_THREAD_OTHER)
}
}
} // else already waiting for a result, don't send another request
override fun finishMatterThreadFlow() {
_matterThreadStep.tryEmit(MatterThreadStep.NOT_STARTED)
}
}

0 comments on commit 8f10be3

Please sign in to comment.