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