1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.volume;
18 
19 import android.content.Context;
20 import android.content.Intent;
21 import android.content.pm.ActivityInfo;
22 import android.content.res.Configuration;
23 import android.media.VolumePolicy;
24 import android.os.Bundle;
25 import android.view.WindowManager.LayoutParams;
26 
27 import com.android.settingslib.applications.InterestingConfigChanges;
28 import com.android.systemui.dagger.SysUISingleton;
29 import com.android.systemui.demomode.DemoMode;
30 import com.android.systemui.demomode.DemoModeController;
31 import com.android.systemui.keyguard.KeyguardViewMediator;
32 import com.android.systemui.plugins.ActivityStarter;
33 import com.android.systemui.plugins.PluginDependencyProvider;
34 import com.android.systemui.plugins.VolumeDialog;
35 import com.android.systemui.plugins.VolumeDialogController;
36 import com.android.systemui.qs.tiles.DndTile;
37 import com.android.systemui.statusbar.policy.ExtensionController;
38 import com.android.systemui.tuner.TunerService;
39 
40 import java.io.FileDescriptor;
41 import java.io.PrintWriter;
42 import java.util.ArrayList;
43 import java.util.List;
44 
45 import javax.inject.Inject;
46 
47 /**
48  * Implementation of VolumeComponent backed by the new volume dialog.
49  */
50 @SysUISingleton
51 public class VolumeDialogComponent implements VolumeComponent, TunerService.Tunable,
52         VolumeDialogControllerImpl.UserActivityListener{
53 
54     public static final String VOLUME_DOWN_SILENT = "sysui_volume_down_silent";
55     public static final String VOLUME_UP_SILENT = "sysui_volume_up_silent";
56     public static final String VOLUME_SILENT_DO_NOT_DISTURB = "sysui_do_not_disturb";
57 
58     public static final boolean DEFAULT_VOLUME_DOWN_TO_ENTER_SILENT = false;
59     public static final boolean DEFAULT_VOLUME_UP_TO_EXIT_SILENT = false;
60     public static final boolean DEFAULT_DO_NOT_DISTURB_WHEN_SILENT = false;
61 
62     protected final Context mContext;
63     private final VolumeDialogControllerImpl mController;
64     private final InterestingConfigChanges mConfigChanges = new InterestingConfigChanges(
65             ActivityInfo.CONFIG_FONT_SCALE | ActivityInfo.CONFIG_LOCALE
66             | ActivityInfo.CONFIG_ASSETS_PATHS | ActivityInfo.CONFIG_UI_MODE);
67     private final KeyguardViewMediator mKeyguardViewMediator;
68     private final ActivityStarter mActivityStarter;
69     private VolumeDialog mDialog;
70     private VolumePolicy mVolumePolicy = new VolumePolicy(
71             DEFAULT_VOLUME_DOWN_TO_ENTER_SILENT,  // volumeDownToEnterSilent
72             DEFAULT_VOLUME_UP_TO_EXIT_SILENT,  // volumeUpToExitSilent
73             DEFAULT_DO_NOT_DISTURB_WHEN_SILENT,  // doNotDisturbWhenSilent
74             400    // vibrateToSilentDebounce
75     );
76 
77     @Inject
VolumeDialogComponent( Context context, KeyguardViewMediator keyguardViewMediator, ActivityStarter activityStarter, VolumeDialogControllerImpl volumeDialogController, DemoModeController demoModeController, PluginDependencyProvider pluginDependencyProvider, ExtensionController extensionController, TunerService tunerService, VolumeDialog volumeDialog)78     public VolumeDialogComponent(
79             Context context,
80             KeyguardViewMediator keyguardViewMediator,
81             ActivityStarter activityStarter,
82             VolumeDialogControllerImpl volumeDialogController,
83             DemoModeController demoModeController,
84             PluginDependencyProvider pluginDependencyProvider,
85             ExtensionController extensionController,
86             TunerService tunerService,
87             VolumeDialog volumeDialog) {
88         mContext = context;
89         mKeyguardViewMediator = keyguardViewMediator;
90         mActivityStarter = activityStarter;
91         mController = volumeDialogController;
92         mController.setUserActivityListener(this);
93         // Allow plugins to reference the VolumeDialogController.
94         pluginDependencyProvider.allowPluginDependency(VolumeDialogController.class);
95         extensionController.newExtension(VolumeDialog.class)
96                 .withPlugin(VolumeDialog.class)
97                 .withDefault(() -> volumeDialog)
98                 .withCallback(dialog -> {
99                     if (mDialog != null) {
100                         mDialog.destroy();
101                     }
102                     mDialog = dialog;
103                     mDialog.init(LayoutParams.TYPE_VOLUME_OVERLAY, mVolumeDialogCallback);
104                 }).build();
105         applyConfiguration();
106         tunerService.addTunable(this, VOLUME_DOWN_SILENT, VOLUME_UP_SILENT,
107                 VOLUME_SILENT_DO_NOT_DISTURB);
108         demoModeController.addCallback(this);
109     }
110 
111     @Override
onTuningChanged(String key, String newValue)112     public void onTuningChanged(String key, String newValue) {
113         boolean volumeDownToEnterSilent = mVolumePolicy.volumeDownToEnterSilent;
114         boolean volumeUpToExitSilent = mVolumePolicy.volumeUpToExitSilent;
115         boolean doNotDisturbWhenSilent = mVolumePolicy.doNotDisturbWhenSilent;
116 
117         if (VOLUME_DOWN_SILENT.equals(key)) {
118             volumeDownToEnterSilent =
119                 TunerService.parseIntegerSwitch(newValue, DEFAULT_VOLUME_DOWN_TO_ENTER_SILENT);
120         } else if (VOLUME_UP_SILENT.equals(key)) {
121             volumeUpToExitSilent =
122                 TunerService.parseIntegerSwitch(newValue, DEFAULT_VOLUME_UP_TO_EXIT_SILENT);
123         } else if (VOLUME_SILENT_DO_NOT_DISTURB.equals(key)) {
124             doNotDisturbWhenSilent =
125                 TunerService.parseIntegerSwitch(newValue, DEFAULT_DO_NOT_DISTURB_WHEN_SILENT);
126         }
127 
128         setVolumePolicy(volumeDownToEnterSilent, volumeUpToExitSilent, doNotDisturbWhenSilent,
129                 mVolumePolicy.vibrateToSilentDebounce);
130     }
131 
setVolumePolicy(boolean volumeDownToEnterSilent, boolean volumeUpToExitSilent, boolean doNotDisturbWhenSilent, int vibrateToSilentDebounce)132     private void setVolumePolicy(boolean volumeDownToEnterSilent, boolean volumeUpToExitSilent,
133             boolean doNotDisturbWhenSilent, int vibrateToSilentDebounce) {
134         mVolumePolicy = new VolumePolicy(volumeDownToEnterSilent, volumeUpToExitSilent,
135                 doNotDisturbWhenSilent, vibrateToSilentDebounce);
136         mController.setVolumePolicy(mVolumePolicy);
137     }
138 
setEnableDialogs(boolean volumeUi, boolean safetyWarning)139     void setEnableDialogs(boolean volumeUi, boolean safetyWarning) {
140         mController.setEnableDialogs(volumeUi, safetyWarning);
141     }
142 
143     @Override
onUserActivity()144     public void onUserActivity() {
145         mKeyguardViewMediator.userActivity();
146     }
147 
applyConfiguration()148     private void applyConfiguration() {
149         mController.setVolumePolicy(mVolumePolicy);
150         mController.showDndTile(true);
151     }
152 
153     @Override
onConfigurationChanged(Configuration newConfig)154     public void onConfigurationChanged(Configuration newConfig) {
155         if (mConfigChanges.applyNewConfig(mContext.getResources())) {
156             mController.mCallbacks.onConfigurationChanged();
157         }
158     }
159 
160     @Override
dismissNow()161     public void dismissNow() {
162         mController.dismiss();
163     }
164 
165     @Override
dispatchDemoCommand(String command, Bundle args)166     public void dispatchDemoCommand(String command, Bundle args) {
167         // noop
168     }
169 
170     @Override
demoCommands()171     public List<String> demoCommands() {
172         List<String> s = new ArrayList<>();
173         s.add(DemoMode.COMMAND_VOLUME);
174         return s;
175     }
176 
177     @Override
register()178     public void register() {
179         mController.register();
180         DndTile.setCombinedIcon(mContext, true);
181     }
182 
183     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)184     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
185     }
186 
startSettings(Intent intent)187     private void startSettings(Intent intent) {
188         mActivityStarter.startActivity(intent, true /* onlyProvisioned */, true /* dismissShade */);
189     }
190 
191     private final VolumeDialogImpl.Callback mVolumeDialogCallback = new VolumeDialogImpl.Callback() {
192         @Override
193         public void onZenSettingsClicked() {
194             startSettings(ZenModePanel.ZEN_SETTINGS);
195         }
196 
197         @Override
198         public void onZenPrioritySettingsClicked() {
199             startSettings(ZenModePanel.ZEN_PRIORITY_SETTINGS);
200         }
201     };
202 
203 }
204