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