1 /* 2 * Copyright (C) 2017 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 15 package com.android.systemui.plugins; 16 17 import android.content.ComponentName; 18 import android.media.AudioManager; 19 import android.media.AudioSystem; 20 import android.os.Handler; 21 import android.os.VibrationEffect; 22 import android.util.SparseArray; 23 24 import androidx.annotation.StringRes; 25 26 import com.android.systemui.plugins.VolumeDialogController.Callbacks; 27 import com.android.systemui.plugins.VolumeDialogController.State; 28 import com.android.systemui.plugins.VolumeDialogController.StreamState; 29 import com.android.systemui.plugins.annotations.DependsOn; 30 import com.android.systemui.plugins.annotations.ProvidesInterface; 31 32 /** 33 * Manages the VolumeDialog. 34 * 35 * Accessible through {@link PluginDependency} 36 */ 37 @ProvidesInterface(version = VolumeDialogController.VERSION) 38 @DependsOn(target = StreamState.class) 39 @DependsOn(target = State.class) 40 @DependsOn(target = Callbacks.class) 41 public interface VolumeDialogController { 42 int VERSION = 1; 43 setActiveStream(int stream)44 void setActiveStream(int stream); setStreamVolume(int stream, int userLevel)45 void setStreamVolume(int stream, int userLevel); setRingerMode(int ringerModeNormal, boolean external)46 void setRingerMode(int ringerModeNormal, boolean external); 47 hasVibrator()48 boolean hasVibrator(); vibrate(VibrationEffect effect)49 void vibrate(VibrationEffect effect); scheduleTouchFeedback()50 void scheduleTouchFeedback(); 51 getAudioManager()52 AudioManager getAudioManager(); 53 notifyVisible(boolean visible)54 void notifyVisible(boolean visible); 55 addCallback(Callbacks callbacks, Handler handler)56 void addCallback(Callbacks callbacks, Handler handler); removeCallback(Callbacks callbacks)57 void removeCallback(Callbacks callbacks); 58 userActivity()59 void userActivity(); getState()60 void getState(); 61 62 /** 63 * Get Captions enabled state 64 * 65 * @param checkForSwitchState set true when we'd like to switch captions enabled state after 66 * getting the latest captions state. 67 */ getCaptionsEnabledState(boolean checkForSwitchState)68 void getCaptionsEnabledState(boolean checkForSwitchState); 69 70 /** 71 * Set Captions enabled state 72 * 73 * @param enabled the captions enabled state we'd like to update. 74 */ setCaptionsEnabledState(boolean enabled)75 void setCaptionsEnabledState(boolean enabled); 76 77 /** 78 * Get Captions component state 79 * 80 * @param fromTooltip if it's triggered from tooltip. 81 */ getCaptionsComponentState(boolean fromTooltip)82 void getCaptionsComponentState(boolean fromTooltip); 83 84 @ProvidesInterface(version = StreamState.VERSION) 85 public static final class StreamState { 86 public static final int VERSION = 1; 87 88 public boolean dynamic; 89 public int level; 90 public int levelMin; 91 public int levelMax; 92 public boolean muted; 93 public boolean muteSupported; 94 public @StringRes int name; 95 public String remoteLabel; 96 public boolean routedToBluetooth; 97 copy()98 public StreamState copy() { 99 final StreamState rt = new StreamState(); 100 rt.dynamic = dynamic; 101 rt.level = level; 102 rt.levelMin = levelMin; 103 rt.levelMax = levelMax; 104 rt.muted = muted; 105 rt.muteSupported = muteSupported; 106 rt.name = name; 107 rt.remoteLabel = remoteLabel; 108 rt.routedToBluetooth = routedToBluetooth; 109 return rt; 110 } 111 } 112 113 @ProvidesInterface(version = State.VERSION) 114 public static final class State { 115 public static final int VERSION = 1; 116 117 public static int NO_ACTIVE_STREAM = -1; 118 119 public final SparseArray<StreamState> states = new SparseArray<>(); 120 121 public int ringerModeInternal; 122 public int ringerModeExternal; 123 public int zenMode; 124 public ComponentName effectsSuppressor; 125 public String effectsSuppressorName; 126 public int activeStream = NO_ACTIVE_STREAM; 127 public boolean disallowAlarms; 128 public boolean disallowMedia; 129 public boolean disallowSystem; 130 public boolean disallowRinger; 131 copy()132 public State copy() { 133 final State rt = new State(); 134 for (int i = 0; i < states.size(); i++) { 135 rt.states.put(states.keyAt(i), states.valueAt(i).copy()); 136 } 137 rt.ringerModeExternal = ringerModeExternal; 138 rt.ringerModeInternal = ringerModeInternal; 139 rt.zenMode = zenMode; 140 if (effectsSuppressor != null) { 141 rt.effectsSuppressor = effectsSuppressor.clone(); 142 } 143 rt.effectsSuppressorName = effectsSuppressorName; 144 rt.activeStream = activeStream; 145 rt.disallowAlarms = disallowAlarms; 146 rt.disallowMedia = disallowMedia; 147 rt.disallowSystem = disallowSystem; 148 rt.disallowRinger = disallowRinger; 149 return rt; 150 } 151 152 @Override toString()153 public String toString() { 154 return toString(0); 155 } 156 toString(int indent)157 public String toString(int indent) { 158 final StringBuilder sb = new StringBuilder("{"); 159 if (indent > 0) sep(sb, indent); 160 for (int i = 0; i < states.size(); i++) { 161 if (i > 0) { 162 sep(sb, indent); 163 } 164 final int stream = states.keyAt(i); 165 final StreamState ss = states.valueAt(i); 166 sb.append(AudioSystem.streamToString(stream)).append(":").append(ss.level) 167 .append('[').append(ss.levelMin).append("..").append(ss.levelMax) 168 .append(']'); 169 if (ss.muted) sb.append(" [MUTED]"); 170 if (ss.dynamic) sb.append(" [DYNAMIC]"); 171 } 172 sep(sb, indent); sb.append("ringerModeExternal:").append(ringerModeExternal); 173 sep(sb, indent); sb.append("ringerModeInternal:").append(ringerModeInternal); 174 sep(sb, indent); sb.append("zenMode:").append(zenMode); 175 sep(sb, indent); sb.append("effectsSuppressor:").append(effectsSuppressor); 176 sep(sb, indent); sb.append("effectsSuppressorName:").append(effectsSuppressorName); 177 sep(sb, indent); sb.append("activeStream:").append(activeStream); 178 sep(sb, indent); sb.append("disallowAlarms:").append(disallowAlarms); 179 sep(sb, indent); sb.append("disallowMedia:").append(disallowMedia); 180 sep(sb, indent); sb.append("disallowSystem:").append(disallowSystem); 181 sep(sb, indent); sb.append("disallowRinger:").append(disallowRinger); 182 if (indent > 0) sep(sb, indent); 183 return sb.append('}').toString(); 184 } 185 sep(StringBuilder sb, int indent)186 private static void sep(StringBuilder sb, int indent) { 187 if (indent > 0) { 188 sb.append('\n'); 189 for (int i = 0; i < indent; i++) { 190 sb.append(' '); 191 } 192 } else { 193 sb.append(','); 194 } 195 } 196 } 197 198 @ProvidesInterface(version = Callbacks.VERSION) 199 public interface Callbacks { 200 int VERSION = 2; 201 202 // requires version 1 onShowRequested(int reason, boolean keyguardLocked, int lockTaskModeState)203 void onShowRequested(int reason, boolean keyguardLocked, int lockTaskModeState); onDismissRequested(int reason)204 void onDismissRequested(int reason); onStateChanged(State state)205 void onStateChanged(State state); onLayoutDirectionChanged(int layoutDirection)206 void onLayoutDirectionChanged(int layoutDirection); onConfigurationChanged()207 void onConfigurationChanged(); onShowVibrateHint()208 void onShowVibrateHint(); onShowSilentHint()209 void onShowSilentHint(); onScreenOff()210 void onScreenOff(); onShowSafetyWarning(int flags)211 void onShowSafetyWarning(int flags); onAccessibilityModeChanged(Boolean showA11yStream)212 void onAccessibilityModeChanged(Boolean showA11yStream); 213 214 /** 215 * Callback function for captions component state changed event 216 * 217 * @param isComponentEnabled the lateset captions component state. 218 * @param fromTooltip if it's triggered from tooltip. 219 */ onCaptionComponentStateChanged(Boolean isComponentEnabled, Boolean fromTooltip)220 void onCaptionComponentStateChanged(Boolean isComponentEnabled, Boolean fromTooltip); 221 222 /** 223 * Callback function for captions enabled state changed event 224 * 225 * @param isEnabled the lateset captions enabled state. 226 * @param checkBeforeSwitch intend to switch captions enabled state after the callback. 227 */ onCaptionEnabledStateChanged(Boolean isEnabled, Boolean checkBeforeSwitch)228 void onCaptionEnabledStateChanged(Boolean isEnabled, Boolean checkBeforeSwitch); 229 // requires version 2 onShowCsdWarning(@udioManager.CsdWarning int csdWarning, int durationMs)230 void onShowCsdWarning(@AudioManager.CsdWarning int csdWarning, int durationMs); 231 232 /** 233 * Callback function for when the volume changed due to a physical key press. 234 */ onVolumeChangedFromKey()235 void onVolumeChangedFromKey(); 236 } 237 } 238