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.customization.picker.clock.data.repository
17 
18 import android.app.NotificationManager
19 import android.content.ComponentName
20 import android.content.Context
21 import android.view.LayoutInflater
22 import com.android.systemui.plugins.Plugin
23 import com.android.systemui.plugins.PluginManager
24 import com.android.systemui.shared.clocks.ClockRegistry
25 import com.android.systemui.shared.clocks.DefaultClockProvider
26 import com.android.systemui.shared.plugins.PluginActionManager
27 import com.android.systemui.shared.plugins.PluginEnabler
28 import com.android.systemui.shared.plugins.PluginInstance
29 import com.android.systemui.shared.plugins.PluginManagerImpl
30 import com.android.systemui.shared.plugins.PluginPrefs
31 import com.android.systemui.shared.system.UncaughtExceptionPreHandlerManager_Factory
32 import com.android.wallpaper.module.InjectorProvider
33 import java.util.concurrent.Executors
34 import kotlinx.coroutines.CoroutineDispatcher
35 import kotlinx.coroutines.CoroutineScope
36 
37 /**
38  * Provide the [ClockRegistry] singleton. Note that we need to make sure that the [PluginManager]
39  * needs to be connected before [ClockRegistry] is ready to use.
40  */
41 class ClockRegistryProvider(
42     private val context: Context,
43     private val coroutineScope: CoroutineScope,
44     private val mainDispatcher: CoroutineDispatcher,
45     private val backgroundDispatcher: CoroutineDispatcher,
46 ) {
<lambda>null47     private val clockRegistry: ClockRegistry by lazy {
48         ClockRegistry(
49             context,
50             createPluginManager(context),
51             coroutineScope,
52             mainDispatcher,
53             backgroundDispatcher,
54             isEnabled = true,
55             handleAllUsers = false,
56             DefaultClockProvider(context, LayoutInflater.from(context), context.resources),
57             keepAllLoaded = true,
58             subTag = "Picker",
59             isTransitClockEnabled =
60                 InjectorProvider.getInjector().getFlags().isTransitClockEnabled(context)
61         )
62     }
63 
64     init {
65         // Listeners in ClockRegistry get cleaned up when app ended
66         clockRegistry.registerListeners()
67     }
68 
getnull69     fun get() = clockRegistry
70 
71     private fun createPluginManager(context: Context): PluginManager {
72         val privilegedPlugins = listOf<String>()
73         val isDebugDevice = true
74 
75         val instanceFactory =
76             PluginInstance.Factory(
77                 this::class.java.classLoader,
78                 PluginInstance.InstanceFactory<Plugin>(),
79                 PluginInstance.VersionCheckerImpl(),
80                 privilegedPlugins,
81                 isDebugDevice,
82             )
83 
84         /*
85          * let SystemUI handle plugin, in this class assume plugins are enabled
86          */
87         val pluginEnabler =
88             object : PluginEnabler {
89                 override fun setEnabled(component: ComponentName) = Unit
90 
91                 override fun setDisabled(
92                     component: ComponentName,
93                     @PluginEnabler.DisableReason reason: Int
94                 ) = Unit
95 
96                 override fun isEnabled(component: ComponentName): Boolean {
97                     return true
98                 }
99 
100                 @PluginEnabler.DisableReason
101                 override fun getDisableReason(componentName: ComponentName): Int {
102                     return PluginEnabler.ENABLED
103                 }
104             }
105 
106         val pluginActionManager =
107             PluginActionManager.Factory(
108                 context,
109                 context.packageManager,
110                 context.mainExecutor,
111                 Executors.newSingleThreadExecutor(),
112                 context.getSystemService(NotificationManager::class.java),
113                 pluginEnabler,
114                 privilegedPlugins,
115                 instanceFactory,
116             )
117         return PluginManagerImpl(
118             context,
119             pluginActionManager,
120             isDebugDevice,
121             UncaughtExceptionPreHandlerManager_Factory.create().get(),
122             pluginEnabler,
123             PluginPrefs(context),
124             listOf(),
125         )
126     }
127 }
128