1 /* 2 * Copyright (C) 2019 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 15 package com.android.settings.display.darkmode; 16 17 import android.content.BroadcastReceiver; 18 import android.content.Context; 19 import android.content.Intent; 20 import android.content.IntentFilter; 21 import android.database.ContentObserver; 22 import android.net.Uri; 23 import android.os.Handler; 24 import android.os.Looper; 25 import android.os.PowerManager; 26 import android.provider.Settings; 27 import android.util.Log; 28 29 import com.android.internal.annotations.VisibleForTesting; 30 31 /** 32 * Observes changes for dark night settings*/ 33 public class DarkModeObserver { 34 private static final String TAG = "DarkModeObserver"; 35 private ContentObserver mContentObserver; 36 private final BroadcastReceiver mBatterySaverReceiver = new BroadcastReceiver() { 37 @Override 38 public void onReceive(Context context, Intent intent) { 39 mCallback.run(); 40 } 41 }; 42 private Runnable mCallback; 43 private Context mContext; 44 DarkModeObserver(Context context)45 public DarkModeObserver(Context context) { 46 mContext = context; 47 mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) { 48 @Override 49 public void onChange(boolean selfChange, Uri uri) { 50 super.onChange(selfChange, uri); 51 final String setting = uri == null ? null : uri.getLastPathSegment(); 52 if (setting != null && mCallback != null) { 53 mCallback.run(); 54 } 55 } 56 }; 57 } 58 59 /** 60 * subscribe callback when night mode changed in the database 61 * 62 * @param callback the callback that gets triggered when subscribed 63 */ subscribe(Runnable callback)64 public void subscribe(Runnable callback) { 65 callback.run(); 66 mCallback = callback; 67 final Uri uri = Settings.Secure.getUriFor(Settings.Secure.UI_NIGHT_MODE); 68 final Uri customType = 69 Settings.Secure.getUriFor(Settings.Secure.UI_NIGHT_MODE_CUSTOM_TYPE); 70 final Uri customStart = 71 Settings.Secure.getUriFor(Settings.Secure.DARK_THEME_CUSTOM_START_TIME); 72 final Uri customEnd = 73 Settings.Secure.getUriFor(Settings.Secure.DARK_THEME_CUSTOM_END_TIME); 74 mContext.getContentResolver() 75 .registerContentObserver(uri, false, mContentObserver); 76 mContext.getContentResolver() 77 .registerContentObserver(customType, false, mContentObserver); 78 mContext.getContentResolver() 79 .registerContentObserver(customStart, false, mContentObserver); 80 mContext.getContentResolver() 81 .registerContentObserver(customEnd, false, mContentObserver); 82 final IntentFilter batteryFilter = new IntentFilter(); 83 batteryFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED); 84 mContext.registerReceiver( 85 mBatterySaverReceiver, batteryFilter); 86 } 87 88 /** 89 * unsubscribe from dark ui database changes 90 */ unsubscribe()91 public void unsubscribe() { 92 mContext.getContentResolver().unregisterContentObserver(mContentObserver); 93 try { 94 mContext.unregisterReceiver(mBatterySaverReceiver); 95 } catch (IllegalArgumentException e) { 96 /* Ignore: unregistering an unregistered receiver */ 97 Log.w(TAG, e.getMessage()); 98 } 99 // NO-OP 100 mCallback = null; 101 } 102 103 @VisibleForTesting setContentObserver(ContentObserver co)104 protected void setContentObserver(ContentObserver co) { 105 mContentObserver = co; 106 } 107 108 @VisibleForTesting getContentObserver()109 protected ContentObserver getContentObserver() { 110 return mContentObserver; 111 } 112 } 113