diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index 07a00fb7e8e33a13661fb9b6bc0e4d1dae97b1d7..c2c334bf896a4dfa283a027897fc16dd746d2878 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -483,6 +483,7 @@ android_library { "androidx.compose.material_material-icons-extended", "androidx.activity_activity-compose", "androidx.compose.animation_animation-graphics", + "androidx.lifecycle_lifecycle-viewmodel-compose", "device_policy_aconfig_flags_lib", ], libs: [ @@ -644,6 +645,7 @@ android_library { "androidx.compose.material_material-icons-extended", "androidx.activity_activity-compose", "androidx.compose.animation_animation-graphics", + "androidx.lifecycle_lifecycle-viewmodel-compose", "TraceurCommon", ], } diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 9c58371a387da0651a999546c5bc6dad3b7df236..a9c4399d81abc4c6709d4fcd4ed20fedfe8ccdf4 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -475,6 +475,15 @@ android:exported="false" android:noHistory="true" /> + <activity android:name=".touchpad.tutorial.ui.view.TouchpadTutorialActivity" + android:exported="true" + android:theme="@style/Theme.AppCompat.NoActionBar"> + <intent-filter> + <action android:name="com.android.systemui.action.TOUCHPAD_TUTORIAL"/> + <category android:name="android.intent.category.DEFAULT"/> + </intent-filter> + </activity> + <service android:name=".screenshot.appclips.AppClipsScreenshotHelperService" android:exported="false" android:singleUser="true" diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java index c2e1e33f5318250d0ad42f98393014601b8cc191..2fbb75ec720a7f09bdebeece06fee821735bfc6b 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java @@ -29,6 +29,7 @@ import com.android.systemui.screenshot.scroll.LongScreenshotActivity; import com.android.systemui.sensorprivacy.SensorUseStartedActivity; import com.android.systemui.settings.brightness.BrightnessDialog; import com.android.systemui.telephony.ui.activity.SwitchToManagedProfileForCallActivity; +import com.android.systemui.touchpad.tutorial.ui.view.TouchpadTutorialActivity; import com.android.systemui.tuner.TunerActivity; import com.android.systemui.usb.UsbAccessoryUriActivity; import com.android.systemui.usb.UsbConfirmActivity; @@ -156,4 +157,10 @@ public abstract class DefaultActivityBinder { @ClassKey(SwitchToManagedProfileForCallActivity.class) public abstract Activity bindSwitchToManagedProfileForCallActivity( SwitchToManagedProfileForCallActivity activity); + + /** Inject into TouchpadTutorialActivity. */ + @Binds + @IntoMap + @ClassKey(TouchpadTutorialActivity.class) + public abstract Activity bindTouchpadTutorialActivity(TouchpadTutorialActivity activity); } diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/GestureViewModelFactory.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/GestureViewModelFactory.kt new file mode 100644 index 0000000000000000000000000000000000000000..504bd5fbcb42df325888ea354a6f010a20e3619e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/GestureViewModelFactory.kt @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.touchpad.tutorial.ui + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider + +sealed class GestureTutorialViewModel : ViewModel() + +class BackGestureTutorialViewModel : GestureTutorialViewModel() + +class HomeGestureTutorialViewModel : GestureTutorialViewModel() + +class GestureViewModelFactory : ViewModelProvider.Factory { + + @Suppress("UNCHECKED_CAST") + override fun <T : ViewModel> create(modelClass: Class<T>): T { + return when (modelClass) { + BackGestureTutorialViewModel::class.java -> BackGestureTutorialViewModel() + HomeGestureTutorialViewModel::class.java -> HomeGestureTutorialViewModel() + else -> error("Unknown ViewModel class: ${modelClass.name}") + } + as T + } +} diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/TouchpadTutorialViewModel.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/TouchpadTutorialViewModel.kt new file mode 100644 index 0000000000000000000000000000000000000000..7669524ee31676c9b05b6494b4ca1655a775e8d6 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/TouchpadTutorialViewModel.kt @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.touchpad.tutorial.ui + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import javax.inject.Inject + +class TouchpadTutorialViewModel : ViewModel() { + + private val _screen = MutableStateFlow(Screen.TUTORIAL_SELECTION) + val screen: StateFlow<Screen> = _screen + + class Factory @Inject constructor() : ViewModelProvider.Factory { + + @Suppress("UNCHECKED_CAST") + override fun <T : ViewModel> create(modelClass: Class<T>): T { + return TouchpadTutorialViewModel() as T + } + } +} + +enum class Screen { + TUTORIAL_SELECTION, + BACK_GESTURE, + HOME_GESTURE, +} diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/TutorialSelectionViewModel.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/TutorialSelectionViewModel.kt new file mode 100644 index 0000000000000000000000000000000000000000..1a8272d8e7e313af0550132d1f3776c84eb1d7e1 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/TutorialSelectionViewModel.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.touchpad.tutorial.ui + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider + +class TutorialSelectionViewModel : ViewModel() + +class TutorialSelectionViewModelFactory : ViewModelProvider.Factory { + + @Suppress("UNCHECKED_CAST") + override fun <T : ViewModel> create(modelClass: Class<T>): T { + return TutorialSelectionViewModel() as T + } +} diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt new file mode 100644 index 0000000000000000000000000000000000000000..09dd909cd9a3f14e4c165542f5d86c08c0f2471b --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.touchpad.tutorial.ui.view + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.lifecycle.Lifecycle.State.STARTED +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.lifecycle.viewmodel.compose.viewModel +import com.android.compose.theme.PlatformTheme +import com.android.systemui.touchpad.tutorial.ui.BackGestureTutorialViewModel +import com.android.systemui.touchpad.tutorial.ui.GestureViewModelFactory +import com.android.systemui.touchpad.tutorial.ui.HomeGestureTutorialViewModel +import com.android.systemui.touchpad.tutorial.ui.Screen.BACK_GESTURE +import com.android.systemui.touchpad.tutorial.ui.Screen.HOME_GESTURE +import com.android.systemui.touchpad.tutorial.ui.Screen.TUTORIAL_SELECTION +import com.android.systemui.touchpad.tutorial.ui.TouchpadTutorialViewModel +import com.android.systemui.touchpad.tutorial.ui.TutorialSelectionViewModel +import com.android.systemui.touchpad.tutorial.ui.TutorialSelectionViewModelFactory +import javax.inject.Inject + +class TouchpadTutorialActivity +@Inject +constructor( + private val viewModelFactory: TouchpadTutorialViewModel.Factory, +) : ComponentActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { PlatformTheme { TouchpadTutorialScreen(viewModelFactory) } } + } +} + +@Composable +fun TouchpadTutorialScreen(viewModelFactory: ViewModelProvider.Factory) { + val vm = viewModel<TouchpadTutorialViewModel>(factory = viewModelFactory) + val activeScreen by vm.screen.collectAsStateWithLifecycle(STARTED) + when (activeScreen) { + TUTORIAL_SELECTION -> TutorialSelectionScreen() + BACK_GESTURE -> BackGestureTutorialScreen() + HOME_GESTURE -> HomeGestureTutorialScreen() + } +} + +@Composable +fun TutorialSelectionScreen() { + val vm = viewModel<TutorialSelectionViewModel>(factory = TutorialSelectionViewModelFactory()) +} + +@Composable +fun BackGestureTutorialScreen() { + val vm = viewModel<BackGestureTutorialViewModel>(factory = GestureViewModelFactory()) +} + +@Composable +fun HomeGestureTutorialScreen() { + val vm = viewModel<HomeGestureTutorialViewModel>(factory = GestureViewModelFactory()) +}