• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.server.display.brightness.clamper;
18 
19 import android.annotation.NonNull;
20 import android.content.ContentResolver;
21 import android.content.Context;
22 import android.database.ContentObserver;
23 import android.hardware.display.BrightnessInfo;
24 import android.hardware.display.DisplayManagerInternal;
25 import android.os.Handler;
26 import android.os.UserHandle;
27 import android.provider.Settings;
28 
29 import com.android.internal.annotations.VisibleForTesting;
30 import com.android.server.display.DisplayBrightnessState;
31 import com.android.server.display.brightness.BrightnessReason;
32 
33 import java.io.PrintWriter;
34 
35 public class BrightnessWearBedtimeModeModifier implements BrightnessStateModifier,
36         BrightnessClamperController.DisplayDeviceDataListener,
37         BrightnessClamperController.StatefulModifier {
38 
39     public static final int BEDTIME_MODE_OFF = 0;
40     public static final int BEDTIME_MODE_ON = 1;
41 
42     private final Context mContext;
43 
44     private final ContentObserver mSettingsObserver;
45     protected final Handler mHandler;
46     protected final BrightnessClamperController.ClamperChangeListener mChangeListener;
47 
48     private float mBrightnessCap;
49     private boolean mIsActive = false;
50     private boolean mApplied = false;
51 
BrightnessWearBedtimeModeModifier(Handler handler, Context context, BrightnessClamperController.ClamperChangeListener listener, WearBedtimeModeData data)52     BrightnessWearBedtimeModeModifier(Handler handler, Context context,
53             BrightnessClamperController.ClamperChangeListener listener, WearBedtimeModeData data) {
54         this(new Injector(), handler, context, listener, data);
55     }
56 
57     @VisibleForTesting
BrightnessWearBedtimeModeModifier(Injector injector, Handler handler, Context context, BrightnessClamperController.ClamperChangeListener listener, WearBedtimeModeData data)58     BrightnessWearBedtimeModeModifier(Injector injector, Handler handler, Context context,
59             BrightnessClamperController.ClamperChangeListener listener, WearBedtimeModeData data) {
60         mHandler = handler;
61         mChangeListener = listener;
62         mContext = context;
63         mBrightnessCap = data.getBrightnessWearBedtimeModeCap();
64         mSettingsObserver = new ContentObserver(mHandler) {
65             @Override
66             public void onChange(boolean selfChange) {
67                 final int bedtimeModeSetting = Settings.Global.getInt(
68                         mContext.getContentResolver(),
69                         Settings.Global.Wearable.BEDTIME_MODE,
70                         BEDTIME_MODE_OFF);
71                 mIsActive = bedtimeModeSetting == BEDTIME_MODE_ON;
72                 mChangeListener.onChanged();
73             }
74         };
75         injector.registerBedtimeModeObserver(context.getContentResolver(), mSettingsObserver);
76     }
77 
78     //region BrightnessStateModifier
79     @Override
apply(DisplayManagerInternal.DisplayPowerRequest request, DisplayBrightnessState.Builder stateBuilder)80     public void apply(DisplayManagerInternal.DisplayPowerRequest request,
81             DisplayBrightnessState.Builder stateBuilder) {
82         if (mIsActive && stateBuilder.getMaxBrightness() > mBrightnessCap) {
83             stateBuilder.setMaxBrightness(mBrightnessCap);
84             stateBuilder.setBrightness(Math.min(stateBuilder.getBrightness(), mBrightnessCap));
85             stateBuilder.setBrightnessMaxReason(
86                     BrightnessInfo.BRIGHTNESS_MAX_REASON_WEAR_BEDTIME_MODE);
87             stateBuilder.getBrightnessReason().addModifier(BrightnessReason.MODIFIER_THROTTLED);
88             // set fast change only when modifier is activated.
89             // this will allow auto brightness to apply slow change even when modifier is active
90             if (!mApplied) {
91                 stateBuilder.setIsSlowChange(false);
92             }
93             mApplied = true;
94         } else {
95             mApplied = false;
96         }
97     }
98 
99     @Override
stop()100     public void stop() {
101         mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
102     }
103 
104     @Override
dump(PrintWriter writer)105     public void dump(PrintWriter writer) {
106         writer.println("BrightnessWearBedtimeModeModifier:");
107         writer.println("  mBrightnessCap: " + mBrightnessCap);
108         writer.println("  mIsActive: " + mIsActive);
109         writer.println("  mApplied: " + mApplied);
110     }
111 
112     @Override
shouldListenToLightSensor()113     public boolean shouldListenToLightSensor() {
114         return false;
115     }
116 
117     @Override
setAmbientLux(float lux)118     public void setAmbientLux(float lux) {
119         // noop
120     }
121     //endregion
122 
123     //region DisplayDeviceDataListener
124     @Override
onDisplayChanged(BrightnessClamperController.DisplayDeviceData data)125     public void onDisplayChanged(BrightnessClamperController.DisplayDeviceData data) {
126         mHandler.post(() -> {
127             mBrightnessCap = data.getBrightnessWearBedtimeModeCap();
128             mChangeListener.onChanged();
129         });
130     }
131     //endregion
132 
133     //region StatefulModifier
134     @Override
applyStateChange( BrightnessClamperController.ModifiersAggregatedState aggregatedState)135     public void applyStateChange(
136             BrightnessClamperController.ModifiersAggregatedState aggregatedState) {
137         if (mIsActive && aggregatedState.mMaxBrightness > mBrightnessCap) {
138             aggregatedState.mMaxBrightness = mBrightnessCap;
139             aggregatedState.mMaxBrightnessReason =
140                     BrightnessInfo.BRIGHTNESS_MAX_REASON_WEAR_BEDTIME_MODE;
141         }
142     }
143     //endregion
144 
145     interface WearBedtimeModeData {
getBrightnessWearBedtimeModeCap()146         float getBrightnessWearBedtimeModeCap();
147     }
148 
149     @VisibleForTesting
150     static class Injector {
registerBedtimeModeObserver(@onNull ContentResolver cr, @NonNull ContentObserver observer)151         void registerBedtimeModeObserver(@NonNull ContentResolver cr,
152                 @NonNull ContentObserver observer) {
153             cr.registerContentObserver(
154                     Settings.Global.getUriFor(Settings.Global.Wearable.BEDTIME_MODE),
155                     /* notifyForDescendants= */ false, observer, UserHandle.USER_ALL);
156         }
157     }
158 }
159