1 /* 2 * Copyright (C) 2019 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 android.hardware.display; 18 19 import android.annotation.NonNull; 20 import android.annotation.UserIdInt; 21 import android.app.ActivityManager; 22 import android.content.ContentResolver; 23 import android.content.Context; 24 import android.database.ContentObserver; 25 import android.net.Uri; 26 import android.os.Handler; 27 import android.os.Looper; 28 import android.provider.Settings.Secure; 29 30 import java.time.LocalTime; 31 32 /** 33 * @hide 34 */ 35 public class NightDisplayListener { 36 37 private final Context mContext; 38 private final ColorDisplayManager mManager; 39 private final Handler mHandler; 40 private final ContentObserver mContentObserver; 41 private final int mUserId; 42 43 private Callback mCallback; 44 NightDisplayListener(@onNull Context context)45 public NightDisplayListener(@NonNull Context context) { 46 this(context, ActivityManager.getCurrentUser(), new Handler(Looper.getMainLooper())); 47 } 48 NightDisplayListener(@onNull Context context, @NonNull Handler handler)49 public NightDisplayListener(@NonNull Context context, @NonNull Handler handler) { 50 this(context, ActivityManager.getCurrentUser(), handler); 51 } 52 NightDisplayListener(@onNull Context context, @UserIdInt int userId, @NonNull Handler handler)53 public NightDisplayListener(@NonNull Context context, @UserIdInt int userId, 54 @NonNull Handler handler) { 55 mContext = context.getApplicationContext(); 56 mManager = mContext.getSystemService(ColorDisplayManager.class); 57 mUserId = userId; 58 59 mHandler = handler; 60 mContentObserver = new ContentObserver(mHandler) { 61 @Override 62 public void onChange(boolean selfChange, Uri uri) { 63 super.onChange(selfChange, uri); 64 final String setting = uri == null ? null : uri.getLastPathSegment(); 65 if (setting != null && mCallback != null) { 66 switch (setting) { 67 case Secure.NIGHT_DISPLAY_ACTIVATED: 68 mCallback.onActivated(mManager.isNightDisplayActivated()); 69 break; 70 case Secure.NIGHT_DISPLAY_AUTO_MODE: 71 mCallback.onAutoModeChanged(mManager.getNightDisplayAutoMode()); 72 break; 73 case Secure.NIGHT_DISPLAY_CUSTOM_START_TIME: 74 mCallback.onCustomStartTimeChanged( 75 mManager.getNightDisplayCustomStartTime()); 76 break; 77 case Secure.NIGHT_DISPLAY_CUSTOM_END_TIME: 78 mCallback.onCustomEndTimeChanged( 79 mManager.getNightDisplayCustomEndTime()); 80 break; 81 case Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE: 82 mCallback.onColorTemperatureChanged( 83 mManager.getNightDisplayColorTemperature()); 84 break; 85 } 86 } 87 } 88 }; 89 } 90 91 /** 92 * Register a callback to be invoked whenever the Night display settings are changed. 93 */ setCallback(Callback callback)94 public void setCallback(Callback callback) { 95 if (Looper.myLooper() != mHandler.getLooper()) { 96 mHandler.post(() -> setCallbackInternal(callback)); 97 } 98 setCallbackInternal(callback); 99 } 100 setCallbackInternal(Callback newCallback)101 private void setCallbackInternal(Callback newCallback) { 102 final Callback oldCallback = mCallback; 103 if (oldCallback != newCallback) { 104 mCallback = newCallback; 105 if (mCallback == null) { 106 mContext.getContentResolver().unregisterContentObserver(mContentObserver); 107 } else if (oldCallback == null) { 108 final ContentResolver cr = mContext.getContentResolver(); 109 cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_ACTIVATED), 110 false /* notifyForDescendants */, mContentObserver, mUserId); 111 cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_AUTO_MODE), 112 false /* notifyForDescendants */, mContentObserver, mUserId); 113 cr.registerContentObserver( 114 Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_START_TIME), 115 false /* notifyForDescendants */, mContentObserver, mUserId); 116 cr.registerContentObserver( 117 Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_END_TIME), 118 false /* notifyForDescendants */, mContentObserver, mUserId); 119 cr.registerContentObserver( 120 Secure.getUriFor(Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE), 121 false /* notifyForDescendants */, mContentObserver, mUserId); 122 } 123 } 124 } 125 126 /** 127 * Callback invoked whenever the Night display settings are changed. 128 */ 129 public interface Callback { 130 131 /** 132 * Callback invoked when the activated state changes. 133 * 134 * @param activated {@code true} if Night display is activated 135 */ onActivated(boolean activated)136 default void onActivated(boolean activated) { 137 } 138 139 /** 140 * Callback invoked when the auto mode changes. 141 * 142 * @param autoMode the auto mode to use 143 */ onAutoModeChanged(int autoMode)144 default void onAutoModeChanged(int autoMode) { 145 } 146 147 /** 148 * Callback invoked when the time to automatically activate Night display changes. 149 * 150 * @param startTime the local time to automatically activate Night display 151 */ onCustomStartTimeChanged(LocalTime startTime)152 default void onCustomStartTimeChanged(LocalTime startTime) { 153 } 154 155 /** 156 * Callback invoked when the time to automatically deactivate Night display changes. 157 * 158 * @param endTime the local time to automatically deactivate Night display 159 */ onCustomEndTimeChanged(LocalTime endTime)160 default void onCustomEndTimeChanged(LocalTime endTime) { 161 } 162 163 /** 164 * Callback invoked when the color temperature changes. 165 * 166 * @param colorTemperature the color temperature to tint the screen 167 */ onColorTemperatureChanged(int colorTemperature)168 default void onColorTemperatureChanged(int colorTemperature) { 169 } 170 } 171 } 172