1/*
2 * Copyright (C) 2016 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
15package com.android.systemui.statusbar.phone;
16
17import android.content.Context;
18import android.os.Handler;
19import android.os.Looper;
20import android.provider.Settings.Secure;
21
22import com.android.internal.annotations.VisibleForTesting;
23import com.android.internal.app.NightDisplayController;
24import com.android.systemui.Dependency;
25import com.android.systemui.Prefs;
26import com.android.systemui.Prefs.Key;
27import com.android.systemui.qs.QSTileHost;
28import com.android.systemui.qs.SecureSetting;
29import com.android.systemui.statusbar.policy.DataSaverController;
30import com.android.systemui.statusbar.policy.DataSaverController.Listener;
31import com.android.systemui.statusbar.policy.HotspotController;
32import com.android.systemui.statusbar.policy.HotspotController.Callback;
33
34/**
35 * Manages which tiles should be automatically added to QS.
36 */
37public class AutoTileManager {
38
39    private final Context mContext;
40    private final QSTileHost mHost;
41    private final Handler mHandler;
42
43    public AutoTileManager(Context context, QSTileHost host) {
44        mContext = context;
45        mHost = host;
46        mHandler = new Handler((Looper) Dependency.get(Dependency.BG_LOOPER));
47        if (!Prefs.getBoolean(context, Key.QS_HOTSPOT_ADDED, false)) {
48            Dependency.get(HotspotController.class).addCallback(mHotspotCallback);
49        }
50        if (!Prefs.getBoolean(context, Key.QS_DATA_SAVER_ADDED, false)) {
51            Dependency.get(DataSaverController.class).addCallback(mDataSaverListener);
52        }
53        if (!Prefs.getBoolean(context, Key.QS_INVERT_COLORS_ADDED, false)) {
54            mColorsSetting = new SecureSetting(mContext, mHandler,
55                    Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED) {
56                @Override
57                protected void handleValueChanged(int value, boolean observedChange) {
58                    if (value != 0) {
59                        mHost.addTile("inversion");
60                        Prefs.putBoolean(mContext, Key.QS_INVERT_COLORS_ADDED, true);
61                        mHandler.post(() -> mColorsSetting.setListening(false));
62                    }
63                }
64            };
65            mColorsSetting.setListening(true);
66        }
67        if (!Prefs.getBoolean(context, Key.QS_WORK_ADDED, false)) {
68            Dependency.get(ManagedProfileController.class).addCallback(mProfileCallback);
69        }
70
71        if (!Prefs.getBoolean(context, Key.QS_NIGHTDISPLAY_ADDED, false)
72                && NightDisplayController.isAvailable(mContext)) {
73            Dependency.get(NightDisplayController.class).setListener(mNightDisplayCallback);
74        }
75    }
76
77    public void destroy() {
78        mColorsSetting.setListening(false);
79        Dependency.get(HotspotController.class).removeCallback(mHotspotCallback);
80        Dependency.get(DataSaverController.class).removeCallback(mDataSaverListener);
81        Dependency.get(ManagedProfileController.class).removeCallback(mProfileCallback);
82        Dependency.get(NightDisplayController.class).setListener(null);
83    }
84
85    private final ManagedProfileController.Callback mProfileCallback =
86            new ManagedProfileController.Callback() {
87                @Override
88                public void onManagedProfileChanged() {
89                    if (Dependency.get(ManagedProfileController.class).hasActiveProfile()) {
90                        mHost.addTile("work");
91                        Prefs.putBoolean(mContext, Key.QS_WORK_ADDED, true);
92                        mHandler.post(() -> Dependency.get(ManagedProfileController.class)
93                                .removeCallback(mProfileCallback));
94                    }
95                }
96
97                @Override
98                public void onManagedProfileRemoved() {
99                }
100            };
101
102    private SecureSetting mColorsSetting;
103
104    private final DataSaverController.Listener mDataSaverListener = new Listener() {
105        @Override
106        public void onDataSaverChanged(boolean isDataSaving) {
107            if (isDataSaving) {
108                mHost.addTile("saver");
109                Prefs.putBoolean(mContext, Key.QS_DATA_SAVER_ADDED, true);
110                mHandler.post(() -> Dependency.get(DataSaverController.class).removeCallback(
111                        mDataSaverListener));
112            }
113        }
114    };
115
116    private final HotspotController.Callback mHotspotCallback = new Callback() {
117        @Override
118        public void onHotspotChanged(boolean enabled) {
119            if (enabled) {
120                mHost.addTile("hotspot");
121                Prefs.putBoolean(mContext, Key.QS_HOTSPOT_ADDED, true);
122                mHandler.post(() -> Dependency.get(HotspotController.class)
123                        .removeCallback(mHotspotCallback));
124            }
125        }
126    };
127
128    @VisibleForTesting
129    final NightDisplayController.Callback mNightDisplayCallback =
130            new NightDisplayController.Callback() {
131        @Override
132        public void onActivated(boolean activated) {
133            if (activated) {
134                addNightTile();
135            }
136        }
137
138        @Override
139        public void onAutoModeChanged(int autoMode) {
140            if (autoMode == NightDisplayController.AUTO_MODE_CUSTOM
141                    || autoMode == NightDisplayController.AUTO_MODE_TWILIGHT) {
142                addNightTile();
143            }
144        }
145
146        private void addNightTile() {
147            mHost.addTile("night");
148            Prefs.putBoolean(mContext, Key.QS_NIGHTDISPLAY_ADDED, true);
149            mHandler.post(() -> Dependency.get(NightDisplayController.class)
150                    .setListener(null));
151        }
152    };
153}
154