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.systemui.accessibility.qs
18 
19 import com.android.systemui.Flags
20 import com.android.systemui.qs.QsEventLogger
21 import com.android.systemui.qs.pipeline.shared.TileSpec
22 import com.android.systemui.qs.shared.model.TileCategory
23 import com.android.systemui.qs.tileimpl.QSTileImpl
24 import com.android.systemui.qs.tiles.ColorCorrectionTile
25 import com.android.systemui.qs.tiles.ColorInversionTile
26 import com.android.systemui.qs.tiles.DreamTile
27 import com.android.systemui.qs.tiles.FontScalingTile
28 import com.android.systemui.qs.tiles.HearingDevicesTile
29 import com.android.systemui.qs.tiles.NightDisplayTile
30 import com.android.systemui.qs.tiles.OneHandedModeTile
31 import com.android.systemui.qs.tiles.ReduceBrightColorsTile
32 import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
33 import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory
34 import com.android.systemui.qs.tiles.impl.colorcorrection.domain.ColorCorrectionTileMapper
35 import com.android.systemui.qs.tiles.impl.colorcorrection.domain.interactor.ColorCorrectionTileDataInteractor
36 import com.android.systemui.qs.tiles.impl.colorcorrection.domain.interactor.ColorCorrectionUserActionInteractor
37 import com.android.systemui.qs.tiles.impl.colorcorrection.domain.model.ColorCorrectionTileModel
38 import com.android.systemui.qs.tiles.impl.fontscaling.domain.FontScalingTileMapper
39 import com.android.systemui.qs.tiles.impl.fontscaling.domain.interactor.FontScalingTileDataInteractor
40 import com.android.systemui.qs.tiles.impl.fontscaling.domain.interactor.FontScalingTileUserActionInteractor
41 import com.android.systemui.qs.tiles.impl.fontscaling.domain.model.FontScalingTileModel
42 import com.android.systemui.qs.tiles.impl.hearingdevices.domain.HearingDevicesTileMapper
43 import com.android.systemui.qs.tiles.impl.hearingdevices.domain.interactor.HearingDevicesTileDataInteractor
44 import com.android.systemui.qs.tiles.impl.hearingdevices.domain.interactor.HearingDevicesTileUserActionInteractor
45 import com.android.systemui.qs.tiles.impl.hearingdevices.domain.model.HearingDevicesTileModel
46 import com.android.systemui.qs.tiles.impl.inversion.domain.ColorInversionTileMapper
47 import com.android.systemui.qs.tiles.impl.inversion.domain.interactor.ColorInversionTileDataInteractor
48 import com.android.systemui.qs.tiles.impl.inversion.domain.interactor.ColorInversionUserActionInteractor
49 import com.android.systemui.qs.tiles.impl.inversion.domain.model.ColorInversionTileModel
50 import com.android.systemui.qs.tiles.impl.night.domain.interactor.NightDisplayTileDataInteractor
51 import com.android.systemui.qs.tiles.impl.night.domain.interactor.NightDisplayTileUserActionInteractor
52 import com.android.systemui.qs.tiles.impl.night.domain.model.NightDisplayTileModel
53 import com.android.systemui.qs.tiles.impl.night.ui.NightDisplayTileMapper
54 import com.android.systemui.qs.tiles.impl.onehanded.domain.OneHandedModeTileDataInteractor
55 import com.android.systemui.qs.tiles.impl.onehanded.domain.OneHandedModeTileUserActionInteractor
56 import com.android.systemui.qs.tiles.impl.onehanded.domain.model.OneHandedModeTileModel
57 import com.android.systemui.qs.tiles.impl.onehanded.ui.OneHandedModeTileMapper
58 import com.android.systemui.qs.tiles.impl.reducebrightness.domain.interactor.ReduceBrightColorsTileDataInteractor
59 import com.android.systemui.qs.tiles.impl.reducebrightness.domain.interactor.ReduceBrightColorsTileUserActionInteractor
60 import com.android.systemui.qs.tiles.impl.reducebrightness.domain.model.ReduceBrightColorsTileModel
61 import com.android.systemui.qs.tiles.impl.reducebrightness.ui.ReduceBrightColorsTileMapper
62 import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
63 import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
64 import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
65 import com.android.systemui.qs.tiles.viewmodel.StubQSTileViewModel
66 import com.android.systemui.res.R
67 import dagger.Binds
68 import dagger.Module
69 import dagger.Provides
70 import dagger.multibindings.IntoMap
71 import dagger.multibindings.StringKey
72 
73 @Module
74 interface QSAccessibilityModule {
75 
76     /** Inject ColorInversionTile into tileMap in QSModule */
77     @Binds
78     @IntoMap
79     @StringKey(ColorInversionTile.TILE_SPEC)
bindColorInversionTilenull80     fun bindColorInversionTile(colorInversionTile: ColorInversionTile): QSTileImpl<*>
81 
82     /** Inject NightDisplayTile into tileMap in QSModule */
83     @Binds
84     @IntoMap
85     @StringKey(NightDisplayTile.TILE_SPEC)
86     fun bindNightDisplayTile(nightDisplayTile: NightDisplayTile): QSTileImpl<*>
87 
88     /** Inject ReduceBrightColorsTile into tileMap in QSModule */
89     @Binds
90     @IntoMap
91     @StringKey(ReduceBrightColorsTile.TILE_SPEC)
92     fun bindReduceBrightColorsTile(reduceBrightColorsTile: ReduceBrightColorsTile): QSTileImpl<*>
93 
94     /** Inject OneHandedModeTile into tileMap in QSModule */
95     @Binds
96     @IntoMap
97     @StringKey(OneHandedModeTile.TILE_SPEC)
98     fun bindOneHandedModeTile(oneHandedModeTile: OneHandedModeTile): QSTileImpl<*>
99 
100     /** Inject ColorCorrectionTile into tileMap in QSModule */
101     @Binds
102     @IntoMap
103     @StringKey(ColorCorrectionTile.TILE_SPEC)
104     fun bindColorCorrectionTile(colorCorrectionTile: ColorCorrectionTile): QSTileImpl<*>
105 
106     /** Inject DreamTile into tileMap in QSModule */
107     @Binds
108     @IntoMap
109     @StringKey(DreamTile.TILE_SPEC)
110     fun bindDreamTile(dreamTile: DreamTile): QSTileImpl<*>
111 
112     /** Inject FontScalingTile into tileMap in QSModule */
113     @Binds
114     @IntoMap
115     @StringKey(FontScalingTile.TILE_SPEC)
116     fun bindFontScalingTile(fontScalingTile: FontScalingTile): QSTileImpl<*>
117 
118     /** Inject HearingDevicesTile into tileMap in QSModule */
119     @Binds
120     @IntoMap
121     @StringKey(HearingDevicesTile.TILE_SPEC)
122     fun bindHearingDevicesTile(hearingDevicesTile: HearingDevicesTile): QSTileImpl<*>
123 
124     @Binds
125     @IntoMap
126     @StringKey(COLOR_CORRECTION_TILE_SPEC)
127     fun provideColorCorrectionAvailabilityInteractor(
128         impl: ColorCorrectionTileDataInteractor
129     ): QSTileAvailabilityInteractor
130 
131     @Binds
132     @IntoMap
133     @StringKey(COLOR_INVERSION_TILE_SPEC)
134     fun provideColorInversionAvailabilityInteractor(
135         impl: ColorCorrectionTileDataInteractor
136     ): QSTileAvailabilityInteractor
137 
138     @Binds
139     @IntoMap
140     @StringKey(FONT_SCALING_TILE_SPEC)
141     fun provideFontScalingAvailabilityInteractor(
142         impl: FontScalingTileDataInteractor
143     ): QSTileAvailabilityInteractor
144 
145     @Binds
146     @IntoMap
147     @StringKey(REDUCE_BRIGHTNESS_TILE_SPEC)
148     fun provideReduceBrightnessAvailabilityInteractor(
149         impl: ReduceBrightColorsTileDataInteractor
150     ): QSTileAvailabilityInteractor
151 
152     @Binds
153     @IntoMap
154     @StringKey(ONE_HANDED_TILE_SPEC)
155     fun provideOneHandedAvailabilityInteractor(
156         impl: OneHandedModeTileDataInteractor
157     ): QSTileAvailabilityInteractor
158 
159     @Binds
160     @IntoMap
161     @StringKey(NIGHT_DISPLAY_TILE_SPEC)
162     fun provideNightDisplayAvailabilityInteractor(
163         impl: NightDisplayTileDataInteractor
164     ): QSTileAvailabilityInteractor
165 
166     @Binds
167     @IntoMap
168     @StringKey(HEARING_DEVICES_TILE_SPEC)
169     fun provideHearingDevicesAvailabilityInteractor(
170         impl: HearingDevicesTileDataInteractor
171     ): QSTileAvailabilityInteractor
172 
173     companion object {
174         const val COLOR_CORRECTION_TILE_SPEC = "color_correction"
175         const val COLOR_INVERSION_TILE_SPEC = "inversion"
176         const val FONT_SCALING_TILE_SPEC = "font_scaling"
177         const val REDUCE_BRIGHTNESS_TILE_SPEC = "reduce_brightness"
178         const val ONE_HANDED_TILE_SPEC = "onehanded"
179         const val NIGHT_DISPLAY_TILE_SPEC = "night"
180         const val HEARING_DEVICES_TILE_SPEC = "hearing_devices"
181 
182         @Provides
183         @IntoMap
184         @StringKey(COLOR_CORRECTION_TILE_SPEC)
185         fun provideColorCorrectionTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
186             QSTileConfig(
187                 tileSpec = TileSpec.create(COLOR_CORRECTION_TILE_SPEC),
188                 uiConfig =
189                     QSTileUIConfig.Resource(
190                         iconRes = R.drawable.ic_qs_color_correction,
191                         labelRes = R.string.quick_settings_color_correction_label,
192                     ),
193                 instanceId = uiEventLogger.getNewInstanceId(),
194                 category = TileCategory.ACCESSIBILITY,
195             )
196 
197         /** Inject ColorCorrectionTile into tileViewModelMap in QSModule */
198         @Provides
199         @IntoMap
200         @StringKey(COLOR_CORRECTION_TILE_SPEC)
201         fun provideColorCorrectionTileViewModel(
202             factory: QSTileViewModelFactory.Static<ColorCorrectionTileModel>,
203             mapper: ColorCorrectionTileMapper,
204             stateInteractor: ColorCorrectionTileDataInteractor,
205             userActionInteractor: ColorCorrectionUserActionInteractor,
206         ): QSTileViewModel =
207             factory.create(
208                 TileSpec.create(COLOR_CORRECTION_TILE_SPEC),
209                 userActionInteractor,
210                 stateInteractor,
211                 mapper,
212             )
213 
214         @Provides
215         @IntoMap
216         @StringKey(COLOR_INVERSION_TILE_SPEC)
217         fun provideColorInversionTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
218             QSTileConfig(
219                 tileSpec = TileSpec.create(COLOR_INVERSION_TILE_SPEC),
220                 uiConfig =
221                     QSTileUIConfig.Resource(
222                         iconRes = R.drawable.qs_invert_colors_icon_off,
223                         labelRes = R.string.quick_settings_inversion_label,
224                     ),
225                 instanceId = uiEventLogger.getNewInstanceId(),
226                 category = TileCategory.ACCESSIBILITY,
227             )
228 
229         /** Inject ColorInversionTile into tileViewModelMap in QSModule */
230         @Provides
231         @IntoMap
232         @StringKey(COLOR_INVERSION_TILE_SPEC)
233         fun provideColorInversionTileViewModel(
234             factory: QSTileViewModelFactory.Static<ColorInversionTileModel>,
235             mapper: ColorInversionTileMapper,
236             stateInteractor: ColorInversionTileDataInteractor,
237             userActionInteractor: ColorInversionUserActionInteractor,
238         ): QSTileViewModel =
239             factory.create(
240                 TileSpec.create(COLOR_INVERSION_TILE_SPEC),
241                 userActionInteractor,
242                 stateInteractor,
243                 mapper,
244             )
245 
246         @Provides
247         @IntoMap
248         @StringKey(FONT_SCALING_TILE_SPEC)
249         fun provideFontScalingTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
250             QSTileConfig(
251                 tileSpec = TileSpec.create(FONT_SCALING_TILE_SPEC),
252                 uiConfig =
253                     QSTileUIConfig.Resource(
254                         iconRes = R.drawable.ic_qs_font_scaling,
255                         labelRes = R.string.quick_settings_font_scaling_label,
256                     ),
257                 instanceId = uiEventLogger.getNewInstanceId(),
258                 category = TileCategory.DISPLAY,
259             )
260 
261         /** Inject FontScaling Tile into tileViewModelMap in QSModule */
262         @Provides
263         @IntoMap
264         @StringKey(FONT_SCALING_TILE_SPEC)
265         fun provideFontScalingTileViewModel(
266             factory: QSTileViewModelFactory.Static<FontScalingTileModel>,
267             mapper: FontScalingTileMapper,
268             stateInteractor: FontScalingTileDataInteractor,
269             userActionInteractor: FontScalingTileUserActionInteractor,
270         ): QSTileViewModel =
271             factory.create(
272                 TileSpec.create(FONT_SCALING_TILE_SPEC),
273                 userActionInteractor,
274                 stateInteractor,
275                 mapper,
276             )
277 
278         @Provides
279         @IntoMap
280         @StringKey(REDUCE_BRIGHTNESS_TILE_SPEC)
281         fun provideReduceBrightColorsTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
282             QSTileConfig(
283                 tileSpec = TileSpec.create(REDUCE_BRIGHTNESS_TILE_SPEC),
284                 uiConfig =
285                     QSTileUIConfig.Resource(
286                         iconRes = R.drawable.qs_extra_dim_icon_on,
287                         labelRes = com.android.internal.R.string.reduce_bright_colors_feature_name,
288                     ),
289                 instanceId = uiEventLogger.getNewInstanceId(),
290                 category = TileCategory.DISPLAY,
291             )
292 
293         /**
294          * Inject Reduce Bright Colors Tile into tileViewModelMap in QSModule. The tile is hidden
295          * behind a flag.
296          */
297         @Provides
298         @IntoMap
299         @StringKey(REDUCE_BRIGHTNESS_TILE_SPEC)
300         fun provideReduceBrightColorsTileViewModel(
301             factory: QSTileViewModelFactory.Static<ReduceBrightColorsTileModel>,
302             mapper: ReduceBrightColorsTileMapper,
303             stateInteractor: ReduceBrightColorsTileDataInteractor,
304             userActionInteractor: ReduceBrightColorsTileUserActionInteractor,
305         ): QSTileViewModel =
306             if (Flags.qsNewTilesFuture())
307                 factory.create(
308                     TileSpec.create(REDUCE_BRIGHTNESS_TILE_SPEC),
309                     userActionInteractor,
310                     stateInteractor,
311                     mapper,
312                 )
313             else StubQSTileViewModel
314 
315         @Provides
316         @IntoMap
317         @StringKey(ONE_HANDED_TILE_SPEC)
318         fun provideOneHandedTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
319             QSTileConfig(
320                 tileSpec = TileSpec.create(ONE_HANDED_TILE_SPEC),
321                 uiConfig =
322                     QSTileUIConfig.Resource(
323                         iconRes = com.android.internal.R.drawable.ic_qs_one_handed_mode,
324                         labelRes = R.string.quick_settings_onehanded_label,
325                     ),
326                 instanceId = uiEventLogger.getNewInstanceId(),
327                 category = TileCategory.ACCESSIBILITY,
328             )
329 
330         /** Inject One Handed Mode Tile into tileViewModelMap in QSModule. */
331         @Provides
332         @IntoMap
333         @StringKey(ONE_HANDED_TILE_SPEC)
334         fun provideOneHandedModeTileViewModel(
335             factory: QSTileViewModelFactory.Static<OneHandedModeTileModel>,
336             mapper: OneHandedModeTileMapper,
337             stateInteractor: OneHandedModeTileDataInteractor,
338             userActionInteractor: OneHandedModeTileUserActionInteractor,
339         ): QSTileViewModel =
340             if (Flags.qsNewTilesFuture())
341                 factory.create(
342                     TileSpec.create(ONE_HANDED_TILE_SPEC),
343                     userActionInteractor,
344                     stateInteractor,
345                     mapper,
346                 )
347             else StubQSTileViewModel
348 
349         @Provides
350         @IntoMap
351         @StringKey(NIGHT_DISPLAY_TILE_SPEC)
352         fun provideNightDisplayTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
353             QSTileConfig(
354                 tileSpec = TileSpec.create(NIGHT_DISPLAY_TILE_SPEC),
355                 uiConfig =
356                     QSTileUIConfig.Resource(
357                         iconRes = R.drawable.qs_nightlight_icon_off,
358                         labelRes = R.string.quick_settings_night_display_label,
359                     ),
360                 instanceId = uiEventLogger.getNewInstanceId(),
361                 category = TileCategory.DISPLAY,
362             )
363 
364         /**
365          * Inject NightDisplay Tile into tileViewModelMap in QSModule. The tile is hidden behind a
366          * flag.
367          */
368         @Provides
369         @IntoMap
370         @StringKey(NIGHT_DISPLAY_TILE_SPEC)
371         fun provideNightDisplayTileViewModel(
372             factory: QSTileViewModelFactory.Static<NightDisplayTileModel>,
373             mapper: NightDisplayTileMapper,
374             stateInteractor: NightDisplayTileDataInteractor,
375             userActionInteractor: NightDisplayTileUserActionInteractor,
376         ): QSTileViewModel =
377             if (Flags.qsNewTilesFuture())
378                 factory.create(
379                     TileSpec.create(NIGHT_DISPLAY_TILE_SPEC),
380                     userActionInteractor,
381                     stateInteractor,
382                     mapper,
383                 )
384             else StubQSTileViewModel
385 
386         @Provides
387         @IntoMap
388         @StringKey(HEARING_DEVICES_TILE_SPEC)
389         fun provideHearingDevicesTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
390             QSTileConfig(
391                 tileSpec = TileSpec.create(HEARING_DEVICES_TILE_SPEC),
392                 uiConfig =
393                     QSTileUIConfig.Resource(
394                         iconRes = R.drawable.qs_hearing_devices_icon,
395                         labelRes = R.string.quick_settings_hearing_devices_label,
396                     ),
397                 instanceId = uiEventLogger.getNewInstanceId(),
398                 category = TileCategory.ACCESSIBILITY,
399             )
400 
401         /**
402          * Inject HearingDevices Tile into tileViewModelMap in QSModule. The tile is hidden behind a
403          * flag.
404          */
405         @Provides
406         @IntoMap
407         @StringKey(HEARING_DEVICES_TILE_SPEC)
408         fun provideHearingDevicesTileViewModel(
409             factory: QSTileViewModelFactory.Static<HearingDevicesTileModel>,
410             mapper: HearingDevicesTileMapper,
411             stateInteractor: HearingDevicesTileDataInteractor,
412             userActionInteractor: HearingDevicesTileUserActionInteractor,
413         ): QSTileViewModel {
414             return if (Flags.hearingAidsQsTileDialog() && Flags.qsNewTilesFuture()) {
415                 factory.create(
416                     TileSpec.create(HEARING_DEVICES_TILE_SPEC),
417                     userActionInteractor,
418                     stateInteractor,
419                     mapper,
420                 )
421             } else StubQSTileViewModel
422         }
423     }
424 }
425