• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.systemui.unfold.data.repository
17 
18 import com.android.systemui.unfold.data.repository.FoldStateRepository.FoldUpdate
19 import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_CLOSED
20 import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_FULL_OPEN
21 import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_HALF_OPEN
22 import com.android.systemui.unfold.updates.FOLD_UPDATE_START_CLOSING
23 import com.android.systemui.unfold.updates.FOLD_UPDATE_START_OPENING
24 import com.android.systemui.unfold.updates.FoldStateProvider
25 import javax.inject.Inject
26 import kotlinx.coroutines.channels.Channel
27 import kotlinx.coroutines.channels.awaitClose
28 import kotlinx.coroutines.flow.Flow
29 import kotlinx.coroutines.flow.buffer
30 import kotlinx.coroutines.flow.callbackFlow
31 
32 /**
33  * Allows to subscribe to main events related to fold/unfold process such as hinge angle update,
34  * start folding/unfolding, screen availability
35  */
36 interface FoldStateRepository {
37     /** Latest fold update, as described by [FoldStateProvider.FoldUpdate]. */
38     val foldUpdate: Flow<FoldUpdate>
39 
40     /** Provides the hinge angle while the fold/unfold is in progress. */
41     val hingeAngle: Flow<Float>
42 
43     enum class FoldUpdate {
44         START_OPENING,
45         START_CLOSING,
46         FINISH_HALF_OPEN,
47         FINISH_FULL_OPEN,
48         FINISH_CLOSED;
49 
50         companion object {
51             /** Maps the old [FoldStateProvider.FoldUpdate] to [FoldStateRepository.FoldUpdate]. */
fromFoldUpdateIdnull52             fun fromFoldUpdateId(@FoldStateProvider.FoldUpdate oldId: Int): FoldUpdate {
53                 return when (oldId) {
54                     FOLD_UPDATE_START_OPENING -> START_OPENING
55                     FOLD_UPDATE_START_CLOSING -> START_CLOSING
56                     FOLD_UPDATE_FINISH_HALF_OPEN -> FINISH_HALF_OPEN
57                     FOLD_UPDATE_FINISH_FULL_OPEN -> FINISH_FULL_OPEN
58                     FOLD_UPDATE_FINISH_CLOSED -> FINISH_CLOSED
59                     else -> error("Fold update with id $oldId is not supported")
60                 }
61             }
62         }
63     }
64 }
65 
66 class FoldStateRepositoryImpl
67 @Inject
68 constructor(
69     private val foldStateProvider: FoldStateProvider,
70 ) : FoldStateRepository {
71 
72     override val hingeAngle: Flow<Float>
73         get() =
<lambda>null74             callbackFlow {
75                     val callback =
76                         object : FoldStateProvider.FoldUpdatesListener {
77                             override fun onHingeAngleUpdate(angle: Float) {
78                                 trySend(angle)
79                             }
80                         }
81                     foldStateProvider.addCallback(callback)
82                     awaitClose { foldStateProvider.removeCallback(callback) }
83                 }
84                 .buffer(capacity = Channel.CONFLATED)
85 
86     override val foldUpdate: Flow<FoldUpdate>
87         get() =
<lambda>null88             callbackFlow {
89                     val callback =
90                         object : FoldStateProvider.FoldUpdatesListener {
91                             override fun onFoldUpdate(update: Int) {
92                                 trySend(FoldUpdate.fromFoldUpdateId(update))
93                             }
94                         }
95                     foldStateProvider.addCallback(callback)
96                     awaitClose { foldStateProvider.removeCallback(callback) }
97                 }
98                 .buffer(capacity = Channel.CONFLATED)
99 }
100