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 final Handler mHandler = new Handler(Looper.getMainLooper()) { 44 @Override 45 public void handleMessage(Message msg) { 46 if (msg.what == MSG_BRIGHTNESS_CHANGED) { 47 float brightnessVal = Float.intBitsToFloat(msg.arg1); 48 notifyListeners(brightnessVal); 49 } 50 } 51 }; 52 53 private final CopyOnWriteArraySet<BrightnessSettingListener> mListeners = 54 new CopyOnWriteArraySet<>(); 55 56 @GuardedBy("mSyncRoot") 57 private float mBrightness; 58 BrightnessSetting(@onNull PersistentDataStore persistentDataStore, @NonNull LogicalDisplay logicalDisplay, DisplayManagerService.SyncRoot syncRoot)59 BrightnessSetting(@NonNull PersistentDataStore persistentDataStore, 60 @NonNull LogicalDisplay logicalDisplay, 61 DisplayManagerService.SyncRoot syncRoot) { 62 mPersistentDataStore = persistentDataStore; 63 mLogicalDisplay = logicalDisplay; 64 mBrightness = mPersistentDataStore.getBrightness( 65 mLogicalDisplay.getPrimaryDisplayDeviceLocked()); 66 mSyncRoot = syncRoot; 67 } 68 69 /** 70 * Returns the brightness from the brightness setting 71 * 72 * @return brightness for the current display 73 */ getBrightness()74 public float getBrightness() { 75 synchronized (mSyncRoot) { 76 return mBrightness; 77 } 78 } 79 80 /** 81 * Registers listener for brightness setting change events. 82 */ registerListener(BrightnessSettingListener l)83 public void registerListener(BrightnessSettingListener l) { 84 if (mListeners.contains(l)) { 85 Slog.wtf(TAG, "Duplicate Listener added"); 86 } 87 mListeners.add(l); 88 } 89 90 /** 91 * Unregisters listener for brightness setting change events. 92 * 93 * @param l listener 94 */ unregisterListener(BrightnessSettingListener l)95 public void unregisterListener(BrightnessSettingListener l) { 96 mListeners.remove(l); 97 } 98 setBrightness(float brightness)99 void setBrightness(float brightness) { 100 if (Float.isNaN(brightness)) { 101 Slog.w(TAG, "Attempting to set invalid brightness"); 102 return; 103 } 104 synchronized (mSyncRoot) { 105 // If the brightness is the same, we still need to update any listeners as the act of 106 // setting the brightness alone has side effects, like clearing any temporary 107 // brightness. We can skip persisting to disk, however, since it hasn't actually 108 // changed. 109 if (brightness != mBrightness) { 110 mPersistentDataStore.setBrightness(mLogicalDisplay.getPrimaryDisplayDeviceLocked(), 111 brightness); 112 } 113 mBrightness = brightness; 114 int toSend = Float.floatToIntBits(mBrightness); 115 Message msg = mHandler.obtainMessage(MSG_BRIGHTNESS_CHANGED, toSend, 0); 116 mHandler.sendMessage(msg); 117 } 118 } 119 120 /** 121 * @return The brightness for the default display in nits. Used when the underlying display 122 * device has changed but we want to persist the nit value. 123 */ getBrightnessNitsForDefaultDisplay()124 float getBrightnessNitsForDefaultDisplay() { 125 return mPersistentDataStore.getBrightnessNitsForDefaultDisplay(); 126 } 127 128 /** 129 * Set brightness in nits for the default display. Used when we want to persist the nit value 130 * even if the underlying display device changes. 131 * @param nits The brightness value in nits 132 */ setBrightnessNitsForDefaultDisplay(float nits)133 void setBrightnessNitsForDefaultDisplay(float nits) { 134 mPersistentDataStore.setBrightnessNitsForDefaultDisplay(nits); 135 } 136 notifyListeners(float brightness)137 private void notifyListeners(float brightness) { 138 for (BrightnessSettingListener l : mListeners) { 139 l.onBrightnessChanged(brightness); 140 } 141 } 142 143 /** 144 * Listener for changes to system brightness. 145 */ 146 public interface BrightnessSettingListener { 147 148 /** 149 * Notify that the brightness has changed. 150 */ onBrightnessChanged(float brightness)151 void onBrightnessChanged(float brightness); 152 } 153 } 154