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