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