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.systemui.contrast 17 18 import android.app.UiModeManager 19 import android.app.UiModeManager.ContrastUtils.CONTRAST_LEVEL_HIGH 20 import android.app.UiModeManager.ContrastUtils.CONTRAST_LEVEL_MEDIUM 21 import android.app.UiModeManager.ContrastUtils.CONTRAST_LEVEL_STANDARD 22 import android.app.UiModeManager.ContrastUtils.fromContrastLevel 23 import android.app.UiModeManager.ContrastUtils.toContrastLevel 24 import android.content.Context 25 import android.os.Bundle 26 import android.provider.Settings 27 import android.view.LayoutInflater 28 import android.view.View 29 import android.widget.FrameLayout 30 import com.android.internal.annotations.VisibleForTesting 31 import com.android.systemui.R 32 import com.android.systemui.dagger.qualifiers.Main 33 import com.android.systemui.settings.UserTracker 34 import com.android.systemui.statusbar.phone.SystemUIDialog 35 import com.android.systemui.util.settings.SecureSettings 36 import java.util.concurrent.Executor 37 38 /** Dialog to select contrast options */ 39 class ContrastDialog( 40 context: Context?, 41 @Main private val mainExecutor: Executor, 42 private val uiModeManager: UiModeManager, 43 private val userTracker: UserTracker, 44 private val secureSettings: SecureSettings, 45 ) : SystemUIDialog(context), UiModeManager.ContrastChangeListener { 46 47 @VisibleForTesting lateinit var contrastButtons: Map<Int, FrameLayout> 48 lateinit var dialogView: View 49 @VisibleForTesting var initialContrast: Float = fromContrastLevel(CONTRAST_LEVEL_STANDARD) 50 51 public override fun onCreate(savedInstanceState: Bundle?) { 52 dialogView = LayoutInflater.from(context).inflate(R.layout.contrast_dialog, null) 53 setView(dialogView) 54 55 setTitle(R.string.quick_settings_contrast_label) 56 setNeutralButton(R.string.cancel) { _, _ -> 57 secureSettings.putFloatForUser( 58 Settings.Secure.CONTRAST_LEVEL, 59 initialContrast, 60 userTracker.userId 61 ) 62 dismiss() 63 } 64 setPositiveButton(R.string.done) { _, _ -> dismiss() } 65 super.onCreate(savedInstanceState) 66 67 contrastButtons = 68 mapOf( 69 CONTRAST_LEVEL_STANDARD to requireViewById(R.id.contrast_button_standard), 70 CONTRAST_LEVEL_MEDIUM to requireViewById(R.id.contrast_button_medium), 71 CONTRAST_LEVEL_HIGH to requireViewById(R.id.contrast_button_high) 72 ) 73 74 contrastButtons.forEach { (contrastLevel, contrastButton) -> 75 contrastButton.setOnClickListener { 76 val contrastValue = fromContrastLevel(contrastLevel) 77 secureSettings.putFloatForUser( 78 Settings.Secure.CONTRAST_LEVEL, 79 contrastValue, 80 userTracker.userId 81 ) 82 } 83 } 84 85 initialContrast = uiModeManager.contrast 86 highlightContrast(toContrastLevel(initialContrast)) 87 } 88 89 override fun start() { 90 uiModeManager.addContrastChangeListener(mainExecutor, this) 91 } 92 93 override fun stop() { 94 uiModeManager.removeContrastChangeListener(this) 95 } 96 97 override fun onContrastChanged(contrast: Float) { 98 highlightContrast(toContrastLevel(contrast)) 99 } 100 101 private fun highlightContrast(contrast: Int) { 102 contrastButtons.forEach { (level, button) -> button.isSelected = level == contrast } 103 } 104 } 105