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 
17 package com.android.egg.landroid
18 
19 import android.service.dreams.DreamService
20 import androidx.compose.foundation.layout.fillMaxSize
21 import androidx.compose.runtime.mutableStateOf
22 import androidx.compose.ui.Modifier
23 import androidx.compose.ui.platform.ComposeView
24 import androidx.lifecycle.Lifecycle
25 import androidx.lifecycle.LifecycleRegistry
26 import androidx.lifecycle.setViewTreeLifecycleOwner
27 import androidx.savedstate.SavedStateRegistryController
28 import androidx.savedstate.SavedStateRegistryOwner
29 import androidx.savedstate.setViewTreeSavedStateRegistryOwner
30 import androidx.window.layout.FoldingFeature
31 import kotlin.random.Random
32 
33 class DreamUniverse : DreamService() {
34     private var foldState = mutableStateOf<FoldingFeature?>(null) // unused
35 
36     private val lifecycleOwner =
37         object : SavedStateRegistryOwner {
38             override val lifecycle = LifecycleRegistry(this)
39             override val savedStateRegistry
40                 get() = savedStateRegistryController.savedStateRegistry
41 
42             private val savedStateRegistryController =
<lambda>null43                 SavedStateRegistryController.create(this).apply { performAttach() }
44 
onCreatenull45             fun onCreate() {
46                 savedStateRegistryController.performRestore(null)
47                 lifecycle.currentState = Lifecycle.State.CREATED
48             }
49 
onStartnull50             fun onStart() {
51                 lifecycle.currentState = Lifecycle.State.STARTED
52             }
53 
onStopnull54             fun onStop() {
55                 lifecycle.currentState = Lifecycle.State.CREATED
56             }
57         }
58 
onAttachedToWindownull59     override fun onAttachedToWindow() {
60         super.onAttachedToWindow()
61 
62         val universe = VisibleUniverse(namer = Namer(resources), randomSeed = randomSeed())
63 
64         isInteractive = false
65 
66         if (TEST_UNIVERSE) {
67             universe.initTest()
68         } else {
69             universe.initRandom()
70 
71             // We actually don't want the deterministic random position of the ship, we want
72             // true randomness to keep things interesting. So use Random (not universe.rng).
73             universe.ship.pos =
74                 universe.star.pos +
75                     Vec2.makeWithAngleMag(
76                         Random.nextFloat() * PI2f,
77                         Random.nextFloatInRange(
78                             PLANET_ORBIT_RANGE.start,
79                             PLANET_ORBIT_RANGE.endInclusive
80                         )
81                     )
82         }
83 
84         // enable autopilot in screensaver mode
85         val autopilot = Autopilot(universe.ship, universe)
86         universe.ship.autopilot = autopilot
87         universe.add(autopilot)
88         autopilot.enabled = true
89 
90         // much more visually interesting in a screensaver context
91         DYNAMIC_ZOOM = true
92 
93         val composeView = ComposeView(this)
94         composeView.setContent {
95             Spaaaace(modifier = Modifier.fillMaxSize(), u = universe, foldState = foldState)
96             DebugText(DEBUG_TEXT)
97             Telemetry(universe)
98         }
99 
100         composeView.setViewTreeLifecycleOwner(lifecycleOwner)
101         composeView.setViewTreeSavedStateRegistryOwner(lifecycleOwner)
102 
103         setContentView(composeView)
104     }
105 
onCreatenull106     override fun onCreate() {
107         super.onCreate()
108         lifecycleOwner.onCreate()
109     }
110 
onDreamingStartednull111     override fun onDreamingStarted() {
112         super.onDreamingStarted()
113         lifecycleOwner.onStart()
114     }
115 
onDreamingStoppednull116     override fun onDreamingStopped() {
117         super.onDreamingStopped()
118         lifecycleOwner.onStop()
119     }
120 }
121