1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.chrome.browser.night_mode; 6 7 import androidx.annotation.NonNull; 8 import androidx.annotation.VisibleForTesting; 9 import androidx.appcompat.app.AppCompatDelegate; 10 11 import org.chromium.base.CommandLine; 12 import org.chromium.chrome.browser.ChromeBaseAppCompatActivity; 13 import org.chromium.chrome.browser.flags.ChromeSwitches; 14 import org.chromium.chrome.browser.preferences.SharedPreferencesManager; 15 16 /** 17 * Holds an instance of {@link NightModeStateProvider} that provides night mode state for the entire 18 * application. 19 */ 20 public class GlobalNightModeStateProviderHolder { 21 private static NightModeStateProvider sInstance; 22 23 /** 24 * Created when night mode is not available or not supported. 25 */ 26 private static class DummyNightModeStateProvider implements NightModeStateProvider { 27 final boolean mIsNightModeForceEnabled; 28 DummyNightModeStateProvider()29 private DummyNightModeStateProvider() { 30 mIsNightModeForceEnabled = 31 CommandLine.getInstance().hasSwitch(ChromeSwitches.FORCE_ENABLE_NIGHT_MODE); 32 // Always stay in night mode if night mode is force enabled, and always stay in light 33 // mode if night mode is not available. 34 AppCompatDelegate.setDefaultNightMode(mIsNightModeForceEnabled 35 ? AppCompatDelegate.MODE_NIGHT_YES 36 : AppCompatDelegate.MODE_NIGHT_NO); 37 } 38 39 @Override isInNightMode()40 public boolean isInNightMode() { 41 return mIsNightModeForceEnabled; 42 } 43 44 @Override addObserver(@onNull Observer observer)45 public void addObserver(@NonNull Observer observer) {} 46 47 @Override removeObserver(@onNull Observer observer)48 public void removeObserver(@NonNull Observer observer) {} 49 } 50 51 /** 52 * @return The {@link NightModeStateProvider} that maintains the night mode state for the entire 53 * application. Note that UI widgets should always get the 54 * {@link NightModeStateProvider} from the {@link ChromeBaseAppCompatActivity} they are 55 * attached to, because the night mode state can be overridden at the activity level. 56 */ getInstance()57 public static NightModeStateProvider getInstance() { 58 if (sInstance == null) { 59 if (CommandLine.getInstance().hasSwitch(ChromeSwitches.FORCE_ENABLE_NIGHT_MODE) 60 || !NightModeUtils.isNightModeSupported()) { 61 sInstance = new DummyNightModeStateProvider(); 62 } else { 63 sInstance = new GlobalNightModeStateController(SystemNightModeMonitor.getInstance(), 64 PowerSavingModeMonitor.getInstance(), 65 SharedPreferencesManager.getInstance()); 66 } 67 } 68 return sInstance; 69 } 70 71 @VisibleForTesting resetInstanceForTesting()72 static void resetInstanceForTesting() { 73 sInstance = null; 74 } 75 } 76