• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2024 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 
17 package com.android.systemui.inputdevice.tutorial.ui.composable
18 
19 import androidx.activity.compose.BackHandler
20 import androidx.compose.foundation.focusable
21 import androidx.compose.foundation.layout.Box
22 import androidx.compose.foundation.layout.fillMaxSize
23 import androidx.compose.runtime.Composable
24 import androidx.compose.runtime.LaunchedEffect
25 import androidx.compose.runtime.getValue
26 import androidx.compose.runtime.mutableStateOf
27 import androidx.compose.runtime.remember
28 import androidx.compose.runtime.saveable.rememberSaveable
29 import androidx.compose.runtime.setValue
30 import androidx.compose.ui.Modifier
31 import androidx.compose.ui.focus.FocusRequester
32 import androidx.compose.ui.focus.focusRequester
33 import androidx.compose.ui.input.key.Key
34 import androidx.compose.ui.input.key.KeyEvent
35 import androidx.compose.ui.input.key.KeyEventType
36 import androidx.compose.ui.input.key.key
37 import androidx.compose.ui.input.key.onKeyEvent
38 import androidx.compose.ui.input.key.type
39 import com.airbnb.lottie.compose.rememberLottieDynamicProperties
40 import com.android.compose.theme.LocalAndroidColorScheme
41 import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState.Finished
42 import com.android.systemui.inputdevice.tutorial.ui.composable.TutorialActionState.NotStarted
43 import com.android.systemui.res.R
44 
45 @Composable
46 fun ActionKeyTutorialScreen(onDoneButtonClicked: () -> Unit, onBack: () -> Unit) {
47     BackHandler(onBack = onBack)
48     val screenConfig = buildScreenConfig()
49     var actionState: TutorialActionState by
50         rememberSaveable(stateSaver = TutorialActionState.stateSaver()) {
51             mutableStateOf(NotStarted)
52         }
53     val focusRequester = remember { FocusRequester() }
54     Box(
55         modifier =
56             Modifier.fillMaxSize()
57                 .onKeyEvent { keyEvent: KeyEvent ->
58                     if (keyEvent.key == Key.MetaLeft && keyEvent.type == KeyEventType.KeyUp) {
59                         actionState = Finished(R.raw.action_key_success)
60                     }
61                     true
62                 }
63                 .focusRequester(focusRequester)
64                 .focusable()
65     ) {
66         ActionTutorialContent(actionState, onDoneButtonClicked, screenConfig)
67     }
68     LaunchedEffect(Unit) {
69         // we need to request focus on main container so it can handle all key events immediately
70         // when it's open. Otherwise user needs to press non-modifier key before modifier key can
71         // be handled as nothing is focused
72         focusRequester.requestFocus()
73     }
74 }
75 
76 @Composable
buildScreenConfignull77 private fun buildScreenConfig() =
78     TutorialScreenConfig(
79         colors = rememberScreenColors(),
80         strings =
81             TutorialScreenConfig.Strings(
82                 titleResId = R.string.tutorial_action_key_title,
83                 bodyResId = R.string.tutorial_action_key_guidance,
84                 titleSuccessResId = R.string.tutorial_action_key_success_title,
85                 bodySuccessResId = R.string.tutorial_action_key_success_body,
86                 // error state for action key is not implemented yet so below should never appear
87                 titleErrorResId = R.string.gesture_error_title,
88                 bodyErrorResId = R.string.touchpad_action_key_error_body,
89             ),
90         animations = TutorialScreenConfig.Animations(educationResId = R.raw.action_key_edu),
91     )
92 
93 @Composable
94 private fun rememberScreenColors(): TutorialScreenConfig.Colors {
95     val primaryFixedDim = LocalAndroidColorScheme.current.primaryFixedDim
96     val secondaryFixedDim = LocalAndroidColorScheme.current.secondaryFixedDim
97     val onSecondaryFixed = LocalAndroidColorScheme.current.onSecondaryFixed
98     val onSecondaryFixedVariant = LocalAndroidColorScheme.current.onSecondaryFixedVariant
99     val dynamicProperties =
100         rememberLottieDynamicProperties(
101             rememberColorFilterProperty(".primaryFixedDim", primaryFixedDim),
102             rememberColorFilterProperty(".secondaryFixedDim", secondaryFixedDim),
103             rememberColorFilterProperty(".onSecondaryFixed", onSecondaryFixed),
104             rememberColorFilterProperty(".onSecondaryFixedVariant", onSecondaryFixedVariant),
105         )
106     val screenColors =
107         remember(dynamicProperties) {
108             TutorialScreenConfig.Colors(
109                 background = onSecondaryFixed,
110                 title = secondaryFixedDim,
111                 animationColors = dynamicProperties,
112             )
113         }
114     return screenColors
115 }
116