summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataInteractor.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataRequest.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/StateUpdateTrigger.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileLifecycle.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileUserAction.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt41
9 files changed, 148 insertions, 0 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataInteractor.kt
new file mode 100644
index 000000000000..1a03481b9fca
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataInteractor.kt
@@ -0,0 +1,26 @@
+package com.android.systemui.qs.tiles.base.interactor
+
+import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.flow.Flow
+
+/**
+ * Provides data and availability for the tile. In most cases it would delegate data retrieval to
+ * repository, manager, controller or a combination of those. Avoid doing long running operations in
+ * these methods because there is no background thread guarantee. Use [Flow.flowOn] (typically
+ * with @Background [CoroutineDispatcher]) instead to move the calculations to another thread.
+ */
+interface QSTileDataInteractor<DATA_TYPE> {
+
+ /**
+ * Returns the data to be mapped to [QSTileState]. Make sure to start the flow [Flow.onStart]
+ * with the current state to update the tile as soon as possible.
+ */
+ fun tileData(qsTileDataRequest: QSTileDataRequest): Flow<DATA_TYPE>
+
+ /**
+ * Returns tile availability - whether this device currently supports this tile. Make sure to
+ * start the flow [Flow.onStart] with the current state to update the tile as soon as possible.
+ */
+ fun availability(): Flow<Boolean>
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataRequest.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataRequest.kt
new file mode 100644
index 000000000000..82897044f06c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataRequest.kt
@@ -0,0 +1,6 @@
+package com.android.systemui.qs.tiles.base.interactor
+
+data class QSTileDataRequest(
+ val userId: Int,
+ val trigger: StateUpdateTrigger,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt
new file mode 100644
index 000000000000..8569fc73adb4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt
@@ -0,0 +1,13 @@
+package com.android.systemui.qs.tiles.base.interactor
+
+import android.annotation.WorkerThread
+import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+
+interface QSTileUserActionInteractor<DATA_TYPE> {
+
+ /**
+ * Processes user input based on [userAction] and [currentData]. It's safe to run long running
+ * computations inside this function in this.
+ */
+ @WorkerThread suspend fun handleInput(userAction: QSTileUserAction, currentData: DATA_TYPE)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/StateUpdateTrigger.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/StateUpdateTrigger.kt
new file mode 100644
index 000000000000..ed7ec8e32de4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/StateUpdateTrigger.kt
@@ -0,0 +1,11 @@
+package com.android.systemui.qs.tiles.base.interactor
+
+import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+
+sealed interface StateUpdateTrigger {
+ class UserAction<T>(val action: QSTileUserAction, val tileState: QSTileState, val tileData: T) :
+ StateUpdateTrigger
+ data object ForceUpdate : StateUpdateTrigger
+ data object InitialRequest : StateUpdateTrigger
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt
new file mode 100644
index 000000000000..a5eaac154230
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt
@@ -0,0 +1,14 @@
+package com.android.systemui.qs.tiles.viewmodel
+
+import android.graphics.drawable.Icon
+import com.android.systemui.qs.pipeline.shared.TileSpec
+
+data class QSTileConfig(
+ val tileSpec: TileSpec,
+ val tileIcon: Icon,
+ val tileLabel: CharSequence,
+// TODO(b/299908705): Fill necessary params
+/*
+val instanceId: InstanceId,
+ */
+)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileLifecycle.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileLifecycle.kt
new file mode 100644
index 000000000000..39db7038bfa2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileLifecycle.kt
@@ -0,0 +1,6 @@
+package com.android.systemui.qs.tiles.viewmodel
+
+enum class QSTileLifecycle {
+ ON_CREATE,
+ ON_DESTROY,
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
new file mode 100644
index 000000000000..53f9edfb954c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
@@ -0,0 +1,18 @@
+package com.android.systemui.qs.tiles.viewmodel
+
+import android.graphics.drawable.Icon
+
+data class QSTileState(
+ val icon: Icon,
+ val label: CharSequence,
+// TODO(b/299908705): Fill necessary params
+/*
+ val subtitle: CharSequence = "",
+ val activeState: ActivationState = Active,
+ val enabledState: Enabled = Enabled,
+ val loopIconAnimation: Boolean = false,
+ val secondaryIcon: Icon? = null,
+ val slashState: SlashState? = null,
+ val supportedActions: Collection<UserAction> = listOf(Click), clicks should be a default action
+*/
+)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileUserAction.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileUserAction.kt
new file mode 100644
index 000000000000..f1f8f0152c67
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileUserAction.kt
@@ -0,0 +1,13 @@
+package com.android.systemui.qs.tiles.viewmodel
+
+import android.content.Context
+import android.view.View
+
+sealed interface QSTileUserAction {
+
+ val context: Context
+ val view: View?
+
+ class Click(override val context: Context, override val view: View?) : QSTileUserAction
+ class LongClick(override val context: Context, override val view: View?) : QSTileUserAction
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt
new file mode 100644
index 000000000000..49077f3f310d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt
@@ -0,0 +1,41 @@
+package com.android.systemui.qs.tiles.viewmodel
+
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
+
+/**
+ * Represents tiles behaviour logic. This ViewModel is a connection between tile view and data
+ * layers.
+ */
+interface QSTileViewModel {
+
+ /**
+ * State of the tile to be shown by the view. Favor reactive consumption over the
+ * [StateFlow.value], because there is no guarantee that current value would be available at any
+ * time.
+ */
+ val state: StateFlow<QSTileState>
+
+ val config: QSTileConfig
+
+ val isAvailable: Flow<Boolean>
+
+ /**
+ * Handles ViewModel lifecycle. Implementations should be inactive outside of
+ * [QSTileLifecycle.ON_CREATE] and [QSTileLifecycle.ON_DESTROY] bounds.
+ */
+ fun onLifecycle(lifecycle: QSTileLifecycle)
+
+ /**
+ * Notifies about the user change. Implementations should avoid using 3rd party userId sources
+ * and use this value instead. This is to maintain consistent and concurrency-free behaviour
+ * across different parts of QS.
+ */
+ fun onUserIdChanged(userId: Int)
+
+ /** Triggers emit of the new [QSTileState] in [state]. */
+ fun forceUpdate()
+
+ /** Notifies underlying logic about user input. */
+ fun onActionPerformed(userAction: QSTileUserAction)
+}