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.Flags 24 import com.android.systemui.modes.shared.ModesUi 25 import com.android.systemui.qs.QsEventLogger 26 import com.android.systemui.qs.pipeline.shared.TileSpec 27 import com.android.systemui.qs.shared.model.TileCategory 28 import com.android.systemui.qs.tileimpl.QSTileImpl 29 import com.android.systemui.qs.tiles.AlarmTile 30 import com.android.systemui.qs.tiles.CameraToggleTile 31 import com.android.systemui.qs.tiles.DndTile 32 import com.android.systemui.qs.tiles.FlashlightTile 33 import com.android.systemui.qs.tiles.LocationTile 34 import com.android.systemui.qs.tiles.MicrophoneToggleTile 35 import com.android.systemui.qs.tiles.ModesDndTile 36 import com.android.systemui.qs.tiles.ModesTile 37 import com.android.systemui.qs.tiles.UiModeNightTile 38 import com.android.systemui.qs.tiles.WorkModeTile 39 import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor 40 import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig 41 import com.android.systemui.qs.tiles.base.shared.model.QSTilePolicy 42 import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig 43 import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel 44 import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory 45 import com.android.systemui.qs.tiles.base.ui.viewmodel.StubQSTileViewModel 46 import com.android.systemui.qs.tiles.impl.alarm.domain.interactor.AlarmTileDataInteractor 47 import com.android.systemui.qs.tiles.impl.alarm.domain.interactor.AlarmTileUserActionInteractor 48 import com.android.systemui.qs.tiles.impl.alarm.domain.model.AlarmTileModel 49 import com.android.systemui.qs.tiles.impl.alarm.ui.mapper.AlarmTileMapper 50 import com.android.systemui.qs.tiles.impl.flashlight.domain.interactor.FlashlightTileDataInteractor 51 import com.android.systemui.qs.tiles.impl.flashlight.domain.interactor.FlashlightTileUserActionInteractor 52 import com.android.systemui.qs.tiles.impl.flashlight.domain.model.FlashlightTileModel 53 import com.android.systemui.qs.tiles.impl.flashlight.ui.mapper.FlashlightMapper 54 import com.android.systemui.qs.tiles.impl.location.domain.interactor.LocationTileDataInteractor 55 import com.android.systemui.qs.tiles.impl.location.domain.interactor.LocationTileUserActionInteractor 56 import com.android.systemui.qs.tiles.impl.location.domain.model.LocationTileModel 57 import com.android.systemui.qs.tiles.impl.location.ui.mapper.LocationTileMapper 58 import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesDndTileDataInteractor 59 import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesDndTileUserActionInteractor 60 import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesTileDataInteractor 61 import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesTileUserActionInteractor 62 import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesDndTileModel 63 import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel 64 import com.android.systemui.qs.tiles.impl.modes.ui.ModesDndTileMapper 65 import com.android.systemui.qs.tiles.impl.modes.ui.mapper.ModesTileMapper 66 import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.interactor.SensorPrivacyToggleTileDataInteractor 67 import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.interactor.SensorPrivacyToggleTileUserActionInteractor 68 import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model.SensorPrivacyToggleTileModel 69 import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.mapper.SensorPrivacyToggleTileMapper 70 import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.model.SensorPrivacyTileResources 71 import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.UiModeNightTileDataInteractor 72 import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.UiModeNightTileUserActionInteractor 73 import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.model.UiModeNightTileModel 74 import com.android.systemui.qs.tiles.impl.uimodenight.ui.mapper.UiModeNightTileMapper 75 import com.android.systemui.qs.tiles.impl.work.domain.interactor.WorkModeTileDataInteractor 76 import com.android.systemui.qs.tiles.impl.work.domain.interactor.WorkModeTileUserActionInteractor 77 import com.android.systemui.qs.tiles.impl.work.domain.model.WorkModeTileModel 78 import com.android.systemui.qs.tiles.impl.work.ui.mapper.WorkModeTileMapper 79 import com.android.systemui.res.R 80 import dagger.Binds 81 import dagger.Module 82 import dagger.Provides 83 import dagger.multibindings.IntoMap 84 import dagger.multibindings.StringKey 85 import javax.inject.Provider 86 87 @Module 88 interface PolicyModule { 89 90 /** Inject WorkModeTile into tileMap in QSModule */ 91 @Binds 92 @IntoMap 93 @StringKey(WorkModeTile.TILE_SPEC) bindWorkModeTilenull94 fun bindWorkModeTile(workModeTile: WorkModeTile): QSTileImpl<*> 95 96 @Binds 97 @IntoMap 98 @StringKey(FLASHLIGHT_TILE_SPEC) 99 fun provideAirplaneModeAvailabilityInteractor( 100 impl: FlashlightTileDataInteractor 101 ): QSTileAvailabilityInteractor 102 103 @Binds 104 @IntoMap 105 @StringKey(LOCATION_TILE_SPEC) 106 fun provideLocationAvailabilityInteractor( 107 impl: LocationTileDataInteractor 108 ): QSTileAvailabilityInteractor 109 110 @Binds 111 @IntoMap 112 @StringKey(ALARM_TILE_SPEC) 113 fun provideAlarmAvailabilityInteractor( 114 impl: AlarmTileDataInteractor 115 ): QSTileAvailabilityInteractor 116 117 @Binds 118 @IntoMap 119 @StringKey(UIMODENIGHT_TILE_SPEC) 120 fun provideUiModeNightAvailabilityInteractor( 121 impl: UiModeNightTileDataInteractor 122 ): QSTileAvailabilityInteractor 123 124 @Binds 125 @IntoMap 126 @StringKey(WORK_MODE_TILE_SPEC) 127 fun provideWorkModeAvailabilityInteractor( 128 impl: WorkModeTileDataInteractor 129 ): QSTileAvailabilityInteractor 130 131 companion object { 132 const val FLASHLIGHT_TILE_SPEC = "flashlight" 133 const val LOCATION_TILE_SPEC = "location" 134 const val ALARM_TILE_SPEC = "alarm" 135 const val UIMODENIGHT_TILE_SPEC = "dark" 136 const val WORK_MODE_TILE_SPEC = "work" 137 const val CAMERA_TOGGLE_TILE_SPEC = "cameratoggle" 138 const val MIC_TOGGLE_TILE_SPEC = "mictoggle" 139 const val DND_TILE_SPEC = "dnd" 140 const val MODES_DND_TILE_SPEC = "modes_dnd" 141 142 /** Inject DndTile or ModesTile into tileMap in QSModule based on feature flag */ 143 @Provides 144 @IntoMap 145 @StringKey(DND_TILE_SPEC) 146 fun bindDndOrModesTile( 147 // Using providers to make sure that the unused tile isn't initialised at all if the 148 // flag is off. 149 dndTile: Provider<DndTile>, 150 modesTile: Provider<ModesTile>, 151 ): QSTileImpl<*> { 152 return if (ModesUi.isEnabled) modesTile.get() else dndTile.get() 153 } 154 155 /** Inject ModesDndTile into tileViewModelMap in QSModule */ 156 @Provides 157 @IntoMap 158 @StringKey(MODES_DND_TILE_SPEC) 159 fun bindDndModeTile(tile: ModesDndTile): QSTileImpl<*> = tile 160 161 /** Inject flashlight config */ 162 @Provides 163 @IntoMap 164 @StringKey(FLASHLIGHT_TILE_SPEC) 165 fun provideFlashlightTileConfig(uiEventLogger: QsEventLogger): QSTileConfig = 166 QSTileConfig( 167 tileSpec = TileSpec.create(FLASHLIGHT_TILE_SPEC), 168 uiConfig = 169 QSTileUIConfig.Resource( 170 iconRes = R.drawable.qs_flashlight_icon_off, 171 labelRes = R.string.quick_settings_flashlight_label, 172 ), 173 instanceId = uiEventLogger.getNewInstanceId(), 174 category = TileCategory.UTILITIES, 175 ) 176 177 /** Inject FlashlightTile into tileViewModelMap in QSModule */ 178 @Provides 179 @IntoMap 180 @StringKey(FLASHLIGHT_TILE_SPEC) 181 fun provideFlashlightTileViewModel( 182 factory: QSTileViewModelFactory.Static<FlashlightTileModel>, 183 mapper: FlashlightMapper, 184 stateInteractor: FlashlightTileDataInteractor, 185 userActionInteractor: FlashlightTileUserActionInteractor, 186 ): QSTileViewModel = 187 factory.create( 188 TileSpec.create(FLASHLIGHT_TILE_SPEC), 189 userActionInteractor, 190 stateInteractor, 191 mapper, 192 ) 193 194 /** Inject location config */ 195 @Provides 196 @IntoMap 197 @StringKey(LOCATION_TILE_SPEC) 198 fun provideLocationTileConfig(uiEventLogger: QsEventLogger): QSTileConfig = 199 QSTileConfig( 200 tileSpec = TileSpec.create(LOCATION_TILE_SPEC), 201 uiConfig = 202 QSTileUIConfig.Resource( 203 iconRes = R.drawable.qs_location_icon_off, 204 labelRes = R.string.quick_settings_location_label, 205 ), 206 instanceId = uiEventLogger.getNewInstanceId(), 207 policy = 208 QSTilePolicy.Restricted( 209 listOf(DISALLOW_SHARE_LOCATION, DISALLOW_CONFIG_LOCATION) 210 ), 211 category = TileCategory.PRIVACY, 212 ) 213 214 /** Inject LocationTile into tileViewModelMap in QSModule */ 215 @Provides 216 @IntoMap 217 @StringKey(LOCATION_TILE_SPEC) 218 fun provideLocationTileViewModel( 219 factory: QSTileViewModelFactory.Static<LocationTileModel>, 220 mapper: LocationTileMapper, 221 stateInteractor: LocationTileDataInteractor, 222 userActionInteractor: LocationTileUserActionInteractor, 223 ): QSTileViewModel = 224 factory.create( 225 TileSpec.create(LOCATION_TILE_SPEC), 226 userActionInteractor, 227 stateInteractor, 228 mapper, 229 ) 230 231 /** Inject alarm config */ 232 @Provides 233 @IntoMap 234 @StringKey(ALARM_TILE_SPEC) 235 fun provideAlarmTileConfig(uiEventLogger: QsEventLogger): QSTileConfig = 236 QSTileConfig( 237 tileSpec = TileSpec.create(ALARM_TILE_SPEC), 238 uiConfig = 239 QSTileUIConfig.Resource( 240 iconRes = R.drawable.ic_alarm, 241 labelRes = R.string.status_bar_alarm, 242 ), 243 instanceId = uiEventLogger.getNewInstanceId(), 244 category = TileCategory.UTILITIES, 245 ) 246 247 /** Inject AlarmTile into tileViewModelMap in QSModule */ 248 @Provides 249 @IntoMap 250 @StringKey(ALARM_TILE_SPEC) 251 fun provideAlarmTileViewModel( 252 factory: QSTileViewModelFactory.Static<AlarmTileModel>, 253 mapper: AlarmTileMapper, 254 stateInteractor: AlarmTileDataInteractor, 255 userActionInteractor: AlarmTileUserActionInteractor, 256 ): QSTileViewModel = 257 factory.create( 258 TileSpec.create(ALARM_TILE_SPEC), 259 userActionInteractor, 260 stateInteractor, 261 mapper, 262 ) 263 264 /** Inject uimodenight config */ 265 @Provides 266 @IntoMap 267 @StringKey(UIMODENIGHT_TILE_SPEC) 268 fun provideUiModeNightTileConfig(uiEventLogger: QsEventLogger): QSTileConfig = 269 QSTileConfig( 270 tileSpec = TileSpec.create(UIMODENIGHT_TILE_SPEC), 271 uiConfig = 272 QSTileUIConfig.Resource( 273 iconRes = R.drawable.qs_light_dark_theme_icon_off, 274 labelRes = R.string.quick_settings_ui_mode_night_label, 275 ), 276 instanceId = uiEventLogger.getNewInstanceId(), 277 category = TileCategory.DISPLAY, 278 ) 279 280 /** Inject uimodenight into tileViewModelMap in QSModule */ 281 @Provides 282 @IntoMap 283 @StringKey(UIMODENIGHT_TILE_SPEC) 284 fun provideUiModeNightTileViewModel( 285 factory: QSTileViewModelFactory.Static<UiModeNightTileModel>, 286 mapper: UiModeNightTileMapper, 287 stateInteractor: UiModeNightTileDataInteractor, 288 userActionInteractor: UiModeNightTileUserActionInteractor, 289 ): QSTileViewModel = 290 factory.create( 291 TileSpec.create(UIMODENIGHT_TILE_SPEC), 292 userActionInteractor, 293 stateInteractor, 294 mapper, 295 ) 296 297 /** Inject work mode tile config */ 298 @Provides 299 @IntoMap 300 @StringKey(WORK_MODE_TILE_SPEC) 301 fun provideWorkModeTileConfig(uiEventLogger: QsEventLogger): QSTileConfig = 302 QSTileConfig( 303 tileSpec = TileSpec.create(WORK_MODE_TILE_SPEC), 304 uiConfig = 305 QSTileUIConfig.Resource( 306 iconRes = com.android.internal.R.drawable.stat_sys_managed_profile_status, 307 labelRes = R.string.quick_settings_work_mode_label, 308 ), 309 instanceId = uiEventLogger.getNewInstanceId(), 310 autoRemoveOnUnavailable = false, 311 category = TileCategory.PRIVACY, 312 ) 313 314 /** Inject work mode into tileViewModelMap in QSModule */ 315 @Provides 316 @IntoMap 317 @StringKey(WORK_MODE_TILE_SPEC) 318 fun provideWorkModeTileViewModel( 319 factory: QSTileViewModelFactory.Static<WorkModeTileModel>, 320 mapper: WorkModeTileMapper, 321 stateInteractor: WorkModeTileDataInteractor, 322 userActionInteractor: WorkModeTileUserActionInteractor, 323 ): QSTileViewModel = 324 factory.create( 325 TileSpec.create(WORK_MODE_TILE_SPEC), 326 userActionInteractor, 327 stateInteractor, 328 mapper, 329 ) 330 331 /** Inject camera toggle config */ 332 @Provides 333 @IntoMap 334 @StringKey(CAMERA_TOGGLE_TILE_SPEC) 335 fun provideCameraToggleTileConfig(uiEventLogger: QsEventLogger): QSTileConfig = 336 QSTileConfig( 337 tileSpec = TileSpec.create(CAMERA_TOGGLE_TILE_SPEC), 338 uiConfig = 339 QSTileUIConfig.Resource( 340 iconRes = R.drawable.qs_camera_access_icon_off, 341 labelRes = R.string.quick_settings_camera_label, 342 ), 343 instanceId = uiEventLogger.getNewInstanceId(), 344 policy = QSTilePolicy.Restricted(listOf(DISALLOW_CAMERA_TOGGLE)), 345 category = TileCategory.PRIVACY, 346 ) 347 348 /** Inject camera toggle tile into tileViewModelMap in QSModule */ 349 @Provides 350 @IntoMap 351 @StringKey(CAMERA_TOGGLE_TILE_SPEC) 352 fun provideCameraToggleTileViewModel( 353 factory: QSTileViewModelFactory.Static<SensorPrivacyToggleTileModel>, 354 mapper: SensorPrivacyToggleTileMapper.Factory, 355 stateInteractor: SensorPrivacyToggleTileDataInteractor.Factory, 356 userActionInteractor: SensorPrivacyToggleTileUserActionInteractor.Factory, 357 ): QSTileViewModel = 358 factory.create( 359 TileSpec.create(CAMERA_TOGGLE_TILE_SPEC), 360 userActionInteractor.create(CAMERA), 361 stateInteractor.create(CAMERA), 362 mapper.create(SensorPrivacyTileResources.CameraPrivacyTileResources), 363 ) 364 365 @Provides 366 @IntoMap 367 @StringKey(CAMERA_TOGGLE_TILE_SPEC) 368 fun provideCameraToggleAvailabilityInteractor( 369 factory: SensorPrivacyToggleTileDataInteractor.Factory 370 ): QSTileAvailabilityInteractor { 371 return factory.create(CAMERA) 372 } 373 374 /** Inject microphone toggle config */ 375 @Provides 376 @IntoMap 377 @StringKey(MIC_TOGGLE_TILE_SPEC) 378 fun provideMicrophoneToggleTileConfig(uiEventLogger: QsEventLogger): QSTileConfig = 379 QSTileConfig( 380 tileSpec = TileSpec.create(MIC_TOGGLE_TILE_SPEC), 381 uiConfig = 382 QSTileUIConfig.Resource( 383 iconRes = R.drawable.qs_mic_access_off, 384 labelRes = R.string.quick_settings_mic_label, 385 ), 386 instanceId = uiEventLogger.getNewInstanceId(), 387 policy = QSTilePolicy.Restricted(listOf(DISALLOW_MICROPHONE_TOGGLE)), 388 category = TileCategory.PRIVACY, 389 ) 390 391 /** Inject microphone toggle tile into tileViewModelMap in QSModule */ 392 @Provides 393 @IntoMap 394 @StringKey(MIC_TOGGLE_TILE_SPEC) 395 fun provideMicrophoneToggleTileViewModel( 396 factory: QSTileViewModelFactory.Static<SensorPrivacyToggleTileModel>, 397 mapper: SensorPrivacyToggleTileMapper.Factory, 398 stateInteractor: SensorPrivacyToggleTileDataInteractor.Factory, 399 userActionInteractor: SensorPrivacyToggleTileUserActionInteractor.Factory, 400 ): QSTileViewModel = 401 factory.create( 402 TileSpec.create(MIC_TOGGLE_TILE_SPEC), 403 userActionInteractor.create(MICROPHONE), 404 stateInteractor.create(MICROPHONE), 405 mapper.create(SensorPrivacyTileResources.MicrophonePrivacyTileResources), 406 ) 407 408 @Provides 409 @IntoMap 410 @StringKey(MIC_TOGGLE_TILE_SPEC) 411 fun provideMicToggleModeAvailabilityInteractor( 412 factory: SensorPrivacyToggleTileDataInteractor.Factory 413 ): QSTileAvailabilityInteractor { 414 return factory.create(MICROPHONE) 415 } 416 417 /** Inject DND tile or Modes tile config based on feature flag */ 418 @Provides 419 @IntoMap 420 @StringKey(DND_TILE_SPEC) 421 fun provideDndOrModesTileConfig(uiEventLogger: QsEventLogger): QSTileConfig = 422 if (ModesUi.isEnabled) { 423 QSTileConfig( 424 tileSpec = TileSpec.create(DND_TILE_SPEC), 425 uiConfig = 426 QSTileUIConfig.Resource( 427 iconRes = com.android.internal.R.drawable.ic_zen_priority_modes, 428 labelRes = R.string.quick_settings_modes_label, 429 ), 430 instanceId = uiEventLogger.getNewInstanceId(), 431 category = TileCategory.CONNECTIVITY, 432 ) 433 } else { 434 QSTileConfig( 435 tileSpec = TileSpec.create(DND_TILE_SPEC), 436 uiConfig = 437 QSTileUIConfig.Resource( 438 iconRes = R.drawable.qs_dnd_icon_off, 439 labelRes = R.string.quick_settings_dnd_label, 440 ), 441 instanceId = uiEventLogger.getNewInstanceId(), 442 category = TileCategory.CONNECTIVITY, 443 ) 444 } 445 446 /** Inject ModesTile into tileViewModelMap in QSModule */ 447 @Provides 448 @IntoMap 449 @StringKey(DND_TILE_SPEC) 450 fun provideModesTileViewModel( 451 factory: QSTileViewModelFactory.Static<ModesTileModel>, 452 mapper: ModesTileMapper, 453 stateInteractor: ModesTileDataInteractor, 454 userActionInteractor: ModesTileUserActionInteractor, 455 ): QSTileViewModel = 456 if (ModesUi.isEnabled && Flags.qsNewTilesFuture()) 457 factory.create( 458 TileSpec.create(DND_TILE_SPEC), 459 userActionInteractor, 460 stateInteractor, 461 mapper, 462 ) 463 else StubQSTileViewModel 464 465 @Provides 466 @IntoMap 467 @StringKey(MODES_DND_TILE_SPEC) 468 fun provideDndModeTileConfig(uiEventLogger: QsEventLogger): QSTileConfig = 469 QSTileConfig( 470 tileSpec = TileSpec.create(MODES_DND_TILE_SPEC), 471 uiConfig = 472 QSTileUIConfig.Resource( 473 iconRes = R.drawable.qs_dnd_icon_off, 474 labelRes = R.string.quick_settings_dnd_label, 475 ), 476 instanceId = uiEventLogger.getNewInstanceId(), 477 category = TileCategory.CONNECTIVITY, 478 ) 479 480 @Provides 481 @IntoMap 482 @StringKey(MODES_DND_TILE_SPEC) 483 fun provideDndModeTileViewModel( 484 factory: QSTileViewModelFactory.Static<ModesDndTileModel>, 485 mapper: ModesDndTileMapper, 486 stateInteractor: ModesDndTileDataInteractor, 487 userActionInteractor: ModesDndTileUserActionInteractor, 488 ): QSTileViewModel = 489 factory.create( 490 TileSpec.create(MODES_DND_TILE_SPEC), 491 userActionInteractor, 492 stateInteractor, 493 mapper, 494 ) 495 } 496 497 /** Inject FlashlightTile into tileMap in QSModule */ 498 @Binds 499 @IntoMap 500 @StringKey(FlashlightTile.TILE_SPEC) bindFlashlightTilenull501 fun bindFlashlightTile(flashlightTile: FlashlightTile): QSTileImpl<*> 502 503 /** Inject LocationTile into tileMap in QSModule */ 504 @Binds 505 @IntoMap 506 @StringKey(LocationTile.TILE_SPEC) 507 fun bindLocationTile(locationTile: LocationTile): QSTileImpl<*> 508 509 /** Inject CameraToggleTile into tileMap in QSModule */ 510 @Binds 511 @IntoMap 512 @StringKey(CameraToggleTile.TILE_SPEC) 513 fun bindCameraToggleTile(cameraToggleTile: CameraToggleTile): QSTileImpl<*> 514 515 /** Inject MicrophoneToggleTile into tileMap in QSModule */ 516 @Binds 517 @IntoMap 518 @StringKey(MicrophoneToggleTile.TILE_SPEC) 519 fun bindMicrophoneToggleTile(microphoneToggleTile: MicrophoneToggleTile): QSTileImpl<*> 520 521 /** Inject AlarmTile into tileMap in QSModule */ 522 @Binds 523 @IntoMap 524 @StringKey(AlarmTile.TILE_SPEC) 525 fun bindAlarmTile(alarmTile: AlarmTile): QSTileImpl<*> 526 527 @Binds 528 @IntoMap 529 @StringKey(UiModeNightTile.TILE_SPEC) 530 fun bindUiModeNightTile(uiModeNightTile: UiModeNightTile): QSTileImpl<*> 531 } 532