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.AudioManager; 24 import android.media.VolumePolicy; 25 import android.os.Bundle; 26 import android.view.WindowManager.LayoutParams; 27 28 import com.android.settingslib.applications.InterestingConfigChanges; 29 import com.android.systemui.Dependency; 30 import com.android.systemui.SystemUI; 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 43 /** 44 * Implementation of VolumeComponent backed by the new volume dialog. 45 */ 46 public class VolumeDialogComponent implements VolumeComponent, TunerService.Tunable, 47 VolumeDialogControllerImpl.UserActivityListener{ 48 49 public static final String VOLUME_DOWN_SILENT = "sysui_volume_down_silent"; 50 public static final String VOLUME_UP_SILENT = "sysui_volume_up_silent"; 51 public static final String VOLUME_SILENT_DO_NOT_DISTURB = "sysui_do_not_disturb"; 52 53 public static final boolean DEFAULT_VOLUME_DOWN_TO_ENTER_SILENT = false; 54 public static final boolean DEFAULT_VOLUME_UP_TO_EXIT_SILENT = false; 55 public static final boolean DEFAULT_DO_NOT_DISTURB_WHEN_SILENT = false; 56 57 private final SystemUI mSysui; 58 protected final Context mContext; 59 private final VolumeDialogControllerImpl mController; 60 private final InterestingConfigChanges mConfigChanges = new InterestingConfigChanges( 61 ActivityInfo.CONFIG_FONT_SCALE | ActivityInfo.CONFIG_LOCALE 62 | ActivityInfo.CONFIG_ASSETS_PATHS | ActivityInfo.CONFIG_UI_MODE); 63 private VolumeDialog mDialog; 64 private VolumePolicy mVolumePolicy = new VolumePolicy( 65 DEFAULT_VOLUME_DOWN_TO_ENTER_SILENT, // volumeDownToEnterSilent 66 DEFAULT_VOLUME_UP_TO_EXIT_SILENT, // volumeUpToExitSilent 67 DEFAULT_DO_NOT_DISTURB_WHEN_SILENT, // doNotDisturbWhenSilent 68 400 // vibrateToSilentDebounce 69 ); 70 71 public VolumeDialogComponent(SystemUI sysui, Context context) { 72 mSysui = sysui; 73 mContext = context; 74 mController = (VolumeDialogControllerImpl) Dependency.get(VolumeDialogController.class); 75 mController.setUserActivityListener(this); 76 // Allow plugins to reference the VolumeDialogController. 77 Dependency.get(PluginDependencyProvider.class) 78 .allowPluginDependency(VolumeDialogController.class); 79 Dependency.get(ExtensionController.class).newExtension(VolumeDialog.class) 80 .withPlugin(VolumeDialog.class) 81 .withDefault(this::createDefault) 82 .withCallback(dialog -> { 83 if (mDialog != null) { 84 mDialog.destroy(); 85 } 86 mDialog = dialog; 87 mDialog.init(LayoutParams.TYPE_VOLUME_OVERLAY, mVolumeDialogCallback); 88 }).build(); 89 applyConfiguration(); 90 Dependency.get(TunerService.class).addTunable(this, VOLUME_DOWN_SILENT, VOLUME_UP_SILENT, 91 VOLUME_SILENT_DO_NOT_DISTURB); 92 } 93 94 protected VolumeDialog createDefault() { 95 VolumeDialogImpl impl = new VolumeDialogImpl(mContext); 96 impl.setStreamImportant(AudioManager.STREAM_SYSTEM, false); 97 impl.setAutomute(true); 98 impl.setSilentMode(false); 99 return impl; 100 } 101 102 @Override 103 public void onTuningChanged(String key, String newValue) { 104 boolean volumeDownToEnterSilent = mVolumePolicy.volumeDownToEnterSilent; 105 boolean volumeUpToExitSilent = mVolumePolicy.volumeUpToExitSilent; 106 boolean doNotDisturbWhenSilent = mVolumePolicy.doNotDisturbWhenSilent; 107 108 if (VOLUME_DOWN_SILENT.equals(key)) { 109 volumeDownToEnterSilent = 110 TunerService.parseIntegerSwitch(newValue, DEFAULT_VOLUME_DOWN_TO_ENTER_SILENT); 111 } else if (VOLUME_UP_SILENT.equals(key)) { 112 volumeUpToExitSilent = 113 TunerService.parseIntegerSwitch(newValue, DEFAULT_VOLUME_UP_TO_EXIT_SILENT); 114 } else if (VOLUME_SILENT_DO_NOT_DISTURB.equals(key)) { 115 doNotDisturbWhenSilent = 116 TunerService.parseIntegerSwitch(newValue, DEFAULT_DO_NOT_DISTURB_WHEN_SILENT); 117 } 118 119 setVolumePolicy(volumeDownToEnterSilent, volumeUpToExitSilent, doNotDisturbWhenSilent, 120 mVolumePolicy.vibrateToSilentDebounce); 121 } 122 123 private void setVolumePolicy(boolean volumeDownToEnterSilent, boolean volumeUpToExitSilent, 124 boolean doNotDisturbWhenSilent, int vibrateToSilentDebounce) { 125 mVolumePolicy = new VolumePolicy(volumeDownToEnterSilent, volumeUpToExitSilent, 126 doNotDisturbWhenSilent, vibrateToSilentDebounce); 127 mController.setVolumePolicy(mVolumePolicy); 128 } 129 130 void setEnableDialogs(boolean volumeUi, boolean safetyWarning) { 131 mController.setEnableDialogs(volumeUi, safetyWarning); 132 } 133 134 @Override 135 public void onUserActivity() { 136 final KeyguardViewMediator kvm = mSysui.getComponent(KeyguardViewMediator.class); 137 if (kvm != null) { 138 kvm.userActivity(); 139 } 140 } 141 142 private void applyConfiguration() { 143 mController.setVolumePolicy(mVolumePolicy); 144 mController.showDndTile(true); 145 } 146 147 @Override 148 public void onConfigurationChanged(Configuration newConfig) { 149 if (mConfigChanges.applyNewConfig(mContext.getResources())) { 150 mController.mCallbacks.onConfigurationChanged(); 151 } 152 } 153 154 @Override 155 public void dismissNow() { 156 mController.dismiss(); 157 } 158 159 @Override 160 public void dispatchDemoCommand(String command, Bundle args) { 161 // noop 162 } 163 164 @Override 165 public void register() { 166 mController.register(); 167 DndTile.setCombinedIcon(mContext, true); 168 } 169 170 @Override 171 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 172 } 173 174 private void startSettings(Intent intent) { 175 Dependency.get(ActivityStarter.class).startActivity(intent, 176 true /* onlyProvisioned */, true /* dismissShade */); 177 } 178 179 private final VolumeDialogImpl.Callback mVolumeDialogCallback = new VolumeDialogImpl.Callback() { 180 @Override 181 public void onZenSettingsClicked() { 182 startSettings(ZenModePanel.ZEN_SETTINGS); 183 } 184 185 @Override 186 public void onZenPrioritySettingsClicked() { 187 startSettings(ZenModePanel.ZEN_PRIORITY_SETTINGS); 188 } 189 }; 190 191 } 192