Loading packages/SystemUI/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserActionHandler.kt→packages/SystemUI/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandler.kt +17 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.qs.tiles.base.actions import android.app.PendingIntent import android.content.Intent import android.view.View import com.android.internal.jank.InteractionJankMonitor Loading @@ -29,7 +30,7 @@ import javax.inject.Inject * dismissing and tile from-view animations. */ @SysUISingleton class QSTileIntentUserActionHandler class QSTileIntentUserInputHandler @Inject constructor(private val activityStarter: ActivityStarter) { Loading @@ -43,4 +44,19 @@ constructor(private val activityStarter: ActivityStarter) { } activityStarter.postStartActivityDismissingKeyguard(intent, 0, animationController) } // TODO(b/249804373): make sure to allow showing activities over the lockscreen. See b/292112939 fun handle(view: View?, pendingIntent: PendingIntent) { if (!pendingIntent.isActivity) { return } val animationController: ActivityLaunchAnimator.Controller? = view?.let { ActivityLaunchAnimator.Controller.fromView( it, InteractionJankMonitor.CUJ_SHADE_APP_LAUNCH_FROM_QS_TILE, ) } activityStarter.postStartActivityDismissingKeyguard(pendingIntent, animationController) } } packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/StateUpdateTrigger.kt→packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/DataUpdateTrigger.kt +13 −7 Original line number Diff line number Diff line Loading @@ -16,12 +16,18 @@ package com.android.systemui.qs.tiles.base.interactor import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction /** Event that triggers data update */ sealed interface DataUpdateTrigger { /** * State update is requested in a response to a user action. * - [action] is the action that happened * - [tileData] is the data state of the tile when that action took place */ class UserInput<T>(val input: QSTileInput<T>) : DataUpdateTrigger /** Force update current state. This is passed when the view needs a new state to show */ data object ForceUpdate : DataUpdateTrigger sealed interface StateUpdateTrigger { class UserAction<T>(val action: QSTileUserAction, val tileState: QSTileState, val tileData: T) : StateUpdateTrigger data object ForceUpdate : StateUpdateTrigger data object InitialRequest : StateUpdateTrigger /** The data is requested loaded for the first time */ data object InitialRequest : DataUpdateTrigger } packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataInteractor.kt +12 −7 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ 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 Loading @@ -29,14 +28,20 @@ import kotlinx.coroutines.flow.Flow 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. * Returns a data flow scoped to the user. This means the subscription will live when the tile * is listened for the [userId]. It's cancelled when the tile is not listened or the user * changes. * * You can use [Flow.onStart] on the returned to update the tile with the current state as soon * as possible. */ fun tileData(qsTileDataRequest: QSTileDataRequest): Flow<DATA_TYPE> fun tileData(userId: Int, triggers: Flow<DataUpdateTrigger>): 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. * Returns tile availability - whether this device currently supports this tile. * * You can use [Flow.onStart] on the returned to update the tile with the current state as soon * as possible. */ fun availability(): Flow<Boolean> fun availability(userId: Int): Flow<Boolean> } packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataRequest.kt→packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileInput.kt +6 −2 Original line number Diff line number Diff line Loading @@ -16,7 +16,11 @@ package com.android.systemui.qs.tiles.base.interactor data class QSTileDataRequest( import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction /** @see QSTileUserActionInteractor.handleInput */ data class QSTileInput<T>( val userId: Int, val trigger: StateUpdateTrigger, val action: QSTileUserAction, val data: T, ) packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt +6 −5 Original line number Diff line number Diff line Loading @@ -17,13 +17,14 @@ 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. * Processes user input based on [QSTileInput.userId], [QSTileInput.action], and * [QSTileInput.data]. It's guaranteed that [QSTileInput.userId] is the same as the id passed to * [QSTileDataInteractor] to get [QSTileInput.data]. * * It's safe to run long running computations inside this function in this. */ @WorkerThread suspend fun handleInput(userAction: QSTileUserAction, currentData: DATA_TYPE) @WorkerThread suspend fun handleInput(input: QSTileInput<DATA_TYPE>) } Loading
packages/SystemUI/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserActionHandler.kt→packages/SystemUI/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandler.kt +17 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.qs.tiles.base.actions import android.app.PendingIntent import android.content.Intent import android.view.View import com.android.internal.jank.InteractionJankMonitor Loading @@ -29,7 +30,7 @@ import javax.inject.Inject * dismissing and tile from-view animations. */ @SysUISingleton class QSTileIntentUserActionHandler class QSTileIntentUserInputHandler @Inject constructor(private val activityStarter: ActivityStarter) { Loading @@ -43,4 +44,19 @@ constructor(private val activityStarter: ActivityStarter) { } activityStarter.postStartActivityDismissingKeyguard(intent, 0, animationController) } // TODO(b/249804373): make sure to allow showing activities over the lockscreen. See b/292112939 fun handle(view: View?, pendingIntent: PendingIntent) { if (!pendingIntent.isActivity) { return } val animationController: ActivityLaunchAnimator.Controller? = view?.let { ActivityLaunchAnimator.Controller.fromView( it, InteractionJankMonitor.CUJ_SHADE_APP_LAUNCH_FROM_QS_TILE, ) } activityStarter.postStartActivityDismissingKeyguard(pendingIntent, animationController) } }
packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/StateUpdateTrigger.kt→packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/DataUpdateTrigger.kt +13 −7 Original line number Diff line number Diff line Loading @@ -16,12 +16,18 @@ package com.android.systemui.qs.tiles.base.interactor import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction /** Event that triggers data update */ sealed interface DataUpdateTrigger { /** * State update is requested in a response to a user action. * - [action] is the action that happened * - [tileData] is the data state of the tile when that action took place */ class UserInput<T>(val input: QSTileInput<T>) : DataUpdateTrigger /** Force update current state. This is passed when the view needs a new state to show */ data object ForceUpdate : DataUpdateTrigger sealed interface StateUpdateTrigger { class UserAction<T>(val action: QSTileUserAction, val tileState: QSTileState, val tileData: T) : StateUpdateTrigger data object ForceUpdate : StateUpdateTrigger data object InitialRequest : StateUpdateTrigger /** The data is requested loaded for the first time */ data object InitialRequest : DataUpdateTrigger }
packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataInteractor.kt +12 −7 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ 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 Loading @@ -29,14 +28,20 @@ import kotlinx.coroutines.flow.Flow 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. * Returns a data flow scoped to the user. This means the subscription will live when the tile * is listened for the [userId]. It's cancelled when the tile is not listened or the user * changes. * * You can use [Flow.onStart] on the returned to update the tile with the current state as soon * as possible. */ fun tileData(qsTileDataRequest: QSTileDataRequest): Flow<DATA_TYPE> fun tileData(userId: Int, triggers: Flow<DataUpdateTrigger>): 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. * Returns tile availability - whether this device currently supports this tile. * * You can use [Flow.onStart] on the returned to update the tile with the current state as soon * as possible. */ fun availability(): Flow<Boolean> fun availability(userId: Int): Flow<Boolean> }
packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataRequest.kt→packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileInput.kt +6 −2 Original line number Diff line number Diff line Loading @@ -16,7 +16,11 @@ package com.android.systemui.qs.tiles.base.interactor data class QSTileDataRequest( import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction /** @see QSTileUserActionInteractor.handleInput */ data class QSTileInput<T>( val userId: Int, val trigger: StateUpdateTrigger, val action: QSTileUserAction, val data: T, )
packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt +6 −5 Original line number Diff line number Diff line Loading @@ -17,13 +17,14 @@ 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. * Processes user input based on [QSTileInput.userId], [QSTileInput.action], and * [QSTileInput.data]. It's guaranteed that [QSTileInput.userId] is the same as the id passed to * [QSTileDataInteractor] to get [QSTileInput.data]. * * It's safe to run long running computations inside this function in this. */ @WorkerThread suspend fun handleInput(userAction: QSTileUserAction, currentData: DATA_TYPE) @WorkerThread suspend fun handleInput(input: QSTileInput<DATA_TYPE>) }