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