1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use mHost file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */
14 
15 package com.android.systemui.statusbar.policy
16 
17 import android.hardware.SensorPrivacyManager.Sensors.CAMERA
18 import android.hardware.SensorPrivacyManager.Sensors.MICROPHONE
19 import android.os.UserManager.DISALLOW_CAMERA_TOGGLE
20 import android.os.UserManager.DISALLOW_CONFIG_LOCATION
21 import android.os.UserManager.DISALLOW_MICROPHONE_TOGGLE
22 import android.os.UserManager.DISALLOW_SHARE_LOCATION
23 import com.android.systemui.qs.QsEventLogger
24 import com.android.systemui.qs.pipeline.shared.TileSpec
25 import com.android.systemui.qs.tileimpl.QSTileImpl
26 import com.android.systemui.qs.tiles.AlarmTile
27 import com.android.systemui.qs.tiles.CameraToggleTile
28 import com.android.systemui.qs.tiles.DndTile
29 import com.android.systemui.qs.tiles.FlashlightTile
30 import com.android.systemui.qs.tiles.LocationTile
31 import com.android.systemui.qs.tiles.MicrophoneToggleTile
32 import com.android.systemui.qs.tiles.UiModeNightTile
33 import com.android.systemui.qs.tiles.WorkModeTile
34 import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
35 import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory
36 import com.android.systemui.qs.tiles.impl.alarm.domain.AlarmTileMapper
37 import com.android.systemui.qs.tiles.impl.alarm.domain.interactor.AlarmTileDataInteractor
38 import com.android.systemui.qs.tiles.impl.alarm.domain.interactor.AlarmTileUserActionInteractor
39 import com.android.systemui.qs.tiles.impl.alarm.domain.model.AlarmTileModel
40 import com.android.systemui.qs.tiles.impl.flashlight.domain.FlashlightMapper
41 import com.android.systemui.qs.tiles.impl.flashlight.domain.interactor.FlashlightTileDataInteractor
42 import com.android.systemui.qs.tiles.impl.flashlight.domain.interactor.FlashlightTileUserActionInteractor
43 import com.android.systemui.qs.tiles.impl.flashlight.domain.model.FlashlightTileModel
44 import com.android.systemui.qs.tiles.impl.location.domain.LocationTileMapper
45 import com.android.systemui.qs.tiles.impl.location.domain.interactor.LocationTileDataInteractor
46 import com.android.systemui.qs.tiles.impl.location.domain.interactor.LocationTileUserActionInteractor
47 import com.android.systemui.qs.tiles.impl.location.domain.model.LocationTileModel
48 import com.android.systemui.qs.tiles.impl.sensorprivacy.SensorPrivacyToggleTileDataInteractor
49 import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.SensorPrivacyToggleTileUserActionInteractor
50 import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model.SensorPrivacyToggleTileModel
51 import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.SensorPrivacyTileResources
52 import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.SensorPrivacyToggleTileMapper
53 import com.android.systemui.qs.tiles.impl.uimodenight.domain.UiModeNightTileMapper
54 import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.UiModeNightTileDataInteractor
55 import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.UiModeNightTileUserActionInteractor
56 import com.android.systemui.qs.tiles.impl.uimodenight.domain.model.UiModeNightTileModel
57 import com.android.systemui.qs.tiles.impl.work.domain.interactor.WorkModeTileDataInteractor
58 import com.android.systemui.qs.tiles.impl.work.domain.interactor.WorkModeTileUserActionInteractor
59 import com.android.systemui.qs.tiles.impl.work.domain.model.WorkModeTileModel
60 import com.android.systemui.qs.tiles.impl.work.ui.WorkModeTileMapper
61 import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
62 import com.android.systemui.qs.tiles.viewmodel.QSTilePolicy
63 import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
64 import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
65 import com.android.systemui.res.R
66 import dagger.Binds
67 import dagger.Module
68 import dagger.Provides
69 import dagger.multibindings.IntoMap
70 import dagger.multibindings.StringKey
71 
72 @Module
73 interface PolicyModule {
74 
75     /** Inject DndTile into tileMap in QSModule */
bindDndTilenull76     @Binds @IntoMap @StringKey(DndTile.TILE_SPEC) fun bindDndTile(dndTile: DndTile): QSTileImpl<*>
77 
78     /** Inject WorkModeTile into tileMap in QSModule */
79     @Binds
80     @IntoMap
81     @StringKey(WorkModeTile.TILE_SPEC)
82     fun bindWorkModeTile(workModeTile: WorkModeTile): QSTileImpl<*>
83 
84     @Binds
85     @IntoMap
86     @StringKey(FLASHLIGHT_TILE_SPEC)
87     fun provideAirplaneModeAvailabilityInteractor(
88             impl: FlashlightTileDataInteractor
89     ): QSTileAvailabilityInteractor
90 
91     @Binds
92     @IntoMap
93     @StringKey(LOCATION_TILE_SPEC)
94     fun provideLocationAvailabilityInteractor(
95             impl: LocationTileDataInteractor
96     ): QSTileAvailabilityInteractor
97 
98     @Binds
99     @IntoMap
100     @StringKey(ALARM_TILE_SPEC)
101     fun provideAlarmAvailabilityInteractor(
102             impl: AlarmTileDataInteractor
103     ): QSTileAvailabilityInteractor
104 
105     @Binds
106     @IntoMap
107     @StringKey(UIMODENIGHT_TILE_SPEC)
108     fun provideUiModeNightAvailabilityInteractor(
109             impl: UiModeNightTileDataInteractor
110     ): QSTileAvailabilityInteractor
111 
112     @Binds
113     @IntoMap
114     @StringKey(WORK_MODE_TILE_SPEC)
115     fun provideWorkModeAvailabilityInteractor(
116             impl: WorkModeTileDataInteractor
117     ): QSTileAvailabilityInteractor
118 
119     companion object {
120         const val FLASHLIGHT_TILE_SPEC = "flashlight"
121         const val LOCATION_TILE_SPEC = "location"
122         const val ALARM_TILE_SPEC = "alarm"
123         const val UIMODENIGHT_TILE_SPEC = "dark"
124         const val WORK_MODE_TILE_SPEC = "work"
125         const val CAMERA_TOGGLE_TILE_SPEC = "cameratoggle"
126         const val MIC_TOGGLE_TILE_SPEC = "mictoggle"
127         const val DND_TILE_SPEC = "dnd"
128 
129         /** Inject flashlight config */
130         @Provides
131         @IntoMap
132         @StringKey(FLASHLIGHT_TILE_SPEC)
133         fun provideFlashlightTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
134             QSTileConfig(
135                 tileSpec = TileSpec.create(FLASHLIGHT_TILE_SPEC),
136                 uiConfig =
137                     QSTileUIConfig.Resource(
138                         iconRes = R.drawable.qs_flashlight_icon_off,
139                         labelRes = R.string.quick_settings_flashlight_label,
140                     ),
141                 instanceId = uiEventLogger.getNewInstanceId(),
142             )
143 
144         /** Inject FlashlightTile into tileViewModelMap in QSModule */
145         @Provides
146         @IntoMap
147         @StringKey(FLASHLIGHT_TILE_SPEC)
148         fun provideFlashlightTileViewModel(
149             factory: QSTileViewModelFactory.Static<FlashlightTileModel>,
150             mapper: FlashlightMapper,
151             stateInteractor: FlashlightTileDataInteractor,
152             userActionInteractor: FlashlightTileUserActionInteractor
153         ): QSTileViewModel =
154             factory.create(
155                 TileSpec.create(FLASHLIGHT_TILE_SPEC),
156                 userActionInteractor,
157                 stateInteractor,
158                 mapper,
159             )
160 
161         /** Inject location config */
162         @Provides
163         @IntoMap
164         @StringKey(LOCATION_TILE_SPEC)
165         fun provideLocationTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
166             QSTileConfig(
167                 tileSpec = TileSpec.create(LOCATION_TILE_SPEC),
168                 uiConfig =
169                     QSTileUIConfig.Resource(
170                         iconRes = R.drawable.qs_location_icon_off,
171                         labelRes = R.string.quick_settings_location_label,
172                     ),
173                 instanceId = uiEventLogger.getNewInstanceId(),
174                 policy =
175                     QSTilePolicy.Restricted(
176                         listOf(DISALLOW_SHARE_LOCATION, DISALLOW_CONFIG_LOCATION)
177                     )
178             )
179 
180         /** Inject LocationTile into tileViewModelMap in QSModule */
181         @Provides
182         @IntoMap
183         @StringKey(LOCATION_TILE_SPEC)
184         fun provideLocationTileViewModel(
185             factory: QSTileViewModelFactory.Static<LocationTileModel>,
186             mapper: LocationTileMapper,
187             stateInteractor: LocationTileDataInteractor,
188             userActionInteractor: LocationTileUserActionInteractor
189         ): QSTileViewModel =
190             factory.create(
191                 TileSpec.create(LOCATION_TILE_SPEC),
192                 userActionInteractor,
193                 stateInteractor,
194                 mapper,
195             )
196 
197         /** Inject alarm config */
198         @Provides
199         @IntoMap
200         @StringKey(ALARM_TILE_SPEC)
201         fun provideAlarmTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
202             QSTileConfig(
203                 tileSpec = TileSpec.create(ALARM_TILE_SPEC),
204                 uiConfig =
205                     QSTileUIConfig.Resource(
206                         iconRes = R.drawable.ic_alarm,
207                         labelRes = R.string.status_bar_alarm,
208                     ),
209                 instanceId = uiEventLogger.getNewInstanceId(),
210             )
211 
212         /** Inject AlarmTile into tileViewModelMap in QSModule */
213         @Provides
214         @IntoMap
215         @StringKey(ALARM_TILE_SPEC)
216         fun provideAlarmTileViewModel(
217             factory: QSTileViewModelFactory.Static<AlarmTileModel>,
218             mapper: AlarmTileMapper,
219             stateInteractor: AlarmTileDataInteractor,
220             userActionInteractor: AlarmTileUserActionInteractor
221         ): QSTileViewModel =
222             factory.create(
223                 TileSpec.create(ALARM_TILE_SPEC),
224                 userActionInteractor,
225                 stateInteractor,
226                 mapper,
227             )
228 
229         /** Inject uimodenight config */
230         @Provides
231         @IntoMap
232         @StringKey(UIMODENIGHT_TILE_SPEC)
233         fun provideUiModeNightTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
234             QSTileConfig(
235                 tileSpec = TileSpec.create(UIMODENIGHT_TILE_SPEC),
236                 uiConfig =
237                     QSTileUIConfig.Resource(
238                         iconRes = R.drawable.qs_light_dark_theme_icon_off,
239                         labelRes = R.string.quick_settings_ui_mode_night_label,
240                     ),
241                 instanceId = uiEventLogger.getNewInstanceId(),
242             )
243 
244         /** Inject uimodenight into tileViewModelMap in QSModule */
245         @Provides
246         @IntoMap
247         @StringKey(UIMODENIGHT_TILE_SPEC)
248         fun provideUiModeNightTileViewModel(
249             factory: QSTileViewModelFactory.Static<UiModeNightTileModel>,
250             mapper: UiModeNightTileMapper,
251             stateInteractor: UiModeNightTileDataInteractor,
252             userActionInteractor: UiModeNightTileUserActionInteractor
253         ): QSTileViewModel =
254             factory.create(
255                 TileSpec.create(UIMODENIGHT_TILE_SPEC),
256                 userActionInteractor,
257                 stateInteractor,
258                 mapper,
259             )
260 
261         /** Inject work mode tile config */
262         @Provides
263         @IntoMap
264         @StringKey(WORK_MODE_TILE_SPEC)
265         fun provideWorkModeTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
266             QSTileConfig(
267                 tileSpec = TileSpec.create(WORK_MODE_TILE_SPEC),
268                 uiConfig =
269                     QSTileUIConfig.Resource(
270                         iconRes = com.android.internal.R.drawable.stat_sys_managed_profile_status,
271                         labelRes = R.string.quick_settings_work_mode_label,
272                     ),
273                 instanceId = uiEventLogger.getNewInstanceId(),
274             )
275 
276         /** Inject work mode into tileViewModelMap in QSModule */
277         @Provides
278         @IntoMap
279         @StringKey(WORK_MODE_TILE_SPEC)
280         fun provideWorkModeTileViewModel(
281             factory: QSTileViewModelFactory.Static<WorkModeTileModel>,
282             mapper: WorkModeTileMapper,
283             stateInteractor: WorkModeTileDataInteractor,
284             userActionInteractor: WorkModeTileUserActionInteractor
285         ): QSTileViewModel =
286             factory.create(
287                 TileSpec.create(WORK_MODE_TILE_SPEC),
288                 userActionInteractor,
289                 stateInteractor,
290                 mapper,
291             )
292 
293         /** Inject camera toggle config */
294         @Provides
295         @IntoMap
296         @StringKey(CAMERA_TOGGLE_TILE_SPEC)
297         fun provideCameraToggleTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
298             QSTileConfig(
299                 tileSpec = TileSpec.create(CAMERA_TOGGLE_TILE_SPEC),
300                 uiConfig =
301                     QSTileUIConfig.Resource(
302                         iconRes = R.drawable.qs_camera_access_icon_off,
303                         labelRes = R.string.quick_settings_camera_label,
304                     ),
305                 instanceId = uiEventLogger.getNewInstanceId(),
306                 policy = QSTilePolicy.Restricted(listOf(DISALLOW_CAMERA_TOGGLE)),
307             )
308 
309         /** Inject camera toggle tile into tileViewModelMap in QSModule */
310         @Provides
311         @IntoMap
312         @StringKey(CAMERA_TOGGLE_TILE_SPEC)
313         fun provideCameraToggleTileViewModel(
314             factory: QSTileViewModelFactory.Static<SensorPrivacyToggleTileModel>,
315             mapper: SensorPrivacyToggleTileMapper.Factory,
316             stateInteractor: SensorPrivacyToggleTileDataInteractor.Factory,
317             userActionInteractor: SensorPrivacyToggleTileUserActionInteractor.Factory,
318         ): QSTileViewModel =
319             factory.create(
320                 TileSpec.create(CAMERA_TOGGLE_TILE_SPEC),
321                 userActionInteractor.create(CAMERA),
322                 stateInteractor.create(CAMERA),
323                 mapper.create(SensorPrivacyTileResources.CameraPrivacyTileResources),
324             )
325 
326         @Provides
327         @IntoMap
328         @StringKey(CAMERA_TOGGLE_TILE_SPEC)
329         fun provideCameraToggleAvailabilityInteractor(
330                 factory: SensorPrivacyToggleTileDataInteractor.Factory
331         ): QSTileAvailabilityInteractor {
332             return factory.create(CAMERA)
333         }
334 
335         /** Inject microphone toggle config */
336         @Provides
337         @IntoMap
338         @StringKey(MIC_TOGGLE_TILE_SPEC)
339         fun provideMicrophoneToggleTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
340             QSTileConfig(
341                 tileSpec = TileSpec.create(MIC_TOGGLE_TILE_SPEC),
342                 uiConfig =
343                     QSTileUIConfig.Resource(
344                         iconRes = R.drawable.qs_mic_access_off,
345                         labelRes = R.string.quick_settings_mic_label,
346                     ),
347                 instanceId = uiEventLogger.getNewInstanceId(),
348                 policy = QSTilePolicy.Restricted(listOf(DISALLOW_MICROPHONE_TOGGLE)),
349             )
350 
351         /** Inject microphone toggle tile into tileViewModelMap in QSModule */
352         @Provides
353         @IntoMap
354         @StringKey(MIC_TOGGLE_TILE_SPEC)
355         fun provideMicrophoneToggleTileViewModel(
356             factory: QSTileViewModelFactory.Static<SensorPrivacyToggleTileModel>,
357             mapper: SensorPrivacyToggleTileMapper.Factory,
358             stateInteractor: SensorPrivacyToggleTileDataInteractor.Factory,
359             userActionInteractor: SensorPrivacyToggleTileUserActionInteractor.Factory,
360         ): QSTileViewModel =
361             factory.create(
362                 TileSpec.create(MIC_TOGGLE_TILE_SPEC),
363                 userActionInteractor.create(MICROPHONE),
364                 stateInteractor.create(MICROPHONE),
365                 mapper.create(SensorPrivacyTileResources.MicrophonePrivacyTileResources),
366             )
367 
368         @Provides
369         @IntoMap
370         @StringKey(MIC_TOGGLE_TILE_SPEC)
371         fun provideMicToggleModeAvailabilityInteractor(
372                 factory: SensorPrivacyToggleTileDataInteractor.Factory
373         ): QSTileAvailabilityInteractor {
374             return factory.create(MICROPHONE)
375         }
376 
377 
378         /** Inject microphone toggle config */
379         @Provides
380         @IntoMap
381         @StringKey(DND_TILE_SPEC)
382         fun provideDndTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
383             QSTileConfig(
384                 tileSpec = TileSpec.create(DND_TILE_SPEC),
385                 uiConfig =
386                     QSTileUIConfig.Resource(
387                         iconRes = R.drawable.qs_dnd_icon_off,
388                         labelRes = R.string.quick_settings_dnd_label,
389                     ),
390                 instanceId = uiEventLogger.getNewInstanceId(),
391             )
392     }
393 
394     /** Inject FlashlightTile into tileMap in QSModule */
395     @Binds
396     @IntoMap
397     @StringKey(FlashlightTile.TILE_SPEC)
bindFlashlightTilenull398     fun bindFlashlightTile(flashlightTile: FlashlightTile): QSTileImpl<*>
399 
400     /** Inject LocationTile into tileMap in QSModule */
401     @Binds
402     @IntoMap
403     @StringKey(LocationTile.TILE_SPEC)
404     fun bindLocationTile(locationTile: LocationTile): QSTileImpl<*>
405 
406     /** Inject CameraToggleTile into tileMap in QSModule */
407     @Binds
408     @IntoMap
409     @StringKey(CameraToggleTile.TILE_SPEC)
410     fun bindCameraToggleTile(cameraToggleTile: CameraToggleTile): QSTileImpl<*>
411 
412     /** Inject MicrophoneToggleTile into tileMap in QSModule */
413     @Binds
414     @IntoMap
415     @StringKey(MicrophoneToggleTile.TILE_SPEC)
416     fun bindMicrophoneToggleTile(microphoneToggleTile: MicrophoneToggleTile): QSTileImpl<*>
417 
418     /** Inject AlarmTile into tileMap in QSModule */
419     @Binds
420     @IntoMap
421     @StringKey(AlarmTile.TILE_SPEC)
422     fun bindAlarmTile(alarmTile: AlarmTile): QSTileImpl<*>
423 
424     @Binds
425     @IntoMap
426     @StringKey(UiModeNightTile.TILE_SPEC)
427     fun bindUiModeNightTile(uiModeNightTile: UiModeNightTile): QSTileImpl<*>
428 }
429