-
-
Notifications
You must be signed in to change notification settings - Fork 664
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Provide interface for external bus outside WebViewActivity (#4338)
- Adds an interface to the app to interact with the external bus outside the WebViewActivity. This should make it possible for the frontend to control more native UI of the app.
- Loading branch information
Showing
8 changed files
with
179 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
...rc/main/java/io/homeassistant/companion/android/webview/externalbus/ExternalBusMessage.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package io.homeassistant.companion.android.webview.externalbus | ||
|
||
import android.webkit.ValueCallback | ||
|
||
data class ExternalBusMessage( | ||
val id: Any, | ||
val type: String, | ||
val success: Boolean, | ||
val result: Any? = null, | ||
val error: Any? = null, | ||
val callback: ValueCallback<String>? = null | ||
) |
16 changes: 16 additions & 0 deletions
16
...src/main/java/io/homeassistant/companion/android/webview/externalbus/ExternalBusModule.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package io.homeassistant.companion.android.webview.externalbus | ||
|
||
import dagger.Binds | ||
import dagger.Module | ||
import dagger.hilt.InstallIn | ||
import dagger.hilt.components.SingletonComponent | ||
import javax.inject.Singleton | ||
|
||
@Module | ||
@InstallIn(SingletonComponent::class) | ||
abstract class ExternalBusModule { | ||
|
||
@Binds | ||
@Singleton | ||
abstract fun externalBusRepository(externalBusRepositoryImpl: ExternalBusRepositoryImpl): ExternalBusRepository | ||
} |
34 changes: 34 additions & 0 deletions
34
...main/java/io/homeassistant/companion/android/webview/externalbus/ExternalBusRepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package io.homeassistant.companion.android.webview.externalbus | ||
|
||
import kotlinx.coroutines.flow.Flow | ||
import org.json.JSONObject | ||
|
||
/** | ||
* A repository to communicate with the external bus which is provided by the frontend, | ||
* in contexts where there is no 'line of sight' to the webview (usually: other activity). | ||
* | ||
* The [WebViewActivity] or listener should be alive for this to work, and the repository | ||
* does not guarantee that the the receiver will immediately receive the message as the | ||
* system can limit background activity. | ||
*/ | ||
interface ExternalBusRepository { | ||
|
||
/** Send a message to the external bus (for native) */ | ||
suspend fun send(message: ExternalBusMessage) | ||
|
||
/** | ||
* Register to receive certain messages from the external bus (for native) | ||
* @param types List of which message `type`s should be received | ||
* @return Flow with received messages for the specified types | ||
*/ | ||
fun receive(types: List<String>): Flow<JSONObject> | ||
|
||
/** Send a message from the external bus to registered receivers (for webview) */ | ||
suspend fun received(message: JSONObject) | ||
|
||
/** | ||
* @return Flow with [ExternalBusMessage]s that should be sent on the external | ||
* bus (for webview) | ||
*/ | ||
fun getSentFlow(): Flow<ExternalBusMessage> | ||
} |
43 changes: 43 additions & 0 deletions
43
.../java/io/homeassistant/companion/android/webview/externalbus/ExternalBusRepositoryImpl.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package io.homeassistant.companion.android.webview.externalbus | ||
|
||
import android.util.Log | ||
import javax.inject.Inject | ||
import kotlinx.coroutines.flow.Flow | ||
import kotlinx.coroutines.flow.MutableSharedFlow | ||
import kotlinx.coroutines.flow.asSharedFlow | ||
import org.json.JSONObject | ||
|
||
class ExternalBusRepositoryImpl @Inject constructor() : ExternalBusRepository { | ||
|
||
companion object { | ||
private const val TAG = "ExternalBusRepo" | ||
} | ||
|
||
private val externalBusFlow = MutableSharedFlow<ExternalBusMessage>( | ||
// Don't suspend if the WebView is temporarily unavailable | ||
extraBufferCapacity = 100 | ||
) | ||
private val receiverFlows = mutableMapOf<List<String>, MutableSharedFlow<JSONObject>>() | ||
|
||
override suspend fun send(message: ExternalBusMessage) { | ||
externalBusFlow.emit(message) | ||
} | ||
|
||
override fun receive(types: List<String>): Flow<JSONObject> { | ||
val flow = receiverFlows[types] ?: MutableSharedFlow() | ||
receiverFlows[types] = flow | ||
return flow.asSharedFlow() | ||
} | ||
|
||
override suspend fun received(message: JSONObject) { | ||
if (!message.has("type")) return | ||
val type = message.getString("type") | ||
val receivers = receiverFlows.filter { it.key.contains(type) } | ||
Log.d(TAG, "Sending message of type $type to ${receivers.size} receiver(s)") | ||
receivers.forEach { (_, flow) -> | ||
flow.emit(message) | ||
} | ||
} | ||
|
||
override fun getSentFlow(): Flow<ExternalBusMessage> = externalBusFlow.asSharedFlow() | ||
} |