1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this 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 package com.android.settings.display; 15 16 import static com.android.settingslib.display.BrightnessUtils.GAMMA_SPACE_MAX; 17 import static com.android.settingslib.display.BrightnessUtils.GAMMA_SPACE_MIN; 18 import static com.android.settingslib.display.BrightnessUtils.convertLinearToGammaFloat; 19 20 import android.content.ContentResolver; 21 import android.content.Context; 22 import android.database.ContentObserver; 23 import android.net.Uri; 24 import android.os.Handler; 25 import android.os.Looper; 26 import android.os.PowerManager; 27 import android.os.RemoteException; 28 import android.os.ServiceManager; 29 import android.provider.Settings; 30 import android.provider.Settings.System; 31 import android.service.vr.IVrManager; 32 import android.util.Log; 33 34 import androidx.annotation.VisibleForTesting; 35 import androidx.preference.Preference; 36 import androidx.preference.PreferenceScreen; 37 38 import com.android.settings.core.PreferenceControllerMixin; 39 import com.android.settingslib.core.AbstractPreferenceController; 40 import com.android.settingslib.core.lifecycle.Lifecycle; 41 import com.android.settingslib.core.lifecycle.LifecycleObserver; 42 import com.android.settingslib.core.lifecycle.events.OnStart; 43 import com.android.settingslib.core.lifecycle.events.OnStop; 44 45 import java.text.NumberFormat; 46 47 public class BrightnessLevelPreferenceController extends AbstractPreferenceController implements 48 PreferenceControllerMixin, LifecycleObserver, OnStart, OnStop { 49 50 private static final String TAG = "BrightnessPrefCtrl"; 51 private static final String KEY_BRIGHTNESS = "brightness"; 52 private static final Uri BRIGHTNESS_URI; 53 private static final Uri BRIGHTNESS_FOR_VR_URI; 54 private static final Uri BRIGHTNESS_ADJ_URI; 55 56 private final float mMinBrightness; 57 private final float mMaxBrightness; 58 private final float mMinVrBrightness; 59 private final float mMaxVrBrightness; 60 private final ContentResolver mContentResolver; 61 62 private Preference mPreference; 63 64 static { 65 BRIGHTNESS_URI = System.getUriFor(System.SCREEN_BRIGHTNESS_FLOAT); 66 BRIGHTNESS_FOR_VR_URI = System.getUriFor(System.SCREEN_BRIGHTNESS_FOR_VR); 67 BRIGHTNESS_ADJ_URI = System.getUriFor(System.SCREEN_AUTO_BRIGHTNESS_ADJ); 68 } 69 70 private ContentObserver mBrightnessObserver = 71 new ContentObserver(new Handler(Looper.getMainLooper())) { 72 @Override 73 public void onChange(boolean selfChange) { 74 updatedSummary(mPreference); 75 } 76 }; 77 BrightnessLevelPreferenceController(Context context, Lifecycle lifecycle)78 public BrightnessLevelPreferenceController(Context context, Lifecycle lifecycle) { 79 super(context); 80 if (lifecycle != null) { 81 lifecycle.addObserver(this); 82 } 83 PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); 84 mMinBrightness = powerManager.getBrightnessConstraint( 85 PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM); 86 mMaxBrightness = powerManager.getBrightnessConstraint( 87 PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM); 88 mMinVrBrightness = powerManager.getBrightnessConstraint( 89 PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM_VR); 90 mMaxVrBrightness = powerManager.getBrightnessConstraint( 91 PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM_VR); 92 mContentResolver = mContext.getContentResolver(); 93 } 94 95 @Override isAvailable()96 public boolean isAvailable() { 97 return true; 98 } 99 100 @Override getPreferenceKey()101 public String getPreferenceKey() { 102 return KEY_BRIGHTNESS; 103 } 104 105 @Override displayPreference(PreferenceScreen screen)106 public void displayPreference(PreferenceScreen screen) { 107 super.displayPreference(screen); 108 mPreference = screen.findPreference(KEY_BRIGHTNESS); 109 } 110 111 @Override updateState(Preference preference)112 public void updateState(Preference preference) { 113 updatedSummary(preference); 114 } 115 116 @Override onStart()117 public void onStart() { 118 mContentResolver.registerContentObserver(BRIGHTNESS_URI, false, mBrightnessObserver); 119 mContentResolver.registerContentObserver(BRIGHTNESS_FOR_VR_URI, false, mBrightnessObserver); 120 mContentResolver.registerContentObserver(BRIGHTNESS_ADJ_URI, false, mBrightnessObserver); 121 } 122 123 @Override onStop()124 public void onStop() { 125 mContentResolver.unregisterContentObserver(mBrightnessObserver); 126 } 127 updatedSummary(Preference preference)128 private void updatedSummary(Preference preference) { 129 if (preference != null) { 130 preference.setSummary(NumberFormat.getPercentInstance().format(getCurrentBrightness())); 131 } 132 } 133 getCurrentBrightness()134 private double getCurrentBrightness() { 135 final int value; 136 if (isInVrMode()) { 137 value = convertLinearToGammaFloat(System.getFloat(mContentResolver, 138 System.SCREEN_BRIGHTNESS_FOR_VR_FLOAT, mMaxBrightness), 139 mMinVrBrightness, mMaxVrBrightness); 140 } else { 141 value = convertLinearToGammaFloat(Settings.System.getFloat(mContentResolver, 142 System.SCREEN_BRIGHTNESS_FLOAT, mMinBrightness), 143 mMinBrightness, mMaxBrightness); 144 } 145 return getPercentage(value, GAMMA_SPACE_MIN, GAMMA_SPACE_MAX); 146 } 147 getPercentage(double value, int min, int max)148 private double getPercentage(double value, int min, int max) { 149 if (value > max) { 150 return 1.0; 151 } 152 if (value < min) { 153 return 0.0; 154 } 155 return (value - min) / (max - min); 156 } 157 158 @VisibleForTesting safeGetVrManager()159 IVrManager safeGetVrManager() { 160 return IVrManager.Stub.asInterface(ServiceManager.getService( 161 Context.VR_SERVICE)); 162 } 163 164 @VisibleForTesting isInVrMode()165 boolean isInVrMode() { 166 IVrManager vrManager = safeGetVrManager(); 167 if (vrManager != null) { 168 try { 169 return vrManager.getVrModeState(); 170 } catch (RemoteException e) { 171 Log.e(TAG, "Failed to check vr mode!", e); 172 } 173 } 174 return false; 175 } 176 } 177