1 /* 2 * Copyright (C) 2021 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.server.display; 18 19 import android.annotation.NonNull; 20 import android.os.Handler; 21 import android.os.Looper; 22 import android.os.Message; 23 import android.util.Slog; 24 25 import com.android.internal.annotations.GuardedBy; 26 27 import java.util.concurrent.CopyOnWriteArraySet; 28 29 /** 30 * Saves brightness to a persistent data store, enabling each logical display to have its own 31 * brightness. 32 */ 33 public class BrightnessSetting { 34 private static final String TAG = "BrightnessSetting"; 35 36 private static final int MSG_BRIGHTNESS_CHANGED = 1; 37 38 private final PersistentDataStore mPersistentDataStore; 39 private final DisplayManagerService.SyncRoot mSyncRoot; 40 41 private final LogicalDisplay mLogicalDisplay; 42 43 private int mUserSerial; 44 private final Handler mHandler = new Handler(Looper.getMainLooper()) { 45 @Override 46 public void handleMessage(Message msg) { 47 if (msg.what == MSG_BRIGHTNESS_CHANGED) { 48 float brightnessVal = Float.intBitsToFloat(msg.arg1); 49 notifyListeners(brightnessVal); 50 } 51 } 52 }; 53 54 private final CopyOnWriteArraySet<BrightnessSettingListener> mListeners = 55 new CopyOnWriteArraySet<>(); 56 57 @GuardedBy("mSyncRoot") 58 private float mBrightness; 59 BrightnessSetting(int userSerial, @NonNull PersistentDataStore persistentDataStore, @NonNull LogicalDisplay logicalDisplay, DisplayManagerService.SyncRoot syncRoot)60 BrightnessSetting(int userSerial, 61 @NonNull PersistentDataStore persistentDataStore, 62 @NonNull LogicalDisplay logicalDisplay, 63 DisplayManagerService.SyncRoot syncRoot) { 64 mPersistentDataStore = persistentDataStore; 65 mLogicalDisplay = logicalDisplay; 66 mUserSerial = userSerial; 67 mBrightness = mPersistentDataStore.getBrightness( 68 mLogicalDisplay.getPrimaryDisplayDeviceLocked(), userSerial); 69 mSyncRoot = syncRoot; 70 } 71 72 /** 73 * Returns the brightness from the brightness setting 74 * 75 * @return brightness for the current display 76 */ getBrightness()77 public float getBrightness() { 78 synchronized (mSyncRoot) { 79 return mBrightness; 80 } 81 } 82 83 /** 84 * Registers listener for brightness setting change events. 85 */ registerListener(BrightnessSettingListener l)86 public void registerListener(BrightnessSettingListener l) { 87 if (mListeners.contains(l)) { 88 Slog.wtf(TAG, "Duplicate Listener added"); 89 } 90 mListeners.add(l); 91 } 92 93 /** 94 * Unregisters listener for brightness setting change events. 95 * 96 * @param l listener 97 */ unregisterListener(BrightnessSettingListener l)98 public void unregisterListener(BrightnessSettingListener l) { 99 mListeners.remove(l); 100 } 101 102 /** Sets the user serial for the brightness setting */ setUserSerial(int userSerial)103 public void setUserSerial(int userSerial) { 104 mUserSerial = userSerial; 105 } 106 107 /** 108 * Sets the brightness and broadcasts the change to the listeners. 109 * @param brightness The value to which the brightness is to be set. 110 */ setBrightness(float brightness)111 public void setBrightness(float brightness) { 112 if (Float.isNaN(brightness)) { 113 Slog.w(TAG, "Attempting to set invalid brightness"); 114 return; 115 } 116 synchronized (mSyncRoot) { 117 // If the brightness is the same, we still need to update any listeners as the act of 118 // setting the brightness alone has side effects, like clearing any temporary 119 // brightness. We can skip persisting to disk, however, since it hasn't actually 120 // changed. 121 if (brightness != mBrightness) { 122 mPersistentDataStore.setBrightness(mLogicalDisplay.getPrimaryDisplayDeviceLocked(), 123 brightness, mUserSerial 124 ); 125 } 126 mBrightness = brightness; 127 int toSend = Float.floatToIntBits(mBrightness); 128 Message msg = mHandler.obtainMessage(MSG_BRIGHTNESS_CHANGED, toSend, 0); 129 mHandler.sendMessage(msg); 130 } 131 } 132 133 /** 134 * Sets the brightness. Does not send update event to listeners. 135 * @param brightness The value to which the brightness is to be set. 136 */ setBrightnessNoNotify(float brightness)137 public void setBrightnessNoNotify(float brightness) { 138 if (Float.isNaN(brightness)) { 139 Slog.w(TAG, "Attempting to init invalid brightness"); 140 return; 141 } 142 synchronized (mSyncRoot) { 143 if (brightness != mBrightness) { 144 mPersistentDataStore.setBrightness(mLogicalDisplay.getPrimaryDisplayDeviceLocked(), 145 brightness, mUserSerial 146 ); 147 } 148 mBrightness = brightness; 149 } 150 } 151 152 /** 153 * @return The brightness for the default display in nits. Used when the underlying display 154 * device has changed but we want to persist the nit value. 155 */ getBrightnessNitsForDefaultDisplay()156 public float getBrightnessNitsForDefaultDisplay() { 157 return mPersistentDataStore.getBrightnessNitsForDefaultDisplay(); 158 } 159 160 /** 161 * Set brightness in nits for the default display. Used when we want to persist the nit value 162 * even if the underlying display device changes. 163 * @param nits The brightness value in nits 164 */ setBrightnessNitsForDefaultDisplay(float nits)165 public void setBrightnessNitsForDefaultDisplay(float nits) { 166 mPersistentDataStore.setBrightnessNitsForDefaultDisplay(nits); 167 } 168 notifyListeners(float brightness)169 private void notifyListeners(float brightness) { 170 for (BrightnessSettingListener l : mListeners) { 171 l.onBrightnessChanged(brightness); 172 } 173 } 174 175 /** 176 * Listener for changes to system brightness. 177 */ 178 public interface BrightnessSettingListener { 179 180 /** 181 * Notify that the brightness has changed. 182 */ onBrightnessChanged(float brightness)183 void onBrightnessChanged(float brightness); 184 } 185 } 186