1 /*
2  * Copyright (C) 2006 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.server.audio;
18 
19 import static android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED;
20 import static android.Manifest.permission.REMOTE_AUDIO_PLAYBACK;
21 import static android.app.BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT;
22 import static android.media.AudioDeviceInfo.TYPE_BLE_HEADSET;
23 import static android.media.AudioDeviceInfo.TYPE_BLE_SPEAKER;
24 import static android.media.AudioDeviceInfo.TYPE_BLUETOOTH_A2DP;
25 import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_HEADPHONES;
26 import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_UNKNOWN;
27 import static android.media.AudioManager.DEVICE_OUT_BLE_HEADSET;
28 import static android.media.AudioManager.DEVICE_OUT_BLE_SPEAKER;
29 import static android.media.AudioManager.DEVICE_OUT_BLUETOOTH_A2DP;
30 import static android.media.AudioManager.RINGER_MODE_NORMAL;
31 import static android.media.AudioManager.RINGER_MODE_SILENT;
32 import static android.media.AudioManager.RINGER_MODE_VIBRATE;
33 import static android.media.AudioManager.STREAM_MUSIC;
34 import static android.media.AudioManager.STREAM_SYSTEM;
35 import static android.os.Process.FIRST_APPLICATION_UID;
36 import static android.os.Process.INVALID_UID;
37 import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE;
38 import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
39 import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE;
40 
41 import static com.android.server.audio.SoundDoseHelper.ACTION_CHECK_MUSIC_ACTIVE;
42 import static com.android.server.utils.EventLogger.Event.ALOGE;
43 import static com.android.server.utils.EventLogger.Event.ALOGI;
44 import static com.android.server.utils.EventLogger.Event.ALOGW;
45 
46 import android.Manifest;
47 import android.annotation.IntDef;
48 import android.annotation.IntRange;
49 import android.annotation.NonNull;
50 import android.annotation.Nullable;
51 import android.annotation.RequiresPermission;
52 import android.annotation.SuppressLint;
53 import android.annotation.UserIdInt;
54 import android.app.ActivityManager;
55 import android.app.ActivityManagerInternal;
56 import android.app.AppGlobals;
57 import android.app.AppOpsManager;
58 import android.app.BroadcastOptions;
59 import android.app.IUidObserver;
60 import android.app.NotificationManager;
61 import android.app.UidObserver;
62 import android.app.role.OnRoleHoldersChangedListener;
63 import android.app.role.RoleManager;
64 import android.bluetooth.BluetoothDevice;
65 import android.bluetooth.BluetoothHeadset;
66 import android.bluetooth.BluetoothProfile;
67 import android.content.BroadcastReceiver;
68 import android.content.ComponentName;
69 import android.content.ContentResolver;
70 import android.content.Context;
71 import android.content.Intent;
72 import android.content.IntentFilter;
73 import android.content.pm.ApplicationInfo;
74 import android.content.pm.PackageInfo;
75 import android.content.pm.PackageManager;
76 import android.content.pm.ResolveInfo;
77 import android.content.pm.UserInfo;
78 import android.content.res.Configuration;
79 import android.content.res.Resources;
80 import android.database.ContentObserver;
81 import android.hardware.SensorPrivacyManager;
82 import android.hardware.SensorPrivacyManagerInternal;
83 import android.hardware.hdmi.HdmiAudioSystemClient;
84 import android.hardware.hdmi.HdmiClient;
85 import android.hardware.hdmi.HdmiControlManager;
86 import android.hardware.hdmi.HdmiPlaybackClient;
87 import android.hardware.hdmi.HdmiTvClient;
88 import android.hardware.input.InputManager;
89 import android.hardware.usb.UsbManager;
90 import android.hidl.manager.V1_0.IServiceManager;
91 import android.media.AudioAttributes;
92 import android.media.AudioAttributes.AttributeSystemUsage;
93 import android.media.AudioDeviceAttributes;
94 import android.media.AudioDeviceInfo;
95 import android.media.AudioDeviceVolumeManager;
96 import android.media.AudioFocusInfo;
97 import android.media.AudioFocusRequest;
98 import android.media.AudioFormat;
99 import android.media.AudioHalVersionInfo;
100 import android.media.AudioManager;
101 import android.media.AudioManager.AudioDeviceCategory;
102 import android.media.AudioManagerInternal;
103 import android.media.AudioMixerAttributes;
104 import android.media.AudioPlaybackConfiguration;
105 import android.media.AudioRecordingConfiguration;
106 import android.media.AudioRoutesInfo;
107 import android.media.AudioSystem;
108 import android.media.BluetoothProfileConnectionInfo;
109 import android.media.IAudioDeviceVolumeDispatcher;
110 import android.media.IAudioFocusDispatcher;
111 import android.media.IAudioModeDispatcher;
112 import android.media.IAudioRoutesObserver;
113 import android.media.IAudioServerStateDispatcher;
114 import android.media.IAudioService;
115 import android.media.ICapturePresetDevicesRoleDispatcher;
116 import android.media.ICommunicationDeviceDispatcher;
117 import android.media.IDeviceVolumeBehaviorDispatcher;
118 import android.media.IDevicesForAttributesCallback;
119 import android.media.IMuteAwaitConnectionCallback;
120 import android.media.IPlaybackConfigDispatcher;
121 import android.media.IPreferredMixerAttributesDispatcher;
122 import android.media.IRecordingConfigDispatcher;
123 import android.media.IRingtonePlayer;
124 import android.media.ISpatializerCallback;
125 import android.media.ISpatializerHeadToSoundStagePoseCallback;
126 import android.media.ISpatializerHeadTrackerAvailableCallback;
127 import android.media.ISpatializerHeadTrackingModeCallback;
128 import android.media.ISpatializerOutputCallback;
129 import android.media.IStrategyNonDefaultDevicesDispatcher;
130 import android.media.IStrategyPreferredDevicesDispatcher;
131 import android.media.IStreamAliasingDispatcher;
132 import android.media.IVolumeController;
133 import android.media.MediaMetrics;
134 import android.media.MediaRecorder.AudioSource;
135 import android.media.PlayerBase;
136 import android.media.Spatializer;
137 import android.media.VolumeInfo;
138 import android.media.VolumePolicy;
139 import android.media.audiofx.AudioEffect;
140 import android.media.audiopolicy.AudioMix;
141 import android.media.audiopolicy.AudioPolicy;
142 import android.media.audiopolicy.AudioPolicyConfig;
143 import android.media.audiopolicy.AudioProductStrategy;
144 import android.media.audiopolicy.AudioVolumeGroup;
145 import android.media.audiopolicy.IAudioPolicyCallback;
146 import android.media.permission.ClearCallingIdentityContext;
147 import android.media.permission.SafeCloseable;
148 import android.media.projection.IMediaProjection;
149 import android.media.projection.IMediaProjectionCallback;
150 import android.media.projection.IMediaProjectionManager;
151 import android.net.Uri;
152 import android.os.Binder;
153 import android.os.Build;
154 import android.os.Bundle;
155 import android.os.Handler;
156 import android.os.HwBinder;
157 import android.os.IBinder;
158 import android.os.Looper;
159 import android.os.Message;
160 import android.os.PermissionEnforcer;
161 import android.os.PersistableBundle;
162 import android.os.PowerManager;
163 import android.os.Process;
164 import android.os.RemoteCallbackList;
165 import android.os.RemoteException;
166 import android.os.ResultReceiver;
167 import android.os.ServiceDebugInfo;
168 import android.os.ServiceManager;
169 import android.os.ShellCallback;
170 import android.os.SystemClock;
171 import android.os.SystemProperties;
172 import android.os.UserHandle;
173 import android.os.UserManager;
174 import android.os.VibrationAttributes;
175 import android.os.VibrationEffect;
176 import android.os.Vibrator;
177 import android.os.VibratorManager;
178 import android.provider.Settings;
179 import android.provider.Settings.System;
180 import android.service.notification.ZenModeConfig;
181 import android.telecom.TelecomManager;
182 import android.telephony.SubscriptionManager;
183 import android.text.TextUtils;
184 import android.util.AndroidRuntimeException;
185 import android.util.ArrayMap;
186 import android.util.ArraySet;
187 import android.util.IntArray;
188 import android.util.Log;
189 import android.util.PrintWriterPrinter;
190 import android.util.Slog;
191 import android.util.SparseArray;
192 import android.util.SparseIntArray;
193 import android.view.KeyEvent;
194 import android.view.accessibility.AccessibilityManager;
195 import android.widget.Toast;
196 
197 import com.android.internal.annotations.GuardedBy;
198 import com.android.internal.annotations.VisibleForTesting;
199 import com.android.internal.os.SomeArgs;
200 import com.android.internal.util.DumpUtils;
201 import com.android.internal.util.Preconditions;
202 import com.android.server.EventLogTags;
203 import com.android.server.LocalServices;
204 import com.android.server.SystemService;
205 import com.android.server.audio.AudioServiceEvents.DeviceVolumeEvent;
206 import com.android.server.audio.AudioServiceEvents.PhoneStateEvent;
207 import com.android.server.audio.AudioServiceEvents.VolChangedBroadcastEvent;
208 import com.android.server.audio.AudioServiceEvents.VolumeEvent;
209 import com.android.server.pm.UserManagerInternal;
210 import com.android.server.pm.UserManagerInternal.UserRestrictionsListener;
211 import com.android.server.pm.UserManagerService;
212 import com.android.server.utils.EventLogger;
213 import com.android.server.wm.ActivityTaskManagerInternal;
214 
215 import java.io.FileDescriptor;
216 import java.io.PrintWriter;
217 import java.lang.annotation.Retention;
218 import java.lang.annotation.RetentionPolicy;
219 import java.text.SimpleDateFormat;
220 import java.util.ArrayList;
221 import java.util.Arrays;
222 import java.util.Collection;
223 import java.util.Date;
224 import java.util.HashMap;
225 import java.util.HashSet;
226 import java.util.Iterator;
227 import java.util.LinkedHashMap;
228 import java.util.List;
229 import java.util.Map;
230 import java.util.NoSuchElementException;
231 import java.util.Objects;
232 import java.util.Set;
233 import java.util.TreeSet;
234 import java.util.UUID;
235 import java.util.concurrent.Executor;
236 import java.util.concurrent.atomic.AtomicBoolean;
237 import java.util.concurrent.atomic.AtomicInteger;
238 import java.util.function.BooleanSupplier;
239 import java.util.stream.Collectors;
240 
241 /**
242  * The implementation of the audio service for volume, audio focus, device management...
243  * <p>
244  * This implementation focuses on delivering a responsive UI. Most methods are
245  * asynchronous to external calls. For example, the task of setting a volume
246  * will update our internal state, but in a separate thread will set the system
247  * volume and later persist to the database. Similarly, setting the ringer mode
248  * will update the state and broadcast a change and in a separate thread later
249  * persist the ringer mode.
250  *
251  * @hide
252  */
253 public class AudioService extends IAudioService.Stub
254         implements AccessibilityManager.TouchExplorationStateChangeListener,
255             AccessibilityManager.AccessibilityServicesStateChangeListener,
256             AudioSystemAdapter.OnRoutingUpdatedListener,
257             AudioSystemAdapter.OnVolRangeInitRequestListener {
258 
259     private static final String TAG = "AS.AudioService";
260 
261     private final AudioSystemAdapter mAudioSystem;
262     private final SystemServerAdapter mSystemServer;
263     private final SettingsAdapter mSettings;
264     private final AudioPolicyFacade mAudioPolicy;
265 
266     /** Debug audio mode */
267     protected static final boolean DEBUG_MODE = false;
268 
269     /** Debug audio policy feature */
270     protected static final boolean DEBUG_AP = false;
271 
272     /** Debug volumes */
273     protected static final boolean DEBUG_VOL = false;
274 
275     /** debug calls to devices APIs */
276     protected static final boolean DEBUG_DEVICES = false;
277 
278     /** Debug communication route */
279     protected static final boolean DEBUG_COMM_RTE = false;
280 
281     /** Debug log sound fx (touchsounds...) in dumpsys */
282     protected static final boolean DEBUG_LOG_SOUND_FX = false;
283 
284     /** How long to delay before persisting a change in volume/ringer mode. */
285     private static final int PERSIST_DELAY = 500;
286 
287     /** How long to delay after a volume down event before unmuting a stream */
288     private static final int UNMUTE_STREAM_DELAY = 350;
289 
290     /**
291      * Delay before disconnecting a device that would cause BECOMING_NOISY intent to be sent,
292      * to give a chance to applications to pause.
293      */
294     @VisibleForTesting
295     public static final int BECOMING_NOISY_DELAY_MS = 1000;
296 
297     /**
298      * Only used in the result from {@link #checkForRingerModeChange(int, int, int)}
299      */
300     private static final int FLAG_ADJUST_VOLUME = 1;
301 
302     final Context mContext;
303     private final ContentResolver mContentResolver;
304     private final AppOpsManager mAppOps;
305 
306     // the platform type affects volume and silent mode behavior
307     private final int mPlatformType;
308 
309     // indicates whether the system maps all streams to a single stream.
310     private final boolean mIsSingleVolume;
311 
312     /**
313      * indicates whether STREAM_NOTIFICATION is aliased to STREAM_RING
314      *     not final due to test method, see {@link #setNotifAliasRingForTest(boolean)}.
315      */
316     private boolean mNotifAliasRing = false;
317 
318     /**
319      * Test method to temporarily override whether STREAM_NOTIFICATION is aliased to STREAM_RING,
320      * volumes will be updated in case of a change.
321      * @param alias if true, STREAM_NOTIFICATION is aliased to STREAM_RING
322      */
323     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setNotifAliasRingForTest(boolean alias)324     public void setNotifAliasRingForTest(boolean alias) {
325         super.setNotifAliasRingForTest_enforcePermission();
326         boolean update = (mNotifAliasRing != alias);
327         mNotifAliasRing = alias;
328         if (update) {
329             updateStreamVolumeAlias(true, "AudioServiceTest");
330         }
331     }
332 
isPlatformVoice()333     /*package*/ boolean isPlatformVoice() {
334         return mPlatformType == AudioSystem.PLATFORM_VOICE;
335     }
336 
isPlatformTelevision()337     /*package*/ boolean isPlatformTelevision() {
338         return mPlatformType == AudioSystem.PLATFORM_TELEVISION;
339     }
340 
isPlatformAutomotive()341     /*package*/ boolean isPlatformAutomotive() {
342         return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
343     }
344 
345     /** The controller for the volume UI. */
346     private final VolumeController mVolumeController = new VolumeController();
347 
348     // sendMsg() flags
349     /** If the msg is already queued, replace it with this one. */
350     private static final int SENDMSG_REPLACE = 0;
351     /** If the msg is already queued, ignore this one and leave the old. */
352     private static final int SENDMSG_NOOP = 1;
353     /** If the msg is already queued, queue this one and leave the old. */
354     private static final int SENDMSG_QUEUE = 2;
355 
356     // AudioHandler messages
357     /*package*/ static final int MSG_SET_DEVICE_VOLUME = 0;
358     private static final int MSG_PERSIST_VOLUME = 1;
359     private static final int MSG_PERSIST_VOLUME_GROUP = 2;
360     private static final int MSG_PERSIST_RINGER_MODE = 3;
361     private static final int MSG_AUDIO_SERVER_DIED = 4;
362     private static final int MSG_PLAY_SOUND_EFFECT = 5;
363     private static final int MSG_LOAD_SOUND_EFFECTS = 7;
364     private static final int MSG_SET_FORCE_USE = 8;
365     private static final int MSG_SET_ALL_VOLUMES = 10;
366     private static final int MSG_UNLOAD_SOUND_EFFECTS = 15;
367     private static final int MSG_SYSTEM_READY = 16;
368     private static final int MSG_UNMUTE_STREAM = 18;
369     private static final int MSG_DYN_POLICY_MIX_STATE_UPDATE = 19;
370     private static final int MSG_INDICATE_SYSTEM_READY = 20;
371     private static final int MSG_ACCESSORY_PLUG_MEDIA_UNMUTE = 21;
372     private static final int MSG_NOTIFY_VOL_EVENT = 22;
373     private static final int MSG_DISPATCH_AUDIO_SERVER_STATE = 23;
374     private static final int MSG_ENABLE_SURROUND_FORMATS = 24;
375     private static final int MSG_UPDATE_RINGER_MODE = 25;
376     private static final int MSG_SET_DEVICE_STREAM_VOLUME = 26;
377     private static final int MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS = 27;
378     private static final int MSG_HDMI_VOLUME_CHECK = 28;
379     private static final int MSG_PLAYBACK_CONFIG_CHANGE = 29;
380     private static final int MSG_BROADCAST_MICROPHONE_MUTE = 30;
381     private static final int MSG_CHECK_MODE_FOR_UID = 31;
382     private static final int MSG_STREAM_DEVICES_CHANGED = 32;
383     private static final int MSG_UPDATE_VOLUME_STATES_FOR_DEVICE = 33;
384     private static final int MSG_REINIT_VOLUMES = 34;
385     private static final int MSG_UPDATE_A11Y_SERVICE_UIDS = 35;
386     private static final int MSG_UPDATE_AUDIO_MODE = 36;
387     private static final int MSG_RECORDING_CONFIG_CHANGE = 37;
388     private static final int MSG_BT_DEV_CHANGED = 38;
389 
390     private static final int MSG_DISPATCH_AUDIO_MODE = 40;
391     private static final int MSG_ROUTING_UPDATED = 41;
392     private static final int MSG_INIT_HEADTRACKING_SENSORS = 42;
393     private static final int MSG_ADD_ASSISTANT_SERVICE_UID = 44;
394     private static final int MSG_REMOVE_ASSISTANT_SERVICE_UID = 45;
395     private static final int MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID = 46;
396     private static final int MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR = 47;
397     private static final int MSG_ROTATION_UPDATE = 48;
398     private static final int MSG_FOLD_UPDATE = 49;
399     private static final int MSG_RESET_SPATIALIZER = 50;
400     private static final int MSG_NO_LOG_FOR_PLAYER_I = 51;
401     private static final int MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES = 52;
402     private static final int MSG_LOWER_VOLUME_TO_RS1 = 53;
403     private static final int MSG_CONFIGURATION_CHANGED = 54;
404 
405     /** Messages handled by the {@link SoundDoseHelper}. */
406     /*package*/ static final int SAFE_MEDIA_VOLUME_MSG_START = 1000;
407 
408     // start of messages handled under wakelock
409     //   these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
410     //   and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
411     private static final int MSG_DISABLE_AUDIO_FOR_UID = 100;
412     private static final int MSG_INIT_STREAMS_VOLUMES = 101;
413     private static final int MSG_INIT_SPATIALIZER = 102;
414     private static final int MSG_INIT_ADI_DEVICE_STATES = 103;
415 
416     // end of messages handled under wakelock
417 
418     // retry delay in case of failure to indicate system ready to AudioFlinger
419     private static final int INDICATE_SYSTEM_READY_RETRY_DELAY_MS = 1000;
420 
421     // List of empty UIDs used to reset the active assistant list
422     private static final int[] NO_ACTIVE_ASSISTANT_SERVICE_UIDS = new int[0];
423 
424     // check playback or record activity every 6 seconds for UIDs owning mode IN_COMMUNICATION
425     private static final int CHECK_MODE_FOR_UID_PERIOD_MS = 6000;
426 
427     /** @see AudioSystemThread */
428     private AudioSystemThread mAudioSystemThread;
429     /** @see AudioHandler */
430     private AudioHandler mAudioHandler;
431     /** @see VolumeStreamState */
432     private VolumeStreamState[] mStreamStates;
433 
getVssVolumeForDevice(int stream, int device)434     /*package*/ int getVssVolumeForDevice(int stream, int device) {
435         return mStreamStates[stream].getIndex(device);
436     }
437 
getVssVolumeForStream(int stream)438     /*package*/ VolumeStreamState getVssVolumeForStream(int stream) {
439         return mStreamStates[stream];
440     }
441 
getMaxVssVolumeForStream(int stream)442     /*package*/ int getMaxVssVolumeForStream(int stream) {
443         return mStreamStates[stream].getMaxIndex();
444     }
445 
446     private SettingsObserver mSettingsObserver;
447 
448     private AtomicInteger mMode = new AtomicInteger(AudioSystem.MODE_NORMAL);
449 
450     // protects mRingerMode
451     private final Object mSettingsLock = new Object();
452 
453    /** Maximum volume index values for audio streams */
454     protected static int[] MAX_STREAM_VOLUME = new int[] {
455         5,  // STREAM_VOICE_CALL
456         7,  // STREAM_SYSTEM
457         7,  // STREAM_RING            // configured by config_audio_ring_vol_steps
458         15, // STREAM_MUSIC
459         7,  // STREAM_ALARM
460         7,  // STREAM_NOTIFICATION    // configured by config_audio_notif_vol_steps
461         15, // STREAM_BLUETOOTH_SCO
462         7,  // STREAM_SYSTEM_ENFORCED
463         15, // STREAM_DTMF
464         15, // STREAM_TTS
465         15, // STREAM_ACCESSIBILITY
466         15  // STREAM_ASSISTANT
467     };
468 
469     /** Minimum volume index values for audio streams */
470     protected static int[] MIN_STREAM_VOLUME = new int[] {
471         1,  // STREAM_VOICE_CALL
472         0,  // STREAM_SYSTEM
473         0,  // STREAM_RING
474         0,  // STREAM_MUSIC
475         1,  // STREAM_ALARM
476         0,  // STREAM_NOTIFICATION
477         0,  // STREAM_BLUETOOTH_SCO
478         0,  // STREAM_SYSTEM_ENFORCED
479         0,  // STREAM_DTMF
480         0,  // STREAM_TTS
481         1,  // STREAM_ACCESSIBILITY
482         0   // STREAM_ASSISTANT
483     };
484 
485     /* mStreamVolumeAlias[] indicates for each stream if it uses the volume settings
486      * of another stream: This avoids multiplying the volume settings for hidden
487      * stream types that follow other stream behavior for volume settings
488      * NOTE: do not create loops in aliases!
489      * Some streams alias to different streams according to device category (phone or tablet) or
490      * use case (in call vs off call...). See updateStreamVolumeAlias() for more details.
491      *  mStreamVolumeAlias contains STREAM_VOLUME_ALIAS_VOICE aliases for a voice capable device
492      *  (phone), STREAM_VOLUME_ALIAS_TELEVISION for a television or set-top box and
493      *  STREAM_VOLUME_ALIAS_DEFAULT for other devices (e.g. tablets).*/
494     private final int[] STREAM_VOLUME_ALIAS_VOICE = new int[] {
495         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
496         AudioSystem.STREAM_RING,            // STREAM_SYSTEM
497         AudioSystem.STREAM_RING,            // STREAM_RING
498         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
499         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
500         AudioSystem.STREAM_RING,            // STREAM_NOTIFICATION
501         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
502         AudioSystem.STREAM_RING,            // STREAM_SYSTEM_ENFORCED
503         AudioSystem.STREAM_RING,            // STREAM_DTMF
504         AudioSystem.STREAM_MUSIC,           // STREAM_TTS
505         AudioSystem.STREAM_MUSIC,           // STREAM_ACCESSIBILITY
506         AudioSystem.STREAM_MUSIC            // STREAM_ASSISTANT
507     };
508     private final int[] STREAM_VOLUME_ALIAS_TELEVISION = new int[] {
509         AudioSystem.STREAM_MUSIC,       // STREAM_VOICE_CALL
510         AudioSystem.STREAM_MUSIC,       // STREAM_SYSTEM
511         AudioSystem.STREAM_MUSIC,       // STREAM_RING
512         AudioSystem.STREAM_MUSIC,       // STREAM_MUSIC
513         AudioSystem.STREAM_MUSIC,       // STREAM_ALARM
514         AudioSystem.STREAM_MUSIC,       // STREAM_NOTIFICATION
515         AudioSystem.STREAM_BLUETOOTH_SCO,       // STREAM_BLUETOOTH_SCO
516         AudioSystem.STREAM_MUSIC,       // STREAM_SYSTEM_ENFORCED
517         AudioSystem.STREAM_MUSIC,       // STREAM_DTMF
518         AudioSystem.STREAM_MUSIC,       // STREAM_TTS
519         AudioSystem.STREAM_MUSIC,       // STREAM_ACCESSIBILITY
520         AudioSystem.STREAM_MUSIC        // STREAM_ASSISTANT
521     };
522     /**
523      * Using Volume groups configuration allows to control volume per attributes
524      * and group definition may differ from stream aliases.
525      * So, do not alias any stream on one another when using volume groups.
526      * TODO(b/181140246): volume group definition hosting alias definition.
527      */
528     private final int[] STREAM_VOLUME_ALIAS_NONE = new int[] {
529         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
530         AudioSystem.STREAM_SYSTEM,          // STREAM_SYSTEM
531         AudioSystem.STREAM_RING,            // STREAM_RING
532         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
533         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
534         AudioSystem.STREAM_NOTIFICATION,    // STREAM_NOTIFICATION
535         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
536         AudioSystem.STREAM_SYSTEM_ENFORCED, // STREAM_SYSTEM_ENFORCED
537         AudioSystem.STREAM_DTMF,            // STREAM_DTMF
538         AudioSystem.STREAM_TTS,             // STREAM_TTS
539         AudioSystem.STREAM_ACCESSIBILITY,   // STREAM_ACCESSIBILITY
540         AudioSystem.STREAM_ASSISTANT        // STREAM_ASSISTANT
541     };
542     private final int[] STREAM_VOLUME_ALIAS_DEFAULT = new int[] {
543         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
544         AudioSystem.STREAM_RING,            // STREAM_SYSTEM
545         AudioSystem.STREAM_RING,            // STREAM_RING
546         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
547         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
548         AudioSystem.STREAM_RING,            // STREAM_NOTIFICATION
549         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
550         AudioSystem.STREAM_RING,            // STREAM_SYSTEM_ENFORCED
551         AudioSystem.STREAM_RING,            // STREAM_DTMF
552         AudioSystem.STREAM_MUSIC,           // STREAM_TTS
553         AudioSystem.STREAM_MUSIC,           // STREAM_ACCESSIBILITY
554         AudioSystem.STREAM_MUSIC            // STREAM_ASSISTANT
555     };
556     protected static int[] mStreamVolumeAlias;
557     private static final int UNSET_INDEX = -1;
558 
559     /**
560      * Map AudioSystem.STREAM_* constants to app ops.  This should be used
561      * after mapping through mStreamVolumeAlias.
562      */
563     private static final int[] STREAM_VOLUME_OPS = new int[] {
564         AppOpsManager.OP_AUDIO_VOICE_VOLUME,            // STREAM_VOICE_CALL
565         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_SYSTEM
566         AppOpsManager.OP_AUDIO_RING_VOLUME,             // STREAM_RING
567         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_MUSIC
568         AppOpsManager.OP_AUDIO_ALARM_VOLUME,            // STREAM_ALARM
569         AppOpsManager.OP_AUDIO_NOTIFICATION_VOLUME,     // STREAM_NOTIFICATION
570         AppOpsManager.OP_AUDIO_BLUETOOTH_VOLUME,        // STREAM_BLUETOOTH_SCO
571         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_SYSTEM_ENFORCED
572         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_DTMF
573         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_TTS
574         AppOpsManager.OP_AUDIO_ACCESSIBILITY_VOLUME,    // STREAM_ACCESSIBILITY
575         AppOpsManager.OP_AUDIO_MEDIA_VOLUME             // STREAM_ASSISTANT
576     };
577 
578     private final boolean mUseFixedVolume;
579     private final boolean mUseVolumeGroupAliases;
580 
581     // If absolute volume is supported in AVRCP device
582     private volatile boolean mAvrcpAbsVolSupported = false;
583 
584     /**
585     * Default stream type used for volume control in the absence of playback
586     * e.g. user on homescreen, no app playing anything, presses hardware volume buttons, this
587     *    stream type is controlled.
588     */
589     protected static final int DEFAULT_VOL_STREAM_NO_PLAYBACK = AudioSystem.STREAM_MUSIC;
590 
591     private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() {
592         public void onError(int error) {
593             switch (error) {
594                 case AudioSystem.AUDIO_STATUS_SERVER_DIED:
595                     // check for null in case error callback is called during instance creation
596                     if (mRecordMonitor != null) {
597                         mRecordMonitor.onAudioServerDied();
598                     }
599                     // Notify the playback monitor that the audio server has died
600                     if (mPlaybackMonitor != null) {
601                         mPlaybackMonitor.onAudioServerDied();
602                     }
603                     sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED,
604                             SENDMSG_NOOP, 0, 0, null, 0);
605                     sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE,
606                             SENDMSG_QUEUE, 0, 0, null, 0);
607                     break;
608                 default:
609                     break;
610             }
611         }
612     };
613 
614     /**
615      * Current ringer mode from one of {@link AudioManager#RINGER_MODE_NORMAL},
616      * {@link AudioManager#RINGER_MODE_SILENT}, or
617      * {@link AudioManager#RINGER_MODE_VIBRATE}.
618      */
619     @GuardedBy("mSettingsLock")
620     private int mRingerMode;  // internal ringer mode, affects muting of underlying streams
621     @GuardedBy("mSettingsLock")
622     private int mRingerModeExternal = -1;  // reported ringer mode to outside clients (AudioManager)
623 
624     /** @see System#MODE_RINGER_STREAMS_AFFECTED */
625     private int mRingerModeAffectedStreams = 0;
626 
627     private int mZenModeAffectedStreams = 0;
628 
629     // Streams currently muted by ringer mode and dnd
630     protected static volatile int sRingerAndZenModeMutedStreams;
631 
632     /** Streams that can be muted. Do not resolve to aliases when checking.
633      * @see System#MUTE_STREAMS_AFFECTED */
634     private int mMuteAffectedStreams;
635 
636     @NonNull
637     private SoundEffectsHelper mSfxHelper;
638 
639     /**
640      * NOTE: setVibrateSetting(), getVibrateSetting(), shouldVibrate() are deprecated.
641      * mVibrateSetting is just maintained during deprecation period but vibration policy is
642      * now only controlled by mHasVibrator and mRingerMode
643      */
644     private int mVibrateSetting;
645 
646     // Is there a vibrator
647     private final boolean mHasVibrator;
648     // Used to play vibrations
649     private Vibrator mVibrator;
650     private static final VibrationAttributes TOUCH_VIBRATION_ATTRIBUTES =
651             VibrationAttributes.createForUsage(VibrationAttributes.USAGE_TOUCH);
652 
653     // Broadcast receiver for device connections intent broadcasts
654     private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver();
655 
656     private IMediaProjectionManager mProjectionService; // to validate projection token
657 
658     /** Interface for UserManagerService. */
659     private final UserManagerInternal mUserManagerInternal;
660     private final ActivityManagerInternal mActivityManagerInternal;
661     private final SensorPrivacyManagerInternal mSensorPrivacyManagerInternal;
662 
663     private final UserRestrictionsListener mUserRestrictionsListener =
664             new AudioServiceUserRestrictionsListener();
665 
666     // List of binder death handlers for setMode() client processes.
667     // The last process to have called setMode() is at the top of the list.
668     // package-private so it can be accessed in AudioDeviceBroker.getSetModeDeathHandlers
669     //TODO candidate to be moved to separate class that handles synchronization
670     @GuardedBy("mDeviceBroker.mSetModeLock")
671     /*package*/ final ArrayList<SetModeDeathHandler> mSetModeDeathHandlers =
672             new ArrayList<SetModeDeathHandler>();
673 
674     // true if boot sequence has been completed
675     private boolean mSystemReady;
676     // true if Intent.ACTION_USER_SWITCHED has ever been received
677     private boolean mUserSwitchedReceived;
678     // previous volume adjustment direction received by checkForRingerModeChange()
679     private int mPrevVolDirection = AudioManager.ADJUST_SAME;
680     // mVolumeControlStream is set by VolumePanel to temporarily force the stream type which volume
681     // is controlled by Vol keys.
682     private int mVolumeControlStream = -1;
683     // interpretation of whether the volume stream has been selected by the user by clicking on a
684     // volume slider to change which volume is controlled by the volume keys. Is false
685     // when mVolumeControlStream is -1.
686     private boolean mUserSelectedVolumeControlStream = false;
687     private final Object mForceControlStreamLock = new Object();
688     // VolumePanel is currently the only client of forceVolumeControlStream() and runs in system
689     // server process so in theory it is not necessary to monitor the client death.
690     // However it is good to be ready for future evolutions.
691     private ForceControlStreamClient mForceControlStreamClient = null;
692     // Used to play ringtones outside system_server
693     private volatile IRingtonePlayer mRingtonePlayer;
694 
695     // Devices for which the volume is fixed (volume is either max or muted)
696     Set<Integer> mFixedVolumeDevices = new HashSet<>(Arrays.asList(
697             AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET,
698             AudioSystem.DEVICE_OUT_AUX_LINE));
699     // Devices for which the volume is always max, no volume panel
700     Set<Integer> mFullVolumeDevices = new HashSet<>(Arrays.asList(
701             AudioSystem.DEVICE_OUT_HDMI_ARC,
702             AudioSystem.DEVICE_OUT_HDMI_EARC
703     ));
704 
705     // Devices where the framework sends a full scale audio signal, and controls the volume of
706     // the external audio system separately.
707     // For possible volume behaviors, see {@link AudioManager.AbsoluteDeviceVolumeBehavior}.
708     Map<Integer, AbsoluteVolumeDeviceInfo> mAbsoluteVolumeDeviceInfoMap = new ArrayMap<>();
709 
710     /**
711      * Stores information about a device using absolute volume behavior.
712      */
713     private static final class AbsoluteVolumeDeviceInfo {
714         private final AudioDeviceAttributes mDevice;
715         private final List<VolumeInfo> mVolumeInfos;
716         private final IAudioDeviceVolumeDispatcher mCallback;
717         private final boolean mHandlesVolumeAdjustment;
718         private @AudioManager.AbsoluteDeviceVolumeBehavior int mDeviceVolumeBehavior;
719 
AbsoluteVolumeDeviceInfo( AudioDeviceAttributes device, List<VolumeInfo> volumeInfos, IAudioDeviceVolumeDispatcher callback, boolean handlesVolumeAdjustment, @AudioManager.AbsoluteDeviceVolumeBehavior int behavior)720         private AbsoluteVolumeDeviceInfo(
721                 AudioDeviceAttributes device,
722                 List<VolumeInfo> volumeInfos,
723                 IAudioDeviceVolumeDispatcher callback,
724                 boolean handlesVolumeAdjustment,
725                 @AudioManager.AbsoluteDeviceVolumeBehavior int behavior) {
726             this.mDevice = device;
727             this.mVolumeInfos = volumeInfos;
728             this.mCallback = callback;
729             this.mHandlesVolumeAdjustment = handlesVolumeAdjustment;
730             this.mDeviceVolumeBehavior = behavior;
731         }
732 
733         /**
734          * Given a stream type, returns a matching VolumeInfo.
735          */
736         @Nullable
getMatchingVolumeInfoForStream(int streamType)737         private VolumeInfo getMatchingVolumeInfoForStream(int streamType) {
738             for (VolumeInfo volumeInfo : mVolumeInfos) {
739                 boolean streamTypeMatches = volumeInfo.hasStreamType()
740                         && volumeInfo.getStreamType() == streamType;
741                 boolean volumeGroupMatches = volumeInfo.hasVolumeGroup()
742                         && Arrays.stream(volumeInfo.getVolumeGroup().getLegacyStreamTypes())
743                         .anyMatch(s -> s == streamType);
744                 if (streamTypeMatches || volumeGroupMatches) {
745                     return volumeInfo;
746                 }
747             }
748             return null;
749         }
750     }
751 
752     // Devices for the which use the "absolute volume" concept (framework sends audio signal
753     // full scale, and volume control separately) and can be used for multiple use cases reflected
754     // by the audio mode (e.g. media playback in MODE_NORMAL, and phone calls in MODE_IN_CALL).
755     Set<Integer> mAbsVolumeMultiModeCaseDevices = new HashSet<>(
756             Arrays.asList(AudioSystem.DEVICE_OUT_HEARING_AID));
757 
758     private final boolean mMonitorRotation;
759 
760     private boolean mDockAudioMediaEnabled = true;
761 
762     /**
763      * RestorableParameters is a thread-safe class used to store a
764      * first-in first-out history of parameters for replay / restoration.
765      *
766      * The idealized implementation of restoration would have a list of setting methods and
767      * values to be called for restoration.  Explicitly managing such setters and
768      * values would be tedious - a simpler method is to store the values and the
769      * method implicitly by lambda capture (the values must be immutable or synchronization
770      * needs to be taken).
771      *
772      * We provide queueRestoreWithRemovalIfTrue() to allow
773      * the caller to provide a BooleanSupplier lambda, which conveniently packages
774      * the setter and its parameters needed for restoration.  If during restoration,
775      * the BooleanSupplier returns true, e.g. on error, it is removed from the mMap
776      * so as not to be called on a subsequent restore.
777      *
778      * We provide a setParameters() method as an example helper method.
779      */
780     private static class RestorableParameters {
781         /**
782          * Sets a parameter and queues for restoration if successful.
783          *
784          * @param id a string handle associated with this parameter.
785          * @param parameter the actual parameter string.
786          * @return the result of AudioSystem.setParameters
787          */
setParameters(@onNull String id, @NonNull String parameter)788         public int setParameters(@NonNull String id, @NonNull String parameter) {
789             Objects.requireNonNull(id, "id must not be null");
790             Objects.requireNonNull(parameter, "parameter must not be null");
791             synchronized (mMap) {
792                 final int status = AudioSystem.setParameters(parameter);
793                 if (status == AudioSystem.AUDIO_STATUS_OK) { // Java uses recursive mutexes.
794                     queueRestoreWithRemovalIfTrue(id, () -> { // remove me if set fails.
795                         return AudioSystem.setParameters(parameter) != AudioSystem.AUDIO_STATUS_OK;
796                     });
797                 }
798                 // Implementation detail: We do not mMap.remove(id); on failure.
799                 return status;
800             }
801         }
802 
803         /**
804          * Queues a restore method which is executed on restoreAll().
805          *
806          * If the supplier null, the id is removed from the restore map.
807          *
808          * Note: When the BooleanSupplier restore method is executed
809          * during restoreAll, if it returns true, it is removed from the
810          * restore map.
811          *
812          * @param id a unique tag associated with the restore method.
813          * @param supplier is a BooleanSupplier lambda.
814          */
queueRestoreWithRemovalIfTrue( @onNull String id, @Nullable BooleanSupplier supplier)815         public void queueRestoreWithRemovalIfTrue(
816                 @NonNull String id, @Nullable BooleanSupplier supplier) {
817             Objects.requireNonNull(id, "id must not be null");
818             synchronized (mMap) {
819                 if (supplier != null) {
820                     mMap.put(id, supplier);
821                 } else {
822                     mMap.remove(id);
823                 }
824             }
825         }
826 
827         /**
828          * Restore all parameters
829          *
830          * During restoration after audioserver death, any BooleanSupplier that returns
831          * true, for example on parameter restoration error, will be removed from mMap
832          * so as not to be executed on a subsequent restoreAll().
833          */
restoreAll()834         public void restoreAll() {
835             synchronized (mMap) {
836                 // Note: removing from values() also removes from the backing map.
837                 // TODO: Consider catching exceptions?
838                 mMap.values().removeIf(v -> {
839                     return v.getAsBoolean(); // this iterates the setters().
840                 });
841             }
842         }
843 
844         /**
845          * mMap is a LinkedHashMap<Key, Value> of parameters restored by restore().
846          * The Key is a unique id tag for identification.
847          * The Value is a lambda expression which returns true if the entry is to
848          *     be removed.
849          *
850          * 1) For memory limitation purposes, mMap keeps the latest MAX_ENTRIES
851          *    accessed in the map.
852          * 2) Parameters are restored in order of queuing, first in first out,
853          *    from earliest to latest.
854          */
855         @GuardedBy("mMap")
856         private Map</* @NonNull */ String, /* @NonNull */ BooleanSupplier> mMap =
857                 new LinkedHashMap<>() {
858             // TODO: do we need this memory limitation?
859             private static final int MAX_ENTRIES = 1000;  // limit our memory for now.
860             @Override
861             protected boolean removeEldestEntry(Map.Entry eldest) {
862                 if (size() <= MAX_ENTRIES) return false;
863                 Log.w(TAG, "Parameter map exceeds "
864                         + MAX_ENTRIES + " removing " + eldest.getKey()); // don't silently remove.
865                 return true;
866             }
867         };
868     }
869 
870     // We currently have one instance for mRestorableParameters used for
871     // setAdditionalOutputDeviceDelay().  Other methods requiring restoration could share this
872     // or use their own instance.
873     private RestorableParameters mRestorableParameters = new RestorableParameters();
874 
875     private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
876 
877     private PowerManager.WakeLock mAudioEventWakeLock;
878 
879     private final MediaFocusControl mMediaFocusControl;
880 
881     // Pre-scale for Bluetooth Absolute Volume
882     private float[] mPrescaleAbsoluteVolume = new float[] {
883         0.6f,    // Pre-scale for index 1
884         0.8f,    // Pre-scale for index 2
885         0.9f,   // Pre-scale for index 3
886     };
887 
888     private NotificationManager mNm;
889     private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate;
890     private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT;
891     private long mLoweredFromNormalToVibrateTime;
892 
893     // Array of Uids of valid assistant services to check if caller is one of them
894     @GuardedBy("mSettingsLock")
895     private final ArraySet<Integer> mAssistantUids = new ArraySet<>();
896     @GuardedBy("mSettingsLock")
897     private int mPrimaryAssistantUid = INVALID_UID;
898 
899     // Array of Uids of valid active assistant service to check if caller is one of them
900     @GuardedBy("mSettingsLock")
901     private int[] mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS;
902 
903     // Array of Uids of valid accessibility services to check if caller is one of them
904     private final Object mAccessibilityServiceUidsLock = new Object();
905     @GuardedBy("mAccessibilityServiceUidsLock")
906     private int[] mAccessibilityServiceUids;
907 
908     // Uid of the active input method service to check if caller is the one or not.
909     private int mInputMethodServiceUid = android.os.Process.INVALID_UID;
910     private final Object mInputMethodServiceUidLock = new Object();
911 
912     private int mEncodedSurroundMode;
913     private String mEnabledSurroundFormats;
914     private boolean mSurroundModeChanged;
915 
916     private boolean mSupportsMicPrivacyToggle;
917 
918     private boolean mMicMuteFromSwitch;
919     private boolean mMicMuteFromApi;
920     private boolean mMicMuteFromRestrictions;
921     private boolean mMicMuteFromPrivacyToggle;
922     // caches the value returned by AudioSystem.isMicrophoneMuted()
923     private boolean mMicMuteFromSystemCached;
924 
925     private boolean mNavigationRepeatSoundEffectsEnabled;
926     private boolean mHomeSoundEffectEnabled;
927 
928     private final SoundDoseHelper mSoundDoseHelper;
929 
930     private final Object mSupportedSystemUsagesLock = new Object();
931     @GuardedBy("mSupportedSystemUsagesLock")
932     private @AttributeSystemUsage int[] mSupportedSystemUsages =
933             new int[]{AudioAttributes.USAGE_CALL_ASSISTANT};
934 
935     // Defines the format for the connection "address" for ALSA devices
makeAlsaAddressString(int card, int device)936     public static String makeAlsaAddressString(int card, int device) {
937         return "card=" + card + ";device=" + device;
938     }
939 
940     public static final class Lifecycle extends SystemService {
941         private AudioService mService;
942 
Lifecycle(Context context)943         public Lifecycle(Context context) {
944             super(context);
945             mService = new AudioService(context,
946                               AudioSystemAdapter.getDefaultAdapter(),
947                               SystemServerAdapter.getDefaultAdapter(context),
948                               SettingsAdapter.getDefaultAdapter(),
949                               new DefaultAudioPolicyFacade(),
950                               null);
951 
952         }
953 
954         @Override
onStart()955         public void onStart() {
956             publishBinderService(Context.AUDIO_SERVICE, mService);
957         }
958 
959         @Override
onBootPhase(int phase)960         public void onBootPhase(int phase) {
961             if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
962                 mService.systemReady();
963             }
964         }
965     }
966 
967     final private IUidObserver mUidObserver = new UidObserver() {
968         @Override public void onUidGone(int uid, boolean disabled) {
969             // Once the uid is no longer running, no need to keep trying to disable its audio.
970             disableAudioForUid(false, uid);
971         }
972 
973         @Override public void onUidCachedChanged(int uid, boolean cached) {
974             disableAudioForUid(cached, uid);
975         }
976 
977         private void disableAudioForUid(boolean disable, int uid) {
978             queueMsgUnderWakeLock(mAudioHandler, MSG_DISABLE_AUDIO_FOR_UID,
979                     disable ? 1 : 0 /* arg1 */,  uid /* arg2 */,
980                     null /* obj */,  0 /* delay */);
981         }
982     };
983 
984     @GuardedBy("mSettingsLock")
985     private boolean mRttEnabled = false;
986 
987     ///////////////////////////////////////////////////////////////////////////
988     // Construction
989     ///////////////////////////////////////////////////////////////////////////
990 
991 
992     /**
993      * @param context
994      * @param audioSystem Adapter for {@link AudioSystem}
995      * @param systemServer Adapter for privilieged functionality for system server components
996      * @param settings Adapter for {@link Settings}
997      * @param looper Looper to use for the service's message handler. If this is null, an
998      *               {@link AudioSystemThread} is created as the messaging thread instead.
999      */
AudioService(Context context, AudioSystemAdapter audioSystem, SystemServerAdapter systemServer, SettingsAdapter settings, AudioPolicyFacade audioPolicy, @Nullable Looper looper)1000     public AudioService(Context context, AudioSystemAdapter audioSystem,
1001             SystemServerAdapter systemServer, SettingsAdapter settings,
1002             AudioPolicyFacade audioPolicy, @Nullable Looper looper) {
1003         this (context, audioSystem, systemServer, settings, audioPolicy, looper,
1004                 context.getSystemService(AppOpsManager.class),
1005                 PermissionEnforcer.fromContext(context));
1006     }
1007 
1008     /**
1009      * @param context
1010      * @param audioSystem Adapter for {@link AudioSystem}
1011      * @param systemServer Adapter for privilieged functionality for system server components
1012      * @param settings Adapter for {@link Settings}
1013      * @param looper Looper to use for the service's message handler. If this is null, an
1014      *               {@link AudioSystemThread} is created as the messaging thread instead.
1015      */
1016     @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
AudioService(Context context, AudioSystemAdapter audioSystem, SystemServerAdapter systemServer, SettingsAdapter settings, AudioPolicyFacade audioPolicy, @Nullable Looper looper, AppOpsManager appOps, @NonNull PermissionEnforcer enforcer)1017     public AudioService(Context context, AudioSystemAdapter audioSystem,
1018             SystemServerAdapter systemServer, SettingsAdapter settings,
1019             AudioPolicyFacade audioPolicy, @Nullable Looper looper, AppOpsManager appOps,
1020             @NonNull PermissionEnforcer enforcer) {
1021         super(enforcer);
1022         sLifecycleLogger.enqueue(new EventLogger.StringEvent("AudioService()"));
1023         mContext = context;
1024         mContentResolver = context.getContentResolver();
1025         mAppOps = appOps;
1026 
1027         mAudioSystem = audioSystem;
1028         mSystemServer = systemServer;
1029         mSettings = settings;
1030         mAudioPolicy = audioPolicy;
1031         mPlatformType = AudioSystem.getPlatformType(context);
1032 
1033         mDeviceBroker = new AudioDeviceBroker(mContext, this, mAudioSystem);
1034 
1035         mIsSingleVolume = AudioSystem.isSingleVolume(context);
1036 
1037         mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
1038         mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
1039         mSensorPrivacyManagerInternal =
1040                 LocalServices.getService(SensorPrivacyManagerInternal.class);
1041 
1042         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
1043         mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent");
1044 
1045         mSfxHelper = new SoundEffectsHelper(mContext, playerBase -> ignorePlayerLogs(playerBase));
1046 
1047         boolean binauralEnabledDefault = SystemProperties.getBoolean(
1048                 "ro.audio.spatializer_binaural_enabled_default", true);
1049         boolean transauralEnabledDefault = SystemProperties.getBoolean(
1050                 "ro.audio.spatializer_transaural_enabled_default", true);
1051         boolean headTrackingEnabledDefault = mContext.getResources().getBoolean(
1052                 com.android.internal.R.bool.config_spatial_audio_head_tracking_enabled_default);
1053 
1054         mSpatializerHelper = new SpatializerHelper(this, mAudioSystem, mDeviceBroker,
1055                 binauralEnabledDefault, transauralEnabledDefault, headTrackingEnabledDefault);
1056 
1057         mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
1058         mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator();
1059 
1060         mSupportsMicPrivacyToggle = context.getSystemService(SensorPrivacyManager.class)
1061                 .supportsSensorToggle(SensorPrivacyManager.Sensors.MICROPHONE);
1062 
1063         mUseVolumeGroupAliases = mContext.getResources().getBoolean(
1064                 com.android.internal.R.bool.config_handleVolumeAliasesUsingVolumeGroups);
1065 
1066         // Initialize volume
1067         // Priority 1 - Android Property
1068         // Priority 2 - Audio Policy Service
1069         // Priority 3 - Default Value
1070         if (AudioProductStrategy.getAudioProductStrategies().size() > 0) {
1071             int numStreamTypes = AudioSystem.getNumStreamTypes();
1072 
1073             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
1074                 AudioAttributes attr =
1075                         AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(
1076                                 streamType);
1077                 int maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr);
1078                 if (maxVolume != -1) {
1079                     MAX_STREAM_VOLUME[streamType] = maxVolume;
1080                 }
1081                 int minVolume = AudioSystem.getMinVolumeIndexForAttributes(attr);
1082                 if (minVolume != -1) {
1083                     MIN_STREAM_VOLUME[streamType] = minVolume;
1084                 }
1085             }
1086             if (mUseVolumeGroupAliases) {
1087                 // Set all default to uninitialized.
1088                 for (int stream = 0; stream < AudioSystem.DEFAULT_STREAM_VOLUME.length; stream++) {
1089                     AudioSystem.DEFAULT_STREAM_VOLUME[stream] = UNSET_INDEX;
1090                 }
1091             }
1092         }
1093 
1094         int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1);
1095         if (maxCallVolume != -1) {
1096             MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxCallVolume;
1097         }
1098 
1099         int defaultCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_default", -1);
1100         if (defaultCallVolume != -1 &&
1101                 defaultCallVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] &&
1102                 defaultCallVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]) {
1103             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = defaultCallVolume;
1104         } else {
1105             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] =
1106                     (MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] * 3) / 4;
1107         }
1108 
1109         int maxMusicVolume = SystemProperties.getInt("ro.config.media_vol_steps", -1);
1110         if (maxMusicVolume != -1) {
1111             MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxMusicVolume;
1112         }
1113 
1114         int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", -1);
1115         if (defaultMusicVolume != -1 &&
1116                 defaultMusicVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] &&
1117                 defaultMusicVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) {
1118             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = defaultMusicVolume;
1119         } else {
1120             if (isPlatformTelevision()) {
1121                 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] =
1122                         MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 4;
1123             } else {
1124                 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] =
1125                         MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 3;
1126             }
1127         }
1128 
1129         int maxAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_steps", -1);
1130         if (maxAlarmVolume != -1) {
1131             MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = maxAlarmVolume;
1132         }
1133 
1134         int defaultAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_default", -1);
1135         if (defaultAlarmVolume != -1 &&
1136                 defaultAlarmVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]) {
1137             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = defaultAlarmVolume;
1138         } else {
1139             // Default is 6 out of 7 (default maximum), so scale accordingly.
1140             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] =
1141                         6 * MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] / 7;
1142         }
1143 
1144         int maxSystemVolume = SystemProperties.getInt("ro.config.system_vol_steps", -1);
1145         if (maxSystemVolume != -1) {
1146             MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = maxSystemVolume;
1147         }
1148 
1149         int defaultSystemVolume = SystemProperties.getInt("ro.config.system_vol_default", -1);
1150         if (defaultSystemVolume != -1 &&
1151                 defaultSystemVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]) {
1152             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = defaultSystemVolume;
1153         } else {
1154             // Default is to use maximum.
1155             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] =
1156                         MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM];
1157         }
1158 
1159         int minAssistantVolume = SystemProperties.getInt("ro.config.assistant_vol_min", -1);
1160         if (minAssistantVolume != -1) {
1161             MIN_STREAM_VOLUME[AudioSystem.STREAM_ASSISTANT] = minAssistantVolume;
1162         }
1163 
1164         // Read following properties to configure max volume (number of steps) and default volume
1165         //   for STREAM_NOTIFICATION and STREAM_RING:
1166         //      config_audio_notif_vol_default
1167         //      config_audio_notif_vol_steps
1168         //      config_audio_ring_vol_default
1169         //      config_audio_ring_vol_steps
1170         int[] streams = { AudioSystem.STREAM_NOTIFICATION, AudioSystem.STREAM_RING };
1171         int[] stepsResId = { com.android.internal.R.integer.config_audio_notif_vol_steps,
1172                 com.android.internal.R.integer.config_audio_ring_vol_steps };
1173         int[] defaultResId = { com.android.internal.R.integer.config_audio_notif_vol_default,
1174                 com.android.internal.R.integer.config_audio_ring_vol_default };
1175         for (int s = 0; s < streams.length; s++) {
1176             try {
1177                 final int maxVol = mContext.getResources().getInteger(stepsResId[s]);
1178                 if (maxVol <= 0) {
1179                     throw new IllegalArgumentException("Invalid negative max volume for stream "
1180                             + streams[s]);
1181                 }
1182                 Log.i(TAG, "Stream " + streams[s] + ": using max vol of " + maxVol);
1183                 MAX_STREAM_VOLUME[streams[s]] = maxVol;
1184             } catch (Resources.NotFoundException e) {
1185                 Log.e(TAG, "Error querying max vol for stream type " + streams[s], e);
1186             }
1187             try {
1188                 final int defaultVol = mContext.getResources().getInteger(defaultResId[s]);
1189                 if (defaultVol > MAX_STREAM_VOLUME[streams[s]]) {
1190                     throw new IllegalArgumentException("Invalid default volume (" + defaultVol
1191                             + ") for stream " + streams[s] + ", greater than max volume of "
1192                             + MAX_STREAM_VOLUME[streams[s]]);
1193                 }
1194                 if (defaultVol < MIN_STREAM_VOLUME[streams[s]]) {
1195                     throw new IllegalArgumentException("Invalid default volume (" + defaultVol
1196                             + ") for stream " + streams[s] + ", lower than min volume of "
1197                             + MIN_STREAM_VOLUME[streams[s]]);
1198                 }
1199                 Log.i(TAG, "Stream " + streams[s] + ": using default vol of " + defaultVol);
1200                 AudioSystem.DEFAULT_STREAM_VOLUME[streams[s]] = defaultVol;
1201             } catch (Resources.NotFoundException e) {
1202                 Log.e(TAG, "Error querying default vol for stream type " + streams[s], e);
1203             }
1204         }
1205 
1206         if (looper == null) {
1207             createAudioSystemThread();
1208         } else {
1209             mAudioHandler = new AudioHandler(looper);
1210         }
1211 
1212         mSoundDoseHelper = new SoundDoseHelper(this, mContext, mAudioHandler, mSettings,
1213                 mVolumeController);
1214 
1215         AudioSystem.setErrorCallback(mAudioSystemCallback);
1216 
1217         updateAudioHalPids();
1218 
1219         mUseFixedVolume = mContext.getResources().getBoolean(
1220                 com.android.internal.R.bool.config_useFixedVolume);
1221 
1222         mRecordMonitor = new RecordingActivityMonitor(mContext);
1223         mRecordMonitor.registerRecordingCallback(mVoiceRecordingActivityMonitor, true);
1224 
1225         // must be called before readPersistedSettings() which needs a valid mStreamVolumeAlias[]
1226         // array initialized by updateStreamVolumeAlias()
1227         updateStreamVolumeAlias(false /*updateVolumes*/, TAG);
1228         readPersistedSettings();
1229         readUserRestrictions();
1230 
1231         mPlaybackMonitor =
1232                 new PlaybackActivityMonitor(context, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM],
1233                         device -> onMuteAwaitConnectionTimeout(device));
1234         mPlaybackMonitor.registerPlaybackCallback(mPlaybackActivityMonitor, true);
1235 
1236         mMediaFocusControl = new MediaFocusControl(mContext, mPlaybackMonitor);
1237 
1238         readAndSetLowRamDevice();
1239 
1240         mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported();
1241 
1242         if (mSystemServer.isPrivileged()) {
1243             LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal());
1244 
1245             mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
1246 
1247             mRecordMonitor.initMonitor();
1248         }
1249 
1250         mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false);
1251 
1252         mHasSpatializerEffect = SystemProperties.getBoolean("ro.audio.spatializer_enabled", false);
1253 
1254         // monitor routing updates coming from native
1255         mAudioSystem.setRoutingListener(this);
1256         // monitor requests for volume range initialization coming from native (typically when
1257         // errors are found by AudioPolicyManager
1258         mAudioSystem.setVolRangeInitReqListener(this);
1259 
1260         // done with service initialization, continue additional work in our Handler thread
1261         queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_STREAMS_VOLUMES,
1262                 0 /* arg1 */,  0 /* arg2 */, null /* obj */,  0 /* delay */);
1263         queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_ADI_DEVICE_STATES,
1264                 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */);
1265         queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_SPATIALIZER,
1266                 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */);
1267     }
1268 
initVolumeStreamStates()1269     private void initVolumeStreamStates() {
1270         int numStreamTypes = AudioSystem.getNumStreamTypes();
1271         synchronized (VolumeStreamState.class) {
1272             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
1273                 VolumeStreamState streamState = mStreamStates[streamType];
1274                 int groupId = getVolumeGroupForStreamType(streamType);
1275                 if (groupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP
1276                         && sVolumeGroupStates.indexOfKey(groupId) >= 0) {
1277                     streamState.setVolumeGroupState(sVolumeGroupStates.get(groupId));
1278                 }
1279             }
1280         }
1281     }
1282 
1283     /**
1284      * Called by handling of MSG_INIT_STREAMS_VOLUMES
1285      */
onInitStreamsAndVolumes()1286     private void onInitStreamsAndVolumes() {
1287         synchronized (mSettingsLock) {
1288             mCameraSoundForced = readCameraSoundForced();
1289             sendMsg(mAudioHandler,
1290                     MSG_SET_FORCE_USE,
1291                     SENDMSG_QUEUE,
1292                     AudioSystem.FOR_SYSTEM,
1293                     mCameraSoundForced
1294                             ? AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE,
1295                     new String("AudioService ctor"),
1296                     0);
1297         }
1298 
1299         createStreamStates();
1300 
1301         // must be called after createStreamStates() as it uses MUSIC volume as default if no
1302         // persistent data
1303         initVolumeGroupStates();
1304 
1305         mSoundDoseHelper.initSafeMediaVolumeIndex();
1306         // Link VGS on VSS
1307         initVolumeStreamStates();
1308 
1309         // Call setRingerModeInt() to apply correct mute
1310         // state on streams affected by ringer mode.
1311         sRingerAndZenModeMutedStreams = 0;
1312         sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent(
1313                 sRingerAndZenModeMutedStreams, "onInitStreamsAndVolumes"));
1314         setRingerModeInt(getRingerModeInternal(), false);
1315 
1316         final float[] preScale = new float[3];
1317         preScale[0] = mContext.getResources().getFraction(
1318                 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index1,
1319                 1, 1);
1320         preScale[1] = mContext.getResources().getFraction(
1321                 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index2,
1322                 1, 1);
1323         preScale[2] = mContext.getResources().getFraction(
1324                 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index3,
1325                 1, 1);
1326         for (int i = 0; i < preScale.length; i++) {
1327             if (0.0f <= preScale[i] && preScale[i] <= 1.0f) {
1328                 mPrescaleAbsoluteVolume[i] = preScale[i];
1329             }
1330         }
1331 
1332         initExternalEventReceivers();
1333 
1334         // check on volume initialization
1335         checkVolumeRangeInitialization("AudioService()");
1336 
1337     }
1338 
1339     private SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionChangedListener =
1340             new SubscriptionManager.OnSubscriptionsChangedListener() {
1341                 @Override
1342                 public void onSubscriptionsChanged() {
1343                     Log.i(TAG, "onSubscriptionsChanged()");
1344                     sendMsg(mAudioHandler, MSG_CONFIGURATION_CHANGED, SENDMSG_REPLACE,
1345                             0, 0, null, 0);
1346                 }
1347             };
1348 
1349     /**
1350      * Initialize intent receives and settings observers for this service.
1351      * Must be called after createStreamStates() as the handling of some events
1352      * may affect or need volumes, e.g. BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED
1353      * (for intent receiver), or Settings.Global.ZEN_MODE (for settings observer)
1354      */
initExternalEventReceivers()1355     private void initExternalEventReceivers() {
1356         mSettingsObserver = new SettingsObserver();
1357 
1358         // Register for device connection intent broadcasts.
1359         IntentFilter intentFilter =
1360                 new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
1361         intentFilter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED);
1362         intentFilter.addAction(Intent.ACTION_DOCK_EVENT);
1363         intentFilter.addAction(Intent.ACTION_SCREEN_ON);
1364         intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
1365         intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
1366         intentFilter.addAction(Intent.ACTION_USER_BACKGROUND);
1367         intentFilter.addAction(Intent.ACTION_USER_FOREGROUND);
1368         intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
1369         intentFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
1370 
1371         intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
1372         if (mMonitorRotation) {
1373             RotationHelper.init(mContext, mAudioHandler,
1374                     rotation -> onRotationUpdate(rotation),
1375                     foldState -> onFoldStateUpdate(foldState));
1376         }
1377 
1378         intentFilter.addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION);
1379         intentFilter.addAction(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION);
1380         intentFilter.addAction(ACTION_CHECK_MUSIC_ACTIVE);
1381         intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
1382 
1383         mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null,
1384                 Context.RECEIVER_EXPORTED);
1385 
1386         SubscriptionManager subscriptionManager = mContext.getSystemService(
1387                 SubscriptionManager.class);
1388         if (subscriptionManager == null) {
1389             Log.e(TAG, "initExternalEventReceivers cannot create SubscriptionManager!");
1390         } else {
1391             subscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionChangedListener);
1392         }
1393     }
1394 
systemReady()1395     public void systemReady() {
1396         sendMsg(mAudioHandler, MSG_SYSTEM_READY, SENDMSG_QUEUE,
1397                 0, 0, null, 0);
1398         if (false) {
1399             // This is turned off for now, because it is racy and thus causes apps to break.
1400             // Currently banning a uid means that if an app tries to start playing an audio
1401             // stream, that will be preventing, and unbanning it will not allow that stream
1402             // to resume.  However these changes in uid state are racy with what the app is doing,
1403             // so that after taking a process out of the cached state we can't guarantee that
1404             // we will unban the uid before the app actually tries to start playing audio.
1405             // (To do that, the activity manager would need to wait until it knows for sure
1406             // that the ban has been removed, before telling the app to do whatever it is
1407             // supposed to do that caused it to go out of the cached state.)
1408             try {
1409                 ActivityManager.getService().registerUidObserver(mUidObserver,
1410                         ActivityManager.UID_OBSERVER_CACHED | ActivityManager.UID_OBSERVER_GONE,
1411                         ActivityManager.PROCESS_STATE_UNKNOWN, null);
1412             } catch (RemoteException e) {
1413                 // ignored; both services live in system_server
1414             }
1415         }
1416     }
1417 
updateVibratorInfos()1418     private void updateVibratorInfos() {
1419         VibratorManager vibratorManager = mContext.getSystemService(VibratorManager.class);
1420         if (vibratorManager == null) {
1421             Slog.e(TAG, "Vibrator manager is not found");
1422             return;
1423         }
1424         int[] vibratorIds = vibratorManager.getVibratorIds();
1425         if (vibratorIds.length == 0) {
1426             Slog.d(TAG, "No vibrator found");
1427             return;
1428         }
1429         List<Vibrator> vibrators = new ArrayList<>(vibratorIds.length);
1430         for (int id : vibratorIds) {
1431             Vibrator vibrator = vibratorManager.getVibrator(id);
1432             if (vibrator != null) {
1433                 vibrators.add(vibrator);
1434             } else {
1435                 Slog.w(TAG, "Vibrator(" + id + ") is not found");
1436             }
1437         }
1438         if (vibrators.isEmpty()) {
1439             Slog.w(TAG, "Cannot find any available vibrator");
1440             return;
1441         }
1442         AudioSystem.setVibratorInfos(vibrators);
1443     }
1444 
onSystemReady()1445     public void onSystemReady() {
1446         mSystemReady = true;
1447         scheduleLoadSoundEffects();
1448 
1449         mDeviceBroker.onSystemReady();
1450 
1451         if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_HDMI_CEC)) {
1452             synchronized (mHdmiClientLock) {
1453                 mHdmiManager = mContext.getSystemService(HdmiControlManager.class);
1454                 if (mHdmiManager != null) {
1455                     mHdmiManager.addHdmiControlStatusChangeListener(
1456                             mHdmiControlStatusChangeListenerCallback);
1457                     mHdmiManager.addHdmiCecVolumeControlFeatureListener(mContext.getMainExecutor(),
1458                             mMyHdmiCecVolumeControlFeatureListener);
1459                 }
1460                 mHdmiTvClient = mHdmiManager.getTvClient();
1461                 if (mHdmiTvClient != null) {
1462                     mFixedVolumeDevices.removeAll(
1463                             AudioSystem.DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET);
1464                 }
1465                 mHdmiPlaybackClient = mHdmiManager.getPlaybackClient();
1466                 mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient();
1467             }
1468         }
1469 
1470         if (mSupportsMicPrivacyToggle) {
1471             mSensorPrivacyManagerInternal.addSensorPrivacyListenerForAllUsers(
1472                     SensorPrivacyManager.Sensors.MICROPHONE, (userId, enabled) -> {
1473                         if (userId == getCurrentUserId()) {
1474                             mMicMuteFromPrivacyToggle = enabled;
1475                             setMicrophoneMuteNoCallerCheck(getCurrentUserId());
1476                         }
1477                     });
1478         }
1479 
1480         mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
1481 
1482         mSoundDoseHelper.configureSafeMedia(/*forced=*/true, TAG);
1483 
1484         initA11yMonitoring();
1485 
1486         mRoleObserver = new RoleObserver();
1487         mRoleObserver.register();
1488 
1489         onIndicateSystemReady();
1490 
1491         mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted();
1492         setMicMuteFromSwitchInput();
1493 
1494         initMinStreamVolumeWithoutModifyAudioSettings();
1495 
1496         updateVibratorInfos();
1497 
1498         synchronized (mSupportedSystemUsagesLock) {
1499             AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages);
1500         }
1501     }
1502 
1503     //-----------------------------------------------------------------
1504     // routing monitoring from AudioSystemAdapter
1505     @Override
onRoutingUpdatedFromNative()1506     public void onRoutingUpdatedFromNative() {
1507         sendMsg(mAudioHandler,
1508                 MSG_ROUTING_UPDATED,
1509                 SENDMSG_REPLACE, 0, 0, null,
1510                 /*delay*/ 0);
1511     }
1512 
1513     /**
1514      * called when handling MSG_ROUTING_UPDATED
1515      */
onRoutingUpdatedFromAudioThread()1516     void onRoutingUpdatedFromAudioThread() {
1517         if (mHasSpatializerEffect) {
1518             mSpatializerHelper.onRoutingUpdated();
1519         }
1520         checkMuteAwaitConnection();
1521     }
1522 
1523     //-----------------------------------------------------------------
1524     // rotation/fold updates coming from RotationHelper
onRotationUpdate(Integer rotation)1525     void onRotationUpdate(Integer rotation) {
1526         mSpatializerHelper.setDisplayOrientation((float) (rotation * Math.PI / 180.));
1527         // use REPLACE as only the last rotation matters
1528         final String rotationParameter = "rotation=" + rotation;
1529         sendMsg(mAudioHandler, MSG_ROTATION_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0,
1530                 /*obj*/ rotationParameter, /*delay*/ 0);
1531     }
1532 
onFoldStateUpdate(Boolean foldState)1533     void onFoldStateUpdate(Boolean foldState) {
1534         mSpatializerHelper.setFoldState(foldState);
1535         // use REPLACE as only the last fold state matters
1536         final String foldStateParameter = "device_folded=" + (foldState ? "on" : "off");
1537         sendMsg(mAudioHandler, MSG_FOLD_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0,
1538                 /*obj*/ foldStateParameter, /*delay*/ 0);
1539     }
1540 
1541     //-----------------------------------------------------------------
1542     // Communicate to PlayackActivityMonitor whether to log or not
1543     // the sound FX activity (useful for removing touch sounds in the activity logs)
ignorePlayerLogs(@onNull PlayerBase playerToIgnore)1544     void ignorePlayerLogs(@NonNull PlayerBase playerToIgnore) {
1545         if (DEBUG_LOG_SOUND_FX) {
1546             return;
1547         }
1548         sendMsg(mAudioHandler, MSG_NO_LOG_FOR_PLAYER_I, SENDMSG_REPLACE,
1549                 /*arg1, piid of the player*/ playerToIgnore.getPlayerIId(),
1550                 /*arg2 ignored*/ 0, /*obj ignored*/ null, /*delay*/ 0);
1551     }
1552 
1553     //-----------------------------------------------------------------
1554     // monitoring requests for volume range initialization
1555     @Override // AudioSystemAdapter.OnVolRangeInitRequestListener
onVolumeRangeInitRequestFromNative()1556     public void onVolumeRangeInitRequestFromNative() {
1557         sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_REPLACE, 0, 0,
1558                 "onVolumeRangeInitRequestFromNative" /*obj: caller, for dumpsys*/, /*delay*/ 0);
1559     }
1560 
1561     //-----------------------------------------------------------------
1562     RoleObserver mRoleObserver;
1563 
1564     class RoleObserver implements OnRoleHoldersChangedListener {
1565         private RoleManager mRm;
1566         private final Executor mExecutor;
1567 
RoleObserver()1568         RoleObserver() {
1569             mExecutor = mContext.getMainExecutor();
1570         }
1571 
register()1572         public void register() {
1573             mRm = (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE);
1574             if (mRm != null) {
1575                 mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.ALL);
1576                 synchronized (mSettingsLock) {
1577                     updateAssistantUIdLocked(/* forceUpdate= */ true);
1578                 }
1579             }
1580         }
1581 
1582         @Override
onRoleHoldersChanged(@onNull String roleName, @NonNull UserHandle user)1583         public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
1584             if (RoleManager.ROLE_ASSISTANT.equals(roleName)) {
1585                 synchronized (mSettingsLock) {
1586                     updateAssistantUIdLocked(/* forceUpdate= */ false);
1587                 }
1588             }
1589         }
1590 
getAssistantRoleHolder()1591         public String getAssistantRoleHolder() {
1592             String assitantPackage = "";
1593             if (mRm != null) {
1594                 List<String> assistants = mRm.getRoleHolders(RoleManager.ROLE_ASSISTANT);
1595                 assitantPackage = assistants.size() == 0 ? "" : assistants.get(0);
1596             }
1597             return assitantPackage;
1598         }
1599     }
1600 
onIndicateSystemReady()1601     void onIndicateSystemReady() {
1602         if (AudioSystem.systemReady() == AudioSystem.SUCCESS) {
1603             return;
1604         }
1605         sendMsg(mAudioHandler,
1606                 MSG_INDICATE_SYSTEM_READY,
1607                 SENDMSG_REPLACE,
1608                 0,
1609                 0,
1610                 null,
1611                 INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
1612     }
1613 
onAudioServerDied()1614     public void onAudioServerDied() {
1615         if (!mSystemReady ||
1616                 (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) {
1617             Log.e(TAG, "Audioserver died.");
1618             sLifecycleLogger.enqueue(new EventLogger.StringEvent(
1619                     "onAudioServerDied() audioserver died"));
1620             sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, SENDMSG_NOOP, 0, 0,
1621                     null, 500);
1622             return;
1623         }
1624         Log.i(TAG, "Audioserver started.");
1625         sLifecycleLogger.enqueue(new EventLogger.StringEvent(
1626                 "onAudioServerDied() audioserver started"));
1627 
1628         updateAudioHalPids();
1629 
1630         // indicate to audio HAL that we start the reconfiguration phase after a media
1631         // server crash
1632         // Note that we only execute this when the media server
1633         // process restarts after a crash, not the first time it is started.
1634         AudioSystem.setParameters("restarting=true");
1635 
1636         readAndSetLowRamDevice();
1637 
1638         mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported();
1639 
1640         // Restore device connection states, BT state
1641         mDeviceBroker.onAudioServerDied();
1642 
1643         // Restore call state
1644         synchronized (mDeviceBroker.mSetModeLock) {
1645             onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(),
1646                     mContext.getPackageName(), true /*force*/);
1647         }
1648         final int forSys;
1649         synchronized (mSettingsLock) {
1650             forSys = mCameraSoundForced ?
1651                     AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE;
1652         }
1653 
1654         mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, forSys, "onAudioServerDied");
1655 
1656         // Restore stream volumes
1657         onReinitVolumes("after audioserver restart");
1658 
1659         // Restore audio volume groups
1660         restoreVolumeGroups();
1661 
1662         // Restore mono mode
1663         updateMasterMono(mContentResolver);
1664 
1665         // Restore audio balance
1666         updateMasterBalance(mContentResolver);
1667 
1668         // Restore ringer mode
1669         setRingerModeInt(getRingerModeInternal(), false);
1670 
1671         // Reset device rotation (if monitored for this device)
1672         if (mMonitorRotation) {
1673             RotationHelper.updateOrientation();
1674         }
1675 
1676         // Restore setParameters and other queued setters.
1677         mRestorableParameters.restoreAll();
1678 
1679         synchronized (mSettingsLock) {
1680             final int forDock = mDockAudioMediaEnabled ?
1681                     AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE;
1682             mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, forDock, "onAudioServerDied");
1683             sendEncodedSurroundMode(mContentResolver, "onAudioServerDied");
1684             sendEnabledSurroundFormats(mContentResolver, true);
1685             AudioSystem.setRttEnabled(mRttEnabled);
1686             resetAssistantServicesUidsLocked();
1687         }
1688 
1689         synchronized (mAccessibilityServiceUidsLock) {
1690             AudioSystem.setA11yServicesUids(mAccessibilityServiceUids);
1691         }
1692         synchronized (mInputMethodServiceUidLock) {
1693             mAudioSystem.setCurrentImeUid(mInputMethodServiceUid);
1694         }
1695         synchronized (mHdmiClientLock) {
1696             if (mHdmiManager != null && mHdmiTvClient != null) {
1697                 setHdmiSystemAudioSupported(mHdmiSystemAudioSupported);
1698             }
1699         }
1700 
1701         synchronized (mSupportedSystemUsagesLock) {
1702             AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages);
1703         }
1704 
1705         synchronized (mAudioPolicies) {
1706             ArrayList<AudioPolicyProxy> invalidProxies = new ArrayList<>();
1707             for (AudioPolicyProxy policy : mAudioPolicies.values()) {
1708                 final int status = policy.connectMixes();
1709                 if (status != AudioSystem.SUCCESS) {
1710                     // note that PERMISSION_DENIED may also indicate trouble getting to APService
1711                     Log.e(TAG, "onAudioServerDied: error "
1712                             + AudioSystem.audioSystemErrorToString(status)
1713                             + " when connecting mixes for policy " + policy.toLogFriendlyString());
1714                     invalidProxies.add(policy);
1715                 } else {
1716                     final int deviceAffinitiesStatus = policy.setupDeviceAffinities();
1717                     if (deviceAffinitiesStatus != AudioSystem.SUCCESS) {
1718                         Log.e(TAG, "onAudioServerDied: error "
1719                                 + AudioSystem.audioSystemErrorToString(deviceAffinitiesStatus)
1720                                 + " when connecting device affinities for policy "
1721                                 + policy.toLogFriendlyString());
1722                         invalidProxies.add(policy);
1723                     }
1724                 }
1725             }
1726             invalidProxies.forEach((policy) -> policy.release());
1727 
1728         }
1729 
1730         // Restore capture policies
1731         synchronized (mPlaybackMonitor) {
1732             HashMap<Integer, Integer> allowedCapturePolicies =
1733                     mPlaybackMonitor.getAllAllowedCapturePolicies();
1734             for (HashMap.Entry<Integer, Integer> entry : allowedCapturePolicies.entrySet()) {
1735                 int result = mAudioSystem.setAllowedCapturePolicy(
1736                         entry.getKey(),
1737                         AudioAttributes.capturePolicyToFlags(entry.getValue(), 0x0));
1738                 if (result != AudioSystem.AUDIO_STATUS_OK) {
1739                     Log.e(TAG, "Failed to restore capture policy, uid: "
1740                             + entry.getKey() + ", capture policy: " + entry.getValue()
1741                             + ", result: " + result);
1742                     // When restoring capture policy failed, set the capture policy as
1743                     // ALLOW_CAPTURE_BY_ALL, which will result in removing the cached
1744                     // capture policy in PlaybackActivityMonitor.
1745                     mPlaybackMonitor.setAllowedCapturePolicy(
1746                             entry.getKey(), AudioAttributes.ALLOW_CAPTURE_BY_ALL);
1747                 }
1748             }
1749         }
1750 
1751         mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect);
1752         mSoundDoseHelper.reset();
1753 
1754         // Restore rotation information.
1755         if (mMonitorRotation) {
1756             RotationHelper.forceUpdate();
1757         }
1758 
1759         onIndicateSystemReady();
1760         // indicate the end of reconfiguration phase to audio HAL
1761         AudioSystem.setParameters("restarting=false");
1762 
1763         sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE,
1764                 SENDMSG_QUEUE, 1, 0, null, 0);
1765 
1766         setMicrophoneMuteNoCallerCheck(getCurrentUserId()); // will also update the mic mute cache
1767         setMicMuteFromSwitchInput();
1768 
1769         // Restore vibrator info
1770         updateVibratorInfos();
1771     }
1772 
onRemoveAssistantServiceUids(int[] uids)1773     private void onRemoveAssistantServiceUids(int[] uids) {
1774         synchronized (mSettingsLock) {
1775             removeAssistantServiceUidsLocked(uids);
1776         }
1777     }
1778 
1779     @GuardedBy("mSettingsLock")
removeAssistantServiceUidsLocked(int[] uids)1780     private void removeAssistantServiceUidsLocked(int[] uids) {
1781         boolean changed = false;
1782         for (int index = 0; index < uids.length; index++) {
1783             if (!mAssistantUids.remove(uids[index])) {
1784                 Slog.e(TAG, TextUtils.formatSimple(
1785                         "Cannot remove assistant service, uid(%d) not present", uids[index]));
1786                 continue;
1787             }
1788             changed = true;
1789         }
1790         if (changed) {
1791             updateAssistantServicesUidsLocked();
1792         }
1793     }
1794 
onAddAssistantServiceUids(int[] uids)1795     private void onAddAssistantServiceUids(int[] uids) {
1796         synchronized (mSettingsLock) {
1797             addAssistantServiceUidsLocked(uids);
1798         }
1799     }
1800 
1801     @GuardedBy("mSettingsLock")
addAssistantServiceUidsLocked(int[] uids)1802     private void addAssistantServiceUidsLocked(int[] uids) {
1803         boolean changed = false;
1804         for (int index = 0; index < uids.length; index++) {
1805             if (uids[index] == INVALID_UID) {
1806                 continue;
1807             }
1808             if (!mAssistantUids.add(uids[index])) {
1809                 Slog.e(TAG, TextUtils.formatSimple(
1810                                 "Cannot add assistant service, uid(%d) already present",
1811                                 uids[index]));
1812                 continue;
1813             }
1814             changed = true;
1815         }
1816         if (changed) {
1817             updateAssistantServicesUidsLocked();
1818         }
1819     }
1820 
1821     @GuardedBy("mSettingsLock")
resetAssistantServicesUidsLocked()1822     private void resetAssistantServicesUidsLocked() {
1823         mAssistantUids.clear();
1824         updateAssistantUIdLocked(/* forceUpdate= */ true);
1825     }
1826 
1827     @GuardedBy("mSettingsLock")
updateAssistantServicesUidsLocked()1828     private void updateAssistantServicesUidsLocked() {
1829         int[] assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray();
1830         AudioSystem.setAssistantServicesUids(assistantUids);
1831     }
1832 
updateActiveAssistantServiceUids()1833     private void updateActiveAssistantServiceUids() {
1834         int [] activeAssistantServiceUids;
1835         synchronized (mSettingsLock) {
1836             activeAssistantServiceUids = mActiveAssistantServiceUids;
1837         }
1838         AudioSystem.setActiveAssistantServicesUids(activeAssistantServiceUids);
1839     }
1840 
onReinitVolumes(@onNull String caller)1841     private void onReinitVolumes(@NonNull String caller) {
1842         final int numStreamTypes = AudioSystem.getNumStreamTypes();
1843         // keep track of any error during stream volume initialization
1844         int status = AudioSystem.AUDIO_STATUS_OK;
1845         for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
1846             VolumeStreamState streamState = mStreamStates[streamType];
1847             final int res = AudioSystem.initStreamVolume(
1848                     streamType, streamState.mIndexMin / 10, streamState.mIndexMax / 10);
1849             if (res != AudioSystem.AUDIO_STATUS_OK) {
1850                 status = res;
1851                 Log.e(TAG, "Failed to initStreamVolume (" + res + ") for stream " + streamType);
1852                 // stream volume initialization failed, no need to try the others, it will be
1853                 // attempted again when MSG_REINIT_VOLUMES is handled
1854                 break;
1855             }
1856             streamState.applyAllVolumes();
1857         }
1858 
1859         // did it work? check based on status
1860         if (status != AudioSystem.AUDIO_STATUS_OK) {
1861             sLifecycleLogger.enqueue(new EventLogger.StringEvent(
1862                     caller + ": initStreamVolume failed with " + status + " will retry")
1863                     .printLog(ALOGE, TAG));
1864             sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0,
1865                     caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
1866             return;
1867         }
1868 
1869         // did it work? check based on min/max values of some basic streams
1870         if (!checkVolumeRangeInitialization(caller)) {
1871             return;
1872         }
1873 
1874         // success
1875         sLifecycleLogger.enqueue(new EventLogger.StringEvent(
1876                 caller + ": initStreamVolume succeeded").printLog(ALOGI, TAG));
1877     }
1878 
1879     /**
1880      * Check volume ranges were properly initialized
1881      * @return true if volume ranges were successfully initialized
1882      */
checkVolumeRangeInitialization(String caller)1883     private boolean checkVolumeRangeInitialization(String caller) {
1884         boolean success = true;
1885         final int[] basicStreams = { AudioSystem.STREAM_ALARM, AudioSystem.STREAM_RING,
1886                 AudioSystem.STREAM_MUSIC, AudioSystem.STREAM_VOICE_CALL,
1887                 AudioSystem.STREAM_ACCESSIBILITY };
1888         for (int streamType : basicStreams) {
1889             final AudioAttributes aa = new AudioAttributes.Builder()
1890                     .setInternalLegacyStreamType(streamType).build();
1891             if (AudioSystem.getMaxVolumeIndexForAttributes(aa) < 0
1892                     || AudioSystem.getMinVolumeIndexForAttributes(aa) < 0) {
1893                 success = false;
1894                 break;
1895             }
1896         }
1897         if (!success) {
1898             sLifecycleLogger.enqueue(new EventLogger.StringEvent(
1899                     caller + ": initStreamVolume succeeded but invalid mix/max levels, will retry")
1900                     .printLog(ALOGW, TAG));
1901             sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0,
1902                     caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
1903         }
1904         return success;
1905     }
1906 
onDispatchAudioServerStateChange(boolean state)1907     private void onDispatchAudioServerStateChange(boolean state) {
1908         synchronized (mAudioServerStateListeners) {
1909             for (AsdProxy asdp : mAudioServerStateListeners.values()) {
1910                 try {
1911                     asdp.callback().dispatchAudioServerStateChange(state);
1912                 } catch (RemoteException e) {
1913                     Log.w(TAG, "Could not call dispatchAudioServerStateChange()", e);
1914                 }
1915             }
1916         }
1917     }
1918 
createAudioSystemThread()1919     private void createAudioSystemThread() {
1920         mAudioSystemThread = new AudioSystemThread();
1921         mAudioSystemThread.start();
1922         waitForAudioHandlerCreation();
1923     }
1924 
1925     /** Waits for the volume handler to be created by the other thread. */
waitForAudioHandlerCreation()1926     private void waitForAudioHandlerCreation() {
1927         synchronized(this) {
1928             while (mAudioHandler == null) {
1929                 try {
1930                     // Wait for mAudioHandler to be set by the other thread
1931                     wait();
1932                 } catch (InterruptedException e) {
1933                     Log.e(TAG, "Interrupted while waiting on volume handler.");
1934                 }
1935             }
1936         }
1937     }
1938 
1939     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
1940     /**
1941      * @see AudioManager#setSupportedSystemUsages(int[])
1942      */
setSupportedSystemUsages(@onNull @ttributeSystemUsage int[] systemUsages)1943     public void setSupportedSystemUsages(@NonNull @AttributeSystemUsage int[] systemUsages) {
1944         super.setSupportedSystemUsages_enforcePermission();
1945 
1946         verifySystemUsages(systemUsages);
1947 
1948         synchronized (mSupportedSystemUsagesLock) {
1949             AudioSystem.setSupportedSystemUsages(systemUsages);
1950             mSupportedSystemUsages = systemUsages;
1951         }
1952     }
1953 
1954     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
1955     /**
1956      * @see AudioManager#getSupportedSystemUsages()
1957      */
getSupportedSystemUsages()1958     public @NonNull @AttributeSystemUsage int[] getSupportedSystemUsages() {
1959         super.getSupportedSystemUsages_enforcePermission();
1960 
1961         synchronized (mSupportedSystemUsagesLock) {
1962             return Arrays.copyOf(mSupportedSystemUsages, mSupportedSystemUsages.length);
1963         }
1964     }
1965 
verifySystemUsages(@onNull int[] systemUsages)1966     private void verifySystemUsages(@NonNull int[] systemUsages) {
1967         for (int i = 0; i < systemUsages.length; i++) {
1968             if (!AudioAttributes.isSystemUsage(systemUsages[i])) {
1969                 throw new IllegalArgumentException("Non-system usage provided: " + systemUsages[i]);
1970             }
1971         }
1972     }
1973 
1974     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
1975     /**
1976      * @return the {@link android.media.audiopolicy.AudioProductStrategy} discovered from the
1977      * platform configuration file.
1978      */
1979     @NonNull
getAudioProductStrategies()1980     public List<AudioProductStrategy> getAudioProductStrategies() {
1981         // verify permissions
1982         super.getAudioProductStrategies_enforcePermission();
1983 
1984         return AudioProductStrategy.getAudioProductStrategies();
1985     }
1986 
1987     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
1988     /**
1989      * @return the List of {@link android.media.audiopolicy.AudioVolumeGroup} discovered from the
1990      * platform configuration file.
1991      */
1992     @NonNull
getAudioVolumeGroups()1993     public List<AudioVolumeGroup> getAudioVolumeGroups() {
1994         // verify permissions
1995         super.getAudioVolumeGroups_enforcePermission();
1996 
1997         return AudioVolumeGroup.getAudioVolumeGroups();
1998     }
1999 
checkAllAliasStreamVolumes()2000     private void checkAllAliasStreamVolumes() {
2001         synchronized (mSettingsLock) {
2002             synchronized (VolumeStreamState.class) {
2003                 int numStreamTypes = AudioSystem.getNumStreamTypes();
2004                 for (int streamType = 0; streamType < numStreamTypes; streamType++) {
2005                     mStreamStates[streamType]
2006                             .setAllIndexes(mStreamStates[mStreamVolumeAlias[streamType]], TAG);
2007                     // apply stream volume
2008                     if (!mStreamStates[streamType].mIsMuted) {
2009                         mStreamStates[streamType].applyAllVolumes();
2010                     }
2011                 }
2012             }
2013         }
2014     }
2015 
2016 
2017     /**
2018      * Called from AudioDeviceBroker when DEVICE_OUT_HDMI is connected or disconnected.
2019      */
postCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)2020     /*package*/ void postCheckVolumeCecOnHdmiConnection(
2021             @AudioService.ConnectionState  int state, String caller) {
2022         sendMsg(mAudioHandler, MSG_HDMI_VOLUME_CHECK, SENDMSG_REPLACE,
2023                 state /*arg1*/, 0 /*arg2 ignored*/, caller /*obj*/, 0 /*delay*/);
2024     }
2025 
onCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)2026     private void onCheckVolumeCecOnHdmiConnection(
2027             @AudioService.ConnectionState int state, String caller) {
2028         if (state == AudioService.CONNECTION_STATE_CONNECTED) {
2029             // DEVICE_OUT_HDMI is now connected
2030             if (mSoundDoseHelper.safeDevicesContains(AudioSystem.DEVICE_OUT_HDMI)) {
2031                 mSoundDoseHelper.scheduleMusicActiveCheck();
2032             }
2033 
2034             if (isPlatformTelevision()) {
2035                 synchronized (mHdmiClientLock) {
2036                     if (mHdmiManager != null && mHdmiPlaybackClient != null) {
2037                         updateHdmiCecSinkLocked(
2038                                 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI));
2039                     }
2040                 }
2041             }
2042             sendEnabledSurroundFormats(mContentResolver, true);
2043         } else {
2044             // DEVICE_OUT_HDMI disconnected
2045             if (isPlatformTelevision()) {
2046                 synchronized (mHdmiClientLock) {
2047                     if (mHdmiManager != null) {
2048                         updateHdmiCecSinkLocked(
2049                                 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI));
2050                     }
2051                 }
2052             }
2053         }
2054     }
2055 
2056     /**
2057      * Asynchronously update volume states for the given device.
2058      *
2059      * @param device a single audio device, ensure that this is not a devices bitmask
2060      * @param caller caller of this method
2061      */
postUpdateVolumeStatesForAudioDevice(int device, String caller)2062     private void postUpdateVolumeStatesForAudioDevice(int device, String caller) {
2063         sendMsg(mAudioHandler,
2064                 MSG_UPDATE_VOLUME_STATES_FOR_DEVICE,
2065                 SENDMSG_QUEUE, device /*arg1*/, 0 /*arg2*/, caller /*obj*/,
2066                 0 /*delay*/);
2067     }
2068 
2069     /**
2070      * Update volume states for the given device.
2071      *
2072      * This will initialize the volume index if no volume index is available.
2073      * If the device is the currently routed device, fixed/full volume policies will be applied.
2074      *
2075      * @param device a single audio device, ensure that this is not a devices bitmask
2076      * @param caller caller of this method
2077      */
onUpdateVolumeStatesForAudioDevice(int device, String caller)2078     private void onUpdateVolumeStatesForAudioDevice(int device, String caller) {
2079         final int numStreamTypes = AudioSystem.getNumStreamTypes();
2080         synchronized (mSettingsLock) {
2081             synchronized (VolumeStreamState.class) {
2082                 for (int streamType = 0; streamType < numStreamTypes; streamType++) {
2083                     updateVolumeStates(device, streamType, caller);
2084                 }
2085             }
2086         }
2087     }
2088 
2089     /**
2090      * Update volume states for the given device and given stream.
2091      *
2092      * This will initialize the volume index if no volume index is available.
2093      * If the device is the currently routed device, fixed/full volume policies will be applied.
2094      *
2095      * @param device a single audio device, ensure that this is not a devices bitmask
2096      * @param streamType streamType to be updated
2097      * @param caller caller of this method
2098      */
updateVolumeStates(int device, int streamType, String caller)2099     private void updateVolumeStates(int device, int streamType, String caller) {
2100         // Handle device volume aliasing of SPEAKER_SAFE.
2101         if (device == AudioSystem.DEVICE_OUT_SPEAKER_SAFE) {
2102             device = AudioSystem.DEVICE_OUT_SPEAKER;
2103         }
2104         if (!mStreamStates[streamType].hasIndexForDevice(device)) {
2105             // set the default value, if device is affected by a full/fix/abs volume rule, it
2106             // will taken into account in checkFixedVolumeDevices()
2107             mStreamStates[streamType].setIndex(
2108                     mStreamStates[mStreamVolumeAlias[streamType]]
2109                             .getIndex(AudioSystem.DEVICE_OUT_DEFAULT),
2110                     device, caller, true /*hasModifyAudioSettings*/);
2111         }
2112 
2113         // Check if device to be updated is routed for the given audio stream
2114         // This may include devices such as SPEAKER_SAFE.
2115         List<AudioDeviceAttributes> devicesForAttributes = getDevicesForAttributesInt(
2116                 new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build(),
2117                 true /* forVolume */);
2118         for (AudioDeviceAttributes deviceAttributes : devicesForAttributes) {
2119             if (deviceAttributes.getType() == AudioDeviceInfo.convertInternalDeviceToDeviceType(
2120                     device)) {
2121                 mStreamStates[streamType].checkFixedVolumeDevices();
2122 
2123                 // Unmute streams if required and device is full volume
2124                 if (isStreamMute(streamType) && mFullVolumeDevices.contains(device)) {
2125                     mStreamStates[streamType].mute(false, "updateVolumeStates(" + caller);
2126                 }
2127             }
2128         }
2129     }
2130 
checkAllFixedVolumeDevices()2131     private void checkAllFixedVolumeDevices()
2132     {
2133         int numStreamTypes = AudioSystem.getNumStreamTypes();
2134         for (int streamType = 0; streamType < numStreamTypes; streamType++) {
2135             mStreamStates[streamType].checkFixedVolumeDevices();
2136         }
2137     }
2138 
checkAllFixedVolumeDevices(int streamType)2139     private void checkAllFixedVolumeDevices(int streamType) {
2140         mStreamStates[streamType].checkFixedVolumeDevices();
2141     }
2142 
checkMuteAffectedStreams()2143     private void checkMuteAffectedStreams() {
2144         // any stream with a min level > 0 is not muteable by definition
2145         // STREAM_VOICE_CALL and STREAM_BLUETOOTH_SCO can be muted by applications
2146         // that has the the MODIFY_PHONE_STATE permission.
2147         for (int i = 0; i < mStreamStates.length; i++) {
2148             final VolumeStreamState vss = mStreamStates[i];
2149             if (vss.mIndexMin > 0 &&
2150                 (vss.mStreamType != AudioSystem.STREAM_VOICE_CALL &&
2151                 vss.mStreamType != AudioSystem.STREAM_BLUETOOTH_SCO)) {
2152                 mMuteAffectedStreams &= ~(1 << vss.mStreamType);
2153             }
2154         }
2155     }
2156 
createStreamStates()2157     private void createStreamStates() {
2158         int numStreamTypes = AudioSystem.getNumStreamTypes();
2159         VolumeStreamState[] streams = mStreamStates = new VolumeStreamState[numStreamTypes];
2160 
2161         for (int i = 0; i < numStreamTypes; i++) {
2162             streams[i] =
2163                     new VolumeStreamState(System.VOLUME_SETTINGS_INT[mStreamVolumeAlias[i]], i);
2164         }
2165 
2166         checkAllFixedVolumeDevices();
2167         checkAllAliasStreamVolumes();
2168         checkMuteAffectedStreams();
2169         updateDefaultVolumes();
2170     }
2171 
2172     /**
2173      * Update default indexes from aliased streams. Must be called after mStreamStates is created
2174      * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for default
2175      * index. Need to make default index configurable and independent of streams.
2176      * Fallback on music stream for default initialization to take benefit of property based default
2177      * initialization.
2178      * For other volume groups not linked to any streams, default music stream index is considered.
2179      */
updateDefaultVolumes()2180     private void updateDefaultVolumes() {
2181         for (int stream = 0; stream < mStreamStates.length; stream++) {
2182             int streamVolumeAlias = mStreamVolumeAlias[stream];
2183             if (mUseVolumeGroupAliases) {
2184                 if (AudioSystem.DEFAULT_STREAM_VOLUME[stream] != UNSET_INDEX) {
2185                     // Already initialized through default property based mecanism.
2186                     continue;
2187                 }
2188                 streamVolumeAlias = AudioSystem.STREAM_MUSIC;
2189                 int defaultAliasVolume = getUiDefaultRescaledIndex(streamVolumeAlias, stream);
2190                 if ((defaultAliasVolume >= MIN_STREAM_VOLUME[stream])
2191                         && (defaultAliasVolume <= MAX_STREAM_VOLUME[stream])) {
2192                     AudioSystem.DEFAULT_STREAM_VOLUME[stream] = defaultAliasVolume;
2193                     continue;
2194                 }
2195             }
2196             if (stream != streamVolumeAlias) {
2197                 AudioSystem.DEFAULT_STREAM_VOLUME[stream] =
2198                         getUiDefaultRescaledIndex(streamVolumeAlias, stream);
2199             }
2200         }
2201     }
2202 
getUiDefaultRescaledIndex(int srcStream, int dstStream)2203     private int getUiDefaultRescaledIndex(int srcStream, int dstStream) {
2204         return (rescaleIndex(AudioSystem.DEFAULT_STREAM_VOLUME[srcStream] * 10,
2205                 srcStream, dstStream) + 5) / 10;
2206     }
2207 
dumpStreamStates(PrintWriter pw)2208     private void dumpStreamStates(PrintWriter pw) {
2209         pw.println("\nStream volumes (device: index)");
2210         int numStreamTypes = AudioSystem.getNumStreamTypes();
2211         for (int i = 0; i < numStreamTypes; i++) {
2212             StringBuilder alias = new StringBuilder();
2213             if (mStreamVolumeAlias[i] != i) {
2214                 alias.append(" (aliased to: ")
2215                         .append(AudioSystem.STREAM_NAMES[mStreamVolumeAlias[i]])
2216                         .append(")");
2217             }
2218             pw.println("- " + AudioSystem.STREAM_NAMES[i] + alias + ":");
2219             mStreamStates[i].dump(pw);
2220             pw.println("");
2221         }
2222         pw.print("\n- mute affected streams = 0x");
2223         pw.println(Integer.toHexString(mMuteAffectedStreams));
2224     }
2225 
updateStreamVolumeAlias(boolean updateVolumes, String caller)2226     private void updateStreamVolumeAlias(boolean updateVolumes, String caller) {
2227         int dtmfStreamAlias;
2228         final int a11yStreamAlias = sIndependentA11yVolume ?
2229                 AudioSystem.STREAM_ACCESSIBILITY : AudioSystem.STREAM_MUSIC;
2230         final int assistantStreamAlias = mContext.getResources().getBoolean(
2231                 com.android.internal.R.bool.config_useAssistantVolume) ?
2232                 AudioSystem.STREAM_ASSISTANT : AudioSystem.STREAM_MUSIC;
2233 
2234         if (mIsSingleVolume) {
2235             mStreamVolumeAlias = STREAM_VOLUME_ALIAS_TELEVISION.clone();
2236             dtmfStreamAlias = AudioSystem.STREAM_MUSIC;
2237         } else if (mUseVolumeGroupAliases) {
2238             mStreamVolumeAlias = STREAM_VOLUME_ALIAS_NONE.clone();
2239             dtmfStreamAlias = AudioSystem.STREAM_DTMF;
2240         } else {
2241             switch (mPlatformType) {
2242                 case AudioSystem.PLATFORM_VOICE:
2243                     mStreamVolumeAlias = STREAM_VOLUME_ALIAS_VOICE.clone();
2244                     dtmfStreamAlias = AudioSystem.STREAM_RING;
2245                     break;
2246                 default:
2247                     mStreamVolumeAlias = STREAM_VOLUME_ALIAS_DEFAULT.clone();
2248                     dtmfStreamAlias = AudioSystem.STREAM_MUSIC;
2249             }
2250             if (!mNotifAliasRing) {
2251                 mStreamVolumeAlias[AudioSystem.STREAM_NOTIFICATION] =
2252                         AudioSystem.STREAM_NOTIFICATION;
2253             }
2254         }
2255 
2256         if (mIsSingleVolume) {
2257             mRingerModeAffectedStreams = 0;
2258         } else {
2259             if (isInCommunication()) {
2260                 dtmfStreamAlias = AudioSystem.STREAM_VOICE_CALL;
2261                 mRingerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF);
2262             } else {
2263                 mRingerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF);
2264             }
2265         }
2266 
2267         mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias;
2268         mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY] = a11yStreamAlias;
2269         mStreamVolumeAlias[AudioSystem.STREAM_ASSISTANT] = assistantStreamAlias;
2270 
2271         if (updateVolumes && mStreamStates != null) {
2272             updateDefaultVolumes();
2273 
2274             synchronized (mSettingsLock) {
2275                 synchronized (VolumeStreamState.class) {
2276                     mStreamStates[AudioSystem.STREAM_DTMF]
2277                             .setAllIndexes(mStreamStates[dtmfStreamAlias], caller);
2278                     mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setSettingName(
2279                             System.VOLUME_SETTINGS_INT[a11yStreamAlias]);
2280                     mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setAllIndexes(
2281                             mStreamStates[a11yStreamAlias], caller);
2282                 }
2283             }
2284             if (sIndependentA11yVolume) {
2285                 // restore the a11y values from the settings
2286                 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].readSettings();
2287             }
2288 
2289             // apply stream mute states according to new value of mRingerModeAffectedStreams
2290             setRingerModeInt(getRingerModeInternal(), false);
2291             sendMsg(mAudioHandler,
2292                     MSG_SET_ALL_VOLUMES,
2293                     SENDMSG_QUEUE,
2294                     0,
2295                     0,
2296                     mStreamStates[AudioSystem.STREAM_DTMF], 0);
2297             sendMsg(mAudioHandler,
2298                     MSG_SET_ALL_VOLUMES,
2299                     SENDMSG_QUEUE,
2300                     0,
2301                     0,
2302                     mStreamStates[AudioSystem.STREAM_ACCESSIBILITY], 0);
2303         }
2304         dispatchStreamAliasingUpdate();
2305     }
2306 
readDockAudioSettings(ContentResolver cr)2307     private void readDockAudioSettings(ContentResolver cr)
2308     {
2309         mDockAudioMediaEnabled = mSettings.getGlobalInt(
2310                                         cr, Settings.Global.DOCK_AUDIO_MEDIA_ENABLED, 0) == 1;
2311 
2312         sendMsg(mAudioHandler,
2313                 MSG_SET_FORCE_USE,
2314                 SENDMSG_QUEUE,
2315                 AudioSystem.FOR_DOCK,
2316                 mDockAudioMediaEnabled ?
2317                         AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE,
2318                 new String("readDockAudioSettings"),
2319                 0);
2320 
2321     }
2322 
2323 
updateMasterMono(ContentResolver cr)2324     private void updateMasterMono(ContentResolver cr)
2325     {
2326         final boolean masterMono = mSettings.getSystemIntForUser(
2327                 cr, System.MASTER_MONO, 0 /* default */, UserHandle.USER_CURRENT) == 1;
2328         if (DEBUG_VOL) {
2329             Log.d(TAG, String.format("Master mono %b", masterMono));
2330         }
2331         AudioSystem.setMasterMono(masterMono);
2332     }
2333 
updateMasterBalance(ContentResolver cr)2334     private void updateMasterBalance(ContentResolver cr) {
2335         final float masterBalance = System.getFloatForUser(
2336                 cr, System.MASTER_BALANCE, 0.f /* default */, UserHandle.USER_CURRENT);
2337         if (DEBUG_VOL) {
2338             Log.d(TAG, String.format("Master balance %f", masterBalance));
2339         }
2340         if (AudioSystem.setMasterBalance(masterBalance) != 0) {
2341             Log.e(TAG, String.format("setMasterBalance failed for %f", masterBalance));
2342         }
2343     }
2344 
sendEncodedSurroundMode(ContentResolver cr, String eventSource)2345     private void sendEncodedSurroundMode(ContentResolver cr, String eventSource)
2346     {
2347         final int encodedSurroundMode = mSettings.getGlobalInt(
2348                 cr, Settings.Global.ENCODED_SURROUND_OUTPUT,
2349                 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
2350         sendEncodedSurroundMode(encodedSurroundMode, eventSource);
2351     }
2352 
sendEncodedSurroundMode(int encodedSurroundMode, String eventSource)2353     private void sendEncodedSurroundMode(int encodedSurroundMode, String eventSource)
2354     {
2355         // initialize to guaranteed bad value
2356         int forceSetting = AudioSystem.NUM_FORCE_CONFIG;
2357         switch (encodedSurroundMode) {
2358             case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO:
2359                 forceSetting = AudioSystem.FORCE_NONE;
2360                 break;
2361             case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER:
2362                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_NEVER;
2363                 break;
2364             case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS:
2365                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_ALWAYS;
2366                 break;
2367             case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL:
2368                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_MANUAL;
2369                 break;
2370             default:
2371                 Log.e(TAG, "updateSurroundSoundSettings: illegal value "
2372                         + encodedSurroundMode);
2373                 break;
2374         }
2375         if (forceSetting != AudioSystem.NUM_FORCE_CONFIG) {
2376             mDeviceBroker.setForceUse_Async(AudioSystem.FOR_ENCODED_SURROUND, forceSetting,
2377                     eventSource);
2378         }
2379     }
2380 
2381     @Override // Binder call
onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)2382     public void onShellCommand(FileDescriptor in, FileDescriptor out,
2383             FileDescriptor err, String[] args, ShellCallback callback,
2384             ResultReceiver resultReceiver) {
2385         if (mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_AUDIO_POLICY)
2386                 != PackageManager.PERMISSION_GRANTED) {
2387             throw new SecurityException("Missing MANAGE_AUDIO_POLICY permission");
2388         }
2389         new AudioManagerShellCommand(AudioService.this).exec(this, in, out, err,
2390                 args, callback, resultReceiver);
2391     }
2392 
2393     /** @see AudioManager#getSurroundFormats() */
2394     @Override
getSurroundFormats()2395     public Map<Integer, Boolean> getSurroundFormats() {
2396         Map<Integer, Boolean> surroundFormats = new HashMap<>();
2397         int status = AudioSystem.getSurroundFormats(surroundFormats);
2398         if (status != AudioManager.SUCCESS) {
2399             // fail and bail!
2400             Log.e(TAG, "getSurroundFormats failed:" + status);
2401             return new HashMap<>(); // Always return a map.
2402         }
2403         return surroundFormats;
2404     }
2405 
2406     /** @see AudioManager#getReportedSurroundFormats() */
2407     @Override
getReportedSurroundFormats()2408     public List<Integer> getReportedSurroundFormats() {
2409         ArrayList<Integer> reportedSurroundFormats = new ArrayList<>();
2410         int status = AudioSystem.getReportedSurroundFormats(reportedSurroundFormats);
2411         if (status != AudioManager.SUCCESS) {
2412             // fail and bail!
2413             Log.e(TAG, "getReportedSurroundFormats failed:" + status);
2414             return new ArrayList<>(); // Always return a list.
2415         }
2416         return reportedSurroundFormats;
2417     }
2418 
2419     /** @see AudioManager#isSurroundFormatEnabled(int) */
2420     @Override
isSurroundFormatEnabled(int audioFormat)2421     public boolean isSurroundFormatEnabled(int audioFormat) {
2422         if (!isSurroundFormat(audioFormat)) {
2423             Log.w(TAG, "audioFormat to enable is not a surround format.");
2424             return false;
2425         }
2426 
2427         final long token = Binder.clearCallingIdentity();
2428         try {
2429             synchronized (mSettingsLock) {
2430                 HashSet<Integer> enabledFormats = getEnabledFormats();
2431                 return enabledFormats.contains(audioFormat);
2432             }
2433         } finally {
2434             Binder.restoreCallingIdentity(token);
2435         }
2436     }
2437 
2438     /** @see AudioManager#setSurroundFormatEnabled(int, boolean) */
2439     @Override
setSurroundFormatEnabled(int audioFormat, boolean enabled)2440     public boolean setSurroundFormatEnabled(int audioFormat, boolean enabled) {
2441         if (!isSurroundFormat(audioFormat)) {
2442             Log.w(TAG, "audioFormat to enable is not a surround format.");
2443             return false;
2444         }
2445         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS)
2446                 != PackageManager.PERMISSION_GRANTED) {
2447             throw new SecurityException("Missing WRITE_SETTINGS permission");
2448         }
2449 
2450         HashSet<Integer> enabledFormats = getEnabledFormats();
2451         if (enabled) {
2452             enabledFormats.add(audioFormat);
2453         } else {
2454             enabledFormats.remove(audioFormat);
2455         }
2456         final long token = Binder.clearCallingIdentity();
2457         try {
2458             synchronized (mSettingsLock) {
2459                 mSettings.putGlobalString(mContentResolver,
2460                         Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
2461                         TextUtils.join(",", enabledFormats));
2462             }
2463         } finally {
2464             Binder.restoreCallingIdentity(token);
2465         }
2466         return true;
2467     }
2468 
2469     /** @see AudioManager#setEncodedSurroundMode(int) */
2470     @Override
setEncodedSurroundMode(@udioManager.EncodedSurroundOutputMode int mode)2471     public boolean setEncodedSurroundMode(@AudioManager.EncodedSurroundOutputMode int mode) {
2472         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS)
2473                 != PackageManager.PERMISSION_GRANTED) {
2474             throw new SecurityException("Missing WRITE_SETTINGS permission");
2475         }
2476 
2477         final long token = Binder.clearCallingIdentity();
2478         try {
2479             synchronized (mSettingsLock) {
2480                 mSettings.putGlobalInt(mContentResolver,
2481                         Settings.Global.ENCODED_SURROUND_OUTPUT,
2482                         toEncodedSurroundSetting(mode));
2483             }
2484         } finally {
2485             Binder.restoreCallingIdentity(token);
2486         }
2487         return true;
2488     }
2489 
2490     /** @see AudioManager#getEncodedSurroundMode() */
2491     @Override
getEncodedSurroundMode(int targetSdkVersion)2492     public int getEncodedSurroundMode(int targetSdkVersion) {
2493         final long token = Binder.clearCallingIdentity();
2494         try {
2495             synchronized (mSettingsLock) {
2496                 int encodedSurroundSetting = mSettings.getGlobalInt(mContentResolver,
2497                         Settings.Global.ENCODED_SURROUND_OUTPUT,
2498                         AudioManager.ENCODED_SURROUND_OUTPUT_AUTO);
2499                 return toEncodedSurroundOutputMode(encodedSurroundSetting, targetSdkVersion);
2500             }
2501         } finally {
2502             Binder.restoreCallingIdentity(token);
2503         }
2504     }
2505 
2506     /** @return the formats that are enabled in global settings */
getEnabledFormats()2507     private HashSet<Integer> getEnabledFormats() {
2508         HashSet<Integer> formats = new HashSet<>();
2509         String enabledFormats = mSettings.getGlobalString(mContentResolver,
2510                 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
2511         if (enabledFormats != null) {
2512             try {
2513                 Arrays.stream(TextUtils.split(enabledFormats, ","))
2514                         .mapToInt(Integer::parseInt)
2515                         .forEach(formats::add);
2516             } catch (NumberFormatException e) {
2517                 Log.w(TAG, "ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS misformatted.", e);
2518             }
2519         }
2520         return formats;
2521     }
2522 
2523     @SuppressWarnings("AndroidFrameworkCompatChange")
2524     @AudioManager.EncodedSurroundOutputMode
toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion)2525     private int toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion) {
2526         if (targetSdkVersion <= Build.VERSION_CODES.S
2527                 && encodedSurroundSetting > Settings.Global.ENCODED_SURROUND_SC_MAX) {
2528             return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN;
2529         }
2530         switch (encodedSurroundSetting) {
2531             case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO:
2532                 return AudioManager.ENCODED_SURROUND_OUTPUT_AUTO;
2533             case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER:
2534                 return AudioManager.ENCODED_SURROUND_OUTPUT_NEVER;
2535             case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS:
2536                 return AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS;
2537             case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL:
2538                 return AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL;
2539             default:
2540                 return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN;
2541         }
2542     }
2543 
toEncodedSurroundSetting( @udioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode)2544     private int toEncodedSurroundSetting(
2545             @AudioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode) {
2546         switch (encodedSurroundOutputMode) {
2547             case AudioManager.ENCODED_SURROUND_OUTPUT_NEVER:
2548                 return Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER;
2549             case AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS:
2550                 return Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS;
2551             case AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL:
2552                 return Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL;
2553             default:
2554                 return Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO;
2555         }
2556     }
2557 
isSurroundFormat(int audioFormat)2558     private boolean isSurroundFormat(int audioFormat) {
2559         for (int sf : AudioFormat.SURROUND_SOUND_ENCODING) {
2560             if (sf == audioFormat) {
2561                 return true;
2562             }
2563         }
2564         return false;
2565     }
2566 
sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate)2567     private void sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate) {
2568         if (mEncodedSurroundMode != Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL) {
2569             // Manually enable surround formats only when the setting is in manual mode.
2570             return;
2571         }
2572         String enabledSurroundFormats = mSettings.getGlobalString(
2573                 cr, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
2574         if (enabledSurroundFormats == null) {
2575             // Never allow enabledSurroundFormats as a null, which could happen when
2576             // ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS is not appear in settings DB.
2577             enabledSurroundFormats = "";
2578         }
2579         if (!forceUpdate && TextUtils.equals(enabledSurroundFormats, mEnabledSurroundFormats)) {
2580             // Update enabled surround formats to AudioPolicyManager only when forceUpdate
2581             // is true or enabled surround formats changed.
2582             return;
2583         }
2584 
2585         mEnabledSurroundFormats = enabledSurroundFormats;
2586         String[] surroundFormats = TextUtils.split(enabledSurroundFormats, ",");
2587         ArrayList<Integer> formats = new ArrayList<>();
2588         for (String format : surroundFormats) {
2589             try {
2590                 int audioFormat = Integer.valueOf(format);
2591                 if (isSurroundFormat(audioFormat) && !formats.contains(audioFormat)) {
2592                     formats.add(audioFormat);
2593                 }
2594             } catch (Exception e) {
2595                 Log.e(TAG, "Invalid enabled surround format:" + format);
2596             }
2597         }
2598         // Set filtered surround formats to settings DB in case
2599         // there are invalid surround formats in original settings.
2600         mSettings.putGlobalString(mContext.getContentResolver(),
2601                 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
2602                 TextUtils.join(",", formats));
2603         sendMsg(mAudioHandler, MSG_ENABLE_SURROUND_FORMATS, SENDMSG_QUEUE, 0, 0, formats, 0);
2604     }
2605 
onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats)2606     private void onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats) {
2607         // Set surround format enabled accordingly.
2608         for (int surroundFormat : AudioFormat.SURROUND_SOUND_ENCODING) {
2609             boolean enabled = enabledSurroundFormats.contains(surroundFormat);
2610             int ret = AudioSystem.setSurroundFormatEnabled(surroundFormat, enabled);
2611             Log.i(TAG, "enable surround format:" + surroundFormat + " " + enabled + " " + ret);
2612         }
2613     }
2614 
2615     @GuardedBy("mSettingsLock")
updateAssistantUIdLocked(boolean forceUpdate)2616     private void updateAssistantUIdLocked(boolean forceUpdate) {
2617         int assistantUid = INVALID_UID;
2618         // Consider assistants in the following order of priority:
2619         // 1) apk in assistant role
2620         // 2) voice interaction service
2621         // 3) assistant service
2622 
2623         String packageName = "";
2624         if (mRoleObserver != null) {
2625             packageName = mRoleObserver.getAssistantRoleHolder();
2626         }
2627         if (TextUtils.isEmpty(packageName)) {
2628             String assistantName = mSettings.getSecureStringForUser(
2629                             mContentResolver,
2630                             Settings.Secure.VOICE_INTERACTION_SERVICE, UserHandle.USER_CURRENT);
2631             if (TextUtils.isEmpty(assistantName)) {
2632                 assistantName = mSettings.getSecureStringForUser(
2633                         mContentResolver,
2634                         Settings.Secure.ASSISTANT, UserHandle.USER_CURRENT);
2635             }
2636             if (!TextUtils.isEmpty(assistantName)) {
2637                 ComponentName componentName = ComponentName.unflattenFromString(assistantName);
2638                 if (componentName == null) {
2639                     Slog.w(TAG, "Invalid service name for "
2640                             + Settings.Secure.VOICE_INTERACTION_SERVICE + ": " + assistantName);
2641                     return;
2642                 }
2643                 packageName = componentName.getPackageName();
2644             }
2645         }
2646         if (!TextUtils.isEmpty(packageName)) {
2647             PackageManager pm = mContext.getPackageManager();
2648 
2649             if (pm.checkPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD, packageName)
2650                     == PackageManager.PERMISSION_GRANTED) {
2651                 try {
2652                     assistantUid = pm.getPackageUidAsUser(packageName, getCurrentUserId());
2653                 } catch (PackageManager.NameNotFoundException e) {
2654                     Log.e(TAG,
2655                             "updateAssistantUId() could not find UID for package: " + packageName);
2656                 }
2657             }
2658         }
2659         if ((mPrimaryAssistantUid != assistantUid) || forceUpdate) {
2660             mAssistantUids.remove(mPrimaryAssistantUid);
2661             mPrimaryAssistantUid = assistantUid;
2662             addAssistantServiceUidsLocked(new int[]{mPrimaryAssistantUid});
2663         }
2664     }
2665 
readPersistedSettings()2666     private void readPersistedSettings() {
2667         if (!mSystemServer.isPrivileged()) {
2668             return;
2669         }
2670         final ContentResolver cr = mContentResolver;
2671 
2672         int ringerModeFromSettings =
2673                 mSettings.getGlobalInt(
2674                         cr, Settings.Global.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
2675         int ringerMode = ringerModeFromSettings;
2676         // validity check in case the settings are restored from a device with incompatible
2677         // ringer modes
2678         if (!isValidRingerMode(ringerMode)) {
2679             ringerMode = AudioManager.RINGER_MODE_NORMAL;
2680         }
2681         if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) {
2682             ringerMode = AudioManager.RINGER_MODE_SILENT;
2683         }
2684         if (ringerMode != ringerModeFromSettings) {
2685             mSettings.putGlobalInt(cr, Settings.Global.MODE_RINGER, ringerMode);
2686         }
2687         if (mUseFixedVolume || mIsSingleVolume) {
2688             ringerMode = AudioManager.RINGER_MODE_NORMAL;
2689         }
2690         synchronized(mSettingsLock) {
2691             mRingerMode = ringerMode;
2692             if (mRingerModeExternal == -1) {
2693                 mRingerModeExternal = mRingerMode;
2694             }
2695 
2696             // System.VIBRATE_ON is not used any more but defaults for mVibrateSetting
2697             // are still needed while setVibrateSetting() and getVibrateSetting() are being
2698             // deprecated.
2699             mVibrateSetting = AudioSystem.getValueForVibrateSetting(0,
2700                                             AudioManager.VIBRATE_TYPE_NOTIFICATION,
2701                                             mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT
2702                                                             : AudioManager.VIBRATE_SETTING_OFF);
2703             mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting,
2704                                             AudioManager.VIBRATE_TYPE_RINGER,
2705                                             mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT
2706                                                             : AudioManager.VIBRATE_SETTING_OFF);
2707 
2708             updateRingerAndZenModeAffectedStreams();
2709             readDockAudioSettings(cr);
2710             sendEncodedSurroundMode(cr, "readPersistedSettings");
2711             sendEnabledSurroundFormats(cr, true);
2712             updateAssistantUIdLocked(/* forceUpdate= */ true);
2713             resetActiveAssistantUidsLocked();
2714             AudioSystem.setRttEnabled(mRttEnabled);
2715         }
2716 
2717         mMuteAffectedStreams = mSettings.getSystemIntForUser(cr,
2718                 System.MUTE_STREAMS_AFFECTED, AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED,
2719                 UserHandle.USER_CURRENT);
2720 
2721         updateMasterMono(cr);
2722 
2723         updateMasterBalance(cr);
2724 
2725         // Each stream will read its own persisted settings
2726 
2727         // Broadcast the sticky intents
2728         broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, mRingerModeExternal);
2729         broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, mRingerMode);
2730 
2731         // Broadcast vibrate settings
2732         broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
2733         broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION);
2734 
2735         // Load settings for the volume controller
2736         mVolumeController.loadSettings(cr);
2737     }
2738 
2739     @GuardedBy("mSettingsLock")
resetActiveAssistantUidsLocked()2740     private void resetActiveAssistantUidsLocked() {
2741         mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS;
2742         updateActiveAssistantServiceUids();
2743     }
2744 
readUserRestrictions()2745     private void readUserRestrictions() {
2746         if (!mSystemServer.isPrivileged()) {
2747             return;
2748         }
2749         final int currentUser = getCurrentUserId();
2750 
2751         // Check the current user restriction.
2752         boolean masterMute =
2753                 mUserManagerInternal.getUserRestriction(currentUser,
2754                         UserManager.DISALLOW_UNMUTE_DEVICE)
2755                         || mUserManagerInternal.getUserRestriction(currentUser,
2756                         UserManager.DISALLOW_ADJUST_VOLUME);
2757         if (mUseFixedVolume) {
2758             masterMute = false;
2759             AudioSystem.setMasterVolume(1.0f);
2760         }
2761         if (DEBUG_VOL) {
2762             Log.d(TAG, String.format("Master mute %s, user=%d", masterMute, currentUser));
2763         }
2764         AudioSystem.setMasterMute(masterMute);
2765         broadcastMasterMuteStatus(masterMute);
2766 
2767         mMicMuteFromRestrictions = mUserManagerInternal.getUserRestriction(
2768                 currentUser, UserManager.DISALLOW_UNMUTE_MICROPHONE);
2769         if (DEBUG_VOL) {
2770             Log.d(TAG, String.format("Mic mute %b, user=%d", mMicMuteFromRestrictions,
2771                     currentUser));
2772         }
2773         setMicrophoneMuteNoCallerCheck(currentUser);
2774     }
2775 
getIndexRange(int streamType)2776     private int getIndexRange(int streamType) {
2777         return (mStreamStates[streamType].getMaxIndex() - mStreamStates[streamType].getMinIndex());
2778     }
2779 
rescaleIndex(VolumeInfo volumeInfo, int dstStream)2780     private int rescaleIndex(VolumeInfo volumeInfo, int dstStream) {
2781         if (volumeInfo.getVolumeIndex() == VolumeInfo.INDEX_NOT_SET
2782                 || volumeInfo.getMinVolumeIndex() == VolumeInfo.INDEX_NOT_SET
2783                 || volumeInfo.getMaxVolumeIndex() == VolumeInfo.INDEX_NOT_SET) {
2784             Log.e(TAG, "rescaleIndex: volumeInfo has invalid index or range");
2785             return mStreamStates[dstStream].getMinIndex();
2786         }
2787         return rescaleIndex(volumeInfo.getVolumeIndex(),
2788                 volumeInfo.getMinVolumeIndex(), volumeInfo.getMaxVolumeIndex(),
2789                 mStreamStates[dstStream].getMinIndex(), mStreamStates[dstStream].getMaxIndex());
2790     }
2791 
rescaleIndex(int index, int srcStream, VolumeInfo dstVolumeInfo)2792     private int rescaleIndex(int index, int srcStream, VolumeInfo dstVolumeInfo) {
2793         int dstMin = dstVolumeInfo.getMinVolumeIndex();
2794         int dstMax = dstVolumeInfo.getMaxVolumeIndex();
2795         // Don't rescale index if the VolumeInfo is missing a min or max index
2796         if (dstMin == VolumeInfo.INDEX_NOT_SET || dstMax == VolumeInfo.INDEX_NOT_SET) {
2797             return index;
2798         }
2799         return rescaleIndex(index,
2800                 mStreamStates[srcStream].getMinIndex(), mStreamStates[srcStream].getMaxIndex(),
2801                 dstMin, dstMax);
2802     }
2803 
rescaleIndex(int index, int srcStream, int dstStream)2804     private int rescaleIndex(int index, int srcStream, int dstStream) {
2805         return rescaleIndex(index,
2806                 mStreamStates[srcStream].getMinIndex(), mStreamStates[srcStream].getMaxIndex(),
2807                 mStreamStates[dstStream].getMinIndex(), mStreamStates[dstStream].getMaxIndex());
2808     }
2809 
rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax)2810     private int rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax) {
2811         int srcRange = srcMax - srcMin;
2812         int dstRange = dstMax - dstMin;
2813         if (srcRange == 0) {
2814             Log.e(TAG, "rescaleIndex : index range should not be zero");
2815             return dstMin;
2816         }
2817         return dstMin + ((index - srcMin) * dstRange + srcRange / 2) / srcRange;
2818     }
2819 
rescaleStep(int step, int srcStream, int dstStream)2820     private int rescaleStep(int step, int srcStream, int dstStream) {
2821         int srcRange = getIndexRange(srcStream);
2822         int dstRange = getIndexRange(dstStream);
2823         if (srcRange == 0) {
2824             Log.e(TAG, "rescaleStep : index range should not be zero");
2825             return 0;
2826         }
2827 
2828         return ((step * dstRange + srcRange / 2) / srcRange);
2829     }
2830 
2831     ///////////////////////////////////////////////////////////////////////////
2832     // IPC methods
2833     ///////////////////////////////////////////////////////////////////////////
2834     /**
2835      * @see AudioManager#setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes)
2836      * @see AudioManager#setPreferredDevicesForStrategy(AudioProductStrategy,
2837      *                                                  List<AudioDeviceAttributes>)
2838      */
2839     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices)2840     public int setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices) {
2841         super.setPreferredDevicesForStrategy_enforcePermission();
2842         if (devices == null) {
2843             return AudioSystem.ERROR;
2844         }
2845 
2846         devices = retrieveBluetoothAddresses(devices);
2847 
2848         final String logString = String.format(
2849                 "setPreferredDevicesForStrategy u/pid:%d/%d strat:%d dev:%s",
2850                 Binder.getCallingUid(), Binder.getCallingPid(), strategy,
2851                 devices.stream().map(e -> e.toString()).collect(Collectors.joining(",")));
2852         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
2853         if (devices.stream().anyMatch(device ->
2854                 device.getRole() == AudioDeviceAttributes.ROLE_INPUT)) {
2855             Log.e(TAG, "Unsupported input routing in " + logString);
2856             return AudioSystem.ERROR;
2857         }
2858 
2859         final int status = mDeviceBroker.setPreferredDevicesForStrategySync(strategy, devices);
2860         if (status != AudioSystem.SUCCESS) {
2861             Log.e(TAG, String.format("Error %d in %s)", status, logString));
2862         }
2863 
2864         return status;
2865     }
2866 
2867     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
2868     /** @see AudioManager#removePreferredDeviceForStrategy(AudioProductStrategy) */
removePreferredDevicesForStrategy(int strategy)2869     public int removePreferredDevicesForStrategy(int strategy) {
2870         super.removePreferredDevicesForStrategy_enforcePermission();
2871 
2872         final String logString =
2873                 String.format("removePreferredDeviceForStrategy strat:%d", strategy);
2874         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
2875 
2876         final int status = mDeviceBroker.removePreferredDevicesForStrategySync(strategy);
2877         if (status != AudioSystem.SUCCESS) {
2878             Log.e(TAG, String.format("Error %d in %s)", status, logString));
2879         }
2880         return status;
2881     }
2882 
2883     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
2884     /**
2885      * @see AudioManager#getPreferredDeviceForStrategy(AudioProductStrategy)
2886      * @see AudioManager#getPreferredDevicesForStrategy(AudioProductStrategy)
2887      */
getPreferredDevicesForStrategy(int strategy)2888     public List<AudioDeviceAttributes> getPreferredDevicesForStrategy(int strategy) {
2889         super.getPreferredDevicesForStrategy_enforcePermission();
2890 
2891         List<AudioDeviceAttributes> devices = new ArrayList<>();
2892         int status = AudioSystem.SUCCESS;
2893         final long identity = Binder.clearCallingIdentity();
2894         try {
2895             status = AudioSystem.getDevicesForRoleAndStrategy(
2896                     strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
2897         } finally {
2898             Binder.restoreCallingIdentity(identity);
2899         }
2900         if (status != AudioSystem.SUCCESS) {
2901             Log.e(TAG, String.format("Error %d in getPreferredDeviceForStrategy(%d)",
2902                     status, strategy));
2903             return new ArrayList<AudioDeviceAttributes>();
2904         } else {
2905             return anonymizeAudioDeviceAttributesList(devices);
2906         }
2907     }
2908 
2909     /**
2910      * @see AudioManager#setDeviceAsNonDefaultForStrategy(AudioProductStrategy,
2911      *                                                    AudioDeviceAttributes)
2912      * @see AudioManager#setDeviceAsNonDefaultForStrategy(AudioProductStrategy,
2913      *                                                     List<AudioDeviceAttributes>)
2914      */
2915     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
setDeviceAsNonDefaultForStrategy(int strategy, @NonNull AudioDeviceAttributes device)2916     public int setDeviceAsNonDefaultForStrategy(int strategy,
2917                                                 @NonNull AudioDeviceAttributes device) {
2918         super.setDeviceAsNonDefaultForStrategy_enforcePermission();
2919         Objects.requireNonNull(device);
2920 
2921         device = retrieveBluetoothAddress(device);
2922 
2923         final String logString = String.format(
2924                 "setDeviceAsNonDefaultForStrategy u/pid:%d/%d strat:%d dev:%s",
2925                 Binder.getCallingUid(), Binder.getCallingPid(), strategy, device.toString());
2926         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
2927         if (device.getRole() == AudioDeviceAttributes.ROLE_INPUT) {
2928             Log.e(TAG, "Unsupported input routing in " + logString);
2929             return AudioSystem.ERROR;
2930         }
2931 
2932         final int status = mDeviceBroker.setDeviceAsNonDefaultForStrategySync(strategy, device);
2933         if (status != AudioSystem.SUCCESS) {
2934             Log.e(TAG, String.format("Error %d in %s)", status, logString));
2935         }
2936 
2937         return status;
2938     }
2939 
2940     /**
2941      * @see AudioManager#removeDeviceAsNonDefaultForStrategy(AudioProductStrategy,
2942      *                                                       AudioDeviceAttributes)
2943      */
2944     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
removeDeviceAsNonDefaultForStrategy(int strategy, AudioDeviceAttributes device)2945     public int removeDeviceAsNonDefaultForStrategy(int strategy,
2946                                                    AudioDeviceAttributes device) {
2947         super.removeDeviceAsNonDefaultForStrategy_enforcePermission();
2948         Objects.requireNonNull(device);
2949 
2950         device = retrieveBluetoothAddress(device);
2951 
2952         final String logString = String.format(
2953                 "removeDeviceAsNonDefaultForStrategy strat:%d dev:%s", strategy, device.toString());
2954         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
2955         if (device.getRole() == AudioDeviceAttributes.ROLE_INPUT) {
2956             Log.e(TAG, "Unsupported input routing in " + logString);
2957             return AudioSystem.ERROR;
2958         }
2959 
2960         final int status = mDeviceBroker.removeDeviceAsNonDefaultForStrategySync(strategy, device);
2961         if (status != AudioSystem.SUCCESS) {
2962             Log.e(TAG, String.format("Error %d in %s)", status, logString));
2963         }
2964         return status;
2965     }
2966 
2967     /**
2968      * @see AudioManager#getNonDefaultDevicesForStrategy(AudioProductStrategy)
2969      */
2970     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
getNonDefaultDevicesForStrategy(int strategy)2971     public List<AudioDeviceAttributes> getNonDefaultDevicesForStrategy(int strategy) {
2972         super.getNonDefaultDevicesForStrategy_enforcePermission();
2973         List<AudioDeviceAttributes> devices = new ArrayList<>();
2974         int status = AudioSystem.ERROR;
2975 
2976         try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
2977             status = AudioSystem.getDevicesForRoleAndStrategy(
2978                     strategy, AudioSystem.DEVICE_ROLE_DISABLED, devices);
2979         }
2980 
2981         if (status != AudioSystem.SUCCESS) {
2982             Log.e(TAG, String.format("Error %d in getNonDefaultDeviceForStrategy(%d)",
2983                     status, strategy));
2984             return new ArrayList<AudioDeviceAttributes>();
2985         } else {
2986             return anonymizeAudioDeviceAttributesList(devices);
2987         }
2988     }
2989 
2990     /** @see AudioManager#addOnPreferredDevicesForStrategyChangedListener(
2991      *               Executor, AudioManager.OnPreferredDevicesForStrategyChangedListener)
2992      */
registerStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)2993     public void registerStrategyPreferredDevicesDispatcher(
2994             @Nullable IStrategyPreferredDevicesDispatcher dispatcher) {
2995         if (dispatcher == null) {
2996             return;
2997         }
2998         enforceModifyAudioRoutingPermission();
2999         mDeviceBroker.registerStrategyPreferredDevicesDispatcher(
3000                 dispatcher, isBluetoothPrividged());
3001     }
3002 
3003     /** @see AudioManager#removeOnPreferredDevicesForStrategyChangedListener(
3004      *               AudioManager.OnPreferredDevicesForStrategyChangedListener)
3005      */
unregisterStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)3006     public void unregisterStrategyPreferredDevicesDispatcher(
3007             @Nullable IStrategyPreferredDevicesDispatcher dispatcher) {
3008         if (dispatcher == null) {
3009             return;
3010         }
3011         enforceModifyAudioRoutingPermission();
3012         mDeviceBroker.unregisterStrategyPreferredDevicesDispatcher(dispatcher);
3013     }
3014 
3015     /** @see AudioManager#addOnNonDefaultDevicesForStrategyChangedListener(
3016      *               Executor, AudioManager.OnNonDefaultDevicesForStrategyChangedListener)
3017      */
registerStrategyNonDefaultDevicesDispatcher( @ullable IStrategyNonDefaultDevicesDispatcher dispatcher)3018     public void registerStrategyNonDefaultDevicesDispatcher(
3019             @Nullable IStrategyNonDefaultDevicesDispatcher dispatcher) {
3020         if (dispatcher == null) {
3021             return;
3022         }
3023         enforceModifyAudioRoutingPermission();
3024         mDeviceBroker.registerStrategyNonDefaultDevicesDispatcher(
3025                 dispatcher, isBluetoothPrividged());
3026     }
3027 
3028     /** @see AudioManager#removeOnNonDefaultDevicesForStrategyChangedListener(
3029      *               AudioManager.OnNonDefaultDevicesForStrategyChangedListener)
3030      */
unregisterStrategyNonDefaultDevicesDispatcher( @ullable IStrategyNonDefaultDevicesDispatcher dispatcher)3031     public void unregisterStrategyNonDefaultDevicesDispatcher(
3032             @Nullable IStrategyNonDefaultDevicesDispatcher dispatcher) {
3033         if (dispatcher == null) {
3034             return;
3035         }
3036         enforceModifyAudioRoutingPermission();
3037         mDeviceBroker.unregisterStrategyNonDefaultDevicesDispatcher(dispatcher);
3038     }
3039 
3040     /**
3041      * @see AudioManager#setPreferredDevicesForCapturePreset(int, AudioDeviceAttributes)
3042      */
setPreferredDevicesForCapturePreset( int capturePreset, List<AudioDeviceAttributes> devices)3043     public int setPreferredDevicesForCapturePreset(
3044             int capturePreset, List<AudioDeviceAttributes> devices) {
3045         if (devices == null) {
3046             return AudioSystem.ERROR;
3047         }
3048         enforceModifyAudioRoutingPermission();
3049         final String logString = String.format(
3050                 "setPreferredDevicesForCapturePreset u/pid:%d/%d source:%d dev:%s",
3051                 Binder.getCallingUid(), Binder.getCallingPid(), capturePreset,
3052                 devices.stream().map(e -> e.toString()).collect(Collectors.joining(",")));
3053         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
3054         if (devices.stream().anyMatch(device ->
3055                 device.getRole() == AudioDeviceAttributes.ROLE_OUTPUT)) {
3056             Log.e(TAG, "Unsupported output routing in " + logString);
3057             return AudioSystem.ERROR;
3058         }
3059 
3060         devices = retrieveBluetoothAddresses(devices);
3061 
3062         final int status = mDeviceBroker.setPreferredDevicesForCapturePresetSync(
3063                 capturePreset, devices);
3064         if (status != AudioSystem.SUCCESS) {
3065             Log.e(TAG, String.format("Error %d in %s)", status, logString));
3066         }
3067 
3068         return status;
3069     }
3070 
3071     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
3072     /** @see AudioManager#clearPreferredDevicesForCapturePreset(int) */
clearPreferredDevicesForCapturePreset(int capturePreset)3073     public int clearPreferredDevicesForCapturePreset(int capturePreset) {
3074         super.clearPreferredDevicesForCapturePreset_enforcePermission();
3075 
3076         final String logString = String.format(
3077                 "removePreferredDeviceForCapturePreset source:%d", capturePreset);
3078         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
3079 
3080         final int status = mDeviceBroker.clearPreferredDevicesForCapturePresetSync(capturePreset);
3081         if (status != AudioSystem.SUCCESS) {
3082             Log.e(TAG, String.format("Error %d in %s", status, logString));
3083         }
3084         return status;
3085     }
3086 
3087     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
3088     /**
3089      * @see AudioManager#getPreferredDevicesForCapturePreset(int)
3090      */
getPreferredDevicesForCapturePreset(int capturePreset)3091     public List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int capturePreset) {
3092         super.getPreferredDevicesForCapturePreset_enforcePermission();
3093 
3094         List<AudioDeviceAttributes> devices = new ArrayList<>();
3095         int status = AudioSystem.SUCCESS;
3096         final long identity = Binder.clearCallingIdentity();
3097         try {
3098             status = AudioSystem.getDevicesForRoleAndCapturePreset(
3099                     capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
3100         } finally {
3101             Binder.restoreCallingIdentity(identity);
3102         }
3103         if (status != AudioSystem.SUCCESS) {
3104             Log.e(TAG, String.format("Error %d in getPreferredDeviceForCapturePreset(%d)",
3105                     status, capturePreset));
3106             return new ArrayList<AudioDeviceAttributes>();
3107         } else {
3108             return anonymizeAudioDeviceAttributesList(devices);
3109         }
3110     }
3111 
3112     /**
3113      * @see AudioManager#addOnPreferredDevicesForCapturePresetChangedListener(
3114      *              Executor, OnPreferredDevicesForCapturePresetChangedListener)
3115      */
registerCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)3116     public void registerCapturePresetDevicesRoleDispatcher(
3117             @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) {
3118         if (dispatcher == null) {
3119             return;
3120         }
3121         enforceModifyAudioRoutingPermission();
3122         mDeviceBroker.registerCapturePresetDevicesRoleDispatcher(
3123                 dispatcher, isBluetoothPrividged());
3124     }
3125 
3126     /**
3127      * @see AudioManager#removeOnPreferredDevicesForCapturePresetChangedListener(
3128      *              AudioManager.OnPreferredDevicesForCapturePresetChangedListener)
3129      */
unregisterCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)3130     public void unregisterCapturePresetDevicesRoleDispatcher(
3131             @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) {
3132         if (dispatcher == null) {
3133             return;
3134         }
3135         enforceModifyAudioRoutingPermission();
3136         mDeviceBroker.unregisterCapturePresetDevicesRoleDispatcher(dispatcher);
3137     }
3138 
3139     /** @see AudioManager#getDevicesForAttributes(AudioAttributes) */
getDevicesForAttributes( @onNull AudioAttributes attributes)3140     public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes(
3141             @NonNull AudioAttributes attributes) {
3142         enforceQueryStateOrModifyRoutingPermission();
3143 
3144         return new ArrayList<AudioDeviceAttributes>(anonymizeAudioDeviceAttributesList(
3145                 getDevicesForAttributesInt(attributes, false /* forVolume */)));
3146     }
3147 
3148     /** @see AudioManager#getAudioDevicesForAttributes(AudioAttributes)
3149      * This method is similar with AudioService#getDevicesForAttributes,
3150      * only it doesn't enforce permissions because it is used by an unprivileged public API
3151      * instead of the system API.
3152      */
getDevicesForAttributesUnprotected( @onNull AudioAttributes attributes)3153     public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesUnprotected(
3154             @NonNull AudioAttributes attributes) {
3155         return new ArrayList<AudioDeviceAttributes>(anonymizeAudioDeviceAttributesList(
3156                 getDevicesForAttributesInt(attributes, false /* forVolume */)));
3157     }
3158 
3159     /**
3160      * @see AudioManager#isMusicActive()
3161      * @param remotely true if query is for remote playback (cast), false for local playback.
3162      */
isMusicActive(boolean remotely)3163     public boolean isMusicActive(boolean remotely) {
3164         // no permission required
3165         final long token = Binder.clearCallingIdentity();
3166         try {
3167             if (remotely) {
3168                 return AudioSystem.isStreamActiveRemotely(AudioSystem.STREAM_MUSIC, 0);
3169             } else {
3170                 return AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0);
3171             }
3172         } finally {
3173             Binder.restoreCallingIdentity(token);
3174         }
3175     }
3176 
getDevicesForAttributesInt( @onNull AudioAttributes attributes, boolean forVolume)3177     protected @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesInt(
3178             @NonNull AudioAttributes attributes, boolean forVolume) {
3179         Objects.requireNonNull(attributes);
3180         return mAudioSystem.getDevicesForAttributes(attributes, forVolume);
3181     }
3182 
3183     /**
3184      * @see AudioManager#addOnDevicesForAttributesChangedListener(
3185      *      AudioAttributes, Executor, OnDevicesForAttributesChangedListener)
3186      */
addOnDevicesForAttributesChangedListener(AudioAttributes attributes, IDevicesForAttributesCallback callback)3187     public void addOnDevicesForAttributesChangedListener(AudioAttributes attributes,
3188             IDevicesForAttributesCallback callback) {
3189         mAudioSystem.addOnDevicesForAttributesChangedListener(
3190                 attributes, false /* forVolume */, callback);
3191     }
3192 
3193     /**
3194      * @see AudioManager#removeOnDevicesForAttributesChangedListener(
3195      *      OnDevicesForAttributesChangedListener)
3196      */
removeOnDevicesForAttributesChangedListener( IDevicesForAttributesCallback callback)3197     public void removeOnDevicesForAttributesChangedListener(
3198             IDevicesForAttributesCallback callback) {
3199         mAudioSystem.removeOnDevicesForAttributesChangedListener(callback);
3200     }
3201 
3202     // pre-condition: event.getKeyCode() is one of KeyEvent.KEYCODE_VOLUME_UP,
3203     //                                   KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_MUTE
handleVolumeKey(@onNull KeyEvent event, boolean isOnTv, @NonNull String callingPackage, @NonNull String caller)3204     public void handleVolumeKey(@NonNull KeyEvent event, boolean isOnTv,
3205             @NonNull String callingPackage, @NonNull String caller) {
3206         int keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_NORMAL;
3207         if (isOnTv) {
3208             if (event.getAction() == KeyEvent.ACTION_DOWN) {
3209                 keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_START;
3210             } else { // may catch more than ACTION_UP, but will end vol adjustement
3211                 // the vol key is either released (ACTION_UP), or multiple keys are pressed
3212                 // (ACTION_MULTIPLE) and we don't know what to do for volume control on CEC, end
3213                 // the repeated volume adjustement
3214                 keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_END;
3215             }
3216         } else if (event.getAction() != KeyEvent.ACTION_DOWN) {
3217             return;
3218         }
3219 
3220         int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND
3221                 | AudioManager.FLAG_FROM_KEY;
3222 
3223         switch (event.getKeyCode()) {
3224             case KeyEvent.KEYCODE_VOLUME_UP:
3225                     adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE,
3226                             AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller,
3227                             Binder.getCallingUid(), Binder.getCallingPid(), true, keyEventMode);
3228                 break;
3229             case KeyEvent.KEYCODE_VOLUME_DOWN:
3230                     adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER,
3231                             AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller,
3232                             Binder.getCallingUid(), Binder.getCallingPid(), true, keyEventMode);
3233                 break;
3234             case KeyEvent.KEYCODE_VOLUME_MUTE:
3235                 if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
3236                     adjustSuggestedStreamVolume(AudioManager.ADJUST_TOGGLE_MUTE,
3237                             AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller,
3238                             Binder.getCallingUid(), Binder.getCallingPid(),
3239                             true, AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
3240                 }
3241                 break;
3242             default:
3243                 Log.e(TAG, "Invalid key code " + event.getKeyCode() + " sent by " + callingPackage);
3244                 return; // not needed but added if code gets added below this switch statement
3245         }
3246     }
3247 
setNavigationRepeatSoundEffectsEnabled(boolean enabled)3248     public void setNavigationRepeatSoundEffectsEnabled(boolean enabled) {
3249         mNavigationRepeatSoundEffectsEnabled = enabled;
3250     }
3251 
3252     /**
3253      * @return true if the fast scroll sound effects are enabled
3254      */
areNavigationRepeatSoundEffectsEnabled()3255     public boolean areNavigationRepeatSoundEffectsEnabled() {
3256         return mNavigationRepeatSoundEffectsEnabled;
3257     }
3258 
setHomeSoundEffectEnabled(boolean enabled)3259     public void setHomeSoundEffectEnabled(boolean enabled) {
3260         mHomeSoundEffectEnabled = enabled;
3261     }
3262 
3263     /**
3264      * @return true if the home sound effect is enabled
3265      */
isHomeSoundEffectEnabled()3266     public boolean isHomeSoundEffectEnabled() {
3267         return mHomeSoundEffectEnabled;
3268     }
3269 
3270     /** All callers come from platform apps/system server, so no attribution tag is needed */
adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, String callingPackage, String caller, int uid, int pid, boolean hasModifyAudioSettings, int keyEventMode)3271     private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
3272             String callingPackage, String caller, int uid, int pid, boolean hasModifyAudioSettings,
3273             int keyEventMode) {
3274         if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream=" + suggestedStreamType
3275                 + ", flags=" + flags + ", caller=" + caller
3276                 + ", volControlStream=" + mVolumeControlStream
3277                 + ", userSelect=" + mUserSelectedVolumeControlStream);
3278         if (direction != AudioManager.ADJUST_SAME) {
3279             sVolumeLogger.enqueue(
3280                     new VolumeEvent(VolumeEvent.VOL_ADJUST_SUGG_VOL, suggestedStreamType,
3281                             direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage)
3282                             .append("/").append(caller).append(" uid:").append(uid).toString()));
3283         }
3284 
3285         boolean hasExternalVolumeController = notifyExternalVolumeController(direction);
3286 
3287         new MediaMetrics.Item(mMetricsId + "adjustSuggestedStreamVolume")
3288                 .setUid(Binder.getCallingUid())
3289                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage)
3290                 .set(MediaMetrics.Property.CLIENT_NAME, caller)
3291                 .set(MediaMetrics.Property.DIRECTION, direction > 0
3292                         ? MediaMetrics.Value.UP : MediaMetrics.Value.DOWN)
3293                 .set(MediaMetrics.Property.EXTERNAL, hasExternalVolumeController
3294                         ? MediaMetrics.Value.YES : MediaMetrics.Value.NO)
3295                 .set(MediaMetrics.Property.FLAGS, flags)
3296                 .record();
3297 
3298         if (hasExternalVolumeController) {
3299             return;
3300         }
3301 
3302         final int streamType;
3303         synchronized (mForceControlStreamLock) {
3304             // Request lock in case mVolumeControlStream is changed by other thread.
3305             if (mUserSelectedVolumeControlStream) { // implies mVolumeControlStream != -1
3306                 streamType = mVolumeControlStream;
3307             } else {
3308                 // TODO discard activity on a muted stream?
3309                 final int maybeActiveStreamType = getActiveStreamType(suggestedStreamType);
3310                 final boolean activeForReal;
3311                 if (maybeActiveStreamType == AudioSystem.STREAM_RING
3312                         || maybeActiveStreamType == AudioSystem.STREAM_NOTIFICATION) {
3313                     activeForReal = wasStreamActiveRecently(maybeActiveStreamType, 0);
3314                 } else {
3315                     activeForReal = mAudioSystem.isStreamActive(maybeActiveStreamType, 0);
3316                 }
3317                 if (activeForReal || mVolumeControlStream == -1) {
3318                     streamType = maybeActiveStreamType;
3319                 } else {
3320                     streamType = mVolumeControlStream;
3321                 }
3322             }
3323         }
3324 
3325         final boolean isMute = isMuteAdjust(direction);
3326 
3327         ensureValidStreamType(streamType);
3328         final int resolvedStream = mStreamVolumeAlias[streamType];
3329 
3330         // Play sounds on STREAM_RING only.
3331         if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 &&
3332                 resolvedStream != AudioSystem.STREAM_RING) {
3333             flags &= ~AudioManager.FLAG_PLAY_SOUND;
3334         }
3335 
3336         // For notifications/ring, show the ui before making any adjustments
3337         // Don't suppress mute/unmute requests
3338         // Don't suppress adjustments for single volume device
3339         if (mVolumeController.suppressAdjustment(resolvedStream, flags, isMute)
3340                 && !mIsSingleVolume) {
3341             direction = 0;
3342             flags &= ~AudioManager.FLAG_PLAY_SOUND;
3343             flags &= ~AudioManager.FLAG_VIBRATE;
3344             if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment");
3345         }
3346 
3347         adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid, pid,
3348                 null, hasModifyAudioSettings, keyEventMode);
3349     }
3350 
notifyExternalVolumeController(int direction)3351     private boolean notifyExternalVolumeController(int direction) {
3352         final IAudioPolicyCallback externalVolumeController;
3353         synchronized (mExtVolumeControllerLock) {
3354             externalVolumeController = mExtVolumeController;
3355         }
3356         if (externalVolumeController == null) {
3357             return false;
3358         }
3359 
3360         sendMsg(mAudioHandler, MSG_NOTIFY_VOL_EVENT, SENDMSG_QUEUE,
3361                 direction, 0 /*ignored*/,
3362                 externalVolumeController, 0 /*delay*/);
3363         return true;
3364     }
3365 
3366     /** Retain API for unsupported app usage */
adjustStreamVolume(int streamType, int direction, int flags, String callingPackage)3367     public void adjustStreamVolume(int streamType, int direction, int flags,
3368             String callingPackage) {
3369         adjustStreamVolumeWithAttribution(streamType, direction, flags, callingPackage, null);
3370     }
3371 
3372     /** @see AudioManager#adjustStreamVolume(int, int, int)
3373      * Part of service interface, check permissions here */
adjustStreamVolumeWithAttribution(int streamType, int direction, int flags, String callingPackage, String attributionTag)3374     public void adjustStreamVolumeWithAttribution(int streamType, int direction, int flags,
3375             String callingPackage, String attributionTag) {
3376         if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {
3377             Log.w(TAG, "Trying to call adjustStreamVolume() for a11y without"
3378                     + "CHANGE_ACCESSIBILITY_VOLUME / callingPackage=" + callingPackage);
3379             return;
3380         }
3381 
3382         final VolumeEvent evt = new VolumeEvent(VolumeEvent.VOL_ADJUST_STREAM_VOL, streamType,
3383                 direction/*val1*/, flags/*val2*/, callingPackage);
3384         sVolumeLogger.enqueue(evt);
3385         // also logging mute/unmute calls to the dedicated logger
3386         if (isMuteAdjust(direction)) {
3387             sMuteLogger.enqueue(evt);
3388         }
3389         adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage,
3390                 Binder.getCallingUid(), Binder.getCallingPid(), attributionTag,
3391                 callingHasAudioSettingsPermission(), AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
3392     }
3393 
adjustStreamVolume(int streamType, int direction, int flags, String callingPackage, String caller, int uid, int pid, String attributionTag, boolean hasModifyAudioSettings, int keyEventMode)3394     protected void adjustStreamVolume(int streamType, int direction, int flags,
3395             String callingPackage, String caller, int uid, int pid, String attributionTag,
3396             boolean hasModifyAudioSettings, int keyEventMode) {
3397         if (mUseFixedVolume) {
3398             return;
3399         }
3400         if (DEBUG_VOL) Log.d(TAG, "adjustStreamVolume() stream=" + streamType + ", dir=" + direction
3401                 + ", flags=" + flags + ", caller=" + caller);
3402 
3403         ensureValidDirection(direction);
3404         ensureValidStreamType(streamType);
3405 
3406         boolean isMuteAdjust = isMuteAdjust(direction);
3407 
3408         if (isMuteAdjust && !isStreamAffectedByMute(streamType)) {
3409             return;
3410         }
3411 
3412         // If adjust is mute and the stream is STREAM_VOICE_CALL or STREAM_BLUETOOTH_SCO, make sure
3413         // that the calling app have the MODIFY_PHONE_STATE permission.
3414         if (isMuteAdjust &&
3415             (streamType == AudioSystem.STREAM_VOICE_CALL ||
3416                 streamType == AudioSystem.STREAM_BLUETOOTH_SCO) &&
3417                 mContext.checkPermission(android.Manifest.permission.MODIFY_PHONE_STATE, pid, uid)
3418                     != PackageManager.PERMISSION_GRANTED) {
3419             Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: adjustStreamVolume from pid="
3420                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
3421             return;
3422         }
3423 
3424         // If the stream is STREAM_ASSISTANT,
3425         // make sure that the calling app have the MODIFY_AUDIO_ROUTING permission.
3426         if (streamType == AudioSystem.STREAM_ASSISTANT &&
3427                 mContext.checkPermission(
3428                 android.Manifest.permission.MODIFY_AUDIO_ROUTING, pid, uid)
3429                     != PackageManager.PERMISSION_GRANTED) {
3430             Log.w(TAG, "MODIFY_AUDIO_ROUTING Permission Denial: adjustStreamVolume from pid="
3431                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
3432             return;
3433         }
3434 
3435         // use stream type alias here so that streams with same alias have the same behavior,
3436         // including with regard to silent mode control (e.g the use of STREAM_RING below and in
3437         // checkForRingerModeChange() in place of STREAM_RING or STREAM_NOTIFICATION)
3438         int streamTypeAlias = mStreamVolumeAlias[streamType];
3439 
3440         VolumeStreamState streamState = mStreamStates[streamTypeAlias];
3441 
3442         final int device = getDeviceForStream(streamTypeAlias);
3443 
3444         int aliasIndex = streamState.getIndex(device);
3445         boolean adjustVolume = true;
3446         int step;
3447 
3448         // skip a2dp absolute volume control request when the device
3449         // is neither an a2dp device nor BLE device
3450         if ((!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
3451                 && !AudioSystem.DEVICE_OUT_ALL_BLE_SET.contains(device))
3452                 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) {
3453             return;
3454         }
3455 
3456         // If we are being called by the system (e.g. hardware keys) check for current user
3457         // so we handle user restrictions correctly.
3458         if (uid == android.os.Process.SYSTEM_UID) {
3459             uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid));
3460         }
3461         // validate calling package and app op
3462         if (!checkNoteAppOp(
3463                 STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage, attributionTag)) {
3464             return;
3465         }
3466 
3467         mSoundDoseHelper.invalidatPendingVolumeCommand();
3468 
3469         flags &= ~AudioManager.FLAG_FIXED_VOLUME;
3470         if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) {
3471             flags |= AudioManager.FLAG_FIXED_VOLUME;
3472 
3473             // Always toggle between max safe volume and 0 for fixed volume devices where safe
3474             // volume is enforced, and max and 0 for the others.
3475             // This is simulated by stepping by the full allowed volume range
3476             step = mSoundDoseHelper.getSafeMediaVolumeIndex(device);
3477             if (step < 0) {
3478                 step = streamState.getMaxIndex();
3479             }
3480             if (aliasIndex != 0) {
3481                 aliasIndex = step;
3482             }
3483         } else {
3484             // convert one UI step (+/-1) into a number of internal units on the stream alias
3485             step = rescaleStep(10, streamType, streamTypeAlias);
3486         }
3487 
3488         // If either the client forces allowing ringer modes for this adjustment,
3489         // or stream is used for UI sonification
3490         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
3491                 (isUiSoundsStreamType(streamTypeAlias))) {
3492             int ringerMode = getRingerModeInternal();
3493             // do not vibrate if already in vibrate mode
3494             if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
3495                 flags &= ~AudioManager.FLAG_VIBRATE;
3496             }
3497             // Check if the ringer mode handles this adjustment. If it does we don't
3498             // need to adjust the volume further.
3499             final int result = checkForRingerModeChange(aliasIndex, direction, step,
3500                     streamState.mIsMuted, callingPackage, flags);
3501             adjustVolume = (result & FLAG_ADJUST_VOLUME) != 0;
3502             // If suppressing a volume adjustment in silent mode, display the UI hint
3503             if ((result & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) {
3504                 flags |= AudioManager.FLAG_SHOW_SILENT_HINT;
3505             }
3506             // If suppressing a volume down adjustment in vibrate mode, display the UI hint
3507             if ((result & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) {
3508                 flags |= AudioManager.FLAG_SHOW_VIBRATE_HINT;
3509             }
3510         } else if (isStreamMutedByRingerOrZenMode(streamTypeAlias) && streamState.mIsMuted) {
3511             // if the stream is currently muted streams by ringer/zen mode
3512             // then it cannot be unmuted (without FLAG_ALLOW_RINGER_MODES) with an unmute or raise
3513             if (direction == AudioManager.ADJUST_TOGGLE_MUTE
3514                     || direction == AudioManager.ADJUST_UNMUTE
3515                     || direction == AudioManager.ADJUST_RAISE) {
3516                 adjustVolume = false;
3517             }
3518         }
3519 
3520         // If the ringer mode or zen is muting the stream, do not change stream unless
3521         // it'll cause us to exit dnd
3522         if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) {
3523             adjustVolume = false;
3524         }
3525         int oldIndex = mStreamStates[streamType].getIndex(device);
3526 
3527         // Check if the volume adjustment should be handled by an absolute volume controller instead
3528         if (isAbsoluteVolumeDevice(device)
3529                 && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) {
3530             AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device);
3531             if (info.mHandlesVolumeAdjustment) {
3532                 dispatchAbsoluteVolumeAdjusted(streamType, info, oldIndex, direction,
3533                         keyEventMode);
3534                 return;
3535             }
3536         }
3537 
3538         if (adjustVolume && (direction != AudioManager.ADJUST_SAME)
3539                 && (keyEventMode != AudioDeviceVolumeManager.ADJUST_MODE_END)) {
3540             mAudioHandler.removeMessages(MSG_UNMUTE_STREAM);
3541 
3542             if (isMuteAdjust && !mFullVolumeDevices.contains(device)) {
3543                 boolean state;
3544                 if (direction == AudioManager.ADJUST_TOGGLE_MUTE) {
3545                     state = !streamState.mIsMuted;
3546                 } else {
3547                     state = direction == AudioManager.ADJUST_MUTE;
3548                 }
3549                 muteAliasStreams(streamTypeAlias, state);
3550             } else if ((direction == AudioManager.ADJUST_RAISE)
3551                     && mSoundDoseHelper.raiseVolumeDisplaySafeMediaVolume(streamTypeAlias,
3552                             aliasIndex + step, device, flags)) {
3553                 Log.e(TAG, "adjustStreamVolume() safe volume index = " + oldIndex);
3554             } else if (!isFullVolumeDevice(device)
3555                     && (streamState.adjustIndex(direction * step, device, caller,
3556                             hasModifyAudioSettings)
3557                             || streamState.mIsMuted)) {
3558                 // Post message to set system volume (it in turn will post a
3559                 // message to persist).
3560                 if (streamState.mIsMuted) {
3561                     // Unmute the stream if it was previously muted
3562                     if (direction == AudioManager.ADJUST_RAISE) {
3563                         // unmute immediately for volume up
3564                         muteAliasStreams(streamTypeAlias, false);
3565                     } else if (direction == AudioManager.ADJUST_LOWER) {
3566                         if (mIsSingleVolume) {
3567                             sendMsg(mAudioHandler, MSG_UNMUTE_STREAM, SENDMSG_QUEUE,
3568                                     streamTypeAlias, flags, null, UNMUTE_STREAM_DELAY);
3569                         }
3570                     }
3571                 }
3572                 sendMsg(mAudioHandler,
3573                         MSG_SET_DEVICE_VOLUME,
3574                         SENDMSG_QUEUE,
3575                         device,
3576                         0,
3577                         streamState,
3578                         0);
3579             }
3580 
3581             int newIndex = mStreamStates[streamType].getIndex(device);
3582 
3583             // Check if volume update should be send to AVRCP
3584             if (streamTypeAlias == AudioSystem.STREAM_MUSIC
3585                     && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
3586                     && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
3587                 if (DEBUG_VOL) {
3588                     Log.d(TAG, "adjustSreamVolume: postSetAvrcpAbsoluteVolumeIndex index="
3589                             + newIndex + "stream=" + streamType);
3590                 }
3591                 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(newIndex / 10);
3592             } else if (isAbsoluteVolumeDevice(device)
3593                     && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) {
3594                 AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device);
3595                 dispatchAbsoluteVolumeChanged(streamType, info, newIndex);
3596             }
3597 
3598             if (AudioSystem.isLeAudioDeviceType(device)
3599                     && streamType == getBluetoothContextualVolumeStream()
3600                     && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
3601                 if (DEBUG_VOL) {
3602                     Log.d(TAG, "adjustSreamVolume postSetLeAudioVolumeIndex index="
3603                             + newIndex + " stream=" + streamType);
3604                 }
3605                 mDeviceBroker.postSetLeAudioVolumeIndex(newIndex,
3606                     mStreamStates[streamType].getMaxIndex(), streamType);
3607             }
3608 
3609             // Check if volume update should be send to Hearing Aid
3610             if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
3611                 // only modify the hearing aid attenuation when the stream to modify matches
3612                 // the one expected by the hearing aid
3613                 if (streamType == getBluetoothContextualVolumeStream()) {
3614                     if (DEBUG_VOL) {
3615                         Log.d(TAG, "adjustSreamVolume postSetHearingAidVolumeIndex index="
3616                                 + newIndex + " stream=" + streamType);
3617                     }
3618                     mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType);
3619                 }
3620             }
3621         }
3622 
3623         final int newIndex = mStreamStates[streamType].getIndex(device);
3624 
3625         if (adjustVolume) {
3626             synchronized (mHdmiClientLock) {
3627                 if (mHdmiManager != null) {
3628                     // At most one of mHdmiPlaybackClient and mHdmiTvClient should be non-null
3629                     HdmiClient fullVolumeHdmiClient = mHdmiPlaybackClient;
3630                     if (mHdmiTvClient != null) {
3631                         fullVolumeHdmiClient = mHdmiTvClient;
3632                     }
3633 
3634                     if (fullVolumeHdmiClient != null
3635                             && mHdmiCecVolumeControlEnabled
3636                             && streamTypeAlias == AudioSystem.STREAM_MUSIC
3637                             // vol change on a full volume device
3638                             && isFullVolumeDevice(device)) {
3639                         int keyCode = KeyEvent.KEYCODE_UNKNOWN;
3640                         switch (direction) {
3641                             case AudioManager.ADJUST_RAISE:
3642                                 keyCode = KeyEvent.KEYCODE_VOLUME_UP;
3643                                 break;
3644                             case AudioManager.ADJUST_LOWER:
3645                                 keyCode = KeyEvent.KEYCODE_VOLUME_DOWN;
3646                                 break;
3647                             case AudioManager.ADJUST_TOGGLE_MUTE:
3648                             case AudioManager.ADJUST_MUTE:
3649                             case AudioManager.ADJUST_UNMUTE:
3650                                 // Many CEC devices only support toggle mute. Therefore, we send the
3651                                 // same keycode for all three mute options.
3652                                 keyCode = KeyEvent.KEYCODE_VOLUME_MUTE;
3653                                 break;
3654                             default:
3655                                 break;
3656                         }
3657                         if (keyCode != KeyEvent.KEYCODE_UNKNOWN) {
3658                             final long ident = Binder.clearCallingIdentity();
3659                             try {
3660                                 switch (keyEventMode) {
3661                                     case AudioDeviceVolumeManager.ADJUST_MODE_NORMAL:
3662                                         fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, true);
3663                                         fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, false);
3664                                         break;
3665                                     case AudioDeviceVolumeManager.ADJUST_MODE_START:
3666                                         fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, true);
3667                                         break;
3668                                     case AudioDeviceVolumeManager.ADJUST_MODE_END:
3669                                         fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, false);
3670                                         break;
3671                                     default:
3672                                         Log.e(TAG, "Invalid keyEventMode " + keyEventMode);
3673                                 }
3674                             } finally {
3675                                 Binder.restoreCallingIdentity(ident);
3676                             }
3677                         }
3678                     }
3679 
3680                     if (streamTypeAlias == AudioSystem.STREAM_MUSIC
3681                             && (oldIndex != newIndex || isMuteAdjust)) {
3682                         maybeSendSystemAudioStatusCommand(isMuteAdjust);
3683                     }
3684                 }
3685             }
3686         }
3687         sendVolumeUpdate(streamType, oldIndex, newIndex, flags, device);
3688     }
3689 
3690     /**
3691      * Loops on aliasted stream, update the mute cache attribute of each
3692      * {@see AudioService#VolumeStreamState}, and then apply the change.
3693      * It prevents to unnecessary {@see AudioSystem#setStreamVolume} done for each stream
3694      * and aliases before mute change changed and after.
3695      */
muteAliasStreams(int streamAlias, boolean state)3696     private void muteAliasStreams(int streamAlias, boolean state) {
3697         // Locking mSettingsLock to avoid inversion when calling doMute -> updateVolumeGroupIndex
3698         synchronized (mSettingsLock) {
3699             synchronized (VolumeStreamState.class) {
3700                 List<Integer> streamsToMute = new ArrayList<>();
3701                 for (int stream = 0; stream < mStreamStates.length; stream++) {
3702                     VolumeStreamState vss = mStreamStates[stream];
3703                     if (streamAlias == mStreamVolumeAlias[stream] && vss.isMutable()) {
3704                         if (!(mCameraSoundForced
3705                                 && (vss.getStreamType()
3706                                 == AudioSystem.STREAM_SYSTEM_ENFORCED))) {
3707                             boolean changed = vss.mute(state, /* apply= */ false,
3708                                     "muteAliasStreams");
3709                             if (changed) {
3710                                 streamsToMute.add(stream);
3711                             }
3712                         }
3713                     }
3714                 }
3715                 streamsToMute.forEach(streamToMute -> {
3716                     mStreamStates[streamToMute].doMute();
3717                     broadcastMuteSetting(streamToMute, state);
3718                 });
3719             }
3720         }
3721     }
3722 
broadcastMuteSetting(int streamType, boolean isMuted)3723     private void broadcastMuteSetting(int streamType, boolean isMuted) {
3724         // Stream mute changed, fire the intent.
3725         Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION);
3726         intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, streamType);
3727         intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, isMuted);
3728         sendBroadcastToAll(intent, null /* options */);
3729     }
3730 
3731     // Called after a delay when volume down is pressed while muted
onUnmuteStream(int stream, int flags)3732     private void onUnmuteStream(int stream, int flags) {
3733         boolean wasMuted;
3734         // Locking mSettingsLock to avoid inversion when calling vss.mute -> vss.doMute ->
3735         // vss.updateVolumeGroupIndex
3736         synchronized (mSettingsLock) {
3737             synchronized (VolumeStreamState.class) {
3738                 final VolumeStreamState streamState = mStreamStates[stream];
3739                 // if unmuting causes a change, it was muted
3740                 wasMuted = streamState.mute(false, "onUnmuteStream");
3741 
3742                 final int device = getDeviceForStream(stream);
3743                 final int index = streamState.getIndex(device);
3744                 sendVolumeUpdate(stream, index, index, flags, device);
3745             }
3746             if (stream == AudioSystem.STREAM_MUSIC && wasMuted) {
3747                 synchronized (mHdmiClientLock) {
3748                     maybeSendSystemAudioStatusCommand(true);
3749                 }
3750             }
3751         }
3752     }
3753 
3754     @GuardedBy("mHdmiClientLock")
maybeSendSystemAudioStatusCommand(boolean isMuteAdjust)3755     private void maybeSendSystemAudioStatusCommand(boolean isMuteAdjust) {
3756         if (mHdmiAudioSystemClient == null
3757                 || !mHdmiSystemAudioSupported
3758                 || !mHdmiCecVolumeControlEnabled) {
3759             return;
3760         }
3761 
3762         final long identity = Binder.clearCallingIdentity();
3763         try {
3764             mHdmiAudioSystemClient.sendReportAudioStatusCecCommand(
3765                     isMuteAdjust, getStreamVolume(AudioSystem.STREAM_MUSIC),
3766                     getStreamMaxVolume(AudioSystem.STREAM_MUSIC),
3767                     isStreamMute(AudioSystem.STREAM_MUSIC));
3768         } finally {
3769             Binder.restoreCallingIdentity(identity);
3770         }
3771     }
3772 
getNewRingerMode(int stream, int index, int flags)3773     private int getNewRingerMode(int stream, int index, int flags) {
3774         // setRingerMode does nothing if the device is single volume,so the value would be unchanged
3775         if (mIsSingleVolume) {
3776             return getRingerModeExternal();
3777         }
3778 
3779         // setting volume on ui sounds stream type also controls silent mode
3780         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
3781                 (stream == getUiSoundsStreamType())) {
3782             int newRingerMode;
3783             if (index == 0) {
3784                 newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE
3785                         : mVolumePolicy.volumeDownToEnterSilent ? AudioManager.RINGER_MODE_SILENT
3786                                 : AudioManager.RINGER_MODE_NORMAL;
3787             } else {
3788                 newRingerMode = AudioManager.RINGER_MODE_NORMAL;
3789             }
3790             return newRingerMode;
3791         }
3792         return getRingerModeExternal();
3793     }
3794 
isAndroidNPlus(String caller)3795     private boolean isAndroidNPlus(String caller) {
3796         try {
3797             final ApplicationInfo applicationInfo =
3798                     mContext.getPackageManager().getApplicationInfoAsUser(
3799                             caller, 0, UserHandle.getUserId(Binder.getCallingUid()));
3800             if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N) {
3801                 return true;
3802             }
3803             return false;
3804         } catch (PackageManager.NameNotFoundException e) {
3805             return true;
3806         }
3807     }
3808 
wouldToggleZenMode(int newMode)3809     private boolean wouldToggleZenMode(int newMode) {
3810         if (getRingerModeExternal() == AudioManager.RINGER_MODE_SILENT
3811                 && newMode != AudioManager.RINGER_MODE_SILENT) {
3812             return true;
3813         } else if (getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT
3814                 && newMode == AudioManager.RINGER_MODE_SILENT) {
3815             return true;
3816         }
3817         return false;
3818     }
3819 
3820     /**
3821      * Update stream volume, ringer mode and mute status after a volume index change
3822      * @param streamType
3823      * @param index
3824      * @param flags
3825      * @param device the device for which the volume is changed
3826      * @param caller
3827      * @param hasModifyAudioSettings
3828      * @param canChangeMute true if the origin of this event is one where the mute state should be
3829      *                      updated following the change in volume index
3830      */
onSetStreamVolume(int streamType, int index, int flags, int device, String caller, boolean hasModifyAudioSettings, boolean canChangeMute)3831     /*package*/ void onSetStreamVolume(int streamType, int index, int flags, int device,
3832             String caller, boolean hasModifyAudioSettings, boolean canChangeMute) {
3833         final int stream = mStreamVolumeAlias[streamType];
3834         // setting volume on ui sounds stream type also controls silent mode
3835         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
3836                 (stream == getUiSoundsStreamType())) {
3837             setRingerMode(getNewRingerMode(stream, index, flags),
3838                     TAG + ".onSetStreamVolume", false /*external*/);
3839         }
3840         setStreamVolumeInt(stream, index, device, false, caller, hasModifyAudioSettings);
3841         // setting non-zero volume for a muted stream unmutes the stream and vice versa
3842         // except for BT SCO stream where only explicit mute is allowed to comply to BT requirements
3843         if ((streamType != AudioSystem.STREAM_BLUETOOTH_SCO) && canChangeMute) {
3844             // As adjustStreamVolume with muteAdjust flags mute/unmutes stream and aliased streams.
3845             muteAliasStreams(stream, index == 0);
3846         }
3847     }
3848 
enforceModifyAudioRoutingPermission()3849     private void enforceModifyAudioRoutingPermission() {
3850         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
3851                 != PackageManager.PERMISSION_GRANTED) {
3852             throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission");
3853         }
3854     }
3855 
enforceAccessUltrasoundPermission()3856     private void enforceAccessUltrasoundPermission() {
3857         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.ACCESS_ULTRASOUND)
3858                 != PackageManager.PERMISSION_GRANTED) {
3859             throw new SecurityException("Missing ACCESS_ULTRASOUND permission");
3860         }
3861     }
3862 
enforceQueryStatePermission()3863     private void enforceQueryStatePermission() {
3864         if (mContext.checkCallingOrSelfPermission(Manifest.permission.QUERY_AUDIO_STATE)
3865                 != PackageManager.PERMISSION_GRANTED) {
3866             throw new SecurityException("Missing QUERY_AUDIO_STATE permissions");
3867         }
3868     }
3869 
enforceQueryStateOrModifyRoutingPermission()3870     private void enforceQueryStateOrModifyRoutingPermission() {
3871         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
3872                 != PackageManager.PERMISSION_GRANTED
3873                 && mContext.checkCallingOrSelfPermission(Manifest.permission.QUERY_AUDIO_STATE)
3874                 != PackageManager.PERMISSION_GRANTED) {
3875             throw new SecurityException(
3876                     "Missing MODIFY_AUDIO_ROUTING or QUERY_AUDIO_STATE permissions");
3877         }
3878     }
3879 
enforceCallAudioInterceptionPermission()3880     private void enforceCallAudioInterceptionPermission() {
3881         if (mContext.checkCallingOrSelfPermission(
3882                 android.Manifest.permission.CALL_AUDIO_INTERCEPTION)
3883                 != PackageManager.PERMISSION_GRANTED) {
3884             throw new SecurityException("Missing CALL_AUDIO_INTERCEPTION permission");
3885         }
3886     }
3887 
3888 
3889     @Override
3890     @android.annotation.EnforcePermission(anyOf = {
3891             MODIFY_AUDIO_SETTINGS_PRIVILEGED,
3892             android.Manifest.permission.MODIFY_AUDIO_ROUTING
3893     })
3894     /** @see AudioManager#setVolumeGroupVolumeIndex(int, int, int) */
setVolumeGroupVolumeIndex(int groupId, int index, int flags, String callingPackage, String attributionTag)3895     public void setVolumeGroupVolumeIndex(int groupId, int index, int flags,
3896             String callingPackage, String attributionTag) {
3897         super.setVolumeGroupVolumeIndex_enforcePermission();
3898         if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
3899             Log.e(TAG, ": no volume group found for id " + groupId);
3900             return;
3901         }
3902         VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
3903 
3904         sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_GROUP_VOL, vgs.name(),
3905                 index, flags, callingPackage + ", user " + getCurrentUserId()));
3906 
3907         vgs.setVolumeIndex(index, flags);
3908 
3909         // For legacy reason, propagate to all streams associated to this volume group
3910         for (int groupedStream : vgs.getLegacyStreamTypes()) {
3911             try {
3912                 ensureValidStreamType(groupedStream);
3913             } catch (IllegalArgumentException e) {
3914                 Log.d(TAG, "volume group " + groupId + " has internal streams (" + groupedStream
3915                         + "), do not change associated stream volume");
3916                 continue;
3917             }
3918             setStreamVolume(groupedStream, index, flags, /*device*/ null,
3919                     callingPackage, callingPackage,
3920                     attributionTag, Binder.getCallingUid(), true /*hasModifyAudioSettings*/);
3921         }
3922     }
3923 
3924     @Nullable
getAudioVolumeGroupById(int volumeGroupId)3925     private AudioVolumeGroup getAudioVolumeGroupById(int volumeGroupId) {
3926         for (AudioVolumeGroup avg : AudioVolumeGroup.getAudioVolumeGroups()) {
3927             if (avg.getId() == volumeGroupId) {
3928                 return avg;
3929             }
3930         }
3931 
3932         Log.e(TAG, ": invalid volume group id: " + volumeGroupId + " requested");
3933         return null;
3934     }
3935 
3936     @Override
3937     @android.annotation.EnforcePermission(anyOf = {
3938             MODIFY_AUDIO_SETTINGS_PRIVILEGED,
3939             android.Manifest.permission.MODIFY_AUDIO_ROUTING
3940     })
3941     /** @see AudioManager#getVolumeGroupVolumeIndex(int) */
getVolumeGroupVolumeIndex(int groupId)3942     public int getVolumeGroupVolumeIndex(int groupId) {
3943         super.getVolumeGroupVolumeIndex_enforcePermission();
3944         synchronized (VolumeStreamState.class) {
3945             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
3946                 throw new IllegalArgumentException("No volume group for id " + groupId);
3947             }
3948             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
3949             // Return 0 when muted, not min index since for e.g. Voice Call, it has a non zero
3950             // min but it mutable on permission condition.
3951             return vgs.isMuted() ? 0 : vgs.getVolumeIndex();
3952         }
3953     }
3954 
3955     /** @see AudioManager#getVolumeGroupMaxVolumeIndex(int) */
3956     @android.annotation.EnforcePermission(anyOf = {
3957             MODIFY_AUDIO_SETTINGS_PRIVILEGED,
3958             android.Manifest.permission.MODIFY_AUDIO_ROUTING
3959     })
getVolumeGroupMaxVolumeIndex(int groupId)3960     public int getVolumeGroupMaxVolumeIndex(int groupId) {
3961         super.getVolumeGroupMaxVolumeIndex_enforcePermission();
3962         synchronized (VolumeStreamState.class) {
3963             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
3964                 throw new IllegalArgumentException("No volume group for id " + groupId);
3965             }
3966             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
3967             return vgs.getMaxIndex();
3968         }
3969     }
3970 
3971     /** @see AudioManager#getVolumeGroupMinVolumeIndex(int) */
3972     @android.annotation.EnforcePermission(anyOf = {
3973             MODIFY_AUDIO_SETTINGS_PRIVILEGED,
3974             android.Manifest.permission.MODIFY_AUDIO_ROUTING
3975     })
getVolumeGroupMinVolumeIndex(int groupId)3976     public int getVolumeGroupMinVolumeIndex(int groupId) {
3977         super.getVolumeGroupMinVolumeIndex_enforcePermission();
3978         synchronized (VolumeStreamState.class) {
3979             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
3980                 throw new IllegalArgumentException("No volume group for id " + groupId);
3981             }
3982             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
3983             return vgs.getMinIndex();
3984         }
3985     }
3986 
3987     @Override
3988     @android.annotation.EnforcePermission(anyOf = {
3989             android.Manifest.permission.MODIFY_AUDIO_ROUTING,
3990             android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED
3991     })
3992     /** @see AudioDeviceVolumeManager#setDeviceVolume(VolumeInfo, AudioDeviceAttributes)
3993      * Part of service interface, check permissions and parameters here
3994      * Note calling package is for logging purposes only, not to be trusted
3995      */
setDeviceVolume(@onNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage)3996     public void setDeviceVolume(@NonNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada,
3997             @NonNull String callingPackage) {
3998         super.setDeviceVolume_enforcePermission();
3999         Objects.requireNonNull(vi);
4000         Objects.requireNonNull(ada);
4001         Objects.requireNonNull(callingPackage);
4002 
4003         if (!vi.hasStreamType()) {
4004             Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception());
4005             return;
4006         }
4007 
4008         int index = vi.getVolumeIndex();
4009         if (index == VolumeInfo.INDEX_NOT_SET && !vi.hasMuteCommand()) {
4010             throw new IllegalArgumentException(
4011                     "changing device volume requires a volume index or mute command");
4012         }
4013 
4014         // force a cache clear to force reevaluating stream type to audio device selection
4015         // that can interfere with the sending of the VOLUME_CHANGED_ACTION intent
4016         mAudioSystem.clearRoutingCache();
4017 
4018         // log the current device that will be used when evaluating the sending of the
4019         // VOLUME_CHANGED_ACTION intent to see if the current device is the one being modified
4020         final int currDev = getDeviceForStream(vi.getStreamType());
4021 
4022         final boolean skipping = (currDev == ada.getInternalType());
4023 
4024         AudioService.sVolumeLogger.enqueue(new DeviceVolumeEvent(vi.getStreamType(), index, ada,
4025                 currDev, callingPackage, skipping));
4026 
4027         if (skipping) {
4028             // setDeviceVolume was called on a device currently being used
4029             return;
4030         }
4031 
4032         // TODO handle unmuting of current audio device
4033         // if a stream is not muted but the VolumeInfo is for muting, set the volume index
4034         // for the device to min volume
4035         if (vi.hasMuteCommand() && vi.isMuted() && !isStreamMute(vi.getStreamType())) {
4036             setStreamVolumeWithAttributionInt(vi.getStreamType(),
4037                     mStreamStates[vi.getStreamType()].getMinIndex(),
4038                     /*flags*/ 0,
4039                     ada, callingPackage, null);
4040             return;
4041         }
4042 
4043         AudioService.sVolumeLogger.enqueueAndLog("setDeviceVolume" + " from:" + callingPackage
4044                 + " " + vi + " " + ada, EventLogger.Event.ALOGI, TAG);
4045 
4046         if (vi.getMinVolumeIndex() == VolumeInfo.INDEX_NOT_SET
4047                 || vi.getMaxVolumeIndex() == VolumeInfo.INDEX_NOT_SET) {
4048             // assume index meant to be in stream type range, validate
4049             if ((index * 10) < mStreamStates[vi.getStreamType()].getMinIndex()
4050                     || (index * 10) > mStreamStates[vi.getStreamType()].getMaxIndex()) {
4051                 throw new IllegalArgumentException("invalid volume index " + index
4052                         + " not between min/max for stream " + vi.getStreamType());
4053             }
4054         } else {
4055             // check if index needs to be rescaled
4056             final int min = (mStreamStates[vi.getStreamType()].getMinIndex() + 5) / 10;
4057             final int max = (mStreamStates[vi.getStreamType()].getMaxIndex() + 5) / 10;
4058             if (vi.getMinVolumeIndex() != min || vi.getMaxVolumeIndex() != max) {
4059                 index = rescaleIndex(index,
4060                         /*srcMin*/ vi.getMinVolumeIndex(), /*srcMax*/ vi.getMaxVolumeIndex(),
4061                         /*dstMin*/ min, /*dstMax*/ max);
4062             }
4063         }
4064         setStreamVolumeWithAttributionInt(vi.getStreamType(), index, /*flags*/ 0,
4065                 ada, callingPackage, null);
4066     }
4067 
4068     /** Retain API for unsupported app usage */
setStreamVolume(int streamType, int index, int flags, String callingPackage)4069     public void setStreamVolume(int streamType, int index, int flags, String callingPackage) {
4070         setStreamVolumeWithAttribution(streamType, index, flags,
4071                 callingPackage, /*attributionTag*/ null);
4072     }
4073 
4074     /** @see AudioManager#adjustVolumeGroupVolume(int, int, int) */
adjustVolumeGroupVolume(int groupId, int direction, int flags, String callingPackage)4075     public void adjustVolumeGroupVolume(int groupId, int direction, int flags,
4076                                         String callingPackage) {
4077         ensureValidDirection(direction);
4078         if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
4079             Log.e(TAG, ": no volume group found for id " + groupId);
4080             return;
4081         }
4082         VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
4083         // For compatibility reason, use stream API if group linked to a valid stream
4084         boolean fallbackOnStream = false;
4085         for (int stream : vgs.getLegacyStreamTypes()) {
4086             try {
4087                 ensureValidStreamType(stream);
4088             } catch (IllegalArgumentException e) {
4089                 Log.d(TAG, "volume group " + groupId + " has internal streams (" + stream
4090                         + "), do not change associated stream volume");
4091                 continue;
4092             }
4093             // Note: Group and Stream does not share same convention, 0 is mute for stream,
4094             // min index is acting as mute for Groups
4095             if (vgs.isVssMuteBijective(stream)) {
4096                 adjustStreamVolume(stream, direction, flags, callingPackage);
4097                 if (isMuteAdjust(direction)) {
4098                     // will be propagated to all aliased streams
4099                     return;
4100                 }
4101                 fallbackOnStream = true;
4102             }
4103         }
4104         if (fallbackOnStream) {
4105             // Handled by at least one stream, will be propagated to group, bailing out.
4106             return;
4107         }
4108         sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_ADJUST_GROUP_VOL, vgs.name(),
4109                 direction, flags, callingPackage));
4110         vgs.adjustVolume(direction, flags);
4111     }
4112 
4113     /** @see AudioManager#getLastAudibleVolumeForVolumeGroup(int) */
4114     @android.annotation.EnforcePermission(android.Manifest.permission.QUERY_AUDIO_STATE)
getLastAudibleVolumeForVolumeGroup(int groupId)4115     public int getLastAudibleVolumeForVolumeGroup(int groupId) {
4116         super.getLastAudibleVolumeForVolumeGroup_enforcePermission();
4117         synchronized (VolumeStreamState.class) {
4118             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
4119                 Log.e(TAG, ": no volume group found for id " + groupId);
4120                 return 0;
4121             }
4122             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
4123             return vgs.getVolumeIndex();
4124         }
4125     }
4126 
4127     /** @see AudioManager#isVolumeGroupMuted(int) */
isVolumeGroupMuted(int groupId)4128     public boolean isVolumeGroupMuted(int groupId) {
4129         synchronized (VolumeStreamState.class) {
4130             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
4131                 Log.e(TAG, ": no volume group found for id " + groupId);
4132                 return false;
4133             }
4134             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
4135             return vgs.isMuted();
4136         }
4137     }
4138 
4139     /** @see AudioManager#setStreamVolume(int, int, int)
4140      * Part of service interface, check permissions here */
setStreamVolumeWithAttribution(int streamType, int index, int flags, String callingPackage, String attributionTag)4141     public void setStreamVolumeWithAttribution(int streamType, int index, int flags,
4142             String callingPackage, String attributionTag) {
4143         setStreamVolumeWithAttributionInt(streamType, index, flags, /*device*/ null,
4144                 callingPackage, attributionTag);
4145     }
4146 
4147     /**
4148      * Internal method for a stream type volume change. Can be used to change the volume on a
4149      * given device only
4150      * @param streamType the stream type whose volume is to be changed
4151      * @param index the volume index
4152      * @param flags options for volume handling
4153      * @param device null when controlling volume for the current routing, otherwise the device
4154      *               for which volume is being changed
4155      * @param callingPackage client side-provided package name of caller, not to be trusted
4156      * @param attributionTag client side-provided attribution name, not to be trusted
4157      */
setStreamVolumeWithAttributionInt(int streamType, int index, int flags, @Nullable AudioDeviceAttributes device, String callingPackage, String attributionTag)4158     protected void setStreamVolumeWithAttributionInt(int streamType, int index, int flags,
4159             @Nullable AudioDeviceAttributes device,
4160             String callingPackage, String attributionTag) {
4161         if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {
4162             Log.w(TAG, "Trying to call setStreamVolume() for a11y without"
4163                     + " CHANGE_ACCESSIBILITY_VOLUME  callingPackage=" + callingPackage);
4164             return;
4165         }
4166         if ((streamType == AudioManager.STREAM_VOICE_CALL) && (index == 0)
4167                 && (mContext.checkCallingOrSelfPermission(
4168                     android.Manifest.permission.MODIFY_PHONE_STATE)
4169                     != PackageManager.PERMISSION_GRANTED)) {
4170             Log.w(TAG, "Trying to call setStreamVolume() for STREAM_VOICE_CALL and index 0 without"
4171                     + " MODIFY_PHONE_STATE  callingPackage=" + callingPackage);
4172             return;
4173         }
4174         if ((streamType == AudioManager.STREAM_ASSISTANT)
4175             && (mContext.checkCallingOrSelfPermission(
4176                     android.Manifest.permission.MODIFY_AUDIO_ROUTING)
4177                     != PackageManager.PERMISSION_GRANTED)) {
4178             Log.w(TAG, "Trying to call setStreamVolume() for STREAM_ASSISTANT without"
4179                     + " MODIFY_AUDIO_ROUTING  callingPackage=" + callingPackage);
4180             return;
4181         }
4182 
4183         if (device == null) {
4184             // call was already logged in setDeviceVolume()
4185             sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType,
4186                     index/*val1*/, flags/*val2*/, callingPackage));
4187         }
4188         setStreamVolume(streamType, index, flags, device,
4189                 callingPackage, callingPackage, attributionTag,
4190                 Binder.getCallingUid(), callingOrSelfHasAudioSettingsPermission());
4191     }
4192 
4193     @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_ULTRASOUND)
4194     /** @see AudioManager#isUltrasoundSupported() */
isUltrasoundSupported()4195     public boolean isUltrasoundSupported() {
4196         super.isUltrasoundSupported_enforcePermission();
4197 
4198         return AudioSystem.isUltrasoundSupported();
4199     }
4200 
4201     /** @see AudioManager#isHotwordStreamSupported() */
4202     @android.annotation.EnforcePermission(android.Manifest.permission.CAPTURE_AUDIO_HOTWORD)
isHotwordStreamSupported(boolean lookbackAudio)4203     public boolean isHotwordStreamSupported(boolean lookbackAudio) {
4204         super.isHotwordStreamSupported_enforcePermission();
4205         try {
4206             return mAudioPolicy.isHotwordStreamSupported(lookbackAudio);
4207         } catch (IllegalStateException e) {
4208             // Suppress connection failure to APM, since the method is purely informative
4209             Log.e(TAG, "Suppressing exception calling into AudioPolicy", e);
4210             return false;
4211         }
4212     }
4213 
4214 
canChangeAccessibilityVolume()4215     private boolean canChangeAccessibilityVolume() {
4216         synchronized (mAccessibilityServiceUidsLock) {
4217             if (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
4218                     android.Manifest.permission.CHANGE_ACCESSIBILITY_VOLUME)) {
4219                 return true;
4220             }
4221             if (mAccessibilityServiceUids != null) {
4222                 int callingUid = Binder.getCallingUid();
4223                 for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
4224                     if (mAccessibilityServiceUids[i] == callingUid) {
4225                         return true;
4226                     }
4227                 }
4228             }
4229             return false;
4230         }
4231     }
4232 
getBluetoothContextualVolumeStream()4233     /*package*/ int getBluetoothContextualVolumeStream() {
4234         return getBluetoothContextualVolumeStream(mMode.get());
4235     }
4236 
getBluetoothContextualVolumeStream(int mode)4237     private int getBluetoothContextualVolumeStream(int mode) {
4238         switch (mode) {
4239             case AudioSystem.MODE_IN_COMMUNICATION:
4240             case AudioSystem.MODE_IN_CALL:
4241                 return AudioSystem.STREAM_VOICE_CALL;
4242             case AudioSystem.MODE_NORMAL:
4243             default:
4244                 // other conditions will influence the stream type choice, read on...
4245                 break;
4246         }
4247         if (mVoicePlaybackActive.get()) {
4248             return AudioSystem.STREAM_VOICE_CALL;
4249         }
4250         return AudioSystem.STREAM_MUSIC;
4251     }
4252 
4253     private AtomicBoolean mVoicePlaybackActive = new AtomicBoolean(false);
4254     private AtomicBoolean mMediaPlaybackActive = new AtomicBoolean(false);
4255 
4256     private final IPlaybackConfigDispatcher mPlaybackActivityMonitor =
4257             new IPlaybackConfigDispatcher.Stub() {
4258         @Override
4259         public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs,
4260                                                  boolean flush) {
4261             sendMsg(mAudioHandler, MSG_PLAYBACK_CONFIG_CHANGE, SENDMSG_REPLACE,
4262                     0 /*arg1 ignored*/, 0 /*arg2 ignored*/,
4263                     configs /*obj*/, 0 /*delay*/);
4264         }
4265     };
4266 
onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs)4267     private void onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) {
4268         boolean voiceActive = false;
4269         boolean mediaActive = false;
4270         for (AudioPlaybackConfiguration config : configs) {
4271             final int usage = config.getAudioAttributes().getUsage();
4272             if (!config.isActive()) {
4273                 continue;
4274             }
4275             if (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION
4276                     || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING) {
4277                 voiceActive = true;
4278             }
4279             if (usage == AudioAttributes.USAGE_MEDIA || usage == AudioAttributes.USAGE_GAME) {
4280                 mediaActive = true;
4281             }
4282         }
4283         if (mVoicePlaybackActive.getAndSet(voiceActive) != voiceActive) {
4284             updateHearingAidVolumeOnVoiceActivityUpdate();
4285         }
4286         if (mMediaPlaybackActive.getAndSet(mediaActive) != mediaActive && mediaActive) {
4287             mSoundDoseHelper.scheduleMusicActiveCheck();
4288         }
4289         // Update playback active state for all apps in audio mode stack.
4290         // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE
4291         // and request an audio mode update immediately. Upon any other change, queue the message
4292         // and request an audio mode update after a grace period.
4293         updateAudioModeHandlers(
4294                 configs /* playbackConfigs */, null /* recordConfigs */);
4295         mDeviceBroker.updateCommunicationRouteClientsActivity(
4296                 configs /* playbackConfigs */, null /* recordConfigs */);
4297     }
4298 
updateAudioModeHandlers(List<AudioPlaybackConfiguration> playbackConfigs, List<AudioRecordingConfiguration> recordConfigs)4299     void updateAudioModeHandlers(List<AudioPlaybackConfiguration> playbackConfigs,
4300                                  List<AudioRecordingConfiguration> recordConfigs) {
4301         synchronized (mDeviceBroker.mSetModeLock) {
4302             boolean updateAudioMode = false;
4303             int existingMsgPolicy = SENDMSG_QUEUE;
4304             int delay = CHECK_MODE_FOR_UID_PERIOD_MS;
4305             for (SetModeDeathHandler h : mSetModeDeathHandlers) {
4306                 boolean wasActive = h.isActive();
4307                 if (playbackConfigs != null) {
4308                     h.setPlaybackActive(false);
4309                     for (AudioPlaybackConfiguration config : playbackConfigs) {
4310                         final int usage = config.getAudioAttributes().getUsage();
4311                         if (config.getClientUid() == h.getUid()
4312                                 && (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION
4313                                 || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING)
4314                                 && config.isActive()) {
4315                             h.setPlaybackActive(true);
4316                             break;
4317                         }
4318                     }
4319                 }
4320                 if (recordConfigs != null) {
4321                     h.setRecordingActive(false);
4322                     for (AudioRecordingConfiguration config : recordConfigs) {
4323                         if (config.getClientUid() == h.getUid() && !config.isClientSilenced()
4324                                 && config.getAudioSource() == AudioSource.VOICE_COMMUNICATION) {
4325                             h.setRecordingActive(true);
4326                             break;
4327                         }
4328                     }
4329                 }
4330                 if (wasActive != h.isActive()) {
4331                     updateAudioMode = true;
4332                     if (h.isActive() && h == getAudioModeOwnerHandler()) {
4333                         existingMsgPolicy = SENDMSG_REPLACE;
4334                         delay = 0;
4335                     }
4336                 }
4337             }
4338             if (updateAudioMode) {
4339                 sendMsg(mAudioHandler,
4340                         MSG_UPDATE_AUDIO_MODE,
4341                         existingMsgPolicy,
4342                         AudioSystem.MODE_CURRENT,
4343                         android.os.Process.myPid(),
4344                         mContext.getPackageName(),
4345                         delay);
4346             }
4347         }
4348     }
4349 
4350     private final IRecordingConfigDispatcher mVoiceRecordingActivityMonitor =
4351             new IRecordingConfigDispatcher.Stub() {
4352         @Override
4353         public void dispatchRecordingConfigChange(List<AudioRecordingConfiguration> configs) {
4354             sendMsg(mAudioHandler, MSG_RECORDING_CONFIG_CHANGE, SENDMSG_REPLACE,
4355                     0 /*arg1 ignored*/, 0 /*arg2 ignored*/,
4356                     configs /*obj*/, 0 /*delay*/);
4357         }
4358     };
4359 
onRecordingConfigChange(List<AudioRecordingConfiguration> configs)4360     private void onRecordingConfigChange(List<AudioRecordingConfiguration> configs) {
4361         // Update recording active state for all apps in audio mode stack.
4362         // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE
4363         // and request an audio mode update immediately. Upon any other change, queue the message
4364         // and request an audio mode update after a grace period.
4365         updateAudioModeHandlers(
4366                 null /* playbackConfigs */, configs /* recordConfigs */);
4367         mDeviceBroker.updateCommunicationRouteClientsActivity(
4368                 null /* playbackConfigs */, configs /* recordConfigs */);
4369     }
4370 
dumpAudioMode(PrintWriter pw)4371     private void dumpAudioMode(PrintWriter pw) {
4372         pw.println("\nAudio mode: ");
4373         pw.println("- Requested mode = " + AudioSystem.modeToString(getMode()));
4374         pw.println("- Actual mode = " + AudioSystem.modeToString(mMode.get()));
4375         pw.println("- Mode owner: ");
4376         SetModeDeathHandler hdlr = getAudioModeOwnerHandler();
4377         if (hdlr != null) {
4378             hdlr.dump(pw, -1);
4379         } else {
4380             pw.println("   None");
4381         }
4382         pw.println("- Mode owner stack: ");
4383         if (mSetModeDeathHandlers.isEmpty()) {
4384             pw.println("   Empty");
4385         } else {
4386             for (int i = 0; i < mSetModeDeathHandlers.size(); i++) {
4387                 mSetModeDeathHandlers.get(i).dump(pw, i);
4388             }
4389         }
4390     }
4391 
updateHearingAidVolumeOnVoiceActivityUpdate()4392     private void updateHearingAidVolumeOnVoiceActivityUpdate() {
4393         final int streamType = getBluetoothContextualVolumeStream();
4394         final int index = getStreamVolume(streamType);
4395         sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_HEARING_AID,
4396                 mVoicePlaybackActive.get(), streamType, index));
4397         mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
4398 
4399     }
4400 
4401     /**
4402      * Manage an audio mode change for audio devices that use an "absolute volume" model,
4403      * i.e. the framework sends the full scale signal, and the actual volume for the use case
4404      * is communicated separately.
4405      */
updateAbsVolumeMultiModeDevices(int oldMode, int newMode)4406     void updateAbsVolumeMultiModeDevices(int oldMode, int newMode) {
4407         if (oldMode == newMode) {
4408             return;
4409         }
4410         switch (newMode) {
4411             case AudioSystem.MODE_IN_COMMUNICATION:
4412             case AudioSystem.MODE_IN_CALL:
4413             case AudioSystem.MODE_NORMAL:
4414             case AudioSystem.MODE_CALL_SCREENING:
4415             case AudioSystem.MODE_CALL_REDIRECT:
4416             case AudioSystem.MODE_COMMUNICATION_REDIRECT:
4417                 break;
4418             default:
4419                 // no-op is enough for all other values
4420                 return;
4421         }
4422 
4423         int streamType = getBluetoothContextualVolumeStream(newMode);
4424 
4425         final Set<Integer> deviceTypes = getDeviceSetForStreamDirect(streamType);
4426         final Set<Integer> absVolumeMultiModeCaseDevices = AudioSystem.intersectionAudioDeviceTypes(
4427                 mAbsVolumeMultiModeCaseDevices, deviceTypes);
4428         if (absVolumeMultiModeCaseDevices.isEmpty()) {
4429             return;
4430         }
4431 
4432         // handling of specific interfaces goes here:
4433         if (AudioSystem.isSingleAudioDeviceType(
4434                 absVolumeMultiModeCaseDevices, AudioSystem.DEVICE_OUT_HEARING_AID)) {
4435             final int index = getStreamVolume(streamType);
4436             sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_MODE_CHANGE_HEARING_AID,
4437                     newMode, streamType, index));
4438             mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
4439         }
4440     }
4441 
setLeAudioVolumeOnModeUpdate(int mode, int device, int streamType, int index, int maxIndex)4442     private void setLeAudioVolumeOnModeUpdate(int mode, int device, int streamType, int index,
4443             int maxIndex) {
4444         switch (mode) {
4445             case AudioSystem.MODE_IN_COMMUNICATION:
4446             case AudioSystem.MODE_IN_CALL:
4447             case AudioSystem.MODE_NORMAL:
4448             case AudioSystem.MODE_CALL_SCREENING:
4449             case AudioSystem.MODE_CALL_REDIRECT:
4450             case AudioSystem.MODE_COMMUNICATION_REDIRECT:
4451                 break;
4452             default:
4453                 // no-op is enough for all other values
4454                 return;
4455         }
4456 
4457         // In some cases (like the outgoing or rejected call) the value of 'device' is not
4458         // DEVICE_OUT_BLE_* even when BLE is connected. Changing the volume level in such case
4459         // may cuase the other devices volume level leaking into the LeAudio device settings.
4460         if (!AudioSystem.isLeAudioDeviceType(device)) {
4461             Log.w(TAG, "setLeAudioVolumeOnModeUpdate ignoring invalid device="
4462                     + device + ", mode=" + mode + ", index=" + index + " maxIndex=" + maxIndex
4463                     + " streamType=" + streamType);
4464             return;
4465         }
4466 
4467         if (DEBUG_VOL) {
4468             Log.d(TAG, "setLeAudioVolumeOnModeUpdate postSetLeAudioVolumeIndex device="
4469                     + device + ", mode=" + mode + ", index=" + index + " maxIndex=" + maxIndex
4470                     + " streamType=" + streamType);
4471         }
4472         mDeviceBroker.postSetLeAudioVolumeIndex(index, maxIndex, streamType);
4473         mDeviceBroker.postApplyVolumeOnDevice(streamType, device, "setLeAudioVolumeOnModeUpdate");
4474     }
4475 
setStreamVolume(int streamType, int index, int flags, @Nullable AudioDeviceAttributes ada, String callingPackage, String caller, String attributionTag, int uid, boolean hasModifyAudioSettings)4476     private void setStreamVolume(int streamType, int index, int flags,
4477             @Nullable AudioDeviceAttributes ada,
4478             String callingPackage, String caller, String attributionTag, int uid,
4479             boolean hasModifyAudioSettings) {
4480         if (DEBUG_VOL) {
4481             Log.d(TAG, "setStreamVolume(stream=" + streamType+", index=" + index
4482                     + ", dev=" + ada
4483                     + ", calling=" + callingPackage + ")");
4484         }
4485         if (mUseFixedVolume) {
4486             return;
4487         }
4488 
4489         ensureValidStreamType(streamType);
4490         int streamTypeAlias = mStreamVolumeAlias[streamType];
4491         VolumeStreamState streamState = mStreamStates[streamTypeAlias];
4492 
4493         final int device = (ada == null)
4494                 ? getDeviceForStream(streamType)
4495                 : ada.getInternalType();
4496         int oldIndex;
4497 
4498         // skip a2dp absolute volume control request when the device
4499         // is neither an a2dp device nor BLE device
4500         if ((!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
4501                 && !AudioSystem.DEVICE_OUT_ALL_BLE_SET.contains(device))
4502                 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) {
4503             return;
4504         }
4505         // If we are being called by the system (e.g. hardware keys) check for current user
4506         // so we handle user restrictions correctly.
4507         if (uid == android.os.Process.SYSTEM_UID) {
4508             uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid));
4509         }
4510         if (!checkNoteAppOp(
4511                 STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage, attributionTag)) {
4512             return;
4513         }
4514 
4515         if (isAndroidNPlus(callingPackage)
4516                 && wouldToggleZenMode(getNewRingerMode(streamTypeAlias, index, flags))
4517                 && !mNm.isNotificationPolicyAccessGrantedForPackage(callingPackage)) {
4518             throw new SecurityException("Not allowed to change Do Not Disturb state");
4519         }
4520 
4521         if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) {
4522             return;
4523         }
4524 
4525         mSoundDoseHelper.invalidatPendingVolumeCommand();
4526 
4527         oldIndex = streamState.getIndex(device);
4528 
4529         index = rescaleIndex(index * 10, streamType, streamTypeAlias);
4530 
4531         if (streamTypeAlias == AudioSystem.STREAM_MUSIC
4532                 && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
4533                 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
4534             if (DEBUG_VOL) {
4535                 Log.d(TAG, "setStreamVolume postSetAvrcpAbsoluteVolumeIndex index=" + index
4536                         + "stream=" + streamType);
4537             }
4538             mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index / 10);
4539         } else if (isAbsoluteVolumeDevice(device)
4540                 && ((flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0)) {
4541             AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device);
4542 
4543             dispatchAbsoluteVolumeChanged(streamType, info, index);
4544         }
4545 
4546         if (AudioSystem.isLeAudioDeviceType(device)
4547                 && streamType == getBluetoothContextualVolumeStream()
4548                 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
4549             if (DEBUG_VOL) {
4550                 Log.d(TAG, "adjustSreamVolume postSetLeAudioVolumeIndex index="
4551                         + index + " stream=" + streamType);
4552             }
4553             mDeviceBroker.postSetLeAudioVolumeIndex(index, mStreamStates[streamType].getMaxIndex(),
4554                     streamType);
4555         }
4556 
4557         if (device == AudioSystem.DEVICE_OUT_HEARING_AID
4558                 && streamType == getBluetoothContextualVolumeStream()) {
4559             Log.i(TAG, "setStreamVolume postSetHearingAidVolumeIndex index=" + index
4560                     + " stream=" + streamType);
4561             mDeviceBroker.postSetHearingAidVolumeIndex(index, streamType);
4562         }
4563 
4564         flags &= ~AudioManager.FLAG_FIXED_VOLUME;
4565         if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) {
4566             flags |= AudioManager.FLAG_FIXED_VOLUME;
4567 
4568             // volume is either 0 or max allowed for fixed volume devices
4569             if (index != 0) {
4570                 index = mSoundDoseHelper.getSafeMediaVolumeIndex(device);
4571                 if (index < 0) {
4572                     index = streamState.getMaxIndex();
4573                 }
4574             }
4575         }
4576 
4577         if (!mSoundDoseHelper.willDisplayWarningAfterCheckVolume(streamType, index, device,
4578                 flags)) {
4579             onSetStreamVolume(streamType, index, flags, device, caller, hasModifyAudioSettings,
4580                     // ada is non-null when called from setDeviceVolume,
4581                     // which shouldn't update the mute state
4582                     ada == null /*canChangeMute*/);
4583             index = mStreamStates[streamType].getIndex(device);
4584         }
4585 
4586         synchronized (mHdmiClientLock) {
4587             if (streamTypeAlias == AudioSystem.STREAM_MUSIC
4588                     && (oldIndex != index)) {
4589                 maybeSendSystemAudioStatusCommand(false);
4590             }
4591         }
4592         if (ada == null) {
4593             // only non-null when coming here from setDeviceVolume
4594             // TODO change test to check early if device is current device or not
4595             sendVolumeUpdate(streamType, oldIndex, index, flags, device);
4596         }
4597     }
4598 
dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, int index)4599     private void dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo,
4600             int index) {
4601         VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType);
4602         if (volumeInfo != null) {
4603             try {
4604                 deviceInfo.mCallback.dispatchDeviceVolumeChanged(deviceInfo.mDevice,
4605                         new VolumeInfo.Builder(volumeInfo)
4606                                 .setVolumeIndex(rescaleIndex(index, streamType, volumeInfo))
4607                                 .build());
4608             } catch (RemoteException e) {
4609                 Log.w(TAG, "Couldn't dispatch absolute volume behavior volume change");
4610             }
4611         }
4612     }
4613 
dispatchAbsoluteVolumeAdjusted(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, int index, int direction, int mode)4614     private void dispatchAbsoluteVolumeAdjusted(int streamType,
4615             AbsoluteVolumeDeviceInfo deviceInfo, int index, int direction, int mode) {
4616         VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType);
4617         if (volumeInfo != null) {
4618             try {
4619                 deviceInfo.mCallback.dispatchDeviceVolumeAdjusted(deviceInfo.mDevice,
4620                         new VolumeInfo.Builder(volumeInfo)
4621                                 .setVolumeIndex(rescaleIndex(index, streamType, volumeInfo))
4622                                 .build(),
4623                         direction,
4624                         mode);
4625             } catch (RemoteException e) {
4626                 Log.w(TAG, "Couldn't dispatch absolute volume behavior volume adjustment");
4627             }
4628         }
4629     }
4630 
4631     // No ringer or zen muted stream volumes can be changed unless it'll exit dnd
volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags)4632     private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) {
4633         switch (mNm.getZenMode()) {
4634             case Settings.Global.ZEN_MODE_OFF:
4635                 return true;
4636             case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
4637             case Settings.Global.ZEN_MODE_ALARMS:
4638             case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
4639                 return !isStreamMutedByRingerOrZenMode(streamTypeAlias)
4640                         || isUiSoundsStreamType(streamTypeAlias)
4641                         || (flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0;
4642         }
4643 
4644         return true;
4645     }
4646 
4647     /** @see AudioManager#forceVolumeControlStream(int) */
forceVolumeControlStream(int streamType, IBinder cb)4648     public void forceVolumeControlStream(int streamType, IBinder cb) {
4649         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
4650                 != PackageManager.PERMISSION_GRANTED) {
4651             return;
4652         }
4653         if (DEBUG_VOL) { Log.d(TAG, String.format("forceVolumeControlStream(%d)", streamType)); }
4654         synchronized(mForceControlStreamLock) {
4655             if (mVolumeControlStream != -1 && streamType != -1) {
4656                 mUserSelectedVolumeControlStream = true;
4657             }
4658             mVolumeControlStream = streamType;
4659             if (mVolumeControlStream == -1) {
4660                 if (mForceControlStreamClient != null) {
4661                     mForceControlStreamClient.release();
4662                     mForceControlStreamClient = null;
4663                 }
4664                 mUserSelectedVolumeControlStream = false;
4665             } else {
4666                 if (null == mForceControlStreamClient) {
4667                     mForceControlStreamClient = new ForceControlStreamClient(cb);
4668                 } else {
4669                     if (mForceControlStreamClient.getBinder() == cb) {
4670                         Log.d(TAG, "forceVolumeControlStream cb:" + cb + " is already linked.");
4671                     } else {
4672                         mForceControlStreamClient.release();
4673                         mForceControlStreamClient = new ForceControlStreamClient(cb);
4674                     }
4675                 }
4676             }
4677         }
4678     }
4679 
4680     private class ForceControlStreamClient implements IBinder.DeathRecipient {
4681         private IBinder mCb; // To be notified of client's death
4682 
ForceControlStreamClient(IBinder cb)4683         ForceControlStreamClient(IBinder cb) {
4684             if (cb != null) {
4685                 try {
4686                     cb.linkToDeath(this, 0);
4687                 } catch (RemoteException e) {
4688                     // Client has died!
4689                     Log.w(TAG, "ForceControlStreamClient() could not link to "+cb+" binder death");
4690                     cb = null;
4691                 }
4692             }
4693             mCb = cb;
4694         }
4695 
binderDied()4696         public void binderDied() {
4697             synchronized(mForceControlStreamLock) {
4698                 Log.w(TAG, "SCO client died");
4699                 if (mForceControlStreamClient != this) {
4700                     Log.w(TAG, "unregistered control stream client died");
4701                 } else {
4702                     mForceControlStreamClient = null;
4703                     mVolumeControlStream = -1;
4704                     mUserSelectedVolumeControlStream = false;
4705                 }
4706             }
4707         }
4708 
release()4709         public void release() {
4710             if (mCb != null) {
4711                 mCb.unlinkToDeath(this, 0);
4712                 mCb = null;
4713             }
4714         }
4715 
getBinder()4716         public IBinder getBinder() {
4717             return mCb;
4718         }
4719     }
4720 
sendBroadcastToAll(Intent intent, Bundle options)4721     private void sendBroadcastToAll(Intent intent, Bundle options) {
4722         if (!mSystemServer.isPrivileged()) {
4723             return;
4724         }
4725         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
4726         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
4727         final long ident = Binder.clearCallingIdentity();
4728         try {
4729             mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
4730                     null /* receiverPermission */, options);
4731         } finally {
4732             Binder.restoreCallingIdentity(ident);
4733         }
4734     }
4735 
sendStickyBroadcastToAll(Intent intent)4736     private void sendStickyBroadcastToAll(Intent intent) {
4737         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
4738         final long ident = Binder.clearCallingIdentity();
4739         try {
4740             mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
4741         } finally {
4742             Binder.restoreCallingIdentity(ident);
4743         }
4744     }
4745 
getCurrentUserId()4746     private int getCurrentUserId() {
4747         final long ident = Binder.clearCallingIdentity();
4748         try {
4749             UserInfo currentUser = ActivityManager.getService().getCurrentUser();
4750             return currentUser.id;
4751         } catch (RemoteException e) {
4752             // Activity manager not running, nothing we can do assume user 0.
4753         } finally {
4754             Binder.restoreCallingIdentity(ident);
4755         }
4756         return UserHandle.USER_SYSTEM;
4757     }
4758 
4759     // UI update and Broadcast Intent
sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device)4760     protected void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device)
4761     {
4762         streamType = mStreamVolumeAlias[streamType];
4763 
4764         if (streamType == AudioSystem.STREAM_MUSIC && isFullVolumeDevice(device)) {
4765             flags &= ~AudioManager.FLAG_SHOW_UI;
4766         }
4767         mVolumeController.postVolumeChanged(streamType, flags);
4768     }
4769 
4770     // Don't show volume UI when:
4771     //  - Hdmi-CEC system audio mode is on and we are a TV panel
updateFlagsForTvPlatform(int flags)4772     private int updateFlagsForTvPlatform(int flags) {
4773         synchronized (mHdmiClientLock) {
4774             if (mHdmiTvClient != null && mHdmiSystemAudioSupported
4775                     && mHdmiCecVolumeControlEnabled) {
4776                 flags &= ~AudioManager.FLAG_SHOW_UI;
4777             }
4778         }
4779         return flags;
4780     }
4781     // UI update and Broadcast Intent
sendMasterMuteUpdate(boolean muted, int flags)4782     private void sendMasterMuteUpdate(boolean muted, int flags) {
4783         mVolumeController.postMasterMuteChanged(updateFlagsForTvPlatform(flags));
4784         broadcastMasterMuteStatus(muted);
4785     }
4786 
broadcastMasterMuteStatus(boolean muted)4787     private void broadcastMasterMuteStatus(boolean muted) {
4788         Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION);
4789         intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, muted);
4790         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
4791                 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
4792         sendStickyBroadcastToAll(intent);
4793     }
4794 
4795     /**
4796      * Sets the stream state's index, and posts a message to set system volume.
4797      * This will not call out to the UI. Assumes a valid stream type.
4798      *
4799      * @param streamType Type of the stream
4800      * @param index Desired volume index of the stream
4801      * @param device the device whose volume must be changed
4802      * @param force If true, set the volume even if the desired volume is same
4803      * @param caller
4804      * @param hasModifyAudioSettings true if the caller is granted MODIFY_AUDIO_SETTINGS or
4805      *                              MODIFY_AUDIO_ROUTING permission
4806      * as the current volume.
4807      */
setStreamVolumeInt(int streamType, int index, int device, boolean force, String caller, boolean hasModifyAudioSettings)4808     private void setStreamVolumeInt(int streamType,
4809                                     int index,
4810                                     int device,
4811                                     boolean force,
4812                                     String caller, boolean hasModifyAudioSettings) {
4813         if (isFullVolumeDevice(device)) {
4814             return;
4815         }
4816         VolumeStreamState streamState = mStreamStates[streamType];
4817 
4818         if (streamState.setIndex(index, device, caller, hasModifyAudioSettings) || force) {
4819             // Post message to set system volume (it in turn will post a message
4820             // to persist).
4821             sendMsg(mAudioHandler,
4822                     MSG_SET_DEVICE_VOLUME,
4823                     SENDMSG_QUEUE,
4824                     device,
4825                     0,
4826                     streamState,
4827                     0);
4828         }
4829     }
4830 
4831     /** get stream mute state. */
isStreamMute(int streamType)4832     public boolean isStreamMute(int streamType) {
4833         if (streamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
4834             streamType = getActiveStreamType(streamType);
4835         }
4836         synchronized (VolumeStreamState.class) {
4837             ensureValidStreamType(streamType);
4838             return mStreamStates[streamType].mIsMuted;
4839         }
4840     }
4841 
4842     private class RmtSbmxFullVolDeathHandler implements IBinder.DeathRecipient {
4843         private IBinder mICallback; // To be notified of client's death
4844 
RmtSbmxFullVolDeathHandler(IBinder cb)4845         RmtSbmxFullVolDeathHandler(IBinder cb) {
4846             mICallback = cb;
4847             try {
4848                 cb.linkToDeath(this, 0/*flags*/);
4849             } catch (RemoteException e) {
4850                 Log.e(TAG, "can't link to death", e);
4851             }
4852         }
4853 
isHandlerFor(IBinder cb)4854         boolean isHandlerFor(IBinder cb) {
4855             return mICallback.equals(cb);
4856         }
4857 
forget()4858         void forget() {
4859             try {
4860                 mICallback.unlinkToDeath(this, 0/*flags*/);
4861             } catch (NoSuchElementException e) {
4862                 Log.e(TAG, "error unlinking to death", e);
4863             }
4864         }
4865 
binderDied()4866         public void binderDied() {
4867             Log.w(TAG, "Recorder with remote submix at full volume died " + mICallback);
4868             forceRemoteSubmixFullVolume(false, mICallback);
4869         }
4870     }
4871 
4872     /**
4873      * call must be synchronized on mRmtSbmxFullVolDeathHandlers
4874      * @return true if there is a registered death handler, false otherwise */
discardRmtSbmxFullVolDeathHandlerFor(IBinder cb)4875     private boolean discardRmtSbmxFullVolDeathHandlerFor(IBinder cb) {
4876         Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator();
4877         while (it.hasNext()) {
4878             final RmtSbmxFullVolDeathHandler handler = it.next();
4879             if (handler.isHandlerFor(cb)) {
4880                 handler.forget();
4881                 mRmtSbmxFullVolDeathHandlers.remove(handler);
4882                 return true;
4883             }
4884         }
4885         return false;
4886     }
4887 
4888     /** call synchronized on mRmtSbmxFullVolDeathHandlers */
hasRmtSbmxFullVolDeathHandlerFor(IBinder cb)4889     private boolean hasRmtSbmxFullVolDeathHandlerFor(IBinder cb) {
4890         Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator();
4891         while (it.hasNext()) {
4892             if (it.next().isHandlerFor(cb)) {
4893                 return true;
4894             }
4895         }
4896         return false;
4897     }
4898 
4899     private int mRmtSbmxFullVolRefCount = 0;
4900     private final ArrayList<RmtSbmxFullVolDeathHandler> mRmtSbmxFullVolDeathHandlers =
4901             new ArrayList<RmtSbmxFullVolDeathHandler>();
4902 
forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb)4903     public void forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb) {
4904         if (cb == null) {
4905             return;
4906         }
4907         if ((PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
4908                         android.Manifest.permission.CAPTURE_AUDIO_OUTPUT))) {
4909             Log.w(TAG, "Trying to call forceRemoteSubmixFullVolume() without CAPTURE_AUDIO_OUTPUT");
4910             return;
4911         }
4912         synchronized(mRmtSbmxFullVolDeathHandlers) {
4913             boolean applyRequired = false;
4914             if (startForcing) {
4915                 if (!hasRmtSbmxFullVolDeathHandlerFor(cb)) {
4916                     mRmtSbmxFullVolDeathHandlers.add(new RmtSbmxFullVolDeathHandler(cb));
4917                     if (mRmtSbmxFullVolRefCount == 0) {
4918                         mFullVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
4919                         mFixedVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
4920                         applyRequired = true;
4921                     }
4922                     mRmtSbmxFullVolRefCount++;
4923                 }
4924             } else {
4925                 if (discardRmtSbmxFullVolDeathHandlerFor(cb) && (mRmtSbmxFullVolRefCount > 0)) {
4926                     mRmtSbmxFullVolRefCount--;
4927                     if (mRmtSbmxFullVolRefCount == 0) {
4928                         mFullVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
4929                         mFixedVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
4930                         applyRequired = true;
4931                     }
4932                 }
4933             }
4934             if (applyRequired) {
4935                 // Assumes only STREAM_MUSIC going through DEVICE_OUT_REMOTE_SUBMIX
4936                 checkAllFixedVolumeDevices(AudioSystem.STREAM_MUSIC);
4937                 mStreamStates[AudioSystem.STREAM_MUSIC].applyAllVolumes();
4938             }
4939         }
4940     }
4941 
setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, int userId, int pid, String attributionTag)4942     private void setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid,
4943             int userId, int pid, String attributionTag) {
4944         // If we are being called by the system check for user we are going to change
4945         // so we handle user restrictions correctly.
4946         if (uid == android.os.Process.SYSTEM_UID) {
4947             uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4948         }
4949         // If OP_AUDIO_MASTER_VOLUME is set, disallow unmuting.
4950         if (!mute && !checkNoteAppOp(
4951                 AppOpsManager.OP_AUDIO_MASTER_VOLUME, uid, callingPackage, attributionTag)) {
4952             return;
4953         }
4954         if (userId != UserHandle.getCallingUserId() &&
4955                 mContext.checkPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4956                         pid, uid)
4957                 != PackageManager.PERMISSION_GRANTED) {
4958             return;
4959         }
4960         setMasterMuteInternalNoCallerCheck(mute, flags, userId);
4961     }
4962 
setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId)4963     private void setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId) {
4964         if (DEBUG_VOL) {
4965             Log.d(TAG, String.format("Master mute %s, %d, user=%d", mute, flags, userId));
4966         }
4967         if (!isPlatformAutomotive() && mUseFixedVolume) {
4968             // If using fixed volume, we don't mute.
4969             // TODO: remove the isPlatformAutomotive check here.
4970             // The isPlatformAutomotive check is added for safety but may not be necessary.
4971             return;
4972         }
4973         // For automotive,
4974         // - the car service is always running as system user
4975         // - foreground users are non-system users
4976         // Car service is in charge of dispatching the key event include global mute to Android.
4977         // Therefore, the getCurrentUser() is always different to the foreground user.
4978         if ((isPlatformAutomotive() && userId == UserHandle.USER_SYSTEM)
4979                 || (getCurrentUserId() == userId)) {
4980             if (mute != AudioSystem.getMasterMute()) {
4981                 AudioSystem.setMasterMute(mute);
4982                 sendMasterMuteUpdate(mute, flags);
4983             }
4984         }
4985     }
4986 
4987     /** get global mute state. */
isMasterMute()4988     public boolean isMasterMute() {
4989         return AudioSystem.getMasterMute();
4990     }
4991 
4992     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
4993     /** @see AudioManager#setMasterMute(boolean, int) */
setMasterMute(boolean mute, int flags, String callingPackage, int userId, String attributionTag)4994     public void setMasterMute(boolean mute, int flags, String callingPackage, int userId,
4995             String attributionTag) {
4996         super.setMasterMute_enforcePermission();
4997 
4998         setMasterMuteInternal(mute, flags, callingPackage,
4999                 Binder.getCallingUid(), userId, Binder.getCallingPid(), attributionTag);
5000     }
5001 
5002     /** @see AudioManager#getStreamVolume(int) */
getStreamVolume(int streamType)5003     public int getStreamVolume(int streamType) {
5004         ensureValidStreamType(streamType);
5005         int device = getDeviceForStream(streamType);
5006         synchronized (VolumeStreamState.class) {
5007             int index = mStreamStates[streamType].getIndex(device);
5008 
5009             // by convention getStreamVolume() returns 0 when a stream is muted.
5010             if (mStreamStates[streamType].mIsMuted) {
5011                 index = 0;
5012             }
5013             if (index != 0 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
5014                     isFixedVolumeDevice(device)) {
5015                 index = mStreamStates[streamType].getMaxIndex();
5016             }
5017             return (index + 5) / 10;
5018         }
5019     }
5020 
5021     @Override
5022     @android.annotation.EnforcePermission(anyOf = {
5023             android.Manifest.permission.MODIFY_AUDIO_ROUTING,
5024             android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED
5025     })
5026     /**
5027      * @see AudioDeviceVolumeManager#getDeviceVolume(VolumeInfo, AudioDeviceAttributes)
5028      */
getDeviceVolume(@onNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage)5029     public @NonNull VolumeInfo getDeviceVolume(@NonNull VolumeInfo vi,
5030             @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage) {
5031         super.getDeviceVolume_enforcePermission();
5032         Objects.requireNonNull(vi);
5033         Objects.requireNonNull(ada);
5034         Objects.requireNonNull(callingPackage);
5035         if (!vi.hasStreamType()) {
5036             Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception());
5037             return getDefaultVolumeInfo();
5038         }
5039 
5040         int streamType = vi.getStreamType();
5041         final VolumeInfo.Builder vib = new VolumeInfo.Builder(vi);
5042         vib.setMinVolumeIndex((mStreamStates[streamType].mIndexMin + 5) / 10);
5043         vib.setMaxVolumeIndex((mStreamStates[streamType].mIndexMax + 5) / 10);
5044         synchronized (VolumeStreamState.class) {
5045             final int index;
5046             if (isFixedVolumeDevice(ada.getInternalType())) {
5047                 index = (mStreamStates[streamType].mIndexMax + 5) / 10;
5048             } else {
5049                 index = (mStreamStates[streamType].getIndex(ada.getInternalType()) + 5) / 10;
5050             }
5051             vib.setVolumeIndex(index);
5052             // only set as a mute command if stream muted
5053             if (mStreamStates[streamType].mIsMuted) {
5054                 vib.setMuted(true);
5055             }
5056             return vib.build();
5057         }
5058     }
5059 
5060     /** @see AudioManager#getStreamMaxVolume(int) */
getStreamMaxVolume(int streamType)5061     public int getStreamMaxVolume(int streamType) {
5062         ensureValidStreamType(streamType);
5063         return (mStreamStates[streamType].getMaxIndex() + 5) / 10;
5064     }
5065 
5066     /** @see AudioManager#getStreamMinVolumeInt(int)
5067      * Part of service interface, check permissions here */
getStreamMinVolume(int streamType)5068     public int getStreamMinVolume(int streamType) {
5069         ensureValidStreamType(streamType);
5070         final boolean isPrivileged =
5071                 Binder.getCallingUid() == Process.SYSTEM_UID
5072                  || callingHasAudioSettingsPermission()
5073                  || (mContext.checkCallingPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)
5074                         == PackageManager.PERMISSION_GRANTED);
5075         return (mStreamStates[streamType].getMinIndex(isPrivileged) + 5) / 10;
5076     }
5077 
5078     @android.annotation.EnforcePermission(android.Manifest.permission.QUERY_AUDIO_STATE)
5079     /** Get last audible volume before stream was muted. */
getLastAudibleStreamVolume(int streamType)5080     public int getLastAudibleStreamVolume(int streamType) {
5081         super.getLastAudibleStreamVolume_enforcePermission();
5082 
5083         ensureValidStreamType(streamType);
5084         int device = getDeviceForStream(streamType);
5085         return (mStreamStates[streamType].getIndex(device) + 5) / 10;
5086     }
5087 
5088     /**
5089      * Default VolumeInfo returned by {@link VolumeInfo#getDefaultVolumeInfo()}
5090      * Lazily initialized in {@link #getDefaultVolumeInfo()}
5091      */
5092     static VolumeInfo sDefaultVolumeInfo;
5093 
5094     /** @see VolumeInfo#getDefaultVolumeInfo() */
getDefaultVolumeInfo()5095     public VolumeInfo getDefaultVolumeInfo() {
5096         if (sDefaultVolumeInfo == null) {
5097             sDefaultVolumeInfo = new VolumeInfo.Builder(AudioSystem.STREAM_MUSIC)
5098                     .setMinVolumeIndex(getStreamMinVolume(AudioSystem.STREAM_MUSIC))
5099                     .setMaxVolumeIndex(getStreamMaxVolume(AudioSystem.STREAM_MUSIC))
5100                     .build();
5101         }
5102         return sDefaultVolumeInfo;
5103     }
5104 
5105     /**
5106      * list of callback dispatchers for stream aliasing updates
5107      */
5108     final RemoteCallbackList<IStreamAliasingDispatcher> mStreamAliasingDispatchers =
5109             new RemoteCallbackList<IStreamAliasingDispatcher>();
5110 
5111     /**
5112      * Register/unregister a callback for stream aliasing updates
5113      * @param isad the callback dispatcher
5114      * @param register whether this for a registration or unregistration
5115      * @see AudioManager#addOnStreamAliasingChangedListener(Executor, Runnable)
5116      * @see AudioManager#removeOnStreamAliasingChangedListener(Runnable)
5117      */
5118     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
registerStreamAliasingDispatcher(IStreamAliasingDispatcher isad, boolean register)5119     public void registerStreamAliasingDispatcher(IStreamAliasingDispatcher isad, boolean register) {
5120         super.registerStreamAliasingDispatcher_enforcePermission();
5121         Objects.requireNonNull(isad);
5122 
5123         if (register) {
5124             mStreamAliasingDispatchers.register(isad);
5125         } else {
5126             mStreamAliasingDispatchers.unregister(isad);
5127         }
5128     }
5129 
dispatchStreamAliasingUpdate()5130     protected void dispatchStreamAliasingUpdate() {
5131         final int nbDispatchers = mStreamAliasingDispatchers.beginBroadcast();
5132         for (int i = 0; i < nbDispatchers; i++) {
5133             try {
5134                 mStreamAliasingDispatchers.getBroadcastItem(i).dispatchStreamAliasingChanged();
5135             } catch (RemoteException e) {
5136                 Log.e(TAG, "Error on stream alias update dispatch", e);
5137             }
5138         }
5139         mStreamAliasingDispatchers.finishBroadcast();
5140     }
5141 
5142     /**
5143      * @see AudioManager#getIndependentStreamTypes()
5144      * @return the list of non-aliased stream types
5145      */
5146     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
getIndependentStreamTypes()5147     public ArrayList<Integer> getIndependentStreamTypes() {
5148         super.getIndependentStreamTypes_enforcePermission();
5149 
5150         if (mUseVolumeGroupAliases) {
5151             return new ArrayList<>(Arrays.stream(AudioManager.getPublicStreamTypes())
5152                     .boxed().toList());
5153         }
5154         ArrayList<Integer> res = new ArrayList(1);
5155         for (int stream : mStreamVolumeAlias) {
5156             if (!res.contains(stream)) {
5157                 res.add(stream);
5158             }
5159         }
5160         return res;
5161     }
5162 
5163     /**
5164      * @see AudioManager#getStreamTypeAlias(int)
5165      * @param sourceStreamType the stream type for which the alias is queried
5166      * @return the stream alias
5167      */
5168     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
5169     public @AudioManager.PublicStreamTypes
getStreamTypeAlias(@udioManager.PublicStreamTypes int sourceStreamType)5170     int getStreamTypeAlias(@AudioManager.PublicStreamTypes int sourceStreamType) {
5171         super.getStreamTypeAlias_enforcePermission();
5172         // verify parameters
5173         ensureValidStreamType(sourceStreamType);
5174 
5175         return mStreamVolumeAlias[sourceStreamType];
5176     }
5177 
5178     /**
5179      * @see AudioManager#isVolumeControlUsingVolumeGroups()
5180      * @return true when volume control is performed through volume groups, false if it uses
5181      *     stream types.
5182      */
5183     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
isVolumeControlUsingVolumeGroups()5184     public boolean isVolumeControlUsingVolumeGroups() {
5185         super.isVolumeControlUsingVolumeGroups_enforcePermission();
5186 
5187         return mUseVolumeGroupAliases;
5188     }
5189 
5190     /** @see AudioManager#getUiSoundsStreamType()
5191      * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for
5192      * UI Sounds identification.
5193      * Fallback on Voice configuration to ensure correct behavior of DnD feature.
5194      */
getUiSoundsStreamType()5195     public int getUiSoundsStreamType() {
5196         return mUseVolumeGroupAliases ? STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM]
5197                 : mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM];
5198     }
5199 
5200     /**
5201      * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for
5202      * UI Sounds identification.
5203      * Fallback on Voice configuration to ensure correct behavior of DnD feature.
5204      */
isUiSoundsStreamType(int aliasStreamType)5205     private boolean isUiSoundsStreamType(int aliasStreamType) {
5206         return mUseVolumeGroupAliases
5207                 ? STREAM_VOLUME_ALIAS_VOICE[aliasStreamType]
5208                         == STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM]
5209                 : aliasStreamType == mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM];
5210     }
5211 
5212     /** @see AudioManager#setMicrophoneMute(boolean) */
5213     @Override
setMicrophoneMute(boolean on, String callingPackage, int userId, String attributionTag)5214     public void setMicrophoneMute(boolean on, String callingPackage, int userId,
5215             String attributionTag) {
5216         // If we are being called by the system check for user we are going to change
5217         // so we handle user restrictions correctly.
5218         int uid = Binder.getCallingUid();
5219         if (uid == android.os.Process.SYSTEM_UID) {
5220             uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
5221         }
5222         MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
5223                 .setUid(uid)
5224                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage)
5225                 .set(MediaMetrics.Property.EVENT, "setMicrophoneMute")
5226                 .set(MediaMetrics.Property.REQUEST, on
5227                         ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE);
5228 
5229         // If OP_MUTE_MICROPHONE is set, disallow unmuting.
5230         if (!on && !checkNoteAppOp(
5231                 AppOpsManager.OP_MUTE_MICROPHONE, uid, callingPackage, attributionTag)) {
5232             mmi.set(MediaMetrics.Property.EARLY_RETURN, "disallow unmuting").record();
5233             return;
5234         }
5235         if (!checkAudioSettingsPermission("setMicrophoneMute()")) {
5236             mmi.set(MediaMetrics.Property.EARLY_RETURN, "!checkAudioSettingsPermission").record();
5237             return;
5238         }
5239         if (userId != UserHandle.getCallingUserId() &&
5240                 mContext.checkCallingOrSelfPermission(
5241                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
5242                 != PackageManager.PERMISSION_GRANTED) {
5243             mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission").record();
5244             return;
5245         }
5246         mMicMuteFromApi = on;
5247         mmi.record(); // record now, the no caller check will set the mute state.
5248         setMicrophoneMuteNoCallerCheck(userId);
5249     }
5250 
5251     /** @see AudioManager#setMicrophoneMuteFromSwitch(boolean) */
setMicrophoneMuteFromSwitch(boolean on)5252     public void setMicrophoneMuteFromSwitch(boolean on) {
5253         int userId = Binder.getCallingUid();
5254         if (userId != android.os.Process.SYSTEM_UID) {
5255             Log.e(TAG, "setMicrophoneMuteFromSwitch() called from non system user!");
5256             return;
5257         }
5258         mMicMuteFromSwitch = on;
5259         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
5260                 .setUid(userId)
5261                 .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteFromSwitch")
5262                 .set(MediaMetrics.Property.REQUEST, on
5263                         ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE)
5264                 .record();
5265         setMicrophoneMuteNoCallerCheck(userId);
5266     }
5267 
setMicMuteFromSwitchInput()5268     private void setMicMuteFromSwitchInput() {
5269         InputManager im = mContext.getSystemService(InputManager.class);
5270         final int isMicMuted = im.isMicMuted();
5271         if (isMicMuted != InputManager.SWITCH_STATE_UNKNOWN) {
5272             setMicrophoneMuteFromSwitch(im.isMicMuted() != InputManager.SWITCH_STATE_OFF);
5273         }
5274     }
5275 
5276     /**
5277      * Returns the microphone mute state as seen from the native audio system
5278      * @return true if microphone is reported as muted by primary HAL
5279      */
isMicrophoneMuted()5280     public boolean isMicrophoneMuted() {
5281         return mMicMuteFromSystemCached
5282                 && (!mMicMuteFromPrivacyToggle
5283                         || mMicMuteFromApi || mMicMuteFromRestrictions || mMicMuteFromSwitch);
5284     }
5285 
isMicrophoneSupposedToBeMuted()5286     private boolean isMicrophoneSupposedToBeMuted() {
5287         return mMicMuteFromSwitch || mMicMuteFromRestrictions || mMicMuteFromApi
5288                 || mMicMuteFromPrivacyToggle;
5289     }
5290 
setMicrophoneMuteNoCallerCheck(int userId)5291     private void setMicrophoneMuteNoCallerCheck(int userId) {
5292         final boolean muted = isMicrophoneSupposedToBeMuted();
5293         if (DEBUG_VOL) {
5294             Log.d(TAG, String.format("Mic mute %b, user=%d", muted, userId));
5295         }
5296         // only mute for the current user
5297         if (getCurrentUserId() == userId || userId == android.os.Process.SYSTEM_UID) {
5298             final boolean currentMute = mAudioSystem.isMicrophoneMuted();
5299             final long identity = Binder.clearCallingIdentity();
5300             try {
5301                 final int ret = mAudioSystem.muteMicrophone(muted);
5302 
5303                 // update cache with the real state independently from what was set
5304                 mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted();
5305                 if (ret != AudioSystem.AUDIO_STATUS_OK) {
5306                     Log.e(TAG, "Error changing mic mute state to " + muted + " current:"
5307                             + mMicMuteFromSystemCached);
5308                 }
5309 
5310                 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
5311                         .setUid(userId)
5312                         .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteNoCallerCheck")
5313                         .set(MediaMetrics.Property.MUTE, mMicMuteFromSystemCached
5314                                 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
5315                         .set(MediaMetrics.Property.REQUEST, muted
5316                                 ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE)
5317                         .set(MediaMetrics.Property.STATUS, ret)
5318                         .record();
5319 
5320                 // send the intent even if there was a failure to change the actual mute state:
5321                 // the AudioManager.setMicrophoneMute API doesn't have a return value to
5322                 // indicate if the call failed to successfully change the mute state, and receiving
5323                 // the intent may be the only time an application can resynchronize its mic mute
5324                 // state with the actual system mic mute state
5325                 if (muted != currentMute) {
5326                     sendMsg(mAudioHandler, MSG_BROADCAST_MICROPHONE_MUTE,
5327                                 SENDMSG_NOOP, 0, 0, null, 0);
5328                 }
5329             } finally {
5330                 Binder.restoreCallingIdentity(identity);
5331             }
5332         }
5333     }
5334 
5335     @Override
getRingerModeExternal()5336     public int getRingerModeExternal() {
5337         synchronized(mSettingsLock) {
5338             return mRingerModeExternal;
5339         }
5340     }
5341 
5342     @Override
getRingerModeInternal()5343     public int getRingerModeInternal() {
5344         synchronized(mSettingsLock) {
5345             return mRingerMode;
5346         }
5347     }
5348 
ensureValidRingerMode(int ringerMode)5349     private void ensureValidRingerMode(int ringerMode) {
5350         if (!isValidRingerMode(ringerMode)) {
5351             throw new IllegalArgumentException("Bad ringer mode " + ringerMode);
5352         }
5353     }
5354 
5355     /** @see AudioManager#isValidRingerMode(int) */
isValidRingerMode(int ringerMode)5356     public boolean isValidRingerMode(int ringerMode) {
5357         return ringerMode >= 0 && ringerMode <= AudioManager.RINGER_MODE_MAX;
5358     }
5359 
setRingerModeExternal(int ringerMode, String caller)5360     public void setRingerModeExternal(int ringerMode, String caller) {
5361         if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode)
5362                 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)) {
5363             throw new SecurityException("Not allowed to change Do Not Disturb state");
5364         }
5365 
5366         setRingerMode(ringerMode, caller, true /*external*/);
5367     }
5368 
setRingerModeInternal(int ringerMode, String caller)5369     public void setRingerModeInternal(int ringerMode, String caller) {
5370         enforceVolumeController("setRingerModeInternal");
5371         setRingerMode(ringerMode, caller, false /*external*/);
5372     }
5373 
silenceRingerModeInternal(String reason)5374     public void silenceRingerModeInternal(String reason) {
5375         VibrationEffect effect = null;
5376         int ringerMode = AudioManager.RINGER_MODE_SILENT;
5377         int toastText = 0;
5378 
5379         int silenceRingerSetting = Settings.Secure.VOLUME_HUSH_OFF;
5380         if (mContext.getResources()
5381                 .getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled)) {
5382             silenceRingerSetting = mSettings.getSecureIntForUser(mContentResolver,
5383                     Settings.Secure.VOLUME_HUSH_GESTURE, VOLUME_HUSH_OFF,
5384                     UserHandle.USER_CURRENT);
5385         }
5386 
5387         switch(silenceRingerSetting) {
5388             case VOLUME_HUSH_MUTE:
5389                 effect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK);
5390                 ringerMode = AudioManager.RINGER_MODE_SILENT;
5391                 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_silent;
5392                 break;
5393             case VOLUME_HUSH_VIBRATE:
5394                 effect = VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK);
5395                 ringerMode = AudioManager.RINGER_MODE_VIBRATE;
5396                 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_vibrate;
5397                 break;
5398         }
5399         maybeVibrate(effect, reason);
5400         setRingerModeInternal(ringerMode, reason);
5401         Toast.makeText(mContext, toastText, Toast.LENGTH_SHORT).show();
5402     }
5403 
maybeVibrate(VibrationEffect effect, String reason)5404     private boolean maybeVibrate(VibrationEffect effect, String reason) {
5405         if (!mHasVibrator) {
5406             return false;
5407         }
5408         if (effect == null) {
5409             return false;
5410         }
5411         mVibrator.vibrate(Binder.getCallingUid(), mContext.getOpPackageName(), effect,
5412                 reason, TOUCH_VIBRATION_ATTRIBUTES);
5413         return true;
5414     }
5415 
setRingerMode(int ringerMode, String caller, boolean external)5416     private void setRingerMode(int ringerMode, String caller, boolean external) {
5417         if (mUseFixedVolume || mIsSingleVolume || mUseVolumeGroupAliases) {
5418             return;
5419         }
5420         if (caller == null || caller.length() == 0) {
5421             throw new IllegalArgumentException("Bad caller: " + caller);
5422         }
5423         ensureValidRingerMode(ringerMode);
5424         if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) {
5425             ringerMode = AudioManager.RINGER_MODE_SILENT;
5426         }
5427         final long identity = Binder.clearCallingIdentity();
5428         try {
5429             synchronized (mSettingsLock) {
5430                 final int ringerModeInternal = getRingerModeInternal();
5431                 final int ringerModeExternal = getRingerModeExternal();
5432                 if (external) {
5433                     setRingerModeExt(ringerMode);
5434                     if (mRingerModeDelegate != null) {
5435                         ringerMode = mRingerModeDelegate.onSetRingerModeExternal(ringerModeExternal,
5436                                 ringerMode, caller, ringerModeInternal, mVolumePolicy);
5437                     }
5438                     if (ringerMode != ringerModeInternal) {
5439                         setRingerModeInt(ringerMode, true /*persist*/);
5440                     }
5441                 } else /*internal*/ {
5442                     if (ringerMode != ringerModeInternal) {
5443                         setRingerModeInt(ringerMode, true /*persist*/);
5444                     }
5445                     if (mRingerModeDelegate != null) {
5446                         ringerMode = mRingerModeDelegate.onSetRingerModeInternal(ringerModeInternal,
5447                                 ringerMode, caller, ringerModeExternal, mVolumePolicy);
5448                     }
5449                     setRingerModeExt(ringerMode);
5450                 }
5451             }
5452         } finally {
5453             Binder.restoreCallingIdentity(identity);
5454         }
5455     }
5456 
setRingerModeExt(int ringerMode)5457     private void setRingerModeExt(int ringerMode) {
5458         synchronized(mSettingsLock) {
5459             if (ringerMode == mRingerModeExternal) return;
5460             mRingerModeExternal = ringerMode;
5461         }
5462         // Send sticky broadcast
5463         broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, ringerMode);
5464     }
5465 
5466     @GuardedBy("mSettingsLock")
muteRingerModeStreams()5467     private void muteRingerModeStreams() {
5468         // Mute stream if not previously muted by ringer mode and (ringer mode
5469         // is not RINGER_MODE_NORMAL OR stream is zen muted) and stream is affected by ringer mode.
5470         // Unmute stream if previously muted by ringer/zen mode and ringer mode
5471         // is RINGER_MODE_NORMAL or stream is not affected by ringer mode.
5472         int numStreamTypes = AudioSystem.getNumStreamTypes();
5473 
5474         if (mNm == null) {
5475             mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
5476         }
5477 
5478         final int ringerMode = mRingerMode; // Read ringer mode as reading primitives is atomic
5479         final boolean ringerModeMute = ringerMode == AudioManager.RINGER_MODE_VIBRATE
5480                 || ringerMode == AudioManager.RINGER_MODE_SILENT;
5481         final boolean shouldRingSco = ringerMode == AudioManager.RINGER_MODE_VIBRATE
5482                 && mDeviceBroker.isBluetoothScoActive();
5483         // Ask audio policy engine to force use Bluetooth SCO channel if needed
5484         final String eventSource = "muteRingerModeStreams() from u/pid:" + Binder.getCallingUid()
5485                 + "/" + Binder.getCallingPid();
5486         sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, AudioSystem.FOR_VIBRATE_RINGING,
5487                 shouldRingSco ? AudioSystem.FORCE_BT_SCO : AudioSystem.FORCE_NONE, eventSource, 0);
5488 
5489         for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
5490             final boolean isMuted = isStreamMutedByRingerOrZenMode(streamType);
5491             final boolean muteAllowedBySco =
5492                     !(shouldRingSco && streamType == AudioSystem.STREAM_RING);
5493             final boolean shouldZenMute = shouldZenMuteStream(streamType);
5494             final boolean shouldMute = shouldZenMute || (ringerModeMute
5495                     && isStreamAffectedByRingerMode(streamType) && muteAllowedBySco);
5496             if (isMuted == shouldMute) continue;
5497             if (!shouldMute) {
5498                 // unmute
5499                 // ring and notifications volume should never be 0 when not silenced
5500                 if (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING
5501                         || mStreamVolumeAlias[streamType] == AudioSystem.STREAM_NOTIFICATION) {
5502                     synchronized (VolumeStreamState.class) {
5503                         final VolumeStreamState vss = mStreamStates[streamType];
5504                         for (int i = 0; i < vss.mIndexMap.size(); i++) {
5505                             int device = vss.mIndexMap.keyAt(i);
5506                             int value = vss.mIndexMap.valueAt(i);
5507                             if (value == 0) {
5508                                 vss.setIndex(10, device, TAG, true /*hasModifyAudioSettings*/);
5509                             }
5510                         }
5511                         // Persist volume for stream ring when it is changed here
5512                       final int device = getDeviceForStream(streamType);
5513                       sendMsg(mAudioHandler,
5514                               MSG_PERSIST_VOLUME,
5515                               SENDMSG_QUEUE,
5516                               device,
5517                               0,
5518                               mStreamStates[streamType],
5519                               PERSIST_DELAY);
5520                     }
5521                 }
5522                 sRingerAndZenModeMutedStreams &= ~(1 << streamType);
5523                 sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent(
5524                         sRingerAndZenModeMutedStreams, "muteRingerModeStreams"));
5525                 mStreamStates[streamType].mute(false, "muteRingerModeStreams");
5526             } else {
5527                 // mute
5528                 sRingerAndZenModeMutedStreams |= (1 << streamType);
5529                 sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent(
5530                         sRingerAndZenModeMutedStreams, "muteRingerModeStreams"));
5531                 mStreamStates[streamType].mute(true, "muteRingerModeStreams");
5532             }
5533         }
5534     }
5535 
isAlarm(int streamType)5536     private boolean isAlarm(int streamType) {
5537         return streamType == AudioSystem.STREAM_ALARM;
5538     }
5539 
isNotificationOrRinger(int streamType)5540     private boolean isNotificationOrRinger(int streamType) {
5541         return streamType == AudioSystem.STREAM_NOTIFICATION
5542                 || streamType == AudioSystem.STREAM_RING;
5543     }
5544 
isMedia(int streamType)5545     private boolean isMedia(int streamType) {
5546         return streamType == AudioSystem.STREAM_MUSIC;
5547     }
5548 
5549 
isSystem(int streamType)5550     private boolean isSystem(int streamType) {
5551         return streamType == AudioSystem.STREAM_SYSTEM;
5552     }
5553 
setRingerModeInt(int ringerMode, boolean persist)5554     private void setRingerModeInt(int ringerMode, boolean persist) {
5555         final boolean change;
5556         synchronized(mSettingsLock) {
5557             change = mRingerMode != ringerMode;
5558             mRingerMode = ringerMode;
5559             muteRingerModeStreams();
5560         }
5561 
5562         // Post a persist ringer mode msg
5563         if (persist) {
5564             sendMsg(mAudioHandler, MSG_PERSIST_RINGER_MODE,
5565                     SENDMSG_REPLACE, 0, 0, null, PERSIST_DELAY);
5566         }
5567         if (change) {
5568             // Send sticky broadcast
5569             broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, ringerMode);
5570         }
5571     }
5572 
postUpdateRingerModeServiceInt()5573     /*package*/ void postUpdateRingerModeServiceInt() {
5574         sendMsg(mAudioHandler, MSG_UPDATE_RINGER_MODE, SENDMSG_QUEUE, 0, 0, null, 0);
5575     }
5576 
onUpdateRingerModeServiceInt()5577     private void onUpdateRingerModeServiceInt() {
5578         setRingerModeInt(getRingerModeInternal(), false);
5579     }
5580 
5581     /** @see AudioManager#shouldVibrate(int) */
shouldVibrate(int vibrateType)5582     public boolean shouldVibrate(int vibrateType) {
5583         if (!mHasVibrator) return false;
5584 
5585         switch (getVibrateSetting(vibrateType)) {
5586 
5587             case AudioManager.VIBRATE_SETTING_ON:
5588                 return getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT;
5589 
5590             case AudioManager.VIBRATE_SETTING_ONLY_SILENT:
5591                 return getRingerModeExternal() == AudioManager.RINGER_MODE_VIBRATE;
5592 
5593             case AudioManager.VIBRATE_SETTING_OFF:
5594                 // return false, even for incoming calls
5595                 return false;
5596 
5597             default:
5598                 return false;
5599         }
5600     }
5601 
5602     /** @see AudioManager#getVibrateSetting(int) */
getVibrateSetting(int vibrateType)5603     public int getVibrateSetting(int vibrateType) {
5604         if (!mHasVibrator) return AudioManager.VIBRATE_SETTING_OFF;
5605         return (mVibrateSetting >> (vibrateType * 2)) & 3;
5606     }
5607 
5608     /** @see AudioManager#setVibrateSetting(int, int) */
setVibrateSetting(int vibrateType, int vibrateSetting)5609     public void setVibrateSetting(int vibrateType, int vibrateSetting) {
5610 
5611         if (!mHasVibrator) return;
5612 
5613         mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, vibrateType,
5614                 vibrateSetting);
5615 
5616         // Broadcast change
5617         broadcastVibrateSetting(vibrateType);
5618 
5619     }
5620 
5621     private class SetModeDeathHandler implements IBinder.DeathRecipient {
5622         private final IBinder mCb; // To be notified of client's death
5623         private final int mPid;
5624         private final int mUid;
5625         private final boolean mIsPrivileged;
5626         private final String mPackage;
5627         private int mMode;
5628         private long mUpdateTime;
5629         private boolean mPlaybackActive = false;
5630         private boolean mRecordingActive = false;
5631 
SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged, String caller, int mode)5632         SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged,
5633                             String caller, int mode) {
5634             mMode = mode;
5635             mCb = cb;
5636             mPid = pid;
5637             mUid = uid;
5638             mPackage = caller;
5639             mIsPrivileged = isPrivileged;
5640             mUpdateTime = java.lang.System.currentTimeMillis();
5641         }
5642 
binderDied()5643         public void binderDied() {
5644             synchronized (mDeviceBroker.mSetModeLock) {
5645                 Log.w(TAG, "SetModeDeathHandler client died");
5646                 int index = mSetModeDeathHandlers.indexOf(this);
5647                 if (index < 0) {
5648                     Log.w(TAG, "unregistered SetModeDeathHandler client died");
5649                 } else {
5650                     SetModeDeathHandler h = mSetModeDeathHandlers.get(index);
5651                     mSetModeDeathHandlers.remove(index);
5652                     sendMsg(mAudioHandler,
5653                             MSG_UPDATE_AUDIO_MODE,
5654                             SENDMSG_QUEUE,
5655                             AudioSystem.MODE_CURRENT,
5656                             android.os.Process.myPid(),
5657                             mContext.getPackageName(),
5658                             0);
5659                 }
5660             }
5661         }
5662 
getPid()5663         public int getPid() {
5664             return mPid;
5665         }
5666 
setMode(int mode)5667         public void setMode(int mode) {
5668             mMode = mode;
5669             mUpdateTime = java.lang.System.currentTimeMillis();
5670         }
5671 
getMode()5672         public int getMode() {
5673             return mMode;
5674         }
5675 
getBinder()5676         public IBinder getBinder() {
5677             return mCb;
5678         }
5679 
getUid()5680         public int getUid() {
5681             return mUid;
5682         }
5683 
getPackage()5684         public String getPackage() {
5685             return mPackage;
5686         }
5687 
isPrivileged()5688         public boolean isPrivileged() {
5689             return mIsPrivileged;
5690         }
5691 
getUpdateTime()5692         public long getUpdateTime() {
5693             return mUpdateTime;
5694         }
5695 
setPlaybackActive(boolean active)5696         public void setPlaybackActive(boolean active) {
5697             mPlaybackActive = active;
5698         }
5699 
setRecordingActive(boolean active)5700         public void setRecordingActive(boolean active) {
5701             mRecordingActive = active;
5702         }
5703 
5704         /**
5705          * An app is considered active if:
5706          * - It is privileged (has MODIFY_PHONE_STATE permission)
5707          *  or
5708          * - It requests mode MODE_IN_COMMUNICATION, and it is either playing
5709          * or recording for VOICE_COMMUNICATION.
5710          *   or
5711          * - It requests a mode different from MODE_IN_COMMUNICATION or MODE_NORMAL
5712          * Note: only privileged apps can request MODE_IN_CALL, MODE_CALL_REDIRECT
5713          * or MODE_COMMUNICATION_REDIRECT.
5714          */
isActive()5715         public boolean isActive() {
5716             return mIsPrivileged
5717                     || ((mMode == AudioSystem.MODE_IN_COMMUNICATION)
5718                         && (mRecordingActive || mPlaybackActive))
5719                     || mMode == AudioSystem.MODE_RINGTONE
5720                     || mMode == AudioSystem.MODE_CALL_SCREENING;
5721         }
5722 
dump(PrintWriter pw, int index)5723         public void dump(PrintWriter pw, int index) {
5724             SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm:ss:SSS");
5725 
5726             if (index >= 0) {
5727                 pw.println("  Requester # " + (index + 1) + ":");
5728             }
5729             pw.println("  - Mode: " + AudioSystem.modeToString(mMode));
5730             pw.println("  - Binder: " + mCb);
5731             pw.println("  - Pid: " + mPid);
5732             pw.println("  - Uid: " + mUid);
5733             pw.println("  - Package: " + mPackage);
5734             pw.println("  - Privileged: " + mIsPrivileged);
5735             pw.println("  - Active: " + isActive());
5736             pw.println("    Playback active: " + mPlaybackActive);
5737             pw.println("    Recording active: " + mRecordingActive);
5738             pw.println("  - update time: " + format.format(new Date(mUpdateTime)));
5739         }
5740     }
5741 
5742     @GuardedBy("mDeviceBroker.mSetModeLock")
getAudioModeOwnerHandler()5743     private SetModeDeathHandler getAudioModeOwnerHandler() {
5744         // The Audio mode owner is:
5745         // 1) the most recent privileged app in the stack
5746         // 2) the most recent active app in the tack
5747         SetModeDeathHandler modeOwner = null;
5748         SetModeDeathHandler privilegedModeOwner = null;
5749         for (SetModeDeathHandler h : mSetModeDeathHandlers) {
5750             if (h.isActive()) {
5751                 // privileged apps are always active
5752                 if (h.isPrivileged()) {
5753                     if (privilegedModeOwner == null
5754                             || h.getUpdateTime() > privilegedModeOwner.getUpdateTime()) {
5755                         privilegedModeOwner = h;
5756                     }
5757                 } else {
5758                     if (modeOwner == null
5759                             || h.getUpdateTime() > modeOwner.getUpdateTime()) {
5760                         modeOwner = h;
5761                     }
5762                 }
5763             }
5764         }
5765         return privilegedModeOwner != null ? privilegedModeOwner :  modeOwner;
5766     }
5767 
5768     /**
5769      * Return information on the current audio mode owner
5770      * @return 0 if nobody owns the mode
5771      */
5772     @GuardedBy("mDeviceBroker.mSetModeLock")
getAudioModeOwner()5773     /*package*/ AudioDeviceBroker.AudioModeInfo getAudioModeOwner() {
5774         SetModeDeathHandler hdlr = getAudioModeOwnerHandler();
5775         if (hdlr != null) {
5776             return new AudioDeviceBroker.AudioModeInfo(
5777                     hdlr.getMode(), hdlr.getPid(), hdlr.getUid());
5778         }
5779         return new AudioDeviceBroker.AudioModeInfo(AudioSystem.MODE_NORMAL, 0 , 0);
5780     }
5781 
5782     /**
5783      * Return the uid of the current audio mode owner
5784      * @return 0 if nobody owns the mode
5785      */
5786     @GuardedBy("mDeviceBroker.mSetModeLock")
getModeOwnerUid()5787     /*package*/ int getModeOwnerUid() {
5788         SetModeDeathHandler hdlr = getAudioModeOwnerHandler();
5789         if (hdlr != null) {
5790             return hdlr.getUid();
5791         }
5792         return 0;
5793     }
5794 
5795     /** @see AudioManager#setMode(int) */
setMode(int mode, IBinder cb, String callingPackage)5796     public void setMode(int mode, IBinder cb, String callingPackage) {
5797         int pid = Binder.getCallingPid();
5798         int uid = Binder.getCallingUid();
5799         if (DEBUG_MODE) {
5800             Log.v(TAG, "setMode(mode=" + mode + ", pid=" + pid
5801                     + ", uid=" + uid + ", caller=" + callingPackage + ")");
5802         }
5803         if (!checkAudioSettingsPermission("setMode()")) {
5804             return;
5805         }
5806         if (cb == null) {
5807             Log.e(TAG, "setMode() called with null binder");
5808             return;
5809         }
5810         if (mode < AudioSystem.MODE_CURRENT || mode >= AudioSystem.NUM_MODES) {
5811             Log.w(TAG, "setMode() invalid mode: " + mode);
5812             return;
5813         }
5814 
5815         if (mode == AudioSystem.MODE_CURRENT) {
5816             mode = getMode();
5817         }
5818 
5819         if (mode == AudioSystem.MODE_CALL_SCREENING && !mIsCallScreeningModeSupported) {
5820             Log.w(TAG, "setMode(MODE_CALL_SCREENING) not permitted "
5821                     + "when call screening is not supported");
5822             return;
5823         }
5824 
5825         final boolean hasModifyPhoneStatePermission = mContext.checkCallingOrSelfPermission(
5826                 android.Manifest.permission.MODIFY_PHONE_STATE)
5827                 == PackageManager.PERMISSION_GRANTED;
5828         if ((mode == AudioSystem.MODE_IN_CALL
5829                 || mode == AudioSystem.MODE_CALL_REDIRECT
5830                 || mode == AudioSystem.MODE_COMMUNICATION_REDIRECT)
5831                 && !hasModifyPhoneStatePermission) {
5832             Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setMode("
5833                     + AudioSystem.modeToString(mode) + ") from pid=" + pid
5834                     + ", uid=" + Binder.getCallingUid());
5835             return;
5836         }
5837 
5838         SetModeDeathHandler currentModeHandler = null;
5839         synchronized (mDeviceBroker.mSetModeLock) {
5840             for (SetModeDeathHandler h : mSetModeDeathHandlers) {
5841                 if (h.getPid() == pid) {
5842                     currentModeHandler = h;
5843                     break;
5844                 }
5845             }
5846 
5847             if (mode == AudioSystem.MODE_NORMAL) {
5848                 if (currentModeHandler != null) {
5849                     if (!currentModeHandler.isPrivileged()
5850                             && currentModeHandler.getMode() == AudioSystem.MODE_IN_COMMUNICATION) {
5851                         mAudioHandler.removeEqualMessages(
5852                                 MSG_CHECK_MODE_FOR_UID, currentModeHandler);
5853                     }
5854                     mSetModeDeathHandlers.remove(currentModeHandler);
5855                     if (DEBUG_MODE) {
5856                         Log.v(TAG, "setMode(" + mode + ") removing hldr for pid: " + pid);
5857                     }
5858                     try {
5859                         currentModeHandler.getBinder().unlinkToDeath(currentModeHandler, 0);
5860                     } catch (NoSuchElementException e) {
5861                         Log.w(TAG, "setMode link does not exist ...");
5862                     }
5863                 }
5864             } else {
5865                 if (currentModeHandler != null) {
5866                     currentModeHandler.setMode(mode);
5867                     if (DEBUG_MODE) {
5868                         Log.v(TAG, "setMode(" + mode + ") updating hldr for pid: " + pid);
5869                     }
5870                 } else {
5871                     currentModeHandler = new SetModeDeathHandler(cb, pid, uid,
5872                             hasModifyPhoneStatePermission, callingPackage, mode);
5873                     // Register for client death notification
5874                     try {
5875                         cb.linkToDeath(currentModeHandler, 0);
5876                     } catch (RemoteException e) {
5877                         // Client has died!
5878                         Log.w(TAG, "setMode() could not link to " + cb + " binder death");
5879                         return;
5880                     }
5881                     mSetModeDeathHandlers.add(currentModeHandler);
5882                     if (DEBUG_MODE) {
5883                         Log.v(TAG, "setMode(" + mode + ") adding handler for pid=" + pid);
5884                     }
5885                 }
5886                 if (mode == AudioSystem.MODE_IN_COMMUNICATION) {
5887                     // Force active state when entering/updating the stack to avoid glitches when
5888                     // an app starts playing/recording after settng the audio mode,
5889                     // and send a reminder to check activity after a grace period.
5890                     if (!currentModeHandler.isPrivileged()) {
5891                         currentModeHandler.setPlaybackActive(true);
5892                         currentModeHandler.setRecordingActive(true);
5893                         sendMsg(mAudioHandler,
5894                                 MSG_CHECK_MODE_FOR_UID,
5895                                 SENDMSG_QUEUE,
5896                                 0,
5897                                 0,
5898                                 currentModeHandler,
5899                                 CHECK_MODE_FOR_UID_PERIOD_MS);
5900                     }
5901                 }
5902             }
5903 
5904             sendMsg(mAudioHandler,
5905                     MSG_UPDATE_AUDIO_MODE,
5906                     SENDMSG_REPLACE,
5907                     mode,
5908                     pid,
5909                     callingPackage,
5910                     0);
5911         }
5912     }
5913 
5914     @GuardedBy("mDeviceBroker.mSetModeLock")
onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage, boolean force)5915     void onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage,
5916                            boolean force) {
5917         if (requestedMode == AudioSystem.MODE_CURRENT) {
5918             requestedMode = getMode();
5919         }
5920         int mode = AudioSystem.MODE_NORMAL;
5921         int uid = 0;
5922         int pid = 0;
5923         SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler();
5924         if (currentModeHandler != null) {
5925             mode = currentModeHandler.getMode();
5926             uid = currentModeHandler.getUid();
5927             pid = currentModeHandler.getPid();
5928         }
5929         if (DEBUG_MODE) {
5930             Log.v(TAG, "onUpdateAudioMode() new mode: " + mode + ", current mode: "
5931                     + mMode.get() + " requested mode: " + requestedMode);
5932         }
5933         if (mode != mMode.get() || force) {
5934             int status = AudioSystem.SUCCESS;
5935             final long identity = Binder.clearCallingIdentity();
5936             try {
5937                 status = mAudioSystem.setPhoneState(mode, uid);
5938             } finally {
5939                 Binder.restoreCallingIdentity(identity);
5940             }
5941             if (status == AudioSystem.AUDIO_STATUS_OK) {
5942                 if (DEBUG_MODE) {
5943                     Log.v(TAG, "onUpdateAudioMode: mode successfully set to " + mode);
5944                 }
5945                 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_MODE, SENDMSG_REPLACE, mode, 0,
5946                         /*obj*/ null, /*delay*/ 0);
5947                 int previousMode = mMode.getAndSet(mode);
5948                 // Note: newModeOwnerPid is always 0 when actualMode is MODE_NORMAL
5949                 mModeLogger.enqueue(new PhoneStateEvent(requesterPackage, requesterPid,
5950                         requestedMode, pid, mode));
5951 
5952                 final int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
5953                 final int device = getDeviceForStream(streamType);
5954                 final int streamAlias = mStreamVolumeAlias[streamType];
5955 
5956                 if (DEBUG_MODE) {
5957                     Log.v(TAG, "onUpdateAudioMode: streamType=" + streamType
5958                             + ", streamAlias=" + streamAlias);
5959                 }
5960 
5961                 final int index = mStreamStates[streamAlias].getIndex(device);
5962                 final int maxIndex = mStreamStates[streamAlias].getMaxIndex();
5963                 setStreamVolumeInt(streamAlias, index, device, true,
5964                         requesterPackage, true /*hasModifyAudioSettings*/);
5965 
5966                 updateStreamVolumeAlias(true /*updateVolumes*/, requesterPackage);
5967 
5968                 // change of mode may require volume to be re-applied on some devices
5969                 updateAbsVolumeMultiModeDevices(previousMode, mode);
5970 
5971                 setLeAudioVolumeOnModeUpdate(mode, device, streamAlias, index, maxIndex);
5972 
5973                 // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all SCO
5974                 // connections not started by the application changing the mode when pid changes
5975                 mDeviceBroker.postSetModeOwner(mode, pid, uid);
5976             } else {
5977                 Log.w(TAG, "onUpdateAudioMode: failed to set audio mode to: " + mode);
5978             }
5979         }
5980     }
5981 
5982     /** @see AudioManager#getMode() */
getMode()5983     public int getMode() {
5984         synchronized (mDeviceBroker.mSetModeLock) {
5985             SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler();
5986             if (currentModeHandler != null) {
5987                 return currentModeHandler.getMode();
5988             }
5989             return AudioSystem.MODE_NORMAL;
5990         }
5991     }
5992 
5993     /** cached value read from audiopolicy manager after initialization. */
5994     private boolean mIsCallScreeningModeSupported = false;
5995 
5996     /** @see AudioManager#isCallScreeningModeSupported() */
isCallScreeningModeSupported()5997     public boolean isCallScreeningModeSupported() {
5998         return mIsCallScreeningModeSupported;
5999     }
6000 
dispatchMode(int mode)6001     protected void dispatchMode(int mode) {
6002         final int nbDispatchers = mModeDispatchers.beginBroadcast();
6003         for (int i = 0; i < nbDispatchers; i++) {
6004             try {
6005                 mModeDispatchers.getBroadcastItem(i).dispatchAudioModeChanged(mode);
6006             } catch (RemoteException e) {
6007             }
6008         }
6009         mModeDispatchers.finishBroadcast();
6010     }
6011 
6012     final RemoteCallbackList<IAudioModeDispatcher> mModeDispatchers =
6013             new RemoteCallbackList<IAudioModeDispatcher>();
6014 
6015     /**
6016      * @see {@link AudioManager#addOnModeChangedListener(Executor, AudioManager.OnModeChangedListener)}
6017      * @param dispatcher
6018      */
registerModeDispatcher( @onNull IAudioModeDispatcher dispatcher)6019     public void registerModeDispatcher(
6020             @NonNull IAudioModeDispatcher dispatcher) {
6021         mModeDispatchers.register(dispatcher);
6022     }
6023 
6024     /**
6025      * @see {@link AudioManager#removeOnModeChangedListener(AudioManager.OnModeChangedListener)}
6026      * @param dispatcher
6027      */
unregisterModeDispatcher( @onNull IAudioModeDispatcher dispatcher)6028     public void unregisterModeDispatcher(
6029             @NonNull IAudioModeDispatcher dispatcher) {
6030         mModeDispatchers.unregister(dispatcher);
6031     }
6032 
6033     @android.annotation.EnforcePermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION)
6034     /** @see AudioManager#isPstnCallAudioInterceptable() */
isPstnCallAudioInterceptable()6035     public boolean isPstnCallAudioInterceptable() {
6036 
6037         super.isPstnCallAudioInterceptable_enforcePermission();
6038 
6039         boolean uplinkDeviceFound = false;
6040         boolean downlinkDeviceFound = false;
6041         AudioDeviceInfo[] devices = AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_ALL);
6042         for (AudioDeviceInfo device : devices) {
6043             if (device.getInternalType() == AudioSystem.DEVICE_OUT_TELEPHONY_TX) {
6044                 uplinkDeviceFound = true;
6045             } else if (device.getInternalType() == AudioSystem.DEVICE_IN_TELEPHONY_RX) {
6046                 downlinkDeviceFound = true;
6047             }
6048             if (uplinkDeviceFound && downlinkDeviceFound) {
6049                 return true;
6050             }
6051         }
6052         return false;
6053     }
6054 
6055     /** @see AudioManager#setRttEnabled() */
6056     @Override
setRttEnabled(boolean rttEnabled)6057     public void setRttEnabled(boolean rttEnabled) {
6058         if (mContext.checkCallingOrSelfPermission(
6059                 android.Manifest.permission.MODIFY_PHONE_STATE)
6060                 != PackageManager.PERMISSION_GRANTED) {
6061             Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setRttEnabled from pid="
6062                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
6063             return;
6064         }
6065         synchronized (mSettingsLock) {
6066             mRttEnabled = rttEnabled;
6067             final long identity = Binder.clearCallingIdentity();
6068             try {
6069                 AudioSystem.setRttEnabled(rttEnabled);
6070             } finally {
6071                 Binder.restoreCallingIdentity(identity);
6072             }
6073         }
6074     }
6075 
6076     /** @see AudioManager#adjustSuggestedStreamVolumeForUid(int, int, int, String, int, int, int) */
6077     @Override
adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6078     public void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags,
6079             @NonNull String packageName, int uid, int pid, UserHandle userHandle,
6080             int targetSdkVersion) {
6081         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
6082             throw new SecurityException("Should only be called from system process");
6083         }
6084 
6085         // direction and stream type swap here because the public
6086         // adjustSuggested has a different order than the other methods.
6087         adjustSuggestedStreamVolume(direction, streamType, flags, packageName, packageName,
6088                 uid, pid, hasAudioSettingsPermission(uid, pid),
6089                 AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
6090     }
6091 
6092     /** @see AudioManager#adjustStreamVolumeForUid(int, int, int, String, int, int, int) */
6093     @Override
adjustStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6094     public void adjustStreamVolumeForUid(int streamType, int direction, int flags,
6095             @NonNull String packageName, int uid, int pid, UserHandle userHandle,
6096             int targetSdkVersion) {
6097         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
6098             throw new SecurityException("Should only be called from system process");
6099         }
6100 
6101         if (direction != AudioManager.ADJUST_SAME) {
6102             sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_ADJUST_VOL_UID, streamType,
6103                     direction/*val1*/, flags/*val2*/,
6104                     new StringBuilder(packageName).append(" uid:").append(uid)
6105                     .toString()));
6106         }
6107 
6108         adjustStreamVolume(streamType, direction, flags, packageName, packageName, uid, pid,
6109                 null, hasAudioSettingsPermission(uid, pid),
6110                 AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
6111     }
6112 
6113     /** @see AudioManager#setStreamVolumeForUid(int, int, int, String, int, int, int) */
6114     @Override
setStreamVolumeForUid(int streamType, int index, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6115     public void setStreamVolumeForUid(int streamType, int index, int flags,
6116             @NonNull String packageName, int uid, int pid, UserHandle userHandle,
6117             int targetSdkVersion) {
6118         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
6119             throw new SecurityException("Should only be called from system process");
6120         }
6121 
6122         setStreamVolume(streamType, index, flags, /*device*/ null,
6123                 packageName, packageName, null, uid,
6124                 hasAudioSettingsPermission(uid, pid));
6125     }
6126 
6127     //==========================================================================================
6128     // Sound Effects
6129     //==========================================================================================
6130     private static final class LoadSoundEffectReply
6131             implements SoundEffectsHelper.OnEffectsLoadCompleteHandler {
6132         private static final int SOUND_EFFECTS_LOADING = 1;
6133         private static final int SOUND_EFFECTS_LOADED = 0;
6134         private static final int SOUND_EFFECTS_ERROR = -1;
6135         private static final int SOUND_EFFECTS_LOAD_TIMEOUT_MS = 5000;
6136 
6137         private int mStatus = SOUND_EFFECTS_LOADING;
6138 
6139         @Override
run(boolean success)6140         public synchronized void run(boolean success) {
6141             mStatus = success ? SOUND_EFFECTS_LOADED : SOUND_EFFECTS_ERROR;
6142             notify();
6143         }
6144 
waitForLoaded(int attempts)6145         public synchronized boolean waitForLoaded(int attempts) {
6146             while ((mStatus == SOUND_EFFECTS_LOADING) && (attempts-- > 0)) {
6147                 try {
6148                     wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS);
6149                 } catch (InterruptedException e) {
6150                     Log.w(TAG, "Interrupted while waiting sound pool loaded.");
6151                 }
6152             }
6153             return mStatus == SOUND_EFFECTS_LOADED;
6154         }
6155     }
6156 
6157     /** @see AudioManager#playSoundEffect(int, int) */
playSoundEffect(int effectType, int userId)6158     public void playSoundEffect(int effectType, int userId) {
6159         if (querySoundEffectsEnabled(userId)) {
6160             playSoundEffectVolume(effectType, -1.0f);
6161         }
6162     }
6163 
6164     /**
6165      * Settings has an in memory cache, so this is fast.
6166      */
querySoundEffectsEnabled(int user)6167     private boolean querySoundEffectsEnabled(int user) {
6168         return mSettings.getSystemIntForUser(getContentResolver(),
6169                 Settings.System.SOUND_EFFECTS_ENABLED, 0, user) != 0;
6170     }
6171 
6172     /** @see AudioManager#playSoundEffect(int, float) */
playSoundEffectVolume(int effectType, float volume)6173     public void playSoundEffectVolume(int effectType, float volume) {
6174         // do not try to play the sound effect if the system stream is muted
6175         if (isStreamMute(STREAM_SYSTEM)) {
6176             return;
6177         }
6178 
6179         if (effectType >= AudioManager.NUM_SOUND_EFFECTS || effectType < 0) {
6180             Log.w(TAG, "AudioService effectType value " + effectType + " out of range");
6181             return;
6182         }
6183 
6184         sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SENDMSG_QUEUE,
6185                 effectType, (int) (volume * 1000), null, 0);
6186     }
6187 
6188     /**
6189      * Loads samples into the soundpool.
6190      * This method must be called at first when sound effects are enabled
6191      */
loadSoundEffects()6192     public boolean loadSoundEffects() {
6193         LoadSoundEffectReply reply = new LoadSoundEffectReply();
6194         sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, reply, 0);
6195         return reply.waitForLoaded(3 /*attempts*/);
6196     }
6197 
6198     /**
6199      * Schedule loading samples into the soundpool.
6200      * This method can be overridden to schedule loading at a later time.
6201      */
scheduleLoadSoundEffects()6202     protected void scheduleLoadSoundEffects() {
6203         sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0);
6204     }
6205 
6206     /**
6207      *  Unloads samples from the sound pool.
6208      *  This method can be called to free some memory when
6209      *  sound effects are disabled.
6210      */
unloadSoundEffects()6211     public void unloadSoundEffects() {
6212         sendMsg(mAudioHandler, MSG_UNLOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0);
6213     }
6214 
6215     /** @see AudioManager#reloadAudioSettings() */
reloadAudioSettings()6216     public void reloadAudioSettings() {
6217         readAudioSettings(false /*userSwitch*/);
6218     }
6219 
readAudioSettings(boolean userSwitch)6220     private void readAudioSettings(boolean userSwitch) {
6221         // restore ringer mode, ringer mode affected streams, mute affected streams and vibrate settings
6222         readPersistedSettings();
6223         readUserRestrictions();
6224 
6225         // restore volume settings
6226         int numStreamTypes = AudioSystem.getNumStreamTypes();
6227         for (int streamType = 0; streamType < numStreamTypes; streamType++) {
6228             VolumeStreamState streamState = mStreamStates[streamType];
6229 
6230             if (userSwitch && mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) {
6231                 continue;
6232             }
6233 
6234             streamState.readSettings();
6235             synchronized (VolumeStreamState.class) {
6236                 // unmute stream that was muted but is not affect by mute anymore
6237                 if (streamState.mIsMuted && ((!isStreamAffectedByMute(streamType) &&
6238                         !isStreamMutedByRingerOrZenMode(streamType)) || mUseFixedVolume)) {
6239                     streamState.mIsMuted = false;
6240                 }
6241             }
6242         }
6243 
6244         readVolumeGroupsSettings(userSwitch);
6245 
6246         // apply new ringer mode before checking volume for alias streams so that streams
6247         // muted by ringer mode have the correct volume
6248         setRingerModeInt(getRingerModeInternal(), false);
6249 
6250         checkAllFixedVolumeDevices();
6251         checkAllAliasStreamVolumes();
6252         checkMuteAffectedStreams();
6253 
6254         mSoundDoseHelper.restoreMusicActiveMs();
6255         mSoundDoseHelper.enforceSafeMediaVolumeIfActive(TAG);
6256 
6257         if (DEBUG_VOL) {
6258             Log.d(TAG, "Restoring device volume behavior");
6259         }
6260         restoreDeviceVolumeBehavior();
6261     }
6262 
6263     /** @see AudioManager#getAvailableCommunicationDevices(int) */
getAvailableCommunicationDeviceIds()6264     public int[] getAvailableCommunicationDeviceIds() {
6265         List<AudioDeviceInfo> commDevices = AudioDeviceBroker.getAvailableCommunicationDevices();
6266         return commDevices.stream().mapToInt(AudioDeviceInfo::getId).toArray();
6267     }
6268 
6269     /**
6270      * @see AudioManager#setCommunicationDevice(int)
6271      * @see AudioManager#clearCommunicationDevice()
6272      */
setCommunicationDevice(IBinder cb, int portId)6273     public boolean setCommunicationDevice(IBinder cb, int portId) {
6274         final int uid = Binder.getCallingUid();
6275         final int pid = Binder.getCallingPid();
6276 
6277         AudioDeviceInfo device = null;
6278         if (portId != 0) {
6279             device = AudioManager.getDeviceForPortId(portId, AudioManager.GET_DEVICES_OUTPUTS);
6280             if (device == null) {
6281                 Log.w(TAG, "setCommunicationDevice: invalid portID " + portId);
6282                 return false;
6283             }
6284             if (!AudioDeviceBroker.isValidCommunicationDevice(device)) {
6285                 if (!device.isSink()) {
6286                     throw new IllegalArgumentException("device must have sink role");
6287                 } else {
6288                     throw new IllegalArgumentException("invalid device type: " + device.getType());
6289                 }
6290             }
6291         }
6292         final String eventSource = new StringBuilder()
6293                 .append(device == null ? "clearCommunicationDevice(" : "setCommunicationDevice(")
6294                 .append(") from u/pid:").append(uid).append("/")
6295                 .append(pid).toString();
6296 
6297         int deviceType = AudioSystem.DEVICE_OUT_DEFAULT;
6298         String deviceAddress = null;
6299         if (device != null) {
6300             deviceType = device.getPort().type();
6301             deviceAddress = device.getAddress();
6302         } else {
6303             AudioDeviceInfo curDevice = mDeviceBroker.getCommunicationDevice();
6304             if (curDevice != null) {
6305                 deviceType = curDevice.getPort().type();
6306                 deviceAddress = curDevice.getAddress();
6307             }
6308         }
6309         // do not log metrics if clearing communication device while no communication device
6310         // was selected
6311         if (deviceType != AudioSystem.DEVICE_OUT_DEFAULT) {
6312             new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
6313                     + MediaMetrics.SEPARATOR + "setCommunicationDevice")
6314                     .set(MediaMetrics.Property.DEVICE,
6315                             AudioSystem.getDeviceName(deviceType))
6316                     .set(MediaMetrics.Property.ADDRESS, deviceAddress)
6317                     .set(MediaMetrics.Property.STATE, device != null
6318                             ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED)
6319                     .record();
6320         }
6321         final boolean isPrivileged = mContext.checkCallingOrSelfPermission(
6322                 android.Manifest.permission.MODIFY_PHONE_STATE)
6323                 == PackageManager.PERMISSION_GRANTED;
6324         final long ident = Binder.clearCallingIdentity();
6325         try {
6326             return mDeviceBroker.setCommunicationDevice(cb, uid, device, isPrivileged, eventSource);
6327         } finally {
6328             Binder.restoreCallingIdentity(ident);
6329         }
6330     }
6331 
6332     /** @see AudioManager#getCommunicationDevice() */
getCommunicationDevice()6333     public int getCommunicationDevice() {
6334         int deviceId = 0;
6335         final long ident = Binder.clearCallingIdentity();
6336         try {
6337             AudioDeviceInfo device = mDeviceBroker.getCommunicationDevice();
6338             deviceId = device != null ? device.getId() : 0;
6339         } finally {
6340             Binder.restoreCallingIdentity(ident);
6341         }
6342         return deviceId;
6343     }
6344 
6345     /** @see AudioManager#addOnCommunicationDeviceChangedListener(
6346      *               Executor, AudioManager.OnCommunicationDeviceChangedListener)
6347      */
registerCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)6348     public void registerCommunicationDeviceDispatcher(
6349             @Nullable ICommunicationDeviceDispatcher dispatcher) {
6350         if (dispatcher == null) {
6351             return;
6352         }
6353         mDeviceBroker.registerCommunicationDeviceDispatcher(dispatcher);
6354     }
6355 
6356     /** @see AudioManager#removeOnCommunicationDeviceChangedListener(
6357      *               AudioManager.OnCommunicationDeviceChangedListener)
6358      */
unregisterCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)6359     public void unregisterCommunicationDeviceDispatcher(
6360             @Nullable ICommunicationDeviceDispatcher dispatcher) {
6361         if (dispatcher == null) {
6362             return;
6363         }
6364         mDeviceBroker.unregisterCommunicationDeviceDispatcher(dispatcher);
6365     }
6366 
6367     /** @see AudioManager#setSpeakerphoneOn(boolean) */
setSpeakerphoneOn(IBinder cb, boolean on)6368     public void setSpeakerphoneOn(IBinder cb, boolean on) {
6369         if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) {
6370             return;
6371         }
6372         final boolean isPrivileged = mContext.checkCallingOrSelfPermission(
6373                 android.Manifest.permission.MODIFY_PHONE_STATE)
6374                 == PackageManager.PERMISSION_GRANTED;
6375 
6376         // for logging only
6377         final int uid = Binder.getCallingUid();
6378         final int pid = Binder.getCallingPid();
6379 
6380         final String eventSource = new StringBuilder("setSpeakerphoneOn(").append(on)
6381                 .append(") from u/pid:").append(uid).append("/")
6382                 .append(pid).toString();
6383         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
6384                 + MediaMetrics.SEPARATOR + "setSpeakerphoneOn")
6385                 .setUid(uid)
6386                 .setPid(pid)
6387                 .set(MediaMetrics.Property.STATE, on
6388                         ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
6389                 .record();
6390 
6391         final long ident = Binder.clearCallingIdentity();
6392         try {
6393             mDeviceBroker.setSpeakerphoneOn(cb, uid, on, isPrivileged, eventSource);
6394         } finally {
6395             Binder.restoreCallingIdentity(ident);
6396         }
6397     }
6398 
6399     /** @see AudioManager#isSpeakerphoneOn() */
isSpeakerphoneOn()6400     public boolean isSpeakerphoneOn() {
6401         return mDeviceBroker.isSpeakerphoneOn();
6402     }
6403 
6404 
6405     /** BT SCO audio state seen by apps using the deprecated API setBluetoothScoOn().
6406      * @see isBluetoothScoOn() */
6407     private boolean mBtScoOnByApp;
6408 
6409     /** @see AudioManager#setBluetoothScoOn(boolean) */
setBluetoothScoOn(boolean on)6410     public void setBluetoothScoOn(boolean on) {
6411         if (!checkAudioSettingsPermission("setBluetoothScoOn()")) {
6412             return;
6413         }
6414 
6415         // Only enable calls from system components
6416         if (UserHandle.getCallingAppId() >= FIRST_APPLICATION_UID) {
6417             mBtScoOnByApp = on;
6418             return;
6419         }
6420 
6421         // for logging only
6422         final int uid = Binder.getCallingUid();
6423         final int pid = Binder.getCallingPid();
6424         final String eventSource = new StringBuilder("setBluetoothScoOn(").append(on)
6425                 .append(") from u/pid:").append(uid).append("/").append(pid).toString();
6426 
6427         //bt sco
6428         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
6429                 + MediaMetrics.SEPARATOR + "setBluetoothScoOn")
6430                 .setUid(uid)
6431                 .setPid(pid)
6432                 .set(MediaMetrics.Property.STATE, on
6433                         ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
6434                 .record();
6435 
6436         mDeviceBroker.setBluetoothScoOn(on, eventSource);
6437     }
6438 
6439     /** @see AudioManager#setA2dpSuspended(boolean) */
6440     @android.annotation.EnforcePermission(android.Manifest.permission.BLUETOOTH_STACK)
setA2dpSuspended(boolean enable)6441     public void setA2dpSuspended(boolean enable) {
6442         super.setA2dpSuspended_enforcePermission();
6443         final String eventSource = new StringBuilder("setA2dpSuspended(").append(enable)
6444                 .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
6445                 .append(Binder.getCallingPid()).toString();
6446         mDeviceBroker.setA2dpSuspended(enable, false /*internal*/, eventSource);
6447     }
6448 
6449     /** @see AudioManager#setA2dpSuspended(boolean) */
6450     @android.annotation.EnforcePermission(android.Manifest.permission.BLUETOOTH_STACK)
setLeAudioSuspended(boolean enable)6451     public void setLeAudioSuspended(boolean enable) {
6452         super.setLeAudioSuspended_enforcePermission();
6453         final String eventSource = new StringBuilder("setLeAudioSuspended(").append(enable)
6454                 .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
6455                 .append(Binder.getCallingPid()).toString();
6456         mDeviceBroker.setLeAudioSuspended(enable, false /*internal*/, eventSource);
6457     }
6458 
6459     /** @see AudioManager#isBluetoothScoOn()
6460      * Note that it doesn't report internal state, but state seen by apps (which may have
6461      * called setBluetoothScoOn() */
isBluetoothScoOn()6462     public boolean isBluetoothScoOn() {
6463         return mBtScoOnByApp || mDeviceBroker.isBluetoothScoOn();
6464     }
6465 
6466     // TODO investigate internal users due to deprecation of SDK API
6467     /** @see AudioManager#setBluetoothA2dpOn(boolean) */
setBluetoothA2dpOn(boolean on)6468     public void setBluetoothA2dpOn(boolean on) {
6469         if (!checkAudioSettingsPermission("setBluetoothA2dpOn()")) {
6470             return;
6471         }
6472 
6473         // for logging only
6474         final int uid = Binder.getCallingUid();
6475         final int pid = Binder.getCallingPid();
6476         final String eventSource = new StringBuilder("setBluetoothA2dpOn(").append(on)
6477                 .append(") from u/pid:").append(uid).append("/")
6478                 .append(pid).toString();
6479 
6480         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
6481                 + MediaMetrics.SEPARATOR + "setBluetoothA2dpOn")
6482                 .setUid(uid)
6483                 .setPid(pid)
6484                 .set(MediaMetrics.Property.STATE, on
6485                         ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
6486                 .record();
6487 
6488         mDeviceBroker.setBluetoothA2dpOn_Async(on, eventSource);
6489     }
6490 
6491     /** @see AudioManager#isBluetoothA2dpOn() */
isBluetoothA2dpOn()6492     public boolean isBluetoothA2dpOn() {
6493         return mDeviceBroker.isBluetoothA2dpOn();
6494     }
6495 
6496     /** @see AudioManager#startBluetoothSco() */
startBluetoothSco(IBinder cb, int targetSdkVersion)6497     public void startBluetoothSco(IBinder cb, int targetSdkVersion) {
6498         if (!checkAudioSettingsPermission("startBluetoothSco()")) {
6499             return;
6500         }
6501 
6502         final int uid = Binder.getCallingUid();
6503         final int pid = Binder.getCallingPid();
6504         final int scoAudioMode =
6505                 (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ?
6506                         BtHelper.SCO_MODE_VIRTUAL_CALL : BtHelper.SCO_MODE_UNDEFINED;
6507         final String eventSource = new StringBuilder("startBluetoothSco()")
6508                 .append(") from u/pid:").append(uid).append("/")
6509                 .append(pid).toString();
6510 
6511         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
6512                 .setUid(uid)
6513                 .setPid(pid)
6514                 .set(MediaMetrics.Property.EVENT, "startBluetoothSco")
6515                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
6516                         BtHelper.scoAudioModeToString(scoAudioMode))
6517                 .record();
6518         startBluetoothScoInt(cb, uid, scoAudioMode, eventSource);
6519 
6520     }
6521 
6522     /** @see AudioManager#startBluetoothScoVirtualCall() */
startBluetoothScoVirtualCall(IBinder cb)6523     public void startBluetoothScoVirtualCall(IBinder cb) {
6524         if (!checkAudioSettingsPermission("startBluetoothScoVirtualCall()")) {
6525             return;
6526         }
6527 
6528         final int uid = Binder.getCallingUid();
6529         final int pid = Binder.getCallingPid();
6530         final String eventSource = new StringBuilder("startBluetoothScoVirtualCall()")
6531                 .append(") from u/pid:").append(uid).append("/")
6532                 .append(pid).toString();
6533 
6534         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
6535                 .setUid(uid)
6536                 .setPid(pid)
6537                 .set(MediaMetrics.Property.EVENT, "startBluetoothScoVirtualCall")
6538                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
6539                         BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_VIRTUAL_CALL))
6540                 .record();
6541         startBluetoothScoInt(cb, uid, BtHelper.SCO_MODE_VIRTUAL_CALL, eventSource);
6542     }
6543 
startBluetoothScoInt(IBinder cb, int uid, int scoAudioMode, @NonNull String eventSource)6544     void startBluetoothScoInt(IBinder cb, int uid, int scoAudioMode, @NonNull String eventSource) {
6545         MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
6546                 .set(MediaMetrics.Property.EVENT, "startBluetoothScoInt")
6547                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
6548                         BtHelper.scoAudioModeToString(scoAudioMode));
6549 
6550         if (!checkAudioSettingsPermission("startBluetoothSco()") ||
6551                 !mSystemReady) {
6552             mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission or systemReady").record();
6553             return;
6554         }
6555         final boolean isPrivileged = mContext.checkCallingOrSelfPermission(
6556                 android.Manifest.permission.MODIFY_PHONE_STATE)
6557                 == PackageManager.PERMISSION_GRANTED;
6558         final long ident = Binder.clearCallingIdentity();
6559         try {
6560             mDeviceBroker.startBluetoothScoForClient(
6561                     cb, uid, scoAudioMode, isPrivileged, eventSource);
6562         } finally {
6563             Binder.restoreCallingIdentity(ident);
6564         }
6565         mmi.record();
6566     }
6567 
6568     /** @see AudioManager#stopBluetoothSco() */
stopBluetoothSco(IBinder cb)6569     public void stopBluetoothSco(IBinder cb){
6570         if (!checkAudioSettingsPermission("stopBluetoothSco()") ||
6571                 !mSystemReady) {
6572             return;
6573         }
6574         final int uid = Binder.getCallingUid();
6575         final int pid = Binder.getCallingPid();
6576         final String eventSource =  new StringBuilder("stopBluetoothSco()")
6577                 .append(") from u/pid:").append(uid).append("/")
6578                 .append(pid).toString();
6579         final boolean isPrivileged = mContext.checkCallingOrSelfPermission(
6580                 android.Manifest.permission.MODIFY_PHONE_STATE)
6581                 == PackageManager.PERMISSION_GRANTED;
6582         final long ident = Binder.clearCallingIdentity();
6583         try {
6584             mDeviceBroker.stopBluetoothScoForClient(cb, uid, isPrivileged, eventSource);
6585         } finally {
6586             Binder.restoreCallingIdentity(ident);
6587         }
6588         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
6589                 .setUid(uid)
6590                 .setPid(pid)
6591                 .set(MediaMetrics.Property.EVENT, "stopBluetoothSco")
6592                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
6593                         BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_UNDEFINED))
6594                 .record();
6595     }
6596 
6597 
getContentResolver()6598     /*package*/ ContentResolver getContentResolver() {
6599         return mContentResolver;
6600     }
6601 
getSettings()6602     /*package*/ SettingsAdapter getSettings() {
6603         return mSettings;
6604     }
6605 
6606     ///////////////////////////////////////////////////////////////////////////
6607     // Internal methods
6608     ///////////////////////////////////////////////////////////////////////////
6609 
6610     /**
6611      * Checks if the adjustment should change ringer mode instead of just
6612      * adjusting volume. If so, this will set the proper ringer mode and volume
6613      * indices on the stream states.
6614      */
checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted, String caller, int flags)6615     private int checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted,
6616             String caller, int flags) {
6617         int result = FLAG_ADJUST_VOLUME;
6618         if (isPlatformTelevision() || mIsSingleVolume) {
6619             return result;
6620         }
6621 
6622         int ringerMode = getRingerModeInternal();
6623 
6624         switch (ringerMode) {
6625         case RINGER_MODE_NORMAL:
6626             if (direction == AudioManager.ADJUST_LOWER) {
6627                 if (mHasVibrator) {
6628                     // "step" is the delta in internal index units corresponding to a
6629                     // change of 1 in UI index units.
6630                     // Because of rounding when rescaling from one stream index range to its alias
6631                     // index range, we cannot simply test oldIndex == step:
6632                     //   (step <= oldIndex < 2 * step) is equivalent to: (old UI index == 1)
6633                     if (step <= oldIndex && oldIndex < 2 * step) {
6634                         ringerMode = RINGER_MODE_VIBRATE;
6635                         mLoweredFromNormalToVibrateTime = SystemClock.uptimeMillis();
6636                     }
6637                 } else {
6638                     if (oldIndex == step && mVolumePolicy.volumeDownToEnterSilent) {
6639                         ringerMode = RINGER_MODE_SILENT;
6640                     }
6641                 }
6642             } else if (mIsSingleVolume && (direction == AudioManager.ADJUST_TOGGLE_MUTE
6643                     || direction == AudioManager.ADJUST_MUTE)) {
6644                 if (mHasVibrator) {
6645                     ringerMode = RINGER_MODE_VIBRATE;
6646                 } else {
6647                     ringerMode = RINGER_MODE_SILENT;
6648                 }
6649                 // Setting the ringer mode will toggle mute
6650                 result &= ~FLAG_ADJUST_VOLUME;
6651             }
6652             break;
6653         case RINGER_MODE_VIBRATE:
6654             if (!mHasVibrator) {
6655                 Log.e(TAG, "checkForRingerModeChange() current ringer mode is vibrate" +
6656                         "but no vibrator is present");
6657                 break;
6658             }
6659             if ((direction == AudioManager.ADJUST_LOWER)) {
6660                 // This is the case we were muted with the volume turned up
6661                 if (mIsSingleVolume && oldIndex >= 2 * step && isMuted) {
6662                     ringerMode = RINGER_MODE_NORMAL;
6663                 } else if (mPrevVolDirection != AudioManager.ADJUST_LOWER) {
6664                     if (mVolumePolicy.volumeDownToEnterSilent) {
6665                         final long diff = SystemClock.uptimeMillis()
6666                                 - mLoweredFromNormalToVibrateTime;
6667                         if (diff > mVolumePolicy.vibrateToSilentDebounce
6668                                 && mRingerModeDelegate.canVolumeDownEnterSilent()) {
6669                             ringerMode = RINGER_MODE_SILENT;
6670                         }
6671                     } else {
6672                         result |= AudioManager.FLAG_SHOW_VIBRATE_HINT;
6673                     }
6674                 }
6675             } else if (direction == AudioManager.ADJUST_RAISE
6676                     || direction == AudioManager.ADJUST_TOGGLE_MUTE
6677                     || direction == AudioManager.ADJUST_UNMUTE) {
6678                 ringerMode = RINGER_MODE_NORMAL;
6679             }
6680             result &= ~FLAG_ADJUST_VOLUME;
6681             break;
6682         case RINGER_MODE_SILENT:
6683             if (mIsSingleVolume && direction == AudioManager.ADJUST_LOWER && oldIndex >= 2 * step && isMuted) {
6684                 // This is the case we were muted with the volume turned up
6685                 ringerMode = RINGER_MODE_NORMAL;
6686             } else if (direction == AudioManager.ADJUST_RAISE
6687                     || direction == AudioManager.ADJUST_TOGGLE_MUTE
6688                     || direction == AudioManager.ADJUST_UNMUTE) {
6689                 if (!mVolumePolicy.volumeUpToExitSilent) {
6690                     result |= AudioManager.FLAG_SHOW_SILENT_HINT;
6691                 } else {
6692                   if (mHasVibrator && direction == AudioManager.ADJUST_RAISE) {
6693                       ringerMode = RINGER_MODE_VIBRATE;
6694                   } else {
6695                       // If we don't have a vibrator or they were toggling mute
6696                       // go straight back to normal.
6697                       ringerMode = RINGER_MODE_NORMAL;
6698                   }
6699                 }
6700             }
6701             result &= ~FLAG_ADJUST_VOLUME;
6702             break;
6703         default:
6704             Log.e(TAG, "checkForRingerModeChange() wrong ringer mode: "+ringerMode);
6705             break;
6706         }
6707 
6708         if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode)
6709                 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)
6710                 && (flags & AudioManager.FLAG_FROM_KEY) == 0) {
6711             throw new SecurityException("Not allowed to change Do Not Disturb state");
6712         }
6713 
6714         setRingerMode(ringerMode, TAG + ".checkForRingerModeChange", false /*external*/);
6715 
6716         mPrevVolDirection = direction;
6717 
6718         return result;
6719     }
6720 
6721     @Override
isStreamAffectedByRingerMode(int streamType)6722     public boolean isStreamAffectedByRingerMode(int streamType) {
6723         return (mRingerModeAffectedStreams & (1 << streamType)) != 0;
6724     }
6725 
shouldZenMuteStream(int streamType)6726     private boolean shouldZenMuteStream(int streamType) {
6727         if (mNm.getZenMode() != Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
6728             return false;
6729         }
6730 
6731         NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy();
6732         final boolean muteAlarms = (zenPolicy.priorityCategories
6733                 & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0;
6734         final boolean muteMedia = (zenPolicy.priorityCategories
6735                 & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0;
6736         final boolean muteSystem = (zenPolicy.priorityCategories
6737                 & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0;
6738         final boolean muteNotificationAndRing = ZenModeConfig
6739                 .areAllPriorityOnlyRingerSoundsMuted(zenPolicy);
6740         return muteAlarms && isAlarm(streamType)
6741                 || muteMedia && isMedia(streamType)
6742                 || muteSystem && isSystem(streamType)
6743                 || muteNotificationAndRing && isNotificationOrRinger(streamType);
6744     }
6745 
isStreamMutedByRingerOrZenMode(int streamType)6746     private boolean isStreamMutedByRingerOrZenMode(int streamType) {
6747         return (sRingerAndZenModeMutedStreams & (1 << streamType)) != 0;
6748     }
6749 
6750     /**
6751      * Notifications, ringer and system sounds are controlled by the ringer:
6752      * {@link ZenModeHelper.RingerModeDelegate#getRingerModeAffectedStreams(int)} but can
6753      * also be muted by DND based on the DND mode:
6754      * DND total silence: media and alarms streams can be muted by DND
6755      * DND alarms only: no streams additionally controlled by DND
6756      * DND priority only: alarms, media, system, ringer and notification streams can be muted by
6757      * DND.  The current applied zenPolicy determines which streams will be muted by DND.
6758      * @return true if changed, else false
6759      */
updateZenModeAffectedStreams()6760     private boolean updateZenModeAffectedStreams() {
6761         if (!mSystemReady) {
6762             return false;
6763         }
6764 
6765         int zenModeAffectedStreams = 0;
6766         final int zenMode = mNm.getZenMode();
6767 
6768         if (zenMode == Settings.Global.ZEN_MODE_NO_INTERRUPTIONS) {
6769             zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM;
6770             zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC;
6771         } else if (zenMode == Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
6772             NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy();
6773             if ((zenPolicy.priorityCategories
6774                     & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0) {
6775                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM;
6776             }
6777 
6778             if ((zenPolicy.priorityCategories
6779                     & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0) {
6780                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC;
6781             }
6782 
6783             // even if zen isn't muting the system stream, the ringer mode can still mute
6784             // the system stream
6785             if ((zenPolicy.priorityCategories
6786                     & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0) {
6787                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM;
6788             }
6789 
6790             if (ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(zenPolicy)) {
6791                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION;
6792                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING;
6793             }
6794         }
6795 
6796         if (mZenModeAffectedStreams != zenModeAffectedStreams) {
6797             mZenModeAffectedStreams = zenModeAffectedStreams;
6798             return true;
6799         }
6800 
6801         return false;
6802     }
6803 
6804     @GuardedBy("mSettingsLock")
updateRingerAndZenModeAffectedStreams()6805     private boolean updateRingerAndZenModeAffectedStreams() {
6806         boolean updatedZenModeAffectedStreams = updateZenModeAffectedStreams();
6807         int ringerModeAffectedStreams = mSettings.getSystemIntForUser(mContentResolver,
6808                 Settings.System.MODE_RINGER_STREAMS_AFFECTED,
6809                 ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
6810                  (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)),
6811                  UserHandle.USER_CURRENT);
6812 
6813         if (mIsSingleVolume) {
6814             ringerModeAffectedStreams = 0;
6815         } else if (mRingerModeDelegate != null) {
6816             ringerModeAffectedStreams = mRingerModeDelegate
6817                     .getRingerModeAffectedStreams(ringerModeAffectedStreams);
6818         }
6819         if (mCameraSoundForced) {
6820             ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
6821         } else {
6822             ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
6823         }
6824         if (mStreamVolumeAlias[AudioSystem.STREAM_DTMF] == AudioSystem.STREAM_RING) {
6825             ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF);
6826         } else {
6827             ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF);
6828         }
6829 
6830         if (ringerModeAffectedStreams != mRingerModeAffectedStreams) {
6831             mSettings.putSystemIntForUser(mContentResolver,
6832                     Settings.System.MODE_RINGER_STREAMS_AFFECTED,
6833                     ringerModeAffectedStreams,
6834                     UserHandle.USER_CURRENT);
6835             mRingerModeAffectedStreams = ringerModeAffectedStreams;
6836             return true;
6837         }
6838         return updatedZenModeAffectedStreams;
6839     }
6840 
6841     @Override
isStreamAffectedByMute(int streamType)6842     public boolean isStreamAffectedByMute(int streamType) {
6843         return (mMuteAffectedStreams & (1 << streamType)) != 0;
6844     }
6845 
ensureValidDirection(int direction)6846     private void ensureValidDirection(int direction) {
6847         switch (direction) {
6848             case AudioManager.ADJUST_LOWER:
6849             case AudioManager.ADJUST_RAISE:
6850             case AudioManager.ADJUST_SAME:
6851             case AudioManager.ADJUST_MUTE:
6852             case AudioManager.ADJUST_UNMUTE:
6853             case AudioManager.ADJUST_TOGGLE_MUTE:
6854                 break;
6855             default:
6856                 throw new IllegalArgumentException("Bad direction " + direction);
6857         }
6858     }
6859 
ensureValidStreamType(int streamType)6860     private void ensureValidStreamType(int streamType) {
6861         if (streamType < 0 || streamType >= mStreamStates.length) {
6862             throw new IllegalArgumentException("Bad stream type " + streamType);
6863         }
6864     }
6865 
isMuteAdjust(int adjust)6866     private boolean isMuteAdjust(int adjust) {
6867         return adjust == AudioManager.ADJUST_MUTE || adjust == AudioManager.ADJUST_UNMUTE
6868                 || adjust == AudioManager.ADJUST_TOGGLE_MUTE;
6869     }
6870 
6871     /** only public for mocking/spying, do not call outside of AudioService */
6872     @VisibleForTesting
isInCommunication()6873     public boolean isInCommunication() {
6874         boolean IsInCall = false;
6875 
6876         TelecomManager telecomManager =
6877                 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
6878 
6879         final long ident = Binder.clearCallingIdentity();
6880         try {
6881             IsInCall = telecomManager.isInCall();
6882         } finally {
6883             Binder.restoreCallingIdentity(ident);
6884         }
6885 
6886         int mode = mMode.get();
6887         return (IsInCall
6888                 || mode == AudioManager.MODE_IN_COMMUNICATION
6889                 || mode == AudioManager.MODE_IN_CALL);
6890     }
6891 
6892     /**
6893      * For code clarity for getActiveStreamType(int)
6894      * @param delay_ms max time since last stream activity to consider
6895      * @return true if stream is active in streams handled by AudioFlinger now or
6896      *     in the last "delay_ms" ms.
6897      */
wasStreamActiveRecently(int stream, int delay_ms)6898     private boolean wasStreamActiveRecently(int stream, int delay_ms) {
6899         return mAudioSystem.isStreamActive(stream, delay_ms)
6900                 || mAudioSystem.isStreamActiveRemotely(stream, delay_ms);
6901     }
6902 
getActiveStreamType(int suggestedStreamType)6903     private int getActiveStreamType(int suggestedStreamType) {
6904         if (mIsSingleVolume
6905                 && suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
6906             return AudioSystem.STREAM_MUSIC;
6907         }
6908 
6909         switch (mPlatformType) {
6910         case AudioSystem.PLATFORM_VOICE:
6911             if (isInCommunication()) {
6912                 if (mDeviceBroker.isBluetoothScoActive()) {
6913                     // Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO...");
6914                     return AudioSystem.STREAM_BLUETOOTH_SCO;
6915                 } else {
6916                     // Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL...");
6917                     return AudioSystem.STREAM_VOICE_CALL;
6918                 }
6919             } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
6920                 if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
6921                     if (DEBUG_VOL)
6922                         Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active");
6923                     return AudioSystem.STREAM_RING;
6924                 } else if (wasStreamActiveRecently(
6925                         AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
6926                         if (DEBUG_VOL) {
6927                             Log.v(
6928                                     TAG,
6929                                     "getActiveStreamType: Forcing STREAM_NOTIFICATION stream"
6930                                             + " active");
6931                         }
6932                         return AudioSystem.STREAM_NOTIFICATION;
6933                 } else {
6934                     if (DEBUG_VOL) {
6935                         Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK("
6936                                 + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default");
6937                     }
6938                     return DEFAULT_VOL_STREAM_NO_PLAYBACK;
6939                 }
6940             } else if (
6941                     wasStreamActiveRecently(AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
6942                 if (DEBUG_VOL)
6943                     Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION stream active");
6944                 return AudioSystem.STREAM_NOTIFICATION;
6945             } else if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
6946                 if (DEBUG_VOL)
6947                     Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active");
6948                 return AudioSystem.STREAM_RING;
6949             }
6950         default:
6951             if (isInCommunication()) {
6952                 if (mDeviceBroker.isBluetoothScoActive()) {
6953                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO");
6954                     return AudioSystem.STREAM_BLUETOOTH_SCO;
6955                 } else {
6956                     if (DEBUG_VOL)  Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL");
6957                     return AudioSystem.STREAM_VOICE_CALL;
6958                 }
6959             } else if (mAudioSystem.isStreamActive(
6960                     AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
6961                 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION");
6962                 return AudioSystem.STREAM_NOTIFICATION;
6963             } else if (mAudioSystem.isStreamActive(
6964                     AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
6965                 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING");
6966                 return AudioSystem.STREAM_RING;
6967             } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
6968                 if (mAudioSystem.isStreamActive(
6969                         AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
6970                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION");
6971                     return AudioSystem.STREAM_NOTIFICATION;
6972                 }
6973                 if (mAudioSystem.isStreamActive(
6974                         AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
6975                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING");
6976                     return AudioSystem.STREAM_RING;
6977                 }
6978                 if (DEBUG_VOL) {
6979                     Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK("
6980                             + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default");
6981                 }
6982                 return DEFAULT_VOL_STREAM_NO_PLAYBACK;
6983             }
6984             break;
6985         }
6986         if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Returning suggested type "
6987                 + suggestedStreamType);
6988         return suggestedStreamType;
6989     }
6990 
broadcastRingerMode(String action, int ringerMode)6991     private void broadcastRingerMode(String action, int ringerMode) {
6992         if (!mSystemServer.isPrivileged()) {
6993             return;
6994         }
6995         // Send sticky broadcast
6996         Intent broadcast = new Intent(action);
6997         broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, ringerMode);
6998         broadcast.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
6999                 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
7000         sendStickyBroadcastToAll(broadcast);
7001     }
7002 
broadcastVibrateSetting(int vibrateType)7003     private void broadcastVibrateSetting(int vibrateType) {
7004         if (!mSystemServer.isPrivileged()) {
7005             return;
7006         }
7007         // Send broadcast
7008         if (mActivityManagerInternal.isSystemReady()) {
7009             Intent broadcast = new Intent(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
7010             broadcast.putExtra(AudioManager.EXTRA_VIBRATE_TYPE, vibrateType);
7011             broadcast.putExtra(AudioManager.EXTRA_VIBRATE_SETTING, getVibrateSetting(vibrateType));
7012             sendBroadcastToAll(broadcast, null /* options */);
7013         }
7014     }
7015 
7016     // Message helper methods
7017     /**
7018      * Queue a message on the given handler's message queue, after acquiring the service wake lock.
7019      * Note that the wake lock needs to be released after the message has been handled.
7020      */
queueMsgUnderWakeLock(Handler handler, int msg, int arg1, int arg2, Object obj, int delay)7021     private void queueMsgUnderWakeLock(Handler handler, int msg,
7022             int arg1, int arg2, Object obj, int delay) {
7023         final long ident = Binder.clearCallingIdentity();
7024         try {
7025             // Always acquire the wake lock as AudioService because it is released by the
7026             // message handler.
7027             mAudioEventWakeLock.acquire();
7028         } finally {
7029             Binder.restoreCallingIdentity(ident);
7030         }
7031         sendMsg(handler, msg, SENDMSG_QUEUE, arg1, arg2, obj, delay);
7032     }
7033 
sendMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, int delay)7034     private static void sendMsg(Handler handler, int msg,
7035             int existingMsgPolicy, int arg1, int arg2, Object obj, int delay) {
7036         if (existingMsgPolicy == SENDMSG_REPLACE) {
7037             handler.removeMessages(msg);
7038         } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) {
7039             return;
7040         }
7041 
7042         final long time = SystemClock.uptimeMillis() + delay;
7043         handler.sendMessageAtTime(handler.obtainMessage(msg, arg1, arg2, obj), time);
7044     }
7045 
sendBundleMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, Bundle bundle, int delay)7046     private static void sendBundleMsg(Handler handler, int msg,
7047             int existingMsgPolicy, int arg1, int arg2, Object obj, Bundle bundle, int delay) {
7048         if (existingMsgPolicy == SENDMSG_REPLACE) {
7049             handler.removeMessages(msg);
7050         } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) {
7051             return;
7052         }
7053 
7054         final long time = SystemClock.uptimeMillis() + delay;
7055         Message message = handler.obtainMessage(msg, arg1, arg2, obj);
7056         message.setData(bundle);
7057         handler.sendMessageAtTime(message, time);
7058     }
7059 
checkAudioSettingsPermission(String method)7060     boolean checkAudioSettingsPermission(String method) {
7061         if (callingOrSelfHasAudioSettingsPermission()) {
7062             return true;
7063         }
7064         String msg = "Audio Settings Permission Denial: " + method + " from pid="
7065                 + Binder.getCallingPid()
7066                 + ", uid=" + Binder.getCallingUid();
7067         Log.w(TAG, msg);
7068         return false;
7069     }
7070 
callingOrSelfHasAudioSettingsPermission()7071     private boolean callingOrSelfHasAudioSettingsPermission() {
7072         return mContext.checkCallingOrSelfPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS)
7073                 == PackageManager.PERMISSION_GRANTED;
7074     }
7075 
callingHasAudioSettingsPermission()7076     private boolean callingHasAudioSettingsPermission() {
7077         return mContext.checkCallingPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS)
7078                 == PackageManager.PERMISSION_GRANTED;
7079     }
7080 
hasAudioSettingsPermission(int uid, int pid)7081     private boolean hasAudioSettingsPermission(int uid, int pid) {
7082         return mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid)
7083                 == PackageManager.PERMISSION_GRANTED;
7084     }
7085 
7086     /**
7087      * Minimum attenuation that can be set for alarms over speaker by an application that
7088      * doesn't have the MODIFY_AUDIO_SETTINGS permission.
7089      */
7090     protected static final float MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB = -36.0f;
7091 
7092     /**
7093      * Configures the VolumeStreamState instances for minimum stream index that can be accessed
7094      * without MODIFY_AUDIO_SETTINGS permission.
7095      * Can only be done successfully once audio policy has finished reading its configuration files
7096      * for the volume curves. If not, getStreamVolumeDB will return NaN, and the min value will
7097      * remain at the stream min index value.
7098      */
initMinStreamVolumeWithoutModifyAudioSettings()7099     protected void initMinStreamVolumeWithoutModifyAudioSettings() {
7100         int idx;
7101         int deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER_SAFE;
7102         if (Float.isNaN(AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM,
7103                 MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM], deviceForAlarm))) {
7104             deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER;
7105         }
7106         for (idx = MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM];
7107                 idx >= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]; idx--) {
7108             if (AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM, idx, deviceForAlarm)
7109                     < MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB) {
7110                 break;
7111             }
7112         }
7113         final int safeIndex = idx <= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]
7114                 ? MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]
7115                 : Math.min(idx + 1, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]);
7116         // update the VolumeStreamState for STREAM_ALARM and its aliases
7117         for (int stream : mStreamVolumeAlias) {
7118             if (mStreamVolumeAlias[stream] == AudioSystem.STREAM_ALARM) {
7119                 mStreamStates[stream].updateNoPermMinIndex(safeIndex);
7120             }
7121         }
7122     }
7123 
7124     /**
7125      * Returns device associated with the stream volume.
7126      *
7127      * Only public for mocking/spying, do not call outside of AudioService.
7128      * Device volume aliasing means DEVICE_OUT_SPEAKER may be returned for
7129      * DEVICE_OUT_SPEAKER_SAFE.
7130      */
7131     @VisibleForTesting
getDeviceForStream(int stream)7132     public int getDeviceForStream(int stream) {
7133         return selectOneAudioDevice(getDeviceSetForStream(stream));
7134     }
7135 
7136     /*
7137      * Must match native apm_extract_one_audio_device() used in getDeviceForVolume()
7138      * or the wrong device volume may be adjusted.
7139      */
selectOneAudioDevice(Set<Integer> deviceSet)7140     private int selectOneAudioDevice(Set<Integer> deviceSet) {
7141         if (deviceSet.isEmpty()) {
7142             return AudioSystem.DEVICE_NONE;
7143         } else if (deviceSet.size() == 1) {
7144             return deviceSet.iterator().next();
7145         } else {
7146             // Multiple device selection is either:
7147             //  - dock + one other device: give priority to dock in this case.
7148             //  - speaker + one other device: give priority to speaker in this case.
7149             //  - one A2DP device + another device: happens with duplicated output. In this case
7150             // retain the device on the A2DP output as the other must not correspond to an active
7151             // selection if not the speaker.
7152             //  - HDMI-CEC system audio mode only output: give priority to available item in order.
7153 
7154             if (deviceSet.contains(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET)) {
7155                 return AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET;
7156             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPEAKER)) {
7157                 return AudioSystem.DEVICE_OUT_SPEAKER;
7158             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPEAKER_SAFE)) {
7159                 // Note: DEVICE_OUT_SPEAKER_SAFE not present in getDeviceSetForStreamDirect
7160                 return AudioSystem.DEVICE_OUT_SPEAKER_SAFE;
7161             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_HDMI_ARC)) {
7162                 return AudioSystem.DEVICE_OUT_HDMI_ARC;
7163             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_HDMI_EARC)) {
7164                 return AudioSystem.DEVICE_OUT_HDMI_EARC;
7165             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_AUX_LINE)) {
7166                 return AudioSystem.DEVICE_OUT_AUX_LINE;
7167             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPDIF)) {
7168                 return AudioSystem.DEVICE_OUT_SPDIF;
7169             } else {
7170                 // At this point, deviceSet should contain exactly one A2DP device;
7171                 // regardless, return the first A2DP device in numeric order.
7172                 // If there is no A2DP device, this falls through to log an error.
7173                 for (int deviceType : deviceSet) {
7174                     if (AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(deviceType)) {
7175                         return deviceType;
7176                     }
7177                 }
7178             }
7179         }
7180         Log.w(TAG, "selectOneAudioDevice returning DEVICE_NONE from invalid device combination "
7181                 + AudioSystem.deviceSetToString(deviceSet));
7182         return AudioSystem.DEVICE_NONE;
7183     }
7184 
7185     /**
7186      * @see AudioManager#getDevicesForStream(int)
7187      * @deprecated on {@link android.os.Build.VERSION_CODES#T} as new devices
7188      *              will have multi-bit device types since S.
7189      *              Use {@link #getDevicesForAttributes()} instead.
7190      */
7191     @Override
7192     @Deprecated
getDeviceMaskForStream(int streamType)7193     public int getDeviceMaskForStream(int streamType) {
7194         ensureValidStreamType(streamType);
7195         // no permission required
7196         final long token = Binder.clearCallingIdentity();
7197         try {
7198             return AudioSystem.getDeviceMaskFromSet(
7199                     getDeviceSetForStreamDirect(streamType));
7200         } finally {
7201             Binder.restoreCallingIdentity(token);
7202         }
7203     }
7204 
7205     /**
7206      * Returns the devices associated with a stream type.
7207      *
7208      * SPEAKER_SAFE will alias to SPEAKER.
7209      */
7210     @NonNull
getDeviceSetForStreamDirect(int stream)7211     private Set<Integer> getDeviceSetForStreamDirect(int stream) {
7212         final AudioAttributes attr =
7213                 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream);
7214         Set<Integer> deviceSet =
7215                 AudioSystem.generateAudioDeviceTypesSet(
7216                         getDevicesForAttributesInt(attr, true /* forVolume */));
7217         return deviceSet;
7218     }
7219 
7220     /**
7221      * Returns a reference to the list of devices for the stream, do not modify.
7222      *
7223      * The device returned may be aliased to the actual device whose volume curve
7224      * will be used.  For example DEVICE_OUT_SPEAKER_SAFE aliases to DEVICE_OUT_SPEAKER.
7225      */
7226     @NonNull
getDeviceSetForStream(int stream)7227     public Set<Integer> getDeviceSetForStream(int stream) {
7228         ensureValidStreamType(stream);
7229         synchronized (VolumeStreamState.class) {
7230             return mStreamStates[stream].observeDevicesForStream_syncVSS(true);
7231         }
7232     }
7233 
onObserveDevicesForAllStreams(int skipStream)7234     private void onObserveDevicesForAllStreams(int skipStream) {
7235         synchronized (mSettingsLock) {
7236             synchronized (VolumeStreamState.class) {
7237                 for (int stream = 0; stream < mStreamStates.length; stream++) {
7238                     if (stream != skipStream) {
7239                         Set<Integer> deviceSet =
7240                                 mStreamStates[stream].observeDevicesForStream_syncVSS(
7241                                         false /*checkOthers*/);
7242                         for (Integer device : deviceSet) {
7243                             // Update volume states for devices routed for the stream
7244                             updateVolumeStates(device, stream,
7245                                     "AudioService#onObserveDevicesForAllStreams");
7246                         }
7247                     }
7248                 }
7249             }
7250         }
7251     }
7252 
7253     /** only public for mocking/spying, do not call outside of AudioService */
7254     @VisibleForTesting
postObserveDevicesForAllStreams()7255     public void postObserveDevicesForAllStreams() {
7256         postObserveDevicesForAllStreams(-1);
7257     }
7258 
7259     /** only public for mocking/spying, do not call outside of AudioService */
7260     @VisibleForTesting
postObserveDevicesForAllStreams(int skipStream)7261     public void postObserveDevicesForAllStreams(int skipStream) {
7262         sendMsg(mAudioHandler,
7263                 MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS,
7264                 SENDMSG_QUEUE, skipStream /*arg1*/, 0 /*arg2*/, null /*obj*/,
7265                 0 /*delay*/);
7266     }
7267 
7268     /**
7269      * @see AudioDeviceVolumeManager#setDeviceAbsoluteMultiVolumeBehavior
7270      *
7271      * @param register Whether the listener is to be registered or unregistered. If false, the
7272      *                 device adopts variable volume behavior.
7273      */
7274     @RequiresPermission(anyOf = { android.Manifest.permission.MODIFY_AUDIO_ROUTING,
7275             android.Manifest.permission.BLUETOOTH_PRIVILEGED })
registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register, IAudioDeviceVolumeDispatcher cb, String packageName, AudioDeviceAttributes device, List<VolumeInfo> volumes, boolean handlesVolumeAdjustment, @AudioManager.AbsoluteDeviceVolumeBehavior int deviceVolumeBehavior)7276     public void registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register,
7277             IAudioDeviceVolumeDispatcher cb, String packageName,
7278             AudioDeviceAttributes device, List<VolumeInfo> volumes,
7279             boolean handlesVolumeAdjustment,
7280             @AudioManager.AbsoluteDeviceVolumeBehavior int deviceVolumeBehavior) {
7281         // verify permissions
7282         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
7283                 != PackageManager.PERMISSION_GRANTED
7284                 && mContext.checkCallingOrSelfPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
7285                 != PackageManager.PERMISSION_GRANTED) {
7286             throw new SecurityException(
7287                     "Missing MODIFY_AUDIO_ROUTING or BLUETOOTH_PRIVILEGED permissions");
7288         }
7289         // verify arguments
7290         Objects.requireNonNull(device);
7291         Objects.requireNonNull(volumes);
7292 
7293         int deviceOut = device.getInternalType();
7294         if (register) {
7295             AbsoluteVolumeDeviceInfo info = new AbsoluteVolumeDeviceInfo(
7296                     device, volumes, cb, handlesVolumeAdjustment, deviceVolumeBehavior);
7297             AbsoluteVolumeDeviceInfo oldInfo = mAbsoluteVolumeDeviceInfoMap.get(deviceOut);
7298             boolean volumeBehaviorChanged = (oldInfo == null)
7299                     || (oldInfo.mDeviceVolumeBehavior != deviceVolumeBehavior);
7300             if (volumeBehaviorChanged) {
7301                 removeAudioSystemDeviceOutFromFullVolumeDevices(deviceOut);
7302                 removeAudioSystemDeviceOutFromFixedVolumeDevices(deviceOut);
7303                 addAudioSystemDeviceOutToAbsVolumeDevices(deviceOut, info);
7304 
7305                 dispatchDeviceVolumeBehavior(device, deviceVolumeBehavior);
7306             }
7307             // Update stream volumes to the given device, if specified in a VolumeInfo.
7308             // Mute state is not updated because it is stream-wide - the only way to mute a
7309             // stream's output to a particular device is to set the volume index to zero.
7310             for (VolumeInfo volumeInfo : volumes) {
7311                 if (volumeInfo.getVolumeIndex() != VolumeInfo.INDEX_NOT_SET
7312                         && volumeInfo.getMinVolumeIndex() != VolumeInfo.INDEX_NOT_SET
7313                         && volumeInfo.getMaxVolumeIndex() != VolumeInfo.INDEX_NOT_SET) {
7314                     if (volumeInfo.hasStreamType()) {
7315                         setStreamVolumeInt(volumeInfo.getStreamType(),
7316                                 rescaleIndex(volumeInfo, volumeInfo.getStreamType()),
7317                                 deviceOut, false /*force*/, packageName,
7318                                 true /*hasModifyAudioSettings*/);
7319                     } else {
7320                         for (int streamType : volumeInfo.getVolumeGroup().getLegacyStreamTypes()) {
7321                             setStreamVolumeInt(streamType, rescaleIndex(volumeInfo, streamType),
7322                                     deviceOut, false /*force*/, packageName,
7323                                     true /*hasModifyAudioSettings*/);
7324                         }
7325                     }
7326                 }
7327             }
7328         } else {
7329             boolean wasAbsVol = removeAudioSystemDeviceOutFromAbsVolumeDevices(deviceOut) != null;
7330             if (wasAbsVol) {
7331                 dispatchDeviceVolumeBehavior(device, AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE);
7332             }
7333         }
7334     }
7335 
7336     /**
7337      * @see AudioManager#setDeviceVolumeBehavior(AudioDeviceAttributes, int)
7338      * @param device the audio device to be affected
7339      * @param deviceVolumeBehavior one of the device behaviors
7340      */
7341     @android.annotation.EnforcePermission(anyOf = {
7342             android.Manifest.permission.MODIFY_AUDIO_ROUTING,
7343             android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED
7344     })
setDeviceVolumeBehavior(@onNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName)7345     public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
7346             @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName) {
7347         // verify permissions
7348         super.setDeviceVolumeBehavior_enforcePermission();
7349         // verify arguments
7350         Objects.requireNonNull(device);
7351         AudioManager.enforceValidVolumeBehavior(deviceVolumeBehavior);
7352 
7353         device = retrieveBluetoothAddress(device);
7354 
7355         sVolumeLogger.enqueue(new EventLogger.StringEvent("setDeviceVolumeBehavior: dev:"
7356                 + AudioSystem.getOutputDeviceName(device.getInternalType()) + " addr:"
7357                 + device.getAddress() + " behavior:"
7358                 + AudioDeviceVolumeManager.volumeBehaviorName(deviceVolumeBehavior)
7359                 + " pack:" + pkgName).printLog(TAG));
7360         if (pkgName == null) {
7361             pkgName = "";
7362         }
7363         if (device.getType() == TYPE_BLUETOOTH_A2DP) {
7364             avrcpSupportsAbsoluteVolume(device.getAddress(),
7365                     deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
7366             return;
7367         }
7368 
7369         setDeviceVolumeBehaviorInternal(device, deviceVolumeBehavior, pkgName);
7370         persistDeviceVolumeBehavior(device.getInternalType(), deviceVolumeBehavior);
7371     }
7372 
setDeviceVolumeBehaviorInternal(@onNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller)7373     private void setDeviceVolumeBehaviorInternal(@NonNull AudioDeviceAttributes device,
7374             @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller) {
7375         int audioSystemDeviceOut = device.getInternalType();
7376         boolean volumeBehaviorChanged = false;
7377         // update device masks based on volume behavior
7378         switch (deviceVolumeBehavior) {
7379             case AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE:
7380                 volumeBehaviorChanged |=
7381                         removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut)
7382                         | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut)
7383                         | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut)
7384                                 != null);
7385                 break;
7386             case AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED:
7387                 volumeBehaviorChanged |=
7388                         removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut)
7389                         | addAudioSystemDeviceOutToFixedVolumeDevices(audioSystemDeviceOut)
7390                         | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut)
7391                                 != null);
7392                 break;
7393             case AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL:
7394                 volumeBehaviorChanged |=
7395                         addAudioSystemDeviceOutToFullVolumeDevices(audioSystemDeviceOut)
7396                         | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut)
7397                         | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut)
7398                                 != null);
7399                 break;
7400             case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE:
7401             case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY:
7402             case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE:
7403                 throw new IllegalArgumentException("Absolute volume unsupported for now");
7404         }
7405 
7406         if (volumeBehaviorChanged) {
7407             sendMsg(mAudioHandler, MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR, SENDMSG_QUEUE,
7408                     deviceVolumeBehavior, 0, device, /*delay*/ 0);
7409         }
7410 
7411         // log event and caller
7412         sDeviceLogger.enqueue(new EventLogger.StringEvent(
7413                 "Volume behavior " + deviceVolumeBehavior + " for dev=0x"
7414                       + Integer.toHexString(audioSystemDeviceOut) + " from:" + caller));
7415         // make sure we have a volume entry for this device, and that volume is updated according
7416         // to volume behavior
7417         postUpdateVolumeStatesForAudioDevice(audioSystemDeviceOut,
7418                 "setDeviceVolumeBehavior:" + caller);
7419     }
7420 
7421     /**
7422      * @see AudioManager#getDeviceVolumeBehavior(AudioDeviceAttributes)
7423      * @param device the audio output device type
7424      * @return the volume behavior for the device
7425      */
7426     @android.annotation.EnforcePermission(anyOf = {
7427             android.Manifest.permission.MODIFY_AUDIO_ROUTING,
7428             android.Manifest.permission.QUERY_AUDIO_STATE,
7429             android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED
7430     })
7431     public @AudioManager.DeviceVolumeBehavior
getDeviceVolumeBehavior(@onNull AudioDeviceAttributes device)7432     int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
7433         // verify permissions
7434         super.getDeviceVolumeBehavior_enforcePermission();
7435         // verify parameters
7436         Objects.requireNonNull(device);
7437 
7438         device = retrieveBluetoothAddress(device);
7439 
7440         return getDeviceVolumeBehaviorInt(device);
7441     }
7442 
7443     private @AudioManager.DeviceVolumeBehavior
getDeviceVolumeBehaviorInt(@onNull AudioDeviceAttributes device)7444             int getDeviceVolumeBehaviorInt(@NonNull AudioDeviceAttributes device) {
7445         // Get the internal type set by the AudioDeviceAttributes constructor which is always more
7446         // exact (avoids double conversions) than a conversion from SDK type via
7447         // AudioDeviceInfo.convertDeviceTypeToInternalDevice()
7448         final int audioSystemDeviceOut = device.getInternalType();
7449 
7450         // setDeviceVolumeBehavior has not been explicitly called for the device type. Deduce the
7451         // current volume behavior.
7452         if (mFullVolumeDevices.contains(audioSystemDeviceOut)) {
7453             return AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL;
7454         }
7455         if (mFixedVolumeDevices.contains(audioSystemDeviceOut)) {
7456             return AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED;
7457         }
7458         if (mAbsVolumeMultiModeCaseDevices.contains(audioSystemDeviceOut)) {
7459             return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE;
7460         }
7461         if (mAbsoluteVolumeDeviceInfoMap.containsKey(audioSystemDeviceOut)) {
7462             return mAbsoluteVolumeDeviceInfoMap.get(audioSystemDeviceOut).mDeviceVolumeBehavior;
7463         }
7464 
7465         if (isA2dpAbsoluteVolumeDevice(audioSystemDeviceOut)
7466                 || AudioSystem.isLeAudioDeviceType(audioSystemDeviceOut)) {
7467             return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE;
7468         }
7469         return AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE;
7470     }
7471 
7472     /**
7473      * @see AudioManager#isVolumeFixed()
7474      * Note there are no permission checks on this operation, as this is part of API 21
7475      * @return true if the current device's volume behavior for media is
7476      *         DEVICE_VOLUME_BEHAVIOR_FIXED
7477      */
isVolumeFixed()7478     public boolean isVolumeFixed() {
7479         if (mUseFixedVolume) {
7480             return true;
7481         }
7482         final AudioAttributes attributes = new AudioAttributes.Builder()
7483                 .setUsage(AudioAttributes.USAGE_MEDIA)
7484                 .build();
7485         // calling getDevice*Int to bypass permission check
7486         final List<AudioDeviceAttributes> devices =
7487                 getDevicesForAttributesInt(attributes, true /* forVolume */);
7488         for (AudioDeviceAttributes device : devices) {
7489             if (getDeviceVolumeBehaviorInt(device) == AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED) {
7490                 return true;
7491             }
7492         }
7493         return false;
7494     }
7495 
7496     /*package*/ static final int CONNECTION_STATE_DISCONNECTED = 0;
7497     /*package*/ static final int CONNECTION_STATE_CONNECTED = 1;
7498     /**
7499      * The states that can be used with AudioService.setWiredDeviceConnectionState()
7500      * Attention: those values differ from those in BluetoothProfile, follow annotations to
7501      * distinguish between @ConnectionState and @BtProfileConnectionState
7502      */
7503     @IntDef({
7504             CONNECTION_STATE_DISCONNECTED,
7505             CONNECTION_STATE_CONNECTED,
7506     })
7507     @Retention(RetentionPolicy.SOURCE)
7508     public @interface ConnectionState {}
7509 
7510     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
7511     /**
7512      * see AudioManager.setWiredDeviceConnectionState()
7513      */
setWiredDeviceConnectionState(@onNull AudioDeviceAttributes attributes, @ConnectionState int state, String caller)7514     public void setWiredDeviceConnectionState(@NonNull AudioDeviceAttributes attributes,
7515             @ConnectionState int state, String caller) {
7516         super.setWiredDeviceConnectionState_enforcePermission();
7517         Objects.requireNonNull(attributes);
7518 
7519         attributes = retrieveBluetoothAddress(attributes);
7520 
7521         if (state != CONNECTION_STATE_CONNECTED
7522                 && state != CONNECTION_STATE_DISCONNECTED) {
7523             throw new IllegalArgumentException("Invalid state " + state);
7524         }
7525         new MediaMetrics.Item(mMetricsId + "setWiredDeviceConnectionState")
7526                 .set(MediaMetrics.Property.ADDRESS, attributes.getAddress())
7527                 .set(MediaMetrics.Property.CLIENT_NAME, caller)
7528                 .set(MediaMetrics.Property.DEVICE,
7529                         AudioSystem.getDeviceName(attributes.getInternalType()))
7530                 .set(MediaMetrics.Property.NAME, attributes.getName())
7531                 .set(MediaMetrics.Property.STATE,
7532                         state == CONNECTION_STATE_CONNECTED ? "connected" : "disconnected")
7533                 .record();
7534         mDeviceBroker.setWiredDeviceConnectionState(attributes, state, caller);
7535         // The Dynamic Soundbar mode feature introduces dynamic presence for an HDMI Audio System
7536         // Client. For example, the device can start with the Audio System Client unavailable.
7537         // When the feature is activated the client becomes available, therefore Audio Service
7538         // requests a new HDMI Audio System Client instance when the ARC status is changed.
7539         if (attributes.getInternalType() == AudioSystem.DEVICE_IN_HDMI_ARC) {
7540             updateHdmiAudioSystemClient();
7541         }
7542     }
7543 
7544     /**
7545      * Replace the current HDMI Audio System Client.
7546      * See {@link #setWiredDeviceConnectionState(AudioDeviceAttributes, int, String)}.
7547      */
updateHdmiAudioSystemClient()7548     private void updateHdmiAudioSystemClient() {
7549         Slog.d(TAG, "Hdmi Audio System Client is updated");
7550         synchronized (mHdmiClientLock) {
7551             mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient();
7552         }
7553     }
7554 
7555     /** @see AudioManager#setTestDeviceConnectionState(AudioDeviceAttributes, boolean) */
setTestDeviceConnectionState(@onNull AudioDeviceAttributes device, boolean connected)7556     public void setTestDeviceConnectionState(@NonNull AudioDeviceAttributes device,
7557             boolean connected) {
7558         Objects.requireNonNull(device);
7559         enforceModifyAudioRoutingPermission();
7560 
7561         device = retrieveBluetoothAddress(device);
7562 
7563         mDeviceBroker.setTestDeviceConnectionState(device,
7564                 connected ? CONNECTION_STATE_CONNECTED : CONNECTION_STATE_DISCONNECTED);
7565         // simulate a routing update from native
7566         sendMsg(mAudioHandler,
7567                 MSG_ROUTING_UPDATED,
7568                 SENDMSG_REPLACE, 0, 0, null,
7569                 /*delay*/ 0);
7570     }
7571 
7572     /**
7573      * @hide
7574      * The states that can be used with AudioService.setBluetoothHearingAidDeviceConnectionState()
7575      * and AudioService.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent()
7576      */
7577     @IntDef({
7578             BluetoothProfile.STATE_DISCONNECTED,
7579             BluetoothProfile.STATE_CONNECTED,
7580     })
7581     @Retention(RetentionPolicy.SOURCE)
7582     public @interface BtProfileConnectionState {}
7583 
7584     /**
7585      * @hide
7586      * The profiles that can be used with AudioService.handleBluetoothActiveDeviceChanged()
7587      */
7588     @IntDef({
7589             BluetoothProfile.HEARING_AID,
7590             BluetoothProfile.A2DP,
7591             BluetoothProfile.A2DP_SINK,
7592             BluetoothProfile.LE_AUDIO,
7593             BluetoothProfile.LE_AUDIO_BROADCAST,
7594     })
7595     @Retention(RetentionPolicy.SOURCE)
7596     public @interface BtProfile {}
7597 
7598 
7599     /**
7600      * See AudioManager.handleBluetoothActiveDeviceChanged(...)
7601      */
handleBluetoothActiveDeviceChanged(BluetoothDevice newDevice, BluetoothDevice previousDevice, @NonNull BluetoothProfileConnectionInfo info)7602     public void handleBluetoothActiveDeviceChanged(BluetoothDevice newDevice,
7603             BluetoothDevice previousDevice, @NonNull BluetoothProfileConnectionInfo info) {
7604         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.BLUETOOTH_STACK)
7605                 != PackageManager.PERMISSION_GRANTED) {
7606             throw new SecurityException("Bluetooth is the only caller allowed");
7607         }
7608         if (info == null) {
7609             throw new IllegalArgumentException("Illegal null BluetoothProfileConnectionInfo for"
7610                     + " device " + previousDevice + " -> " + newDevice);
7611         }
7612         final int profile = info.getProfile();
7613         if (profile != BluetoothProfile.A2DP && profile != BluetoothProfile.A2DP_SINK
7614                 && profile != BluetoothProfile.LE_AUDIO
7615                 && profile != BluetoothProfile.LE_AUDIO_BROADCAST
7616                 && profile != BluetoothProfile.HEARING_AID) {
7617             throw new IllegalArgumentException("Illegal BluetoothProfile profile for device "
7618                     + previousDevice + " -> " + newDevice + ". Got: " + profile);
7619         }
7620 
7621         sDeviceLogger.enqueue(new EventLogger.StringEvent("BlutoothActiveDeviceChanged for "
7622                 + BluetoothProfile.getProfileName(profile) + ", device update " + previousDevice
7623                 + " -> " + newDevice));
7624         AudioDeviceBroker.BtDeviceChangedData data =
7625                 new AudioDeviceBroker.BtDeviceChangedData(newDevice, previousDevice, info,
7626                         "AudioService");
7627         sendMsg(mAudioHandler, MSG_BT_DEV_CHANGED, SENDMSG_QUEUE, 0, 0,
7628                 /*obj*/ data, /*delay*/ 0);
7629     }
7630 
7631     /** only public for mocking/spying, do not call outside of AudioService */
7632     @VisibleForTesting
setMusicMute(boolean mute)7633     public void setMusicMute(boolean mute) {
7634         mStreamStates[AudioSystem.STREAM_MUSIC].muteInternally(mute);
7635     }
7636 
7637     private static final Set<Integer> DEVICE_MEDIA_UNMUTED_ON_PLUG_SET;
7638     static {
7639         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET = new HashSet<>();
7640         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADSET);
7641         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE);
7642         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_LINE);
7643         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_A2DP_SET);
7644         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_BLE_SET);
7645         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_USB_SET);
7646         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_HDMI);
7647     }
7648 
7649     /** only public for mocking/spying, do not call outside of AudioService */
7650     @VisibleForTesting
postAccessoryPlugMediaUnmute(int newDevice)7651     public void postAccessoryPlugMediaUnmute(int newDevice) {
7652         sendMsg(mAudioHandler, MSG_ACCESSORY_PLUG_MEDIA_UNMUTE, SENDMSG_QUEUE,
7653                 newDevice, 0, null, 0);
7654     }
7655 
onAccessoryPlugMediaUnmute(int newDevice)7656     private void onAccessoryPlugMediaUnmute(int newDevice) {
7657         if (DEBUG_VOL) {
7658             Log.i(TAG, String.format("onAccessoryPlugMediaUnmute newDevice=%d [%s]",
7659                     newDevice, AudioSystem.getOutputDeviceName(newDevice)));
7660         }
7661 
7662         if (mNm.getZenMode() != Settings.Global.ZEN_MODE_NO_INTERRUPTIONS
7663                 && !isStreamMutedByRingerOrZenMode(AudioSystem.STREAM_MUSIC)
7664                 && DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.contains(newDevice)
7665                 && mStreamStates[AudioSystem.STREAM_MUSIC].mIsMuted
7666                 && mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(newDevice) != 0
7667                 && getDeviceSetForStreamDirect(AudioSystem.STREAM_MUSIC).contains(newDevice)) {
7668             if (DEBUG_VOL) {
7669                 Log.i(TAG, String.format("onAccessoryPlugMediaUnmute unmuting device=%d [%s]",
7670                         newDevice, AudioSystem.getOutputDeviceName(newDevice)));
7671             }
7672             // Locking mSettingsLock to avoid inversion when calling vss.mute -> vss.doMute ->
7673             // vss.updateVolumeGroupIndex
7674             synchronized (mSettingsLock) {
7675                 mStreamStates[AudioSystem.STREAM_MUSIC].mute(false, "onAccessoryPlugMediaUnmute");
7676             }
7677         }
7678     }
7679 
7680     /**
7681      * See AudioManager.hasHapticChannels(Context, Uri).
7682      */
hasHapticChannels(Uri uri)7683     public boolean hasHapticChannels(Uri uri) {
7684         return AudioManager.hasHapticChannelsImpl(mContext, uri);
7685     }
7686 
7687     ///////////////////////////////////////////////////////////////////////////
7688     // Inner classes
7689     ///////////////////////////////////////////////////////////////////////////
7690     /**
7691      * Key is the AudioManager VolumeGroupId
7692      * Value is the VolumeGroupState
7693      */
7694     private static final SparseArray<VolumeGroupState> sVolumeGroupStates = new SparseArray<>();
7695 
initVolumeGroupStates()7696     private void initVolumeGroupStates() {
7697         for (final AudioVolumeGroup avg : getAudioVolumeGroups()) {
7698             try {
7699                 // if no valid attributes, this volume group is not controllable, throw exception
7700                 ensureValidAttributes(avg);
7701                 sVolumeGroupStates.append(avg.getId(), new VolumeGroupState(avg));
7702             } catch (IllegalArgumentException e) {
7703                 // Volume Groups without attributes are not controllable through set/get volume
7704                 // using attributes. Do not append them.
7705                 if (DEBUG_VOL) {
7706                     Log.d(TAG, "volume group " + avg.name() + " for internal policy needs");
7707                 }
7708                 continue;
7709             }
7710         }
7711 
7712         // need mSettingsLock for vgs.applyAllVolumes -> vss.setIndex which grabs this lock after
7713         // VSS.class. Locking order needs to be preserved
7714         synchronized (mSettingsLock) {
7715             for (int i = 0; i < sVolumeGroupStates.size(); i++) {
7716                 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
7717                 vgs.applyAllVolumes(/* userSwitch= */ false);
7718             }
7719         }
7720     }
7721 
ensureValidAttributes(AudioVolumeGroup avg)7722     private void ensureValidAttributes(AudioVolumeGroup avg) {
7723         boolean hasAtLeastOneValidAudioAttributes = avg.getAudioAttributes().stream()
7724                 .anyMatch(aa -> !aa.equals(AudioProductStrategy.getDefaultAttributes()));
7725         if (!hasAtLeastOneValidAudioAttributes) {
7726             throw new IllegalArgumentException("Volume Group " + avg.name()
7727                     + " has no valid audio attributes");
7728         }
7729     }
7730 
readVolumeGroupsSettings(boolean userSwitch)7731     private void readVolumeGroupsSettings(boolean userSwitch) {
7732         synchronized (mSettingsLock) {
7733             synchronized (VolumeStreamState.class) {
7734                 if (DEBUG_VOL) {
7735                     Log.d(TAG, "readVolumeGroupsSettings userSwitch=" + userSwitch);
7736                 }
7737                 for (int i = 0; i < sVolumeGroupStates.size(); i++) {
7738                     VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
7739                     // as for STREAM_MUSIC, preserve volume from one user to the next.
7740                     if (!(userSwitch && vgs.isMusic())) {
7741                         vgs.clearIndexCache();
7742                         vgs.readSettings();
7743                     }
7744                     vgs.applyAllVolumes(userSwitch);
7745                 }
7746             }
7747         }
7748     }
7749 
7750     // Called upon crash of AudioServer
restoreVolumeGroups()7751     private void restoreVolumeGroups() {
7752         if (DEBUG_VOL) {
7753             Log.v(TAG, "restoreVolumeGroups");
7754         }
7755 
7756         // need mSettingsLock for vgs.applyAllVolumes -> vss.setIndex which grabs this lock after
7757         // VSS.class. Locking order needs to be preserved
7758         synchronized (mSettingsLock) {
7759             for (int i = 0; i < sVolumeGroupStates.size(); i++) {
7760                 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
7761                 vgs.applyAllVolumes(false/*userSwitch*/);
7762             }
7763         }
7764     }
7765 
dumpVolumeGroups(PrintWriter pw)7766     private void dumpVolumeGroups(PrintWriter pw) {
7767         pw.println("\nVolume Groups (device: index)");
7768         for (int i = 0; i < sVolumeGroupStates.size(); i++) {
7769             final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
7770             vgs.dump(pw);
7771             pw.println("");
7772         }
7773     }
7774 
isCallStream(int stream)7775     private static boolean isCallStream(int stream) {
7776         return stream == AudioSystem.STREAM_VOICE_CALL
7777                 || stream == AudioSystem.STREAM_BLUETOOTH_SCO;
7778     }
7779 
getVolumeGroupForStreamType(int stream)7780     private static int getVolumeGroupForStreamType(int stream) {
7781         AudioAttributes attributes =
7782                 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream);
7783         if (attributes.equals(new AudioAttributes.Builder().build())) {
7784             return AudioVolumeGroup.DEFAULT_VOLUME_GROUP;
7785         }
7786         return AudioProductStrategy.getVolumeGroupIdForAudioAttributes(
7787                 attributes, /* fallbackOnDefault= */ false);
7788     }
7789 
7790     // NOTE: Locking order for synchronized objects related to volume management:
7791     //  1     mSettingsLock
7792     //  2       VolumeStreamState.class
7793     private class VolumeGroupState {
7794         private final AudioVolumeGroup mAudioVolumeGroup;
7795         private final SparseIntArray mIndexMap = new SparseIntArray(8);
7796         private int mIndexMin;
7797         private int mIndexMax;
7798         private boolean mHasValidStreamType = false;
7799         private int mPublicStreamType = AudioSystem.STREAM_MUSIC;
7800         private AudioAttributes mAudioAttributes = AudioProductStrategy.getDefaultAttributes();
7801         private boolean mIsMuted = false;
7802         private String mSettingName;
7803 
7804         // No API in AudioSystem to get a device from strategy or from attributes.
7805         // Need a valid public stream type to use current API getDeviceForStream
getDeviceForVolume()7806         private int getDeviceForVolume() {
7807             return getDeviceForStream(mPublicStreamType);
7808         }
7809 
VolumeGroupState(AudioVolumeGroup avg)7810         private VolumeGroupState(AudioVolumeGroup avg) {
7811             mAudioVolumeGroup = avg;
7812             if (DEBUG_VOL) {
7813                 Log.v(TAG, "VolumeGroupState for " + avg.toString());
7814             }
7815             // mAudioAttributes is the default at this point
7816             for (AudioAttributes aa : avg.getAudioAttributes()) {
7817                 if (!aa.equals(mAudioAttributes)) {
7818                     mAudioAttributes = aa;
7819                     break;
7820                 }
7821             }
7822             int[] streamTypes = mAudioVolumeGroup.getLegacyStreamTypes();
7823             String streamSettingName = "";
7824             if (streamTypes.length != 0) {
7825                 // Uses already initialized MIN / MAX if a stream type is attached to group
7826                 for (int streamType : streamTypes) {
7827                     if (streamType != AudioSystem.STREAM_DEFAULT
7828                             && streamType < AudioSystem.getNumStreamTypes()) {
7829                         mPublicStreamType = streamType;
7830                         mHasValidStreamType = true;
7831                         streamSettingName = System.VOLUME_SETTINGS_INT[mPublicStreamType];
7832                         break;
7833                     }
7834                 }
7835                 mIndexMin = MIN_STREAM_VOLUME[mPublicStreamType];
7836                 mIndexMax = MAX_STREAM_VOLUME[mPublicStreamType];
7837             } else if (!avg.getAudioAttributes().isEmpty()) {
7838                 mIndexMin = AudioSystem.getMinVolumeIndexForAttributes(mAudioAttributes);
7839                 mIndexMax = AudioSystem.getMaxVolumeIndexForAttributes(mAudioAttributes);
7840             } else {
7841                 throw new IllegalArgumentException("volume group: " + mAudioVolumeGroup.name()
7842                         + " has neither valid attributes nor valid stream types assigned");
7843             }
7844             mSettingName = !streamSettingName.isEmpty() ? streamSettingName : ("volume_" + name());
7845             // Load volume indexes from data base
7846             readSettings();
7847         }
7848 
getLegacyStreamTypes()7849         public @NonNull int[] getLegacyStreamTypes() {
7850             return mAudioVolumeGroup.getLegacyStreamTypes();
7851         }
7852 
name()7853         public String name() {
7854             return mAudioVolumeGroup.name();
7855         }
7856 
7857         /**
7858          * Volume group with non null minimum index are considered as non mutable, thus
7859          * bijectivity is broken with potential associated stream type.
7860          * VOICE_CALL stream has minVolumeIndex > 0  but can be muted directly by an
7861          * app that has MODIFY_PHONE_STATE permission.
7862          */
isVssMuteBijective(int stream)7863         private boolean isVssMuteBijective(int stream) {
7864             return isStreamAffectedByMute(stream)
7865                     && (getMinIndex() == (mStreamStates[stream].mIndexMin + 5) / 10)
7866                     && (getMinIndex() == 0 || isCallStream(stream));
7867         }
7868 
isMutable()7869         private boolean isMutable() {
7870             return mIndexMin == 0 || (mHasValidStreamType && isVssMuteBijective(mPublicStreamType));
7871         }
7872         /**
7873          * Mute/unmute the volume group
7874          * @param muted the new mute state
7875          */
7876         @GuardedBy("AudioService.VolumeStreamState.class")
mute(boolean muted)7877         public boolean mute(boolean muted) {
7878             if (!isMutable()) {
7879                 // Non mutable volume group
7880                 if (DEBUG_VOL) {
7881                     Log.d(TAG, "invalid mute on unmutable volume group " + name());
7882                 }
7883                 return false;
7884             }
7885             boolean changed = (mIsMuted != muted);
7886             // As for VSS, mute shall apply minIndex to all devices found in IndexMap and default.
7887             if (changed) {
7888                 mIsMuted = muted;
7889                 applyAllVolumes(false /*userSwitch*/);
7890             }
7891             return changed;
7892         }
7893 
isMuted()7894         public boolean isMuted() {
7895             return mIsMuted;
7896         }
7897 
adjustVolume(int direction, int flags)7898         public void adjustVolume(int direction, int flags) {
7899             synchronized (mSettingsLock) {
7900                 synchronized (AudioService.VolumeStreamState.class) {
7901                     int device = getDeviceForVolume();
7902                     int previousIndex = getIndex(device);
7903                     if (isMuteAdjust(direction) && !isMutable()) {
7904                         // Non mutable volume group
7905                         if (DEBUG_VOL) {
7906                             Log.d(TAG, "invalid mute on unmutable volume group " + name());
7907                         }
7908                         return;
7909                     }
7910                     switch (direction) {
7911                         case AudioManager.ADJUST_TOGGLE_MUTE: {
7912                             // Note: If muted by volume 0, unmute will restore volume 0.
7913                             mute(!mIsMuted);
7914                             break;
7915                         }
7916                         case AudioManager.ADJUST_UNMUTE:
7917                             // Note: If muted by volume 0, unmute will restore volume 0.
7918                             mute(false);
7919                             break;
7920                         case AudioManager.ADJUST_MUTE:
7921                             // May be already muted by setvolume 0, prevent from setting same value
7922                             if (previousIndex != 0) {
7923                                 // bypass persist
7924                                 mute(true);
7925                             }
7926                             mIsMuted = true;
7927                             break;
7928                         case AudioManager.ADJUST_RAISE:
7929                             // As for stream, RAISE during mute will increment the index
7930                             setVolumeIndex(Math.min(previousIndex + 1, mIndexMax),  device, flags);
7931                             break;
7932                         case AudioManager.ADJUST_LOWER:
7933                             // For stream, ADJUST_LOWER on a muted VSS is a no-op
7934                             // If we decide to unmute on ADJUST_LOWER, cannot fallback on
7935                             // adjustStreamVolume for group associated to legacy stream type
7936                             if (isMuted() && previousIndex != 0) {
7937                                 mute(false);
7938                             } else {
7939                                 int newIndex = Math.max(previousIndex - 1, mIndexMin);
7940                                 setVolumeIndex(newIndex, device, flags);
7941                             }
7942                             break;
7943                     }
7944                 }
7945             }
7946         }
7947 
getVolumeIndex()7948         public int getVolumeIndex() {
7949             synchronized (AudioService.VolumeStreamState.class) {
7950                 return getIndex(getDeviceForVolume());
7951             }
7952         }
7953 
setVolumeIndex(int index, int flags)7954         public void setVolumeIndex(int index, int flags) {
7955             synchronized (mSettingsLock) {
7956                 synchronized (AudioService.VolumeStreamState.class) {
7957                     if (mUseFixedVolume) {
7958                         return;
7959                     }
7960                     setVolumeIndex(index, getDeviceForVolume(), flags);
7961                 }
7962             }
7963         }
7964 
7965         @GuardedBy("AudioService.VolumeStreamState.class")
setVolumeIndex(int index, int device, int flags)7966         private void setVolumeIndex(int index, int device, int flags) {
7967             // Update cache & persist (muted by volume 0 shall be persisted)
7968             updateVolumeIndex(index, device);
7969             // setting non-zero volume for a muted stream unmutes the stream and vice versa,
7970             boolean changed = mute(index == 0);
7971             if (!changed) {
7972                 // Set the volume index only if mute operation is a no-op
7973                 index = getValidIndex(index);
7974                 setVolumeIndexInt(index, device, flags);
7975             }
7976         }
7977 
7978         @GuardedBy("AudioService.VolumeStreamState.class")
updateVolumeIndex(int index, int device)7979         public void updateVolumeIndex(int index, int device) {
7980             // Filter persistency if already exist and the index has not changed
7981             if (mIndexMap.indexOfKey(device) < 0 || mIndexMap.get(device) != index) {
7982                 // Update local cache
7983                 mIndexMap.put(device, getValidIndex(index));
7984 
7985                 // update data base - post a persist volume group msg
7986                 sendMsg(mAudioHandler,
7987                         MSG_PERSIST_VOLUME_GROUP,
7988                         SENDMSG_QUEUE,
7989                         device,
7990                         0,
7991                         this,
7992                         PERSIST_DELAY);
7993             }
7994         }
7995 
7996         @GuardedBy("AudioService.VolumeStreamState.class")
setVolumeIndexInt(int index, int device, int flags)7997         private void setVolumeIndexInt(int index, int device, int flags) {
7998             // Reflect mute state of corresponding stream by forcing index to 0 if muted
7999             // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted.
8000             // This allows RX path muting by the audio HAL only when explicitly muted but not when
8001             // index is just set to 0 to repect BT requirements
8002             if (mHasValidStreamType && isVssMuteBijective(mPublicStreamType)
8003                     && mStreamStates[mPublicStreamType].isFullyMuted()) {
8004                 index = 0;
8005             } else if (mPublicStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0) {
8006                 index = 1;
8007             }
8008             // Set the volume index
8009             AudioSystem.setVolumeIndexForAttributes(mAudioAttributes, index, device);
8010         }
8011 
8012         @GuardedBy("AudioService.VolumeStreamState.class")
getIndex(int device)8013         private int getIndex(int device) {
8014             int index = mIndexMap.get(device, -1);
8015             // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
8016             return (index != -1) ? index : mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT);
8017         }
8018 
8019         @GuardedBy("AudioService.VolumeStreamState.class")
hasIndexForDevice(int device)8020         private boolean hasIndexForDevice(int device) {
8021             return (mIndexMap.get(device, -1) != -1);
8022         }
8023 
getMaxIndex()8024         public int getMaxIndex() {
8025             return mIndexMax;
8026         }
8027 
getMinIndex()8028         public int getMinIndex() {
8029             return mIndexMin;
8030         }
8031 
isValidStream(int stream)8032         private boolean isValidStream(int stream) {
8033             return (stream != AudioSystem.STREAM_DEFAULT) && (stream < mStreamStates.length);
8034         }
8035 
isMusic()8036         public boolean isMusic() {
8037             return mHasValidStreamType && mPublicStreamType == AudioSystem.STREAM_MUSIC;
8038         }
8039 
applyAllVolumes(boolean userSwitch)8040         public void applyAllVolumes(boolean userSwitch) {
8041             String caller = "from vgs";
8042             synchronized (AudioService.VolumeStreamState.class) {
8043                 // apply device specific volumes first
8044                 for (int i = 0; i < mIndexMap.size(); i++) {
8045                     int device = mIndexMap.keyAt(i);
8046                     int index = mIndexMap.valueAt(i);
8047                     boolean synced = false;
8048                     if (device != AudioSystem.DEVICE_OUT_DEFAULT) {
8049                         for (int stream : getLegacyStreamTypes()) {
8050                             if (isValidStream(stream)) {
8051                                 boolean streamMuted = mStreamStates[stream].mIsMuted;
8052                                 int deviceForStream = getDeviceForStream(stream);
8053                                 int indexForStream =
8054                                         (mStreamStates[stream].getIndex(deviceForStream) + 5) / 10;
8055                                 if (device == deviceForStream) {
8056                                     if (indexForStream == index && (isMuted() == streamMuted)
8057                                             && isVssMuteBijective(stream)) {
8058                                         synced = true;
8059                                         continue;
8060                                     }
8061                                     if (indexForStream != index) {
8062                                         mStreamStates[stream].setIndex(index * 10, device, caller,
8063                                                 true /*hasModifyAudioSettings*/);
8064                                     }
8065                                     if ((isMuted() != streamMuted) && isVssMuteBijective(stream)) {
8066                                         mStreamStates[stream].mute(isMuted(),
8067                                                 "VGS.applyAllVolumes#1");
8068                                     }
8069                                 }
8070                             }
8071                         }
8072                         if (!synced) {
8073                             if (DEBUG_VOL) {
8074                                 Log.d(TAG, "applyAllVolumes: apply index " + index + ", group "
8075                                         + mAudioVolumeGroup.name() + " and device "
8076                                         + AudioSystem.getOutputDeviceName(device));
8077                             }
8078                             setVolumeIndexInt(isMuted() ? 0 : index, device, 0 /*flags*/);
8079                         }
8080                     }
8081                 }
8082                 // apply default volume last: by convention , default device volume will be used
8083                 // by audio policy manager if no explicit volume is present for a given device type
8084                 int index = getIndex(AudioSystem.DEVICE_OUT_DEFAULT);
8085                 boolean synced = false;
8086                 int deviceForVolume = getDeviceForVolume();
8087                 boolean forceDeviceSync = userSwitch && (mIndexMap.indexOfKey(deviceForVolume) < 0);
8088                 for (int stream : getLegacyStreamTypes()) {
8089                     if (isValidStream(stream)) {
8090                         boolean streamMuted = mStreamStates[stream].mIsMuted;
8091                         int defaultStreamIndex = (mStreamStates[stream].getIndex(
8092                                         AudioSystem.DEVICE_OUT_DEFAULT) + 5) / 10;
8093                         if (forceDeviceSync) {
8094                             mStreamStates[stream].setIndex(index * 10, deviceForVolume, caller,
8095                                     true /*hasModifyAudioSettings*/);
8096                         }
8097                         if (defaultStreamIndex == index && (isMuted() == streamMuted)
8098                                 && isVssMuteBijective(stream)) {
8099                             synced = true;
8100                             continue;
8101                         }
8102                         if (defaultStreamIndex != index) {
8103                             mStreamStates[stream].setIndex(
8104                                     index * 10, AudioSystem.DEVICE_OUT_DEFAULT, caller,
8105                                     true /*hasModifyAudioSettings*/);
8106                         }
8107                         if ((isMuted() != streamMuted) && isVssMuteBijective(stream)) {
8108                             mStreamStates[stream].mute(isMuted(), "VGS.applyAllVolumes#2");
8109                         }
8110                     }
8111                 }
8112                 if (!synced) {
8113                     if (DEBUG_VOL) {
8114                         Log.d(TAG, "applyAllVolumes: apply default device index " + index
8115                                 + ", group " + mAudioVolumeGroup.name());
8116                     }
8117                     setVolumeIndexInt(
8118                             isMuted() ? 0 : index, AudioSystem.DEVICE_OUT_DEFAULT, 0 /*flags*/);
8119                 }
8120                 if (forceDeviceSync) {
8121                     if (DEBUG_VOL) {
8122                         Log.d(TAG, "applyAllVolumes: forceDeviceSync index " + index
8123                                 + ", device " + AudioSystem.getOutputDeviceName(deviceForVolume)
8124                                 + ", group " + mAudioVolumeGroup.name());
8125                     }
8126                     setVolumeIndexInt(isMuted() ? 0 : index, deviceForVolume, 0);
8127                 }
8128             }
8129         }
8130 
clearIndexCache()8131         public void clearIndexCache() {
8132             mIndexMap.clear();
8133         }
8134 
persistVolumeGroup(int device)8135         private void persistVolumeGroup(int device) {
8136             // No need to persist the index if the volume group is backed up
8137             // by a public stream type as this is redundant
8138             if (mUseFixedVolume || mHasValidStreamType) {
8139                 return;
8140             }
8141             if (DEBUG_VOL) {
8142                 Log.v(TAG, "persistVolumeGroup: storing index " + getIndex(device) + " for group "
8143                         + mAudioVolumeGroup.name()
8144                         + ", device " + AudioSystem.getOutputDeviceName(device)
8145                         + " and User=" + getCurrentUserId()
8146                         + " mSettingName: " + mSettingName);
8147             }
8148 
8149             boolean success = mSettings.putSystemIntForUser(mContentResolver,
8150                     getSettingNameForDevice(device),
8151                     getIndex(device),
8152                     isMusic() ? UserHandle.USER_SYSTEM : UserHandle.USER_CURRENT);
8153             if (!success) {
8154                 Log.e(TAG, "persistVolumeGroup failed for group " +  mAudioVolumeGroup.name());
8155             }
8156         }
8157 
readSettings()8158         public void readSettings() {
8159             synchronized (AudioService.VolumeStreamState.class) {
8160                 // force maximum volume on all streams if fixed volume property is set
8161                 if (mUseFixedVolume) {
8162                     mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
8163                     return;
8164                 }
8165                 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
8166                     // retrieve current volume for device
8167                     // if no volume stored for current volume group and device, use default volume
8168                     // if default device, continue otherwise
8169                     int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT)
8170                             ? AudioSystem.DEFAULT_STREAM_VOLUME[mPublicStreamType] : -1;
8171                     int index;
8172                     String name = getSettingNameForDevice(device);
8173                     index = mSettings.getSystemIntForUser(
8174                             mContentResolver, name, defaultIndex,
8175                             isMusic() ? UserHandle.USER_SYSTEM : UserHandle.USER_CURRENT);
8176                     if (index == -1) {
8177                         continue;
8178                     }
8179                     if (mPublicStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED
8180                             && mCameraSoundForced) {
8181                         index = mIndexMax;
8182                     }
8183                     if (DEBUG_VOL) {
8184                         Log.v(TAG, "readSettings: found stored index " + getValidIndex(index)
8185                                  + " for group " + mAudioVolumeGroup.name() + ", device: " + name
8186                                  + ", User=" + getCurrentUserId());
8187                     }
8188                     mIndexMap.put(device, getValidIndex(index));
8189                 }
8190             }
8191         }
8192 
8193         @GuardedBy("AudioService.VolumeStreamState.class")
getValidIndex(int index)8194         private int getValidIndex(int index) {
8195             if (index < mIndexMin) {
8196                 return mIndexMin;
8197             } else if (mUseFixedVolume || index > mIndexMax) {
8198                 return mIndexMax;
8199             }
8200             return index;
8201         }
8202 
getSettingNameForDevice(int device)8203         public @NonNull String getSettingNameForDevice(int device) {
8204             String suffix = AudioSystem.getOutputDeviceName(device);
8205             if (suffix.isEmpty()) {
8206                 return mSettingName;
8207             }
8208             return mSettingName + "_" + AudioSystem.getOutputDeviceName(device);
8209         }
8210 
setSettingName(String settingName)8211         void setSettingName(String settingName) {
8212             mSettingName = settingName;
8213         }
8214 
getSettingName()8215         String getSettingName() {
8216             return mSettingName;
8217         }
8218 
dump(PrintWriter pw)8219         private void dump(PrintWriter pw) {
8220             pw.println("- VOLUME GROUP " + mAudioVolumeGroup.name() + ":");
8221             pw.print("   Muted: ");
8222             pw.println(mIsMuted);
8223             pw.print("   Min: ");
8224             pw.println(mIndexMin);
8225             pw.print("   Max: ");
8226             pw.println(mIndexMax);
8227             pw.print("   Current: ");
8228             for (int i = 0; i < mIndexMap.size(); i++) {
8229                 if (i > 0) {
8230                     pw.print(", ");
8231                 }
8232                 int device = mIndexMap.keyAt(i);
8233                 pw.print(Integer.toHexString(device));
8234                 String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
8235                         : AudioSystem.getOutputDeviceName(device);
8236                 if (!deviceName.isEmpty()) {
8237                     pw.print(" (");
8238                     pw.print(deviceName);
8239                     pw.print(")");
8240                 }
8241                 pw.print(": ");
8242                 pw.print(mIndexMap.valueAt(i));
8243             }
8244             pw.println();
8245             pw.print("   Devices: ");
8246             int n = 0;
8247             int devices = getDeviceForVolume();
8248             for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
8249                 if ((devices & device) == device) {
8250                     if (n++ > 0) {
8251                         pw.print(", ");
8252                     }
8253                     pw.print(AudioSystem.getOutputDeviceName(device));
8254                 }
8255             }
8256             pw.println();
8257             pw.print("   Streams: ");
8258             Arrays.stream(getLegacyStreamTypes())
8259                     .forEach(stream -> pw.print(AudioSystem.streamToString(stream) + " "));
8260         }
8261     }
8262 
8263 
8264     // NOTE: Locking order for synchronized objects related to volume or ringer mode management:
8265     //  1 mScoclient OR mSafeMediaVolumeState
8266     //  2   mSetModeLock
8267     //  3     mSettingsLock
8268     //  4       VolumeStreamState.class
8269     /*package*/ class VolumeStreamState {
8270         private final int mStreamType;
8271         private VolumeGroupState mVolumeGroupState = null;
8272         private int mIndexMin;
8273         // min index when user doesn't have permission to change audio settings
8274         private int mIndexMinNoPerm;
8275         private int mIndexMax;
8276 
8277         private boolean mIsMuted = false;
8278         private boolean mIsMutedInternally = false;
8279         private String mVolumeIndexSettingName;
8280         @NonNull private Set<Integer> mObservedDeviceSet = new TreeSet<>();
8281 
8282         private final SparseIntArray mIndexMap = new SparseIntArray(8) {
8283             @Override
8284             public void put(int key, int value) {
8285                 super.put(key, value);
8286                 record("put", key, value);
8287             }
8288             @Override
8289             public void setValueAt(int index, int value) {
8290                 super.setValueAt(index, value);
8291                 record("setValueAt", keyAt(index), value);
8292             }
8293 
8294             // Record all changes in the VolumeStreamState
8295             private void record(String event, int key, int value) {
8296                 final String device = key == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
8297                         : AudioSystem.getOutputDeviceName(key);
8298                 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_VOLUME + MediaMetrics.SEPARATOR
8299                         + AudioSystem.streamToString(mStreamType)
8300                         + "." + device)
8301                         .set(MediaMetrics.Property.EVENT, event)
8302                         .set(MediaMetrics.Property.INDEX, value)
8303                         .set(MediaMetrics.Property.MIN_INDEX, mIndexMin)
8304                         .set(MediaMetrics.Property.MAX_INDEX, mIndexMax)
8305                         .record();
8306             }
8307         };
8308         private final Intent mVolumeChanged;
8309         private final Bundle mVolumeChangedOptions;
8310         private final Intent mStreamDevicesChanged;
8311         private final Bundle mStreamDevicesChangedOptions;
8312 
VolumeStreamState(String settingName, int streamType)8313         private VolumeStreamState(String settingName, int streamType) {
8314             mVolumeIndexSettingName = settingName;
8315 
8316             mStreamType = streamType;
8317             mIndexMin = MIN_STREAM_VOLUME[streamType] * 10;
8318             mIndexMinNoPerm = mIndexMin; // may be overwritten later in updateNoPermMinIndex()
8319             mIndexMax = MAX_STREAM_VOLUME[streamType] * 10;
8320             final int status = AudioSystem.initStreamVolume(
8321                     streamType, mIndexMin / 10, mIndexMax / 10);
8322             if (status != AudioSystem.AUDIO_STATUS_OK) {
8323                 sLifecycleLogger.enqueue(new EventLogger.StringEvent(
8324                          "VSS() stream:" + streamType + " initStreamVolume=" + status)
8325                         .printLog(ALOGE, TAG));
8326                 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0,
8327                         "VSS()" /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
8328             }
8329 
8330             readSettings();
8331             mVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION);
8332             mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
8333             final BroadcastOptions volumeChangedOptions = BroadcastOptions.makeBasic();
8334             // This allows us to discard older broadcasts still waiting to be delivered
8335             // which have the same namespace (VOLUME_CHANGED_ACTION) and key (mStreamType).
8336             volumeChangedOptions.setDeliveryGroupPolicy(DELIVERY_GROUP_POLICY_MOST_RECENT);
8337             volumeChangedOptions.setDeliveryGroupMatchingKey(
8338                     AudioManager.VOLUME_CHANGED_ACTION, String.valueOf(mStreamType));
8339             volumeChangedOptions.setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE);
8340             mVolumeChangedOptions = volumeChangedOptions.toBundle();
8341 
8342             mStreamDevicesChanged = new Intent(AudioManager.STREAM_DEVICES_CHANGED_ACTION);
8343             mStreamDevicesChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
8344             final BroadcastOptions streamDevicesChangedOptions = BroadcastOptions.makeBasic();
8345             streamDevicesChangedOptions.setDeliveryGroupPolicy(DELIVERY_GROUP_POLICY_MOST_RECENT);
8346             streamDevicesChangedOptions.setDeliveryGroupMatchingKey(
8347                     AudioManager.STREAM_DEVICES_CHANGED_ACTION, String.valueOf(mStreamType));
8348             streamDevicesChangedOptions.setDeferralPolicy(
8349                     BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE);
8350             mStreamDevicesChangedOptions = streamDevicesChangedOptions.toBundle();
8351         }
8352 
8353         /**
8354          * Associate a {@link volumeGroupState} on the {@link VolumeStreamState}.
8355          * <p> It helps to synchronize the index, mute attributes on the maching
8356          * {@link volumeGroupState}
8357          * @param volumeGroupState matching the {@link VolumeStreamState}
8358          */
setVolumeGroupState(VolumeGroupState volumeGroupState)8359         public void setVolumeGroupState(VolumeGroupState volumeGroupState) {
8360             mVolumeGroupState = volumeGroupState;
8361             if (mVolumeGroupState != null) {
8362                 mVolumeGroupState.setSettingName(mVolumeIndexSettingName);
8363             }
8364         }
8365         /**
8366          * Update the minimum index that can be used without MODIFY_AUDIO_SETTINGS permission
8367          * @param index minimum index expressed in "UI units", i.e. no 10x factor
8368          */
updateNoPermMinIndex(int index)8369         public void updateNoPermMinIndex(int index) {
8370             mIndexMinNoPerm = index * 10;
8371             if (mIndexMinNoPerm < mIndexMin) {
8372                 Log.e(TAG, "Invalid mIndexMinNoPerm for stream " + mStreamType);
8373                 mIndexMinNoPerm = mIndexMin;
8374             }
8375         }
8376 
8377         /**
8378          * Returns a list of devices associated with the stream type.
8379          *
8380          * This is a reference to the local list, do not modify.
8381          */
8382         @GuardedBy("VolumeStreamState.class")
8383         @NonNull
observeDevicesForStream_syncVSS( boolean checkOthers)8384         public Set<Integer> observeDevicesForStream_syncVSS(
8385                 boolean checkOthers) {
8386             if (!mSystemServer.isPrivileged()) {
8387                 return new TreeSet<Integer>();
8388             }
8389             final Set<Integer> deviceSet =
8390                     getDeviceSetForStreamDirect(mStreamType);
8391             if (deviceSet.equals(mObservedDeviceSet)) {
8392                 return mObservedDeviceSet;
8393             }
8394 
8395             // Use legacy bit masks for message signalling.
8396             // TODO(b/185386781): message needs update since it uses devices bit-mask.
8397             final int devices = AudioSystem.getDeviceMaskFromSet(deviceSet);
8398             final int prevDevices = AudioSystem.getDeviceMaskFromSet(mObservedDeviceSet);
8399 
8400             mObservedDeviceSet = deviceSet;
8401             if (checkOthers) {
8402                 // one stream's devices have changed, check the others
8403                 postObserveDevicesForAllStreams(mStreamType);
8404             }
8405             // log base stream changes to the event log
8406             if (mStreamVolumeAlias[mStreamType] == mStreamType) {
8407                 EventLogTags.writeStreamDevicesChanged(mStreamType, prevDevices, devices);
8408             }
8409             // send STREAM_DEVICES_CHANGED_ACTION on the message handler so it is scheduled after
8410             // the postObserveDevicesForStreams is handled
8411             final SomeArgs args = SomeArgs.obtain();
8412             args.arg1 = mStreamDevicesChanged;
8413             args.arg2 = mStreamDevicesChangedOptions;
8414             sendMsg(mAudioHandler,
8415                     MSG_STREAM_DEVICES_CHANGED,
8416                     SENDMSG_QUEUE, prevDevices /*arg1*/, devices /*arg2*/,
8417                     // ok to send reference to this object, it is final
8418                     args /*obj*/, 0 /*delay*/);
8419             return mObservedDeviceSet;
8420         }
8421 
getSettingNameForDevice(int device)8422         public @Nullable String getSettingNameForDevice(int device) {
8423             if (!hasValidSettingsName()) {
8424                 return null;
8425             }
8426             final String suffix = AudioSystem.getOutputDeviceName(device);
8427             if (suffix.isEmpty()) {
8428                 return mVolumeIndexSettingName;
8429             }
8430             return mVolumeIndexSettingName + "_" + suffix;
8431         }
8432 
hasValidSettingsName()8433         private boolean hasValidSettingsName() {
8434             return (mVolumeIndexSettingName != null && !mVolumeIndexSettingName.isEmpty());
8435         }
8436 
setSettingName(String settingName)8437         void setSettingName(String settingName) {
8438             mVolumeIndexSettingName = settingName;
8439             if (mVolumeGroupState != null) {
8440                 mVolumeGroupState.setSettingName(mVolumeIndexSettingName);
8441             }
8442         }
8443 
getSettingName()8444         String getSettingName() {
8445             return mVolumeIndexSettingName;
8446         }
8447 
readSettings()8448         public void readSettings() {
8449             synchronized (mSettingsLock) {
8450                 synchronized (VolumeStreamState.class) {
8451                     // force maximum volume on all streams if fixed volume property is set
8452                     if (mUseFixedVolume) {
8453                         mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
8454                         return;
8455                     }
8456                     // do not read system stream volume from settings: this stream is always aliased
8457                     // to another stream type and its volume is never persisted. Values in settings can
8458                     // only be stale values
8459                     if ((mStreamType == AudioSystem.STREAM_SYSTEM) ||
8460                             (mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED)) {
8461                         int index = 10 * AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType];
8462                         if (mCameraSoundForced) {
8463                             index = mIndexMax;
8464                         }
8465                         mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, index);
8466                         return;
8467                     }
8468                 }
8469             }
8470             synchronized (VolumeStreamState.class) {
8471                 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
8472 
8473                     // retrieve current volume for device
8474                     // if no volume stored for current stream and device, use default volume if default
8475                     // device, continue otherwise
8476                     int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) ?
8477                             AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType] : -1;
8478                     int index;
8479                     if (!hasValidSettingsName()) {
8480                         index = defaultIndex;
8481                     } else {
8482                         String name = getSettingNameForDevice(device);
8483                         index = mSettings.getSystemIntForUser(
8484                                 mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT);
8485                     }
8486                     if (index == -1) {
8487                         continue;
8488                     }
8489 
8490                     mIndexMap.put(device, getValidIndex(10 * index,
8491                             true /*hasModifyAudioSettings*/));
8492                 }
8493             }
8494         }
8495 
getAbsoluteVolumeIndex(int index)8496         private int getAbsoluteVolumeIndex(int index) {
8497             /* Special handling for Bluetooth Absolute Volume scenario
8498              * If we send full audio gain, some accessories are too loud even at its lowest
8499              * volume. We are not able to enumerate all such accessories, so here is the
8500              * workaround from phone side.
8501              * Pre-scale volume at lowest volume steps 1 2 and 3.
8502              * For volume step 0, set audio gain to 0 as some accessories won't mute on their end.
8503              */
8504             if (index == 0) {
8505                 // 0% for volume 0
8506                 index = 0;
8507             } else if (index > 0 && index <= 3) {
8508                 // Pre-scale for volume steps 1 2 and 3
8509                 index = (int) (mIndexMax * mPrescaleAbsoluteVolume[index - 1]) / 10;
8510             } else {
8511                 // otherwise, full gain
8512                 index = (mIndexMax + 5) / 10;
8513             }
8514             return index;
8515         }
8516 
setStreamVolumeIndex(int index, int device)8517         private void setStreamVolumeIndex(int index, int device) {
8518             // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted.
8519             // This allows RX path muting by the audio HAL only when explicitly muted but not when
8520             // index is just set to 0 to repect BT requirements
8521             if (mStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0
8522                     && !isFullyMuted()) {
8523                 index = 1;
8524             }
8525             mAudioSystem.setStreamVolumeIndexAS(mStreamType, index, device);
8526         }
8527 
8528         // must be called while synchronized VolumeStreamState.class
applyDeviceVolume_syncVSS(int device)8529         /*package*/ void applyDeviceVolume_syncVSS(int device) {
8530             int index;
8531             if (isFullyMuted()) {
8532                 index = 0;
8533             } else if (isAbsoluteVolumeDevice(device)
8534                     || isA2dpAbsoluteVolumeDevice(device)
8535                     || AudioSystem.isLeAudioDeviceType(device)) {
8536                 index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10);
8537             } else if (isFullVolumeDevice(device)) {
8538                 index = (mIndexMax + 5)/10;
8539             } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
8540                 index = (mIndexMax + 5)/10;
8541             } else {
8542                 index = (getIndex(device) + 5)/10;
8543             }
8544             setStreamVolumeIndex(index, device);
8545         }
8546 
applyAllVolumes()8547         public void applyAllVolumes() {
8548             synchronized (VolumeStreamState.class) {
8549                 // apply device specific volumes first
8550                 int index;
8551                 boolean isAbsoluteVolume = false;
8552                 for (int i = 0; i < mIndexMap.size(); i++) {
8553                     final int device = mIndexMap.keyAt(i);
8554                     if (device != AudioSystem.DEVICE_OUT_DEFAULT) {
8555                         if (isFullyMuted()) {
8556                             index = 0;
8557                         } else if (isAbsoluteVolumeDevice(device)
8558                                 || isA2dpAbsoluteVolumeDevice(device)
8559                                 || AudioSystem.isLeAudioDeviceType(device)) {
8560                             isAbsoluteVolume = true;
8561                             index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10);
8562                         } else if (isFullVolumeDevice(device)) {
8563                             index = (mIndexMax + 5)/10;
8564                         } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
8565                             index = (mIndexMax + 5)/10;
8566                         } else {
8567                             index = (mIndexMap.valueAt(i) + 5)/10;
8568                         }
8569 
8570                         sendMsg(mAudioHandler, SoundDoseHelper.MSG_CSD_UPDATE_ATTENUATION,
8571                                 SENDMSG_REPLACE, device,  isAbsoluteVolume ? 1 : 0, this,
8572                                 /*delay=*/0);
8573 
8574                         setStreamVolumeIndex(index, device);
8575                     }
8576                 }
8577                 // apply default volume last: by convention , default device volume will be used
8578                 // by audio policy manager if no explicit volume is present for a given device type
8579                 if (isFullyMuted()) {
8580                     index = 0;
8581                 } else {
8582                     index = (getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)/10;
8583                 }
8584                 setStreamVolumeIndex(index, AudioSystem.DEVICE_OUT_DEFAULT);
8585             }
8586         }
8587 
adjustIndex(int deltaIndex, int device, String caller, boolean hasModifyAudioSettings)8588         public boolean adjustIndex(int deltaIndex, int device, String caller,
8589                 boolean hasModifyAudioSettings) {
8590             return setIndex(getIndex(device) + deltaIndex, device, caller,
8591                     hasModifyAudioSettings);
8592         }
8593 
setIndex(int index, int device, String caller, boolean hasModifyAudioSettings)8594         public boolean setIndex(int index, int device, String caller,
8595                 boolean hasModifyAudioSettings) {
8596             boolean changed;
8597             int oldIndex;
8598             final boolean isCurrentDevice;
8599             synchronized (mSettingsLock) {
8600                 synchronized (VolumeStreamState.class) {
8601                     oldIndex = getIndex(device);
8602                     index = getValidIndex(index, hasModifyAudioSettings);
8603                     if ((mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED) && mCameraSoundForced) {
8604                         index = mIndexMax;
8605                     }
8606                     mIndexMap.put(device, index);
8607 
8608                     changed = oldIndex != index;
8609                     // Apply change to all streams using this one as alias if:
8610                     // - the index actually changed OR
8611                     // - there is no volume index stored for this device on alias stream.
8612                     // If changing volume of current device, also change volume of current
8613                     // device on aliased stream
8614                     isCurrentDevice = (device == getDeviceForStream(mStreamType));
8615                     final int numStreamTypes = AudioSystem.getNumStreamTypes();
8616                     for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
8617                         final VolumeStreamState aliasStreamState = mStreamStates[streamType];
8618                         if (streamType != mStreamType &&
8619                                 mStreamVolumeAlias[streamType] == mStreamType &&
8620                                 (changed || !aliasStreamState.hasIndexForDevice(device))) {
8621                             final int scaledIndex = rescaleIndex(index, mStreamType, streamType);
8622                             aliasStreamState.setIndex(scaledIndex, device, caller,
8623                                     hasModifyAudioSettings);
8624                             if (isCurrentDevice) {
8625                                 aliasStreamState.setIndex(scaledIndex,
8626                                         getDeviceForStream(streamType), caller,
8627                                         hasModifyAudioSettings);
8628                             }
8629                         }
8630                     }
8631                     // Mirror changes in SPEAKER ringtone volume on SCO when
8632                     if (changed && mStreamType == AudioSystem.STREAM_RING
8633                             && device == AudioSystem.DEVICE_OUT_SPEAKER) {
8634                         for (int i = 0; i < mIndexMap.size(); i++) {
8635                             int otherDevice = mIndexMap.keyAt(i);
8636                             if (AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(otherDevice)) {
8637                                 mIndexMap.put(otherDevice, index);
8638                             }
8639                         }
8640                     }
8641                 }
8642             }
8643             if (changed) {
8644                 // If associated to volume group, update group cache
8645                 updateVolumeGroupIndex(device, /* forceMuteState= */ false);
8646 
8647                 oldIndex = (oldIndex + 5) / 10;
8648                 index = (index + 5) / 10;
8649                 // log base stream changes to the event log
8650                 if (mStreamVolumeAlias[mStreamType] == mStreamType) {
8651                     if (caller == null) {
8652                         Log.w(TAG, "No caller for volume_changed event", new Throwable());
8653                     }
8654                     EventLogTags.writeVolumeChanged(mStreamType, oldIndex, index, mIndexMax / 10,
8655                             caller);
8656                 }
8657                 // fire changed intents for all streams, but only when the device it changed on
8658                 //  is the current device
8659                 if ((index != oldIndex) && isCurrentDevice) {
8660                     mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index);
8661                     mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex);
8662                     mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS,
8663                             mStreamVolumeAlias[mStreamType]);
8664                     AudioService.sVolumeLogger.enqueue(new VolChangedBroadcastEvent(
8665                             mStreamType, mStreamVolumeAlias[mStreamType], index));
8666                     sendBroadcastToAll(mVolumeChanged, mVolumeChangedOptions);
8667                 }
8668             }
8669             return changed;
8670         }
8671 
getIndex(int device)8672         public int getIndex(int device) {
8673             synchronized (VolumeStreamState.class) {
8674                 int index = mIndexMap.get(device, -1);
8675                 if (index == -1) {
8676                     // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
8677                     index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT);
8678                 }
8679                 return index;
8680             }
8681         }
8682 
getVolumeInfo(int device)8683         public @NonNull VolumeInfo getVolumeInfo(int device) {
8684             synchronized (VolumeStreamState.class) {
8685                 int index = mIndexMap.get(device, -1);
8686                 if (index == -1) {
8687                     // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
8688                     index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT);
8689                 }
8690                 final VolumeInfo vi = new VolumeInfo.Builder(mStreamType)
8691                         .setMinVolumeIndex(mIndexMin)
8692                         .setMaxVolumeIndex(mIndexMax)
8693                         .setVolumeIndex(index)
8694                         .setMuted(isFullyMuted())
8695                         .build();
8696                 return vi;
8697             }
8698         }
8699 
hasIndexForDevice(int device)8700         public boolean hasIndexForDevice(int device) {
8701             synchronized (VolumeStreamState.class) {
8702                 return (mIndexMap.get(device, -1) != -1);
8703             }
8704         }
8705 
getMaxIndex()8706         public int getMaxIndex() {
8707             return mIndexMax;
8708         }
8709 
8710         /**
8711          * @return the lowest index regardless of permissions
8712          */
getMinIndex()8713         public int getMinIndex() {
8714             return mIndexMin;
8715         }
8716 
8717         /**
8718          * @param isPrivileged true if the caller is privileged and not subject to minimum
8719          *                     volume index thresholds
8720          * @return the lowest index that this caller can set or adjust to
8721          */
getMinIndex(boolean isPrivileged)8722         public int getMinIndex(boolean isPrivileged) {
8723             return isPrivileged ? mIndexMin : mIndexMinNoPerm;
8724         }
8725 
8726         /**
8727          * Copies all device/index pairs from the given VolumeStreamState after initializing
8728          * them with the volume for DEVICE_OUT_DEFAULT. No-op if the source VolumeStreamState
8729          * has the same stream type as this instance.
8730          * @param srcStream
8731          * @param caller
8732          */
8733         // must be sync'd on mSettingsLock before VolumeStreamState.class
8734         @GuardedBy("VolumeStreamState.class")
setAllIndexes(VolumeStreamState srcStream, String caller)8735         public void setAllIndexes(VolumeStreamState srcStream, String caller) {
8736             if (mStreamType == srcStream.mStreamType) {
8737                 return;
8738             }
8739             int srcStreamType = srcStream.getStreamType();
8740             // apply default device volume from source stream to all devices first in case
8741             // some devices are present in this stream state but not in source stream state
8742             int index = srcStream.getIndex(AudioSystem.DEVICE_OUT_DEFAULT);
8743             index = rescaleIndex(index, srcStreamType, mStreamType);
8744             for (int i = 0; i < mIndexMap.size(); i++) {
8745                 mIndexMap.put(mIndexMap.keyAt(i), index);
8746             }
8747             // Now apply actual volume for devices in source stream state
8748             SparseIntArray srcMap = srcStream.mIndexMap;
8749             for (int i = 0; i < srcMap.size(); i++) {
8750                 int device = srcMap.keyAt(i);
8751                 index = srcMap.valueAt(i);
8752                 index = rescaleIndex(index, srcStreamType, mStreamType);
8753 
8754                 setIndex(index, device, caller, true /*hasModifyAudioSettings*/);
8755             }
8756         }
8757 
8758         // must be sync'd on mSettingsLock before VolumeStreamState.class
8759         @GuardedBy("VolumeStreamState.class")
setAllIndexesToMax()8760         public void setAllIndexesToMax() {
8761             for (int i = 0; i < mIndexMap.size(); i++) {
8762                 mIndexMap.put(mIndexMap.keyAt(i), mIndexMax);
8763             }
8764         }
8765 
8766         // If associated to volume group, update group cache
updateVolumeGroupIndex(int device, boolean forceMuteState)8767         private void updateVolumeGroupIndex(int device, boolean forceMuteState) {
8768             // need mSettingsLock when called from setIndex for vgs.mute -> vgs.applyAllVolumes ->
8769             // vss.setIndex which grabs this lock after VSS.class. Locking order needs to be
8770             // preserved
8771             synchronized (mSettingsLock) {
8772                 synchronized (VolumeStreamState.class) {
8773                     if (mVolumeGroupState != null) {
8774                         int groupIndex = (getIndex(device) + 5) / 10;
8775                         if (DEBUG_VOL) {
8776                             Log.d(TAG, "updateVolumeGroupIndex for stream " + mStreamType
8777                                     + ", muted=" + mIsMuted + ", device=" + device + ", index="
8778                                     + getIndex(device) + ", group " + mVolumeGroupState.name()
8779                                     + " Muted=" + mVolumeGroupState.isMuted() + ", Index="
8780                                     + groupIndex + ", forceMuteState=" + forceMuteState);
8781                         }
8782                         mVolumeGroupState.updateVolumeIndex(groupIndex, device);
8783                         // Only propage mute of stream when applicable
8784                         if (isMutable()) {
8785                             // For call stream, align mute only when muted, not when index is set to
8786                             // 0
8787                             mVolumeGroupState.mute(
8788                                     forceMuteState ? mIsMuted :
8789                                             (groupIndex == 0 && !isCallStream(mStreamType))
8790                                                     || mIsMuted);
8791                         }
8792                     }
8793                 }
8794             }
8795         }
8796 
8797         /**
8798          * Mute/unmute the stream
8799          * @param state the new mute state
8800          * @return true if the mute state was changed
8801          */
mute(boolean state, String source)8802         public boolean mute(boolean state, String source) {
8803             boolean changed = false;
8804             synchronized (VolumeStreamState.class) {
8805                 changed = mute(state, true, source);
8806             }
8807             if (changed) {
8808                 broadcastMuteSetting(mStreamType, state);
8809             }
8810             return changed;
8811         }
8812 
8813         /**
8814          * Mute/unmute the stream by AudioService
8815          * @param state the new mute state
8816          * @return true if the mute state was changed
8817          */
muteInternally(boolean state)8818         public boolean muteInternally(boolean state) {
8819             boolean changed = false;
8820             synchronized (VolumeStreamState.class) {
8821                 if (state != mIsMutedInternally) {
8822                     changed = true;
8823                     mIsMutedInternally = state;
8824                     // mute immediately to avoid delay and preemption when using a message.
8825                     applyAllVolumes();
8826                 }
8827             }
8828             if (changed) {
8829                 sVolumeLogger.enqueue(new VolumeEvent(
8830                         VolumeEvent.VOL_MUTE_STREAM_INT, mStreamType, state));
8831             }
8832             return changed;
8833         }
8834 
8835         @GuardedBy("VolumeStreamState.class")
isFullyMuted()8836         public boolean isFullyMuted() {
8837             return mIsMuted || mIsMutedInternally;
8838         }
8839 
8840 
isMutable()8841         private boolean isMutable() {
8842             return isStreamAffectedByMute(mStreamType)
8843                     && (mIndexMin == 0 || isCallStream(mStreamType));
8844         }
8845 
8846         /**
8847          * Mute/unmute the stream
8848          * @param state the new mute state
8849          * @param apply true to propagate to HW, or false just to update the cache. May be needed
8850          * to mute a stream and its aliases as applyAllVolume will force settings to aliases.
8851          * It prevents unnecessary calls to {@see AudioSystem#setStreamVolume}
8852          * @return true if the mute state was changed
8853          */
mute(boolean state, boolean apply, String src)8854         public boolean mute(boolean state, boolean apply, String src) {
8855             synchronized (VolumeStreamState.class) {
8856                 boolean changed = state != mIsMuted;
8857                 if (changed) {
8858                     sMuteLogger.enqueue(
8859                             new AudioServiceEvents.StreamMuteEvent(mStreamType, state, src));
8860                     // check to see if unmuting should not have happened due to ringer muted streams
8861                     if (!state && isStreamMutedByRingerOrZenMode(mStreamType)) {
8862                         Log.e(TAG, "Unmuting stream " + mStreamType
8863                                 + " despite ringer-zen muted stream 0x"
8864                                 + Integer.toHexString(AudioService.sRingerAndZenModeMutedStreams),
8865                                 new Exception()); // this will put a stack trace in the logs
8866                         sMuteLogger.enqueue(new AudioServiceEvents.StreamUnmuteErrorEvent(
8867                                 mStreamType, AudioService.sRingerAndZenModeMutedStreams));
8868                     }
8869                     mIsMuted = state;
8870                     if (apply) {
8871                         doMute();
8872                     }
8873                 }
8874                 return changed;
8875             }
8876         }
8877 
doMute()8878         public void doMute() {
8879             synchronized (VolumeStreamState.class) {
8880                 // If associated to volume group, update group cache
8881                 updateVolumeGroupIndex(getDeviceForStream(mStreamType), /* forceMuteState= */ true);
8882 
8883                 // Set the new mute volume. This propagates the values to
8884                 // the audio system, otherwise the volume won't be changed
8885                 // at the lower level.
8886                 sendMsg(mAudioHandler,
8887                         MSG_SET_ALL_VOLUMES,
8888                         SENDMSG_QUEUE,
8889                         0,
8890                         0,
8891                         this, 0);
8892             }
8893         }
8894 
getStreamType()8895         public int getStreamType() {
8896             return mStreamType;
8897         }
8898 
checkFixedVolumeDevices()8899         public void checkFixedVolumeDevices() {
8900             synchronized (VolumeStreamState.class) {
8901                 // ignore settings for fixed volume devices: volume should always be at max or 0
8902                 if (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_MUSIC) {
8903                     for (int i = 0; i < mIndexMap.size(); i++) {
8904                         int device = mIndexMap.keyAt(i);
8905                         int index = mIndexMap.valueAt(i);
8906                         if (isFullVolumeDevice(device)
8907                                 || (isFixedVolumeDevice(device) && index != 0)) {
8908                             mIndexMap.put(device, mIndexMax);
8909                         }
8910                         applyDeviceVolume_syncVSS(device);
8911                     }
8912                 }
8913             }
8914         }
8915 
getValidIndex(int index, boolean hasModifyAudioSettings)8916         private int getValidIndex(int index, boolean hasModifyAudioSettings) {
8917             final int indexMin = hasModifyAudioSettings ? mIndexMin : mIndexMinNoPerm;
8918             if (index < indexMin) {
8919                 return indexMin;
8920             } else if (mUseFixedVolume || index > mIndexMax) {
8921                 return mIndexMax;
8922             }
8923 
8924             return index;
8925         }
8926 
dump(PrintWriter pw)8927         private void dump(PrintWriter pw) {
8928             pw.print("   Muted: ");
8929             pw.println(mIsMuted);
8930             pw.print("   Muted Internally: ");
8931             pw.println(mIsMutedInternally);
8932             pw.print("   Min: ");
8933             pw.print((mIndexMin + 5) / 10);
8934             if (mIndexMin != mIndexMinNoPerm) {
8935                 pw.print(" w/o perm:");
8936                 pw.println((mIndexMinNoPerm + 5) / 10);
8937             } else {
8938                 pw.println();
8939             }
8940             pw.print("   Max: ");
8941             pw.println((mIndexMax + 5) / 10);
8942             pw.print("   streamVolume:"); pw.println(getStreamVolume(mStreamType));
8943             pw.print("   Current: ");
8944             for (int i = 0; i < mIndexMap.size(); i++) {
8945                 if (i > 0) {
8946                     pw.print(", ");
8947                 }
8948                 final int device = mIndexMap.keyAt(i);
8949                 pw.print(Integer.toHexString(device));
8950                 final String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
8951                         : AudioSystem.getOutputDeviceName(device);
8952                 if (!deviceName.isEmpty()) {
8953                     pw.print(" (");
8954                     pw.print(deviceName);
8955                     pw.print(")");
8956                 }
8957                 pw.print(": ");
8958                 final int index = (mIndexMap.valueAt(i) + 5) / 10;
8959                 pw.print(index);
8960             }
8961             pw.println();
8962             pw.print("   Devices: ");
8963             pw.print(AudioSystem.deviceSetToString(getDeviceSetForStream(mStreamType)));
8964             pw.println();
8965             pw.print("   Volume Group: ");
8966             pw.println(mVolumeGroupState != null ? mVolumeGroupState.name() : "n/a");
8967         }
8968     }
8969 
8970     /** Thread that handles native AudioSystem control. */
8971     private class AudioSystemThread extends Thread {
AudioSystemThread()8972         AudioSystemThread() {
8973             super("AudioService");
8974         }
8975 
8976         @Override
run()8977         public void run() {
8978             // Set this thread up so the handler will work on it
8979             Looper.prepare();
8980 
8981             synchronized(AudioService.this) {
8982                 mAudioHandler = new AudioHandler();
8983 
8984                 // Notify that the handler has been created
8985                 AudioService.this.notify();
8986             }
8987 
8988             // Listen for volume change requests that are set by VolumePanel
8989             Looper.loop();
8990         }
8991     }
8992 
8993     private static final class DeviceVolumeUpdate {
8994         final int mStreamType;
8995         final int mDevice;
8996         final @NonNull String mCaller;
8997         private static final int NO_NEW_INDEX = -2049;
8998         private final int mVssVolIndex;
8999 
9000         // Constructor with volume index, meant to cause this volume to be set and applied for the
9001         // given stream type on the given device
DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller)9002         DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller) {
9003             mStreamType = streamType;
9004             mVssVolIndex = vssVolIndex;
9005             mDevice = device;
9006             mCaller = caller;
9007         }
9008 
9009         // Constructor with no volume index, meant to cause re-apply of volume for the given
9010         // stream type on the given device
DeviceVolumeUpdate(int streamType, int device, @NonNull String caller)9011         DeviceVolumeUpdate(int streamType, int device, @NonNull String caller) {
9012             mStreamType = streamType;
9013             mVssVolIndex = NO_NEW_INDEX;
9014             mDevice = device;
9015             mCaller = caller;
9016         }
9017 
hasVolumeIndex()9018         boolean hasVolumeIndex() {
9019             return mVssVolIndex != NO_NEW_INDEX;
9020         }
9021 
getVolumeIndex()9022         int getVolumeIndex() throws IllegalStateException {
9023             Preconditions.checkState(mVssVolIndex != NO_NEW_INDEX);
9024             return mVssVolIndex;
9025         }
9026     }
9027 
9028     /** only public for mocking/spying, do not call outside of AudioService */
9029     @VisibleForTesting
postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device, String caller)9030     public void postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device,
9031                                                 String caller) {
9032         sendMsg(mAudioHandler,
9033                 MSG_SET_DEVICE_STREAM_VOLUME,
9034                 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/,
9035                 new DeviceVolumeUpdate(streamType, vssVolIndex, device, caller),
9036                 0 /*delay*/);
9037     }
9038 
postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller)9039     /*package*/ void postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller) {
9040         sendMsg(mAudioHandler,
9041                 MSG_SET_DEVICE_STREAM_VOLUME,
9042                 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/,
9043                 new DeviceVolumeUpdate(streamType, device, caller),
9044                 0 /*delay*/);
9045     }
9046 
onSetVolumeIndexOnDevice(@onNull DeviceVolumeUpdate update)9047     private void onSetVolumeIndexOnDevice(@NonNull DeviceVolumeUpdate update) {
9048         final VolumeStreamState streamState = mStreamStates[update.mStreamType];
9049         if (update.hasVolumeIndex()) {
9050             int index = update.getVolumeIndex();
9051             if (mSoundDoseHelper.checkSafeMediaVolume(update.mStreamType, index, update.mDevice)) {
9052                 index = mSoundDoseHelper.safeMediaVolumeIndex(update.mDevice);
9053             }
9054             streamState.setIndex(index, update.mDevice, update.mCaller,
9055                     // trusted as index is always validated before message is posted
9056                     true /*hasModifyAudioSettings*/);
9057             sVolumeLogger.enqueue(new EventLogger.StringEvent(update.mCaller + " dev:0x"
9058                     + Integer.toHexString(update.mDevice) + " volIdx:" + index));
9059         } else {
9060             sVolumeLogger.enqueue(new EventLogger.StringEvent(update.mCaller
9061                     + " update vol on dev:0x" + Integer.toHexString(update.mDevice)));
9062         }
9063         setDeviceVolume(streamState, update.mDevice);
9064     }
9065 
setDeviceVolume(VolumeStreamState streamState, int device)9066     /*package*/ void setDeviceVolume(VolumeStreamState streamState, int device) {
9067 
9068         synchronized (VolumeStreamState.class) {
9069             sendMsg(mAudioHandler, SoundDoseHelper.MSG_CSD_UPDATE_ATTENUATION, SENDMSG_REPLACE,
9070                     device, (isAbsoluteVolumeDevice(device) || isA2dpAbsoluteVolumeDevice(device)
9071                             || AudioSystem.isLeAudioDeviceType(device) ? 1 : 0),
9072                     streamState, /*delay=*/0);
9073             // Apply volume
9074             streamState.applyDeviceVolume_syncVSS(device);
9075 
9076             // Apply change to all streams using this one as alias
9077             int numStreamTypes = AudioSystem.getNumStreamTypes();
9078             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
9079                 if (streamType != streamState.mStreamType &&
9080                         mStreamVolumeAlias[streamType] == streamState.mStreamType) {
9081                     // Make sure volume is also maxed out on A2DP device for aliased stream
9082                     // that may have a different device selected
9083                     int streamDevice = getDeviceForStream(streamType);
9084                     if ((device != streamDevice)
9085                             && (isAbsoluteVolumeDevice(device)
9086                                 || isA2dpAbsoluteVolumeDevice(device)
9087                                 || AudioSystem.isLeAudioDeviceType(device))) {
9088                         mStreamStates[streamType].applyDeviceVolume_syncVSS(device);
9089                     }
9090                     mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice);
9091                 }
9092             }
9093         }
9094         // Post a persist volume msg
9095         sendMsg(mAudioHandler,
9096                 MSG_PERSIST_VOLUME,
9097                 SENDMSG_QUEUE,
9098                 device,
9099                 0,
9100                 streamState,
9101                 PERSIST_DELAY);
9102 
9103     }
9104 
9105     /** Handles internal volume messages in separate volume thread. */
9106     /*package*/ class AudioHandler extends Handler {
9107 
AudioHandler()9108         AudioHandler() {
9109             super();
9110         }
9111 
AudioHandler(Looper looper)9112         AudioHandler(Looper looper) {
9113             super(looper);
9114         }
9115 
setAllVolumes(VolumeStreamState streamState)9116         private void setAllVolumes(VolumeStreamState streamState) {
9117 
9118             // Apply volume
9119             streamState.applyAllVolumes();
9120 
9121             // Apply change to all streams using this one as alias
9122             int numStreamTypes = AudioSystem.getNumStreamTypes();
9123             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
9124                 if (streamType != streamState.mStreamType &&
9125                         mStreamVolumeAlias[streamType] == streamState.mStreamType) {
9126                     mStreamStates[streamType].applyAllVolumes();
9127                 }
9128             }
9129         }
9130 
persistVolume(VolumeStreamState streamState, int device)9131         private void persistVolume(VolumeStreamState streamState, int device) {
9132             if (mUseFixedVolume) {
9133                 return;
9134             }
9135             if (mIsSingleVolume && (streamState.mStreamType != AudioSystem.STREAM_MUSIC)) {
9136                 return;
9137             }
9138             if (streamState.hasValidSettingsName()) {
9139                 mSettings.putSystemIntForUser(mContentResolver,
9140                         streamState.getSettingNameForDevice(device),
9141                         (streamState.getIndex(device) + 5) / 10,
9142                         UserHandle.USER_CURRENT);
9143             }
9144         }
9145 
persistRingerMode(int ringerMode)9146         private void persistRingerMode(int ringerMode) {
9147             if (mUseFixedVolume) {
9148                 return;
9149             }
9150             mSettings.putGlobalInt(mContentResolver, Settings.Global.MODE_RINGER, ringerMode);
9151         }
9152 
onNotifyVolumeEvent(@onNull IAudioPolicyCallback apc, @AudioManager.VolumeAdjustment int direction)9153         private void onNotifyVolumeEvent(@NonNull IAudioPolicyCallback apc,
9154                 @AudioManager.VolumeAdjustment int direction) {
9155             try {
9156                 apc.notifyVolumeAdjust(direction);
9157             } catch(Exception e) {
9158                 // nothing we can do about this. Do not log error, too much potential for spam
9159             }
9160         }
9161 
9162         @Override
handleMessage(Message msg)9163         public void handleMessage(Message msg) {
9164             switch (msg.what) {
9165 
9166                 case MSG_SET_DEVICE_VOLUME:
9167                     setDeviceVolume((VolumeStreamState) msg.obj, msg.arg1);
9168                     break;
9169 
9170                 case MSG_SET_ALL_VOLUMES:
9171                     setAllVolumes((VolumeStreamState) msg.obj);
9172                     break;
9173 
9174                 case MSG_PERSIST_VOLUME:
9175                     persistVolume((VolumeStreamState) msg.obj, msg.arg1);
9176                     break;
9177 
9178                 case MSG_PERSIST_VOLUME_GROUP:
9179                     final VolumeGroupState vgs = (VolumeGroupState) msg.obj;
9180                     vgs.persistVolumeGroup(msg.arg1);
9181                     break;
9182 
9183                 case MSG_PERSIST_RINGER_MODE:
9184                     // note that the value persisted is the current ringer mode, not the
9185                     // value of ringer mode as of the time the request was made to persist
9186                     persistRingerMode(getRingerModeInternal());
9187                     break;
9188 
9189                 case MSG_AUDIO_SERVER_DIED:
9190                     onAudioServerDied();
9191                     break;
9192 
9193                 case MSG_DISPATCH_AUDIO_SERVER_STATE:
9194                     onDispatchAudioServerStateChange(msg.arg1 == 1);
9195                     break;
9196 
9197                 case MSG_UNLOAD_SOUND_EFFECTS:
9198                     mSfxHelper.unloadSoundEffects();
9199                     break;
9200 
9201                 case MSG_LOAD_SOUND_EFFECTS:
9202                 {
9203                     LoadSoundEffectReply reply = (LoadSoundEffectReply) msg.obj;
9204                     if (mSystemReady) {
9205                         mSfxHelper.loadSoundEffects(reply);
9206                     } else {
9207                         Log.w(TAG, "[schedule]loadSoundEffects() called before boot complete");
9208                         if (reply != null) {
9209                             reply.run(false);
9210                         }
9211                     }
9212                 }
9213                     break;
9214 
9215                 case MSG_PLAY_SOUND_EFFECT:
9216                     mSfxHelper.playSoundEffect(msg.arg1, msg.arg2);
9217                     break;
9218 
9219                 case MSG_SET_FORCE_USE:
9220                 {
9221                     final String eventSource = (String) msg.obj;
9222                     final int useCase = msg.arg1;
9223                     final int config = msg.arg2;
9224                     if (useCase == AudioSystem.FOR_MEDIA) {
9225                         Log.wtf(TAG, "Invalid force use FOR_MEDIA in AudioService from "
9226                                 + eventSource);
9227                         break;
9228                     }
9229                     new MediaMetrics.Item(MediaMetrics.Name.AUDIO_FORCE_USE
9230                             + MediaMetrics.SEPARATOR + AudioSystem.forceUseUsageToString(useCase))
9231                             .set(MediaMetrics.Property.EVENT, "setForceUse")
9232                             .set(MediaMetrics.Property.FORCE_USE_DUE_TO, eventSource)
9233                             .set(MediaMetrics.Property.FORCE_USE_MODE,
9234                                     AudioSystem.forceUseConfigToString(config))
9235                             .record();
9236                     sForceUseLogger.enqueue(
9237                             new AudioServiceEvents.ForceUseEvent(useCase, config, eventSource));
9238                     mAudioSystem.setForceUse(useCase, config);
9239                 }
9240                     break;
9241 
9242                 case MSG_DISABLE_AUDIO_FOR_UID:
9243                     mPlaybackMonitor.disableAudioForUid( msg.arg1 == 1 /* disable */,
9244                             msg.arg2 /* uid */);
9245                     mAudioEventWakeLock.release();
9246                     break;
9247 
9248                 case MSG_INIT_STREAMS_VOLUMES:
9249                     onInitStreamsAndVolumes();
9250                     mAudioEventWakeLock.release();
9251                     break;
9252 
9253                 case MSG_INIT_ADI_DEVICE_STATES:
9254                     onInitAdiDeviceStates();
9255                     mAudioEventWakeLock.release();
9256                     break;
9257 
9258                 case MSG_INIT_SPATIALIZER:
9259                     onInitSpatializer();
9260                     mAudioEventWakeLock.release();
9261                     break;
9262 
9263                 case MSG_INIT_HEADTRACKING_SENSORS:
9264                     mSpatializerHelper.onInitSensors();
9265                     break;
9266 
9267                 case MSG_RESET_SPATIALIZER:
9268                     mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect);
9269                     break;
9270 
9271                 case MSG_SYSTEM_READY:
9272                     onSystemReady();
9273                     break;
9274 
9275                 case MSG_INDICATE_SYSTEM_READY:
9276                     onIndicateSystemReady();
9277                     break;
9278 
9279                 case MSG_ACCESSORY_PLUG_MEDIA_UNMUTE:
9280                     onAccessoryPlugMediaUnmute(msg.arg1);
9281                     break;
9282 
9283                 case MSG_UNMUTE_STREAM:
9284                     onUnmuteStream(msg.arg1, msg.arg2);
9285                     break;
9286 
9287                 case MSG_DYN_POLICY_MIX_STATE_UPDATE:
9288                     onDynPolicyMixStateUpdate((String) msg.obj, msg.arg1);
9289                     break;
9290 
9291                 case MSG_NOTIFY_VOL_EVENT:
9292                     onNotifyVolumeEvent((IAudioPolicyCallback) msg.obj, msg.arg1);
9293                     break;
9294 
9295                 case MSG_ENABLE_SURROUND_FORMATS:
9296                     onEnableSurroundFormats((ArrayList<Integer>) msg.obj);
9297                     break;
9298 
9299                 case MSG_UPDATE_RINGER_MODE:
9300                     onUpdateRingerModeServiceInt();
9301                     break;
9302 
9303                 case MSG_SET_DEVICE_STREAM_VOLUME:
9304                     onSetVolumeIndexOnDevice((DeviceVolumeUpdate) msg.obj);
9305                     break;
9306 
9307                 case MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS:
9308                     onObserveDevicesForAllStreams(/*skipStream*/ msg.arg1);
9309                     break;
9310 
9311                 case MSG_HDMI_VOLUME_CHECK:
9312                     onCheckVolumeCecOnHdmiConnection(msg.arg1, (String) msg.obj);
9313                     break;
9314 
9315                 case MSG_PLAYBACK_CONFIG_CHANGE:
9316                     onPlaybackConfigChange((List<AudioPlaybackConfiguration>) msg.obj);
9317                     break;
9318                 case MSG_RECORDING_CONFIG_CHANGE:
9319                     onRecordingConfigChange((List<AudioRecordingConfiguration>) msg.obj);
9320                     break;
9321 
9322                 case MSG_BROADCAST_MICROPHONE_MUTE:
9323                     mSystemServer.sendMicrophoneMuteChangedIntent();
9324                     break;
9325 
9326                 case MSG_CHECK_MODE_FOR_UID:
9327                     synchronized (mDeviceBroker.mSetModeLock) {
9328                         if (msg.obj == null) {
9329                             break;
9330                         }
9331                         // Update active playback/recording for apps requesting IN_COMMUNICATION
9332                         // mode after a grace period following the mode change
9333                         SetModeDeathHandler h = (SetModeDeathHandler) msg.obj;
9334                         if (mSetModeDeathHandlers.indexOf(h) < 0) {
9335                             break;
9336                         }
9337                         boolean wasActive = h.isActive();
9338                         h.setPlaybackActive(isPlaybackActiveForUid(h.getUid()));
9339                         h.setRecordingActive(isRecordingActiveForUid(h.getUid()));
9340                         if (wasActive != h.isActive()) {
9341                             onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(),
9342                                     mContext.getPackageName(), false /*force*/);
9343                         }
9344                     }
9345                     break;
9346 
9347                 case MSG_STREAM_DEVICES_CHANGED:
9348                     final SomeArgs args = (SomeArgs) msg.obj;
9349                     final Intent intent = (Intent) args.arg1;
9350                     final Bundle options = (Bundle) args.arg2;
9351                     args.recycle();
9352                     sendBroadcastToAll(intent
9353                             .putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_DEVICES, msg.arg1)
9354                             .putExtra(AudioManager.EXTRA_VOLUME_STREAM_DEVICES, msg.arg2),
9355                             options);
9356                     break;
9357 
9358                 case MSG_UPDATE_VOLUME_STATES_FOR_DEVICE:
9359                     onUpdateVolumeStatesForAudioDevice(msg.arg1, (String) msg.obj);
9360                     break;
9361 
9362                 case MSG_REINIT_VOLUMES:
9363                     onReinitVolumes((String) msg.obj);
9364                     break;
9365 
9366                 case MSG_UPDATE_A11Y_SERVICE_UIDS:
9367                     onUpdateAccessibilityServiceUids();
9368                     break;
9369 
9370                 case MSG_UPDATE_AUDIO_MODE:
9371                     synchronized (mDeviceBroker.mSetModeLock) {
9372                         onUpdateAudioMode(msg.arg1, msg.arg2, (String) msg.obj, false /*force*/);
9373                     }
9374                     break;
9375 
9376                 case MSG_BT_DEV_CHANGED:
9377                     mDeviceBroker.queueOnBluetoothActiveDeviceChanged(
9378                             (AudioDeviceBroker.BtDeviceChangedData) msg.obj);
9379                     break;
9380 
9381                 case MSG_DISPATCH_AUDIO_MODE:
9382                     dispatchMode(msg.arg1);
9383                     break;
9384 
9385                 case MSG_ROUTING_UPDATED:
9386                     onRoutingUpdatedFromAudioThread();
9387                     break;
9388 
9389                 case MSG_ADD_ASSISTANT_SERVICE_UID:
9390                     onAddAssistantServiceUids(new int[]{msg.arg1});
9391                     break;
9392 
9393                 case MSG_REMOVE_ASSISTANT_SERVICE_UID:
9394                     onRemoveAssistantServiceUids(new int[]{msg.arg1});
9395                     break;
9396                 case MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID:
9397                     updateActiveAssistantServiceUids();
9398                     break;
9399 
9400                 case MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR:
9401                     dispatchDeviceVolumeBehavior((AudioDeviceAttributes) msg.obj, msg.arg1);
9402                     break;
9403 
9404                 case MSG_ROTATION_UPDATE:
9405                     // rotation parameter format: "rotation=x" where x is one of 0, 90, 180, 270
9406                     mAudioSystem.setParameters((String) msg.obj);
9407                     break;
9408 
9409                 case MSG_FOLD_UPDATE:
9410                     // fold parameter format: "device_folded=x" where x is one of on, off
9411                     mAudioSystem.setParameters((String) msg.obj);
9412                     break;
9413 
9414                 case MSG_NO_LOG_FOR_PLAYER_I:
9415                     mPlaybackMonitor.ignorePlayerIId(msg.arg1);
9416                     break;
9417 
9418                 case MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES:
9419                     onDispatchPreferredMixerAttributesChanged(msg.getData(), msg.arg1);
9420                     break;
9421 
9422                 case MSG_LOWER_VOLUME_TO_RS1:
9423                     onLowerVolumeToRs1();
9424                     break;
9425 
9426                 case MSG_CONFIGURATION_CHANGED:
9427                     onConfigurationChanged();
9428                     break;
9429 
9430                 default:
9431                     if (msg.what >= SAFE_MEDIA_VOLUME_MSG_START) {
9432                         // msg could be for the SoundDoseHelper
9433                         mSoundDoseHelper.handleMessage(msg);
9434                     }
9435             }
9436         }
9437     }
9438 
9439     private class SettingsObserver extends ContentObserver {
9440 
SettingsObserver()9441         SettingsObserver() {
9442             super(new Handler());
9443             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
9444                     Settings.Global.ZEN_MODE), false, this);
9445             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
9446                     Settings.Global.ZEN_MODE_CONFIG_ETAG), false, this);
9447             mContentResolver.registerContentObserver(Settings.System.getUriFor(
9448                 Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this);
9449             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
9450                 Settings.Global.DOCK_AUDIO_MEDIA_ENABLED), false, this);
9451             mContentResolver.registerContentObserver(Settings.System.getUriFor(
9452                     Settings.System.MASTER_MONO), false, this);
9453             mContentResolver.registerContentObserver(Settings.System.getUriFor(
9454                     Settings.System.MASTER_BALANCE), false, this);
9455 
9456             mEncodedSurroundMode = mSettings.getGlobalInt(
9457                     mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT,
9458                     Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
9459             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
9460                     Settings.Global.ENCODED_SURROUND_OUTPUT), false, this);
9461             mEnabledSurroundFormats = mSettings.getGlobalString(
9462                     mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
9463             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
9464                     Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS), false, this);
9465 
9466             mContentResolver.registerContentObserver(Settings.Secure.getUriFor(
9467                     Settings.Secure.VOICE_INTERACTION_SERVICE), false, this);
9468         }
9469 
9470         @Override
onChange(boolean selfChange)9471         public void onChange(boolean selfChange) {
9472             super.onChange(selfChange);
9473             // FIXME This synchronized is not necessary if mSettingsLock only protects mRingerMode.
9474             //       However there appear to be some missing locks around sRingerAndZenModeMutedStreams
9475             //       and mRingerModeAffectedStreams, so will leave this synchronized for now.
9476             //       sRingerAndZenModeMutedStreams and mMuteAffectedStreams are safe (only accessed once).
9477             synchronized (mSettingsLock) {
9478                 if (updateRingerAndZenModeAffectedStreams()) {
9479                     /*
9480                      * Ensure all stream types that should be affected by ringer mode
9481                      * are in the proper state.
9482                      */
9483                     setRingerModeInt(getRingerModeInternal(), false);
9484                 }
9485                 readDockAudioSettings(mContentResolver);
9486                 updateMasterMono(mContentResolver);
9487                 updateMasterBalance(mContentResolver);
9488                 updateEncodedSurroundOutput();
9489                 sendEnabledSurroundFormats(mContentResolver, mSurroundModeChanged);
9490                 updateAssistantUIdLocked(/* forceUpdate= */ false);
9491             }
9492         }
9493 
updateEncodedSurroundOutput()9494         private void updateEncodedSurroundOutput() {
9495             int newSurroundMode = mSettings.getGlobalInt(
9496                 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT,
9497                 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
9498             // Did it change?
9499             if (mEncodedSurroundMode != newSurroundMode) {
9500                 // Send to AudioPolicyManager
9501                 sendEncodedSurroundMode(newSurroundMode, "SettingsObserver");
9502                 mDeviceBroker.toggleHdmiIfConnected_Async();
9503                 mEncodedSurroundMode = newSurroundMode;
9504                 mSurroundModeChanged = true;
9505             } else {
9506                 mSurroundModeChanged = false;
9507             }
9508         }
9509     }
9510 
avrcpSupportsAbsoluteVolume(String address, boolean support)9511     private void avrcpSupportsAbsoluteVolume(String address, boolean support) {
9512         // address is not used for now, but may be used when multiple a2dp devices are supported
9513         sVolumeLogger.enqueue(new EventLogger.StringEvent("avrcpSupportsAbsoluteVolume addr="
9514                 + address + " support=" + support).printLog(TAG));
9515         mDeviceBroker.setAvrcpAbsoluteVolumeSupported(support);
9516         setAvrcpAbsoluteVolumeSupported(support);
9517     }
9518 
setAvrcpAbsoluteVolumeSupported(boolean support)9519     /*package*/ void setAvrcpAbsoluteVolumeSupported(boolean support) {
9520         mAvrcpAbsVolSupported = support;
9521         sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE,
9522                     AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0,
9523                     mStreamStates[AudioSystem.STREAM_MUSIC], 0);
9524     }
9525 
9526     /**
9527      * @return true if there is currently a registered dynamic mixing policy that affects media
9528      * and is not a render + loopback policy
9529      */
9530     // only public for mocking/spying
9531     @VisibleForTesting
hasMediaDynamicPolicy()9532     public boolean hasMediaDynamicPolicy() {
9533         synchronized (mAudioPolicies) {
9534             if (mAudioPolicies.isEmpty()) {
9535                 return false;
9536             }
9537             final Collection<AudioPolicyProxy> appColl = mAudioPolicies.values();
9538             for (AudioPolicyProxy app : appColl) {
9539                 if (app.hasMixAffectingUsage(AudioAttributes.USAGE_MEDIA,
9540                         AudioMix.ROUTE_FLAG_LOOP_BACK_RENDER)) {
9541                     return true;
9542                 }
9543             }
9544             return false;
9545         }
9546     }
9547 
9548     /** only public for mocking/spying, do not call outside of AudioService */
9549     @VisibleForTesting
checkMusicActive(int deviceType, String caller)9550     public void checkMusicActive(int deviceType, String caller) {
9551         if (mSoundDoseHelper.safeDevicesContains(deviceType)) {
9552             mSoundDoseHelper.scheduleMusicActiveCheck();
9553         }
9554     }
9555 
9556     /**
9557      * Receiver for misc intent broadcasts the Phone app cares about.
9558      */
9559     private class AudioServiceBroadcastReceiver extends BroadcastReceiver {
9560         @Override
onReceive(Context context, Intent intent)9561         public void onReceive(Context context, Intent intent) {
9562             final String action = intent.getAction();
9563             int outDevice;
9564             int inDevice;
9565             int state;
9566 
9567             if (action.equals(Intent.ACTION_DOCK_EVENT)) {
9568                 int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
9569                         Intent.EXTRA_DOCK_STATE_UNDOCKED);
9570                 int config;
9571                 switch (dockState) {
9572                     case Intent.EXTRA_DOCK_STATE_DESK:
9573                         config = AudioSystem.FORCE_BT_DESK_DOCK;
9574                         break;
9575                     case Intent.EXTRA_DOCK_STATE_CAR:
9576                         config = AudioSystem.FORCE_BT_CAR_DOCK;
9577                         break;
9578                     case Intent.EXTRA_DOCK_STATE_LE_DESK:
9579                         config = AudioSystem.FORCE_ANALOG_DOCK;
9580                         break;
9581                     case Intent.EXTRA_DOCK_STATE_HE_DESK:
9582                         config = AudioSystem.FORCE_DIGITAL_DOCK;
9583                         break;
9584                     case Intent.EXTRA_DOCK_STATE_UNDOCKED:
9585                     default:
9586                         config = AudioSystem.FORCE_NONE;
9587                 }
9588                 // Low end docks have a menu to enable or disable audio
9589                 // (see mDockAudioMediaEnabled)
9590                 if (!((dockState == Intent.EXTRA_DOCK_STATE_LE_DESK)
9591                         || ((dockState == Intent.EXTRA_DOCK_STATE_UNDOCKED)
9592                                 && (mDockState == Intent.EXTRA_DOCK_STATE_LE_DESK)))) {
9593                     mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, config,
9594                             "ACTION_DOCK_EVENT intent");
9595                 }
9596                 mDockState = dockState;
9597             } else if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED)
9598                     || action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
9599                 mDeviceBroker.postReceiveBtEvent(intent);
9600             } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
9601                 if (mMonitorRotation) {
9602                     RotationHelper.enable();
9603                 }
9604                 AudioSystem.setParameters("screen_state=on");
9605             } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
9606                 if (mMonitorRotation) {
9607                     //reduce wakeups (save current) by only listening when display is on
9608                     RotationHelper.disable();
9609                 }
9610                 AudioSystem.setParameters("screen_state=off");
9611             } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
9612                 sendMsg(mAudioHandler,
9613                         MSG_CONFIGURATION_CHANGED,
9614                         SENDMSG_REPLACE,
9615                         0,
9616                         0,
9617                         null, 0);
9618             } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
9619                 if (mUserSwitchedReceived) {
9620                     // attempt to stop music playback for background user except on first user
9621                     // switch (i.e. first boot)
9622                     mDeviceBroker.postBroadcastBecomingNoisy();
9623                 }
9624                 mUserSwitchedReceived = true;
9625                 // the current audio focus owner is no longer valid
9626                 mMediaFocusControl.discardAudioFocusOwner();
9627 
9628                 if (mSupportsMicPrivacyToggle) {
9629                     mMicMuteFromPrivacyToggle = mSensorPrivacyManagerInternal
9630                             .isSensorPrivacyEnabled(getCurrentUserId(),
9631                                     SensorPrivacyManager.Sensors.MICROPHONE);
9632                     setMicrophoneMuteNoCallerCheck(getCurrentUserId());
9633                 }
9634 
9635                 // load volume settings for new user
9636                 readAudioSettings(true /*userSwitch*/);
9637                 // preserve STREAM_MUSIC volume from one user to the next.
9638                 sendMsg(mAudioHandler,
9639                         MSG_SET_ALL_VOLUMES,
9640                         SENDMSG_QUEUE,
9641                         0,
9642                         0,
9643                         mStreamStates[AudioSystem.STREAM_MUSIC], 0);
9644             } else if (action.equals(Intent.ACTION_USER_BACKGROUND)) {
9645                 // Disable audio recording for the background user/profile
9646                 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
9647                 if (userId >= 0) {
9648                     // TODO Kill recording streams instead of killing processes holding permission
9649                     UserInfo userInfo = UserManagerService.getInstance().getUserInfo(userId);
9650                     killBackgroundUserProcessesWithRecordAudioPermission(userInfo);
9651                 }
9652                 try {
9653                     UserManagerService.getInstance().setUserRestriction(
9654                             UserManager.DISALLOW_RECORD_AUDIO, true, userId);
9655                 } catch (IllegalArgumentException e) {
9656                     Slog.w(TAG, "Failed to apply DISALLOW_RECORD_AUDIO restriction: " + e);
9657                 }
9658             } else if (action.equals(Intent.ACTION_USER_FOREGROUND)) {
9659                 // Enable audio recording for foreground user/profile
9660                 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
9661                 try {
9662                     UserManagerService.getInstance().setUserRestriction(
9663                             UserManager.DISALLOW_RECORD_AUDIO, false, userId);
9664                 } catch (IllegalArgumentException e) {
9665                     Slog.w(TAG, "Failed to apply DISALLOW_RECORD_AUDIO restriction: " + e);
9666                 }
9667             } else if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION) ||
9668                     action.equals(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION)) {
9669                 handleAudioEffectBroadcast(context, intent);
9670             } else if (action.equals(Intent.ACTION_PACKAGES_SUSPENDED)) {
9671                 final int[] suspendedUids = intent.getIntArrayExtra(Intent.EXTRA_CHANGED_UID_LIST);
9672                 final String[] suspendedPackages =
9673                         intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
9674                 if (suspendedPackages == null || suspendedUids == null
9675                         || suspendedPackages.length != suspendedUids.length) {
9676                     return;
9677                 }
9678                 for (int i = 0; i < suspendedUids.length; i++) {
9679                     if (!TextUtils.isEmpty(suspendedPackages[i])) {
9680                         mMediaFocusControl.noFocusForSuspendedApp(
9681                                 suspendedPackages[i], suspendedUids[i]);
9682                     }
9683                 }
9684             } else if (action.equals(ACTION_CHECK_MUSIC_ACTIVE)) {
9685                 mSoundDoseHelper.onCheckMusicActive(ACTION_CHECK_MUSIC_ACTIVE,
9686                         mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0));
9687             }
9688         }
9689     } // end class AudioServiceBroadcastReceiver
9690 
9691     private class AudioServiceUserRestrictionsListener implements UserRestrictionsListener {
9692 
9693         @Override
onUserRestrictionsChanged(int userId, Bundle newRestrictions, Bundle prevRestrictions)9694         public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
9695                 Bundle prevRestrictions) {
9696             // Update mic mute state.
9697             {
9698                 final boolean wasRestricted =
9699                         prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE);
9700                 final boolean isRestricted =
9701                         newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE);
9702                 if (wasRestricted != isRestricted) {
9703                     mMicMuteFromRestrictions = isRestricted;
9704                     setMicrophoneMuteNoCallerCheck(userId);
9705                 }
9706             }
9707 
9708             // Update speaker mute state.
9709             {
9710                 final boolean wasRestricted =
9711                         prevRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME)
9712                                 || prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE);
9713                 final boolean isRestricted =
9714                         newRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME)
9715                                 || newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE);
9716                 if (wasRestricted != isRestricted) {
9717                     setMasterMuteInternalNoCallerCheck(isRestricted, /* flags =*/ 0, userId);
9718                 }
9719             }
9720         }
9721     } // end class AudioServiceUserRestrictionsListener
9722 
handleAudioEffectBroadcast(Context context, Intent intent)9723     private void handleAudioEffectBroadcast(Context context, Intent intent) {
9724         String target = intent.getPackage();
9725         if (target != null) {
9726             Log.w(TAG, "effect broadcast already targeted to " + target);
9727             return;
9728         }
9729         intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
9730         // TODO this should target a user-selected panel
9731         List<ResolveInfo> ril = context.getPackageManager().queryBroadcastReceivers(
9732                 intent, 0 /* flags */);
9733         if (ril != null && ril.size() != 0) {
9734             ResolveInfo ri = ril.get(0);
9735             if (ri != null && ri.activityInfo != null && ri.activityInfo.packageName != null) {
9736                 intent.setPackage(ri.activityInfo.packageName);
9737                 context.sendBroadcastAsUser(intent, UserHandle.ALL);
9738                 return;
9739             }
9740         }
9741         Log.w(TAG, "couldn't find receiver package for effect intent");
9742     }
9743 
killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser)9744     private void killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser) {
9745         PackageManager pm = mContext.getPackageManager();
9746         // Find the home activity of the user. It should not be killed to avoid expensive restart,
9747         // when the user switches back. For managed profiles, we should kill all recording apps
9748         ComponentName homeActivityName = null;
9749         if (!oldUser.isManagedProfile()) {
9750             homeActivityName = LocalServices.getService(
9751                     ActivityTaskManagerInternal.class).getHomeActivityForUser(oldUser.id);
9752         }
9753         final String[] permissions = { Manifest.permission.RECORD_AUDIO };
9754         List<PackageInfo> packages;
9755         try {
9756             packages = AppGlobals.getPackageManager()
9757                     .getPackagesHoldingPermissions(permissions, 0, oldUser.id).getList();
9758         } catch (RemoteException e) {
9759             throw new AndroidRuntimeException(e);
9760         }
9761         for (int j = packages.size() - 1; j >= 0; j--) {
9762             PackageInfo pkg = packages.get(j);
9763             // Skip system processes
9764             if (UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID) {
9765                 continue;
9766             }
9767             // Skip packages that have permission to interact across users
9768             if (pm.checkPermission(Manifest.permission.INTERACT_ACROSS_USERS, pkg.packageName)
9769                     == PackageManager.PERMISSION_GRANTED) {
9770                 continue;
9771             }
9772             if (homeActivityName != null
9773                     && pkg.packageName.equals(homeActivityName.getPackageName())
9774                     && pkg.applicationInfo.isSystemApp()) {
9775                 continue;
9776             }
9777             try {
9778                 final int uid = pkg.applicationInfo.uid;
9779                 ActivityManager.getService().killUid(UserHandle.getAppId(uid),
9780                         UserHandle.getUserId(uid),
9781                         "killBackgroundUserProcessesWithAudioRecordPermission");
9782             } catch (RemoteException e) {
9783                 Log.w(TAG, "Error calling killUid", e);
9784             }
9785         }
9786     }
9787 
9788 
9789     //==========================================================================================
9790     // Audio Focus
9791     //==========================================================================================
9792     /**
9793      * Returns whether a focus request is eligible to force ducking.
9794      * Will return true if:
9795      * - the AudioAttributes have a usage of USAGE_ASSISTANCE_ACCESSIBILITY,
9796      * - the focus request is AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK,
9797      * - the associated Bundle has KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING set to true,
9798      * - the uid of the requester is a known accessibility service or root.
9799      * @param aa AudioAttributes of the focus request
9800      * @param uid uid of the focus requester
9801      * @return true if ducking is to be forced
9802      */
forceFocusDuckingForAccessibility(@ullable AudioAttributes aa, int request, int uid)9803     private boolean forceFocusDuckingForAccessibility(@Nullable AudioAttributes aa,
9804             int request, int uid) {
9805         if (aa == null || aa.getUsage() != AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY
9806                 || request != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) {
9807             return false;
9808         }
9809         final Bundle extraInfo = aa.getBundle();
9810         if (extraInfo == null ||
9811                 !extraInfo.getBoolean(AudioFocusRequest.KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING)) {
9812             return false;
9813         }
9814         if (uid == 0) {
9815             return true;
9816         }
9817         synchronized (mAccessibilityServiceUidsLock) {
9818             if (mAccessibilityServiceUids != null) {
9819                 int callingUid = Binder.getCallingUid();
9820                 for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
9821                     if (mAccessibilityServiceUids[i] == callingUid) {
9822                         return true;
9823                     }
9824                 }
9825             }
9826         }
9827         return false;
9828     }
9829 
isSupportedSystemUsage(@udioAttributes.AttributeUsage int usage)9830     private boolean isSupportedSystemUsage(@AudioAttributes.AttributeUsage int usage) {
9831         synchronized (mSupportedSystemUsagesLock) {
9832             for (int i = 0; i < mSupportedSystemUsages.length; i++) {
9833                 if (mSupportedSystemUsages[i] == usage) {
9834                     return true;
9835                 }
9836             }
9837             return false;
9838         }
9839     }
9840 
validateAudioAttributesUsage(@onNull AudioAttributes audioAttributes)9841     private void validateAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) {
9842         @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage();
9843         if (AudioAttributes.isSystemUsage(usage)) {
9844             if ((usage == AudioAttributes.USAGE_CALL_ASSISTANT
9845                     && (audioAttributes.getAllFlags() & AudioAttributes.FLAG_CALL_REDIRECTION) != 0
9846                     && callerHasPermission(Manifest.permission.CALL_AUDIO_INTERCEPTION))
9847                     || callerHasPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)) {
9848                 if (!isSupportedSystemUsage(usage)) {
9849                     throw new IllegalArgumentException(
9850                             "Unsupported usage " + AudioAttributes.usageToString(usage));
9851                 }
9852             } else {
9853                 throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission");
9854             }
9855         }
9856     }
9857 
isValidAudioAttributesUsage(@onNull AudioAttributes audioAttributes)9858     private boolean isValidAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) {
9859         @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage();
9860         if (AudioAttributes.isSystemUsage(usage)) {
9861             return isSupportedSystemUsage(usage)
9862                     && ((usage == AudioAttributes.USAGE_CALL_ASSISTANT
9863                         && (audioAttributes.getAllFlags()
9864                             & AudioAttributes.FLAG_CALL_REDIRECTION) != 0
9865                         && callerHasPermission(Manifest.permission.CALL_AUDIO_INTERCEPTION))
9866                         || callerHasPermission(Manifest.permission.MODIFY_AUDIO_ROUTING));
9867         }
9868         return true;
9869     }
9870 
requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb, IAudioFocusDispatcher fd, String clientId, String callingPackageName, String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk)9871     public int requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb,
9872             IAudioFocusDispatcher fd, String clientId, String callingPackageName,
9873             String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk) {
9874         if ((flags & AudioManager.AUDIOFOCUS_FLAG_TEST) != 0) {
9875             throw new IllegalArgumentException("Invalid test flag");
9876         }
9877         final int uid = Binder.getCallingUid();
9878         MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus")
9879                 .setUid(uid)
9880                 //.putInt("durationHint", durationHint)
9881                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName)
9882                 .set(MediaMetrics.Property.CLIENT_NAME, clientId)
9883                 .set(MediaMetrics.Property.EVENT, "requestAudioFocus")
9884                 .set(MediaMetrics.Property.FLAGS, flags);
9885 
9886         // permission checks
9887         if (aa != null && !isValidAudioAttributesUsage(aa)) {
9888             final String reason = "Request using unsupported usage";
9889             Log.w(TAG, reason);
9890             mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
9891                     .record();
9892             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9893         }
9894         if ((flags & AudioManager.AUDIOFOCUS_FLAG_LOCK) == AudioManager.AUDIOFOCUS_FLAG_LOCK) {
9895             if (AudioSystem.IN_VOICE_COMM_FOCUS_ID.equals(clientId)) {
9896                 if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
9897                             android.Manifest.permission.MODIFY_PHONE_STATE)) {
9898                     final String reason = "Invalid permission to (un)lock audio focus";
9899                     Log.e(TAG, reason, new Exception());
9900                     mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
9901                             .record();
9902                     return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9903                 }
9904             } else {
9905                 // only a registered audio policy can be used to lock focus
9906                 synchronized (mAudioPolicies) {
9907                     if (!mAudioPolicies.containsKey(pcb.asBinder())) {
9908                         final String reason =
9909                                 "Invalid unregistered AudioPolicy to (un)lock audio focus";
9910                         Log.e(TAG, reason);
9911                         mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
9912                                 .record();
9913                         return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9914                     }
9915                 }
9916             }
9917         }
9918 
9919         if (callingPackageName == null || clientId == null || aa == null) {
9920             final String reason = "Invalid null parameter to request audio focus";
9921             Log.e(TAG, reason);
9922             mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
9923                     .record();
9924             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9925         }
9926         mmi.record();
9927         return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd,
9928                 clientId, callingPackageName, attributionTag, flags, sdk,
9929                 forceFocusDuckingForAccessibility(aa, durationHint, uid), -1 /*testUid, ignored*/);
9930     }
9931 
9932     /** see {@link AudioManager#requestAudioFocusForTest(AudioFocusRequest, String, int, int)} */
requestAudioFocusForTest(AudioAttributes aa, int durationHint, IBinder cb, IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags, int fakeUid, int sdk)9933     public int requestAudioFocusForTest(AudioAttributes aa, int durationHint, IBinder cb,
9934             IAudioFocusDispatcher fd, String clientId, String callingPackageName,
9935             int flags, int fakeUid, int sdk) {
9936         if (!enforceQueryAudioStateForTest("focus request")) {
9937             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9938         }
9939         if (callingPackageName == null || clientId == null || aa == null) {
9940             final String reason = "Invalid null parameter to request audio focus";
9941             Log.e(TAG, reason);
9942             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9943         }
9944         return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd,
9945                 clientId, callingPackageName, null, flags,
9946                 sdk, false /*forceDuck*/, fakeUid);
9947     }
9948 
abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)9949     public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa,
9950             String callingPackageName) {
9951         MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus")
9952                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName)
9953                 .set(MediaMetrics.Property.CLIENT_NAME, clientId)
9954                 .set(MediaMetrics.Property.EVENT, "abandonAudioFocus");
9955 
9956         if (aa != null && !isValidAudioAttributesUsage(aa)) {
9957             Log.w(TAG, "Request using unsupported usage.");
9958             mmi.set(MediaMetrics.Property.EARLY_RETURN, "unsupported usage").record();
9959 
9960             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9961         }
9962         mmi.record();
9963         return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName);
9964     }
9965 
9966     /** see {@link AudioManager#abandonAudioFocusForTest(AudioFocusRequest, String)} */
abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)9967     public int abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId,
9968             AudioAttributes aa, String callingPackageName) {
9969         if (!enforceQueryAudioStateForTest("focus abandon")) {
9970             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9971         }
9972         return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName);
9973     }
9974 
unregisterAudioFocusClient(String clientId)9975     public void unregisterAudioFocusClient(String clientId) {
9976         new MediaMetrics.Item(mMetricsId + "focus")
9977                 .set(MediaMetrics.Property.CLIENT_NAME, clientId)
9978                 .set(MediaMetrics.Property.EVENT, "unregisterAudioFocusClient")
9979                 .record();
9980         mMediaFocusControl.unregisterAudioFocusClient(clientId);
9981     }
9982 
getCurrentAudioFocus()9983     public int getCurrentAudioFocus() {
9984         return mMediaFocusControl.getCurrentAudioFocus();
9985     }
9986 
getFocusRampTimeMs(int focusGain, AudioAttributes attr)9987     public int getFocusRampTimeMs(int focusGain, AudioAttributes attr) {
9988         return mMediaFocusControl.getFocusRampTimeMs(focusGain, attr);
9989     }
9990 
9991     /** only public for mocking/spying, do not call outside of AudioService */
9992     @VisibleForTesting
hasAudioFocusUsers()9993     public boolean hasAudioFocusUsers() {
9994         return mMediaFocusControl.hasAudioFocusUsers();
9995     }
9996 
9997     /** see {@link AudioManager#getFadeOutDurationOnFocusLossMillis(AudioAttributes)} */
getFadeOutDurationOnFocusLossMillis(AudioAttributes aa)9998     public long getFadeOutDurationOnFocusLossMillis(AudioAttributes aa) {
9999         if (!enforceQueryAudioStateForTest("fade out duration")) {
10000             return 0;
10001         }
10002         return mMediaFocusControl.getFadeOutDurationOnFocusLossMillis(aa);
10003     }
10004 
enforceQueryAudioStateForTest(String mssg)10005     private boolean enforceQueryAudioStateForTest(String mssg) {
10006         if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
10007                 Manifest.permission.QUERY_AUDIO_STATE)) {
10008             final String reason = "Doesn't have QUERY_AUDIO_STATE permission for "
10009                     + mssg + " test API";
10010             Log.e(TAG, reason, new Exception());
10011             return false;
10012         }
10013         return true;
10014     }
10015 
10016     //==========================================================================================
10017     private final @NonNull SpatializerHelper mSpatializerHelper;
10018     /**
10019      * Initialized from property ro.audio.spatializer_enabled
10020      * Should only be 1 when the device ships with a Spatializer effect
10021      */
10022     private final boolean mHasSpatializerEffect;
10023     /**
10024      * Default value for the spatial audio feature
10025      */
10026     private static final boolean SPATIAL_AUDIO_ENABLED_DEFAULT = true;
10027 
enforceModifyDefaultAudioEffectsPermission()10028     private void enforceModifyDefaultAudioEffectsPermission() {
10029         if (mContext.checkCallingOrSelfPermission(
10030                 android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10031                 != PackageManager.PERMISSION_GRANTED) {
10032             throw new SecurityException("Missing MODIFY_DEFAULT_AUDIO_EFFECTS permission");
10033         }
10034     }
10035 
10036     /**
10037      * Returns the immersive audio level that the platform is capable of
10038      * @see Spatializer#getImmersiveAudioLevel()
10039      */
getSpatializerImmersiveAudioLevel()10040     public int getSpatializerImmersiveAudioLevel() {
10041         return mSpatializerHelper.getCapableImmersiveAudioLevel();
10042     }
10043 
10044     /** @see Spatializer#isEnabled() */
isSpatializerEnabled()10045     public boolean isSpatializerEnabled() {
10046         return mSpatializerHelper.isEnabled();
10047     }
10048 
10049     /** @see Spatializer#isAvailable() */
isSpatializerAvailable()10050     public boolean isSpatializerAvailable() {
10051         return mSpatializerHelper.isAvailable();
10052     }
10053 
10054     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10055     /** @see Spatializer#isAvailableForDevice(AudioDeviceAttributes) */
isSpatializerAvailableForDevice(@onNull AudioDeviceAttributes device)10056     public boolean isSpatializerAvailableForDevice(@NonNull AudioDeviceAttributes device)  {
10057         super.isSpatializerAvailableForDevice_enforcePermission();
10058 
10059         return mSpatializerHelper.isAvailableForDevice(Objects.requireNonNull(device));
10060     }
10061 
10062     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10063     /** @see Spatializer#hasHeadTracker(AudioDeviceAttributes) */
hasHeadTracker(@onNull AudioDeviceAttributes device)10064     public boolean hasHeadTracker(@NonNull AudioDeviceAttributes device) {
10065         super.hasHeadTracker_enforcePermission();
10066 
10067         return mSpatializerHelper.hasHeadTracker(Objects.requireNonNull(device));
10068     }
10069 
10070     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10071     /** @see Spatializer#setHeadTrackerEnabled(boolean, AudioDeviceAttributes) */
setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device)10072     public void setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device) {
10073         super.setHeadTrackerEnabled_enforcePermission();
10074 
10075         mSpatializerHelper.setHeadTrackerEnabled(enabled, Objects.requireNonNull(device));
10076     }
10077 
10078     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10079     /** @see Spatializer#isHeadTrackerEnabled(AudioDeviceAttributes) */
isHeadTrackerEnabled(@onNull AudioDeviceAttributes device)10080     public boolean isHeadTrackerEnabled(@NonNull AudioDeviceAttributes device) {
10081         super.isHeadTrackerEnabled_enforcePermission();
10082 
10083         return mSpatializerHelper.isHeadTrackerEnabled(Objects.requireNonNull(device));
10084     }
10085 
10086     /** @see Spatializer#isHeadTrackerAvailable() */
isHeadTrackerAvailable()10087     public boolean isHeadTrackerAvailable() {
10088         return mSpatializerHelper.isHeadTrackerAvailable();
10089     }
10090 
10091     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10092     /** @see Spatializer#setSpatializerEnabled(boolean) */
setSpatializerEnabled(boolean enabled)10093     public void setSpatializerEnabled(boolean enabled) {
10094         super.setSpatializerEnabled_enforcePermission();
10095 
10096         mSpatializerHelper.setFeatureEnabled(enabled);
10097     }
10098 
10099     /** @see Spatializer#canBeSpatialized() */
canBeSpatialized( @onNull AudioAttributes attributes, @NonNull AudioFormat format)10100     public boolean canBeSpatialized(
10101             @NonNull AudioAttributes attributes, @NonNull AudioFormat format) {
10102         Objects.requireNonNull(attributes);
10103         Objects.requireNonNull(format);
10104         return mSpatializerHelper.canBeSpatialized(attributes, format);
10105     }
10106 
10107     /** @see Spatializer.SpatializerInfoDispatcherStub */
registerSpatializerCallback( @onNull ISpatializerCallback cb)10108     public void registerSpatializerCallback(
10109             @NonNull ISpatializerCallback cb) {
10110         Objects.requireNonNull(cb);
10111         mSpatializerHelper.registerStateCallback(cb);
10112     }
10113 
10114     /** @see Spatializer.SpatializerInfoDispatcherStub */
unregisterSpatializerCallback( @onNull ISpatializerCallback cb)10115     public void unregisterSpatializerCallback(
10116             @NonNull ISpatializerCallback cb) {
10117         Objects.requireNonNull(cb);
10118         mSpatializerHelper.unregisterStateCallback(cb);
10119     }
10120 
10121     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10122     /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */
registerSpatializerHeadTrackingCallback( @onNull ISpatializerHeadTrackingModeCallback cb)10123     public void registerSpatializerHeadTrackingCallback(
10124             @NonNull ISpatializerHeadTrackingModeCallback cb) {
10125         super.registerSpatializerHeadTrackingCallback_enforcePermission();
10126 
10127         Objects.requireNonNull(cb);
10128         mSpatializerHelper.registerHeadTrackingModeCallback(cb);
10129     }
10130 
10131     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10132     /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */
unregisterSpatializerHeadTrackingCallback( @onNull ISpatializerHeadTrackingModeCallback cb)10133     public void unregisterSpatializerHeadTrackingCallback(
10134             @NonNull ISpatializerHeadTrackingModeCallback cb) {
10135         super.unregisterSpatializerHeadTrackingCallback_enforcePermission();
10136 
10137         Objects.requireNonNull(cb);
10138         mSpatializerHelper.unregisterHeadTrackingModeCallback(cb);
10139     }
10140 
10141     /** @see Spatializer.SpatializerHeadTrackerAvailableDispatcherStub */
registerSpatializerHeadTrackerAvailableCallback( @onNull ISpatializerHeadTrackerAvailableCallback cb, boolean register)10142     public void registerSpatializerHeadTrackerAvailableCallback(
10143             @NonNull ISpatializerHeadTrackerAvailableCallback cb, boolean register) {
10144         Objects.requireNonNull(cb);
10145         mSpatializerHelper.registerHeadTrackerAvailableCallback(cb, register);
10146     }
10147 
10148     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10149     /** @see Spatializer#setOnHeadToSoundstagePoseUpdatedListener */
registerHeadToSoundstagePoseCallback( @onNull ISpatializerHeadToSoundStagePoseCallback cb)10150     public void registerHeadToSoundstagePoseCallback(
10151             @NonNull ISpatializerHeadToSoundStagePoseCallback cb) {
10152         super.registerHeadToSoundstagePoseCallback_enforcePermission();
10153 
10154         Objects.requireNonNull(cb);
10155         mSpatializerHelper.registerHeadToSoundstagePoseCallback(cb);
10156     }
10157 
10158     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10159     /** @see Spatializer#clearOnHeadToSoundstagePoseUpdatedListener */
unregisterHeadToSoundstagePoseCallback( @onNull ISpatializerHeadToSoundStagePoseCallback cb)10160     public void unregisterHeadToSoundstagePoseCallback(
10161             @NonNull ISpatializerHeadToSoundStagePoseCallback cb) {
10162         super.unregisterHeadToSoundstagePoseCallback_enforcePermission();
10163 
10164         Objects.requireNonNull(cb);
10165         mSpatializerHelper.unregisterHeadToSoundstagePoseCallback(cb);
10166     }
10167 
10168     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10169     /** @see Spatializer#getSpatializerCompatibleAudioDevices() */
getSpatializerCompatibleAudioDevices()10170     public @NonNull List<AudioDeviceAttributes> getSpatializerCompatibleAudioDevices() {
10171         super.getSpatializerCompatibleAudioDevices_enforcePermission();
10172 
10173         return mSpatializerHelper.getCompatibleAudioDevices();
10174     }
10175 
10176     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10177     /** @see Spatializer#addSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */
addSpatializerCompatibleAudioDevice(@onNull AudioDeviceAttributes ada)10178     public void addSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
10179         super.addSpatializerCompatibleAudioDevice_enforcePermission();
10180 
10181         Objects.requireNonNull(ada);
10182         mSpatializerHelper.addCompatibleAudioDevice(ada);
10183     }
10184 
10185     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10186     /** @see Spatializer#removeSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */
removeSpatializerCompatibleAudioDevice(@onNull AudioDeviceAttributes ada)10187     public void removeSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
10188         super.removeSpatializerCompatibleAudioDevice_enforcePermission();
10189 
10190         Objects.requireNonNull(ada);
10191         mSpatializerHelper.removeCompatibleAudioDevice(ada);
10192     }
10193 
10194     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10195     /** @see Spatializer#getSupportedHeadTrackingModes() */
getSupportedHeadTrackingModes()10196     public int[] getSupportedHeadTrackingModes() {
10197         super.getSupportedHeadTrackingModes_enforcePermission();
10198 
10199         return mSpatializerHelper.getSupportedHeadTrackingModes();
10200     }
10201 
10202     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10203     /** @see Spatializer#getHeadTrackingMode() */
getActualHeadTrackingMode()10204     public int getActualHeadTrackingMode() {
10205         super.getActualHeadTrackingMode_enforcePermission();
10206 
10207         return mSpatializerHelper.getActualHeadTrackingMode();
10208     }
10209 
10210     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10211     /** @see Spatializer#getDesiredHeadTrackingMode() */
getDesiredHeadTrackingMode()10212     public int getDesiredHeadTrackingMode() {
10213         super.getDesiredHeadTrackingMode_enforcePermission();
10214 
10215         return mSpatializerHelper.getDesiredHeadTrackingMode();
10216     }
10217 
10218     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10219     /** @see Spatializer#setGlobalTransform */
setSpatializerGlobalTransform(@onNull float[] transform)10220     public void setSpatializerGlobalTransform(@NonNull float[] transform) {
10221         super.setSpatializerGlobalTransform_enforcePermission();
10222 
10223         Objects.requireNonNull(transform);
10224         mSpatializerHelper.setGlobalTransform(transform);
10225     }
10226 
10227     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10228     /** @see Spatializer#recenterHeadTracker() */
recenterHeadTracker()10229     public void recenterHeadTracker() {
10230         super.recenterHeadTracker_enforcePermission();
10231 
10232         mSpatializerHelper.recenterHeadTracker();
10233     }
10234 
10235     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10236     /** @see Spatializer#setDesiredHeadTrackingMode */
setDesiredHeadTrackingMode(@patializer.HeadTrackingModeSet int mode)10237     public void setDesiredHeadTrackingMode(@Spatializer.HeadTrackingModeSet int mode) {
10238         super.setDesiredHeadTrackingMode_enforcePermission();
10239 
10240         switch(mode) {
10241             case Spatializer.HEAD_TRACKING_MODE_DISABLED:
10242             case Spatializer.HEAD_TRACKING_MODE_RELATIVE_WORLD:
10243             case Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE:
10244                 break;
10245             default:
10246                 return;
10247         }
10248         mSpatializerHelper.setDesiredHeadTrackingMode(mode);
10249     }
10250 
10251     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10252     /** @see Spatializer#setEffectParameter */
setSpatializerParameter(int key, @NonNull byte[] value)10253     public void setSpatializerParameter(int key, @NonNull byte[] value) {
10254         super.setSpatializerParameter_enforcePermission();
10255 
10256         Objects.requireNonNull(value);
10257         mSpatializerHelper.setEffectParameter(key, value);
10258     }
10259 
10260     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10261     /** @see Spatializer#getEffectParameter */
getSpatializerParameter(int key, @NonNull byte[] value)10262     public void getSpatializerParameter(int key, @NonNull byte[] value) {
10263         super.getSpatializerParameter_enforcePermission();
10264 
10265         Objects.requireNonNull(value);
10266         mSpatializerHelper.getEffectParameter(key, value);
10267     }
10268 
10269     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10270     /** @see Spatializer#getOutput */
getSpatializerOutput()10271     public int getSpatializerOutput() {
10272         super.getSpatializerOutput_enforcePermission();
10273 
10274         return mSpatializerHelper.getOutput();
10275     }
10276 
10277     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10278     /** @see Spatializer#setOnSpatializerOutputChangedListener */
registerSpatializerOutputCallback(ISpatializerOutputCallback cb)10279     public void registerSpatializerOutputCallback(ISpatializerOutputCallback cb) {
10280         super.registerSpatializerOutputCallback_enforcePermission();
10281 
10282         Objects.requireNonNull(cb);
10283         mSpatializerHelper.registerSpatializerOutputCallback(cb);
10284     }
10285 
10286     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10287     /** @see Spatializer#clearOnSpatializerOutputChangedListener */
unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb)10288     public void unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb) {
10289         super.unregisterSpatializerOutputCallback_enforcePermission();
10290 
10291         Objects.requireNonNull(cb);
10292         mSpatializerHelper.unregisterSpatializerOutputCallback(cb);
10293     }
10294 
10295     /**
10296      * post a message to schedule init/release of head tracking sensors
10297      * whether to initialize or release sensors is based on the state of spatializer
10298      */
postInitSpatializerHeadTrackingSensors()10299     void postInitSpatializerHeadTrackingSensors() {
10300         sendMsg(mAudioHandler,
10301                 MSG_INIT_HEADTRACKING_SENSORS,
10302                 SENDMSG_REPLACE,
10303                 /*arg1*/ 0, /*arg2*/ 0, TAG, /*delay*/ 0);
10304     }
10305 
10306     /**
10307      * post a message to schedule a reset of the spatializer state
10308      */
postResetSpatializer()10309     void postResetSpatializer() {
10310         sendMsg(mAudioHandler,
10311                 MSG_RESET_SPATIALIZER,
10312                 SENDMSG_REPLACE,
10313                 /*arg1*/ 0, /*arg2*/ 0, TAG, /*delay*/ 0);
10314     }
10315 
onInitAdiDeviceStates()10316     void onInitAdiDeviceStates() {
10317         mDeviceBroker.onReadAudioDeviceSettings();
10318         mSoundDoseHelper.initCachedAudioDeviceCategories(
10319                 mDeviceBroker.getImmutableDeviceInventory());
10320     }
10321 
onInitSpatializer()10322     void onInitSpatializer() {
10323         mSpatializerHelper.init(/*effectExpected*/ mHasSpatializerEffect);
10324         mSpatializerHelper.setFeatureEnabled(mHasSpatializerEffect);
10325     }
10326 
isBluetoothPrividged()10327     private boolean isBluetoothPrividged() {
10328         return PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
10329                 android.Manifest.permission.BLUETOOTH_CONNECT)
10330                 || Binder.getCallingUid() == Process.SYSTEM_UID;
10331     }
10332 
retrieveBluetoothAddresses(List<AudioDeviceAttributes> devices)10333     List<AudioDeviceAttributes> retrieveBluetoothAddresses(List<AudioDeviceAttributes> devices) {
10334         if (isBluetoothPrividged()) {
10335             return devices;
10336         }
10337 
10338         List<AudioDeviceAttributes> checkedDevices = new ArrayList<AudioDeviceAttributes>();
10339         for (AudioDeviceAttributes ada : devices) {
10340             if (ada == null) {
10341                 continue;
10342             }
10343             checkedDevices.add(retrieveBluetoothAddressUncheked(ada));
10344         }
10345         return checkedDevices;
10346     }
10347 
retrieveBluetoothAddress(@onNull AudioDeviceAttributes ada)10348     AudioDeviceAttributes retrieveBluetoothAddress(@NonNull AudioDeviceAttributes ada) {
10349         if (isBluetoothPrividged()) {
10350             return ada;
10351         }
10352         return retrieveBluetoothAddressUncheked(ada);
10353     }
10354 
retrieveBluetoothAddressUncheked(@onNull AudioDeviceAttributes ada)10355     AudioDeviceAttributes retrieveBluetoothAddressUncheked(@NonNull AudioDeviceAttributes ada) {
10356         Objects.requireNonNull(ada);
10357         if (AudioSystem.isBluetoothDevice(ada.getInternalType())) {
10358             String anonymizedAddress = anonymizeBluetoothAddress(ada.getAddress());
10359             for (AdiDeviceState ads : mDeviceBroker.getImmutableDeviceInventory()) {
10360                 if (!(AudioSystem.isBluetoothDevice(ads.getInternalDeviceType())
10361                         && (ada.getInternalType() == ads.getInternalDeviceType())
10362                         && anonymizedAddress.equals(anonymizeBluetoothAddress(
10363                                 ads.getDeviceAddress())))) {
10364                     continue;
10365                 }
10366                 ada.setAddress(ads.getDeviceAddress());
10367                 break;
10368             }
10369         }
10370         return ada;
10371     }
10372 
10373     /**
10374      * Convert a Bluetooth MAC address to an anonymized one when exposed to a non privileged app
10375      * Must match the implementation of BluetoothUtils.toAnonymizedAddress()
10376      * @param address Mac address to be anonymized
10377      * @return anonymized mac address
10378      */
anonymizeBluetoothAddress(String address)10379     static String anonymizeBluetoothAddress(String address) {
10380         if (address == null || address.length() != "AA:BB:CC:DD:EE:FF".length()) {
10381             return null;
10382         }
10383         return "XX:XX:XX:XX" + address.substring("XX:XX:XX:XX".length());
10384     }
10385 
anonymizeAudioDeviceAttributesList( List<AudioDeviceAttributes> devices)10386     private List<AudioDeviceAttributes> anonymizeAudioDeviceAttributesList(
10387                 List<AudioDeviceAttributes> devices) {
10388         if (isBluetoothPrividged()) {
10389             return devices;
10390         }
10391         return anonymizeAudioDeviceAttributesListUnchecked(devices);
10392     }
10393 
anonymizeAudioDeviceAttributesListUnchecked( List<AudioDeviceAttributes> devices)10394     /* package */ List<AudioDeviceAttributes> anonymizeAudioDeviceAttributesListUnchecked(
10395             List<AudioDeviceAttributes> devices) {
10396         List<AudioDeviceAttributes> anonymizedDevices = new ArrayList<AudioDeviceAttributes>();
10397         for (AudioDeviceAttributes ada : devices) {
10398             anonymizedDevices.add(anonymizeAudioDeviceAttributesUnchecked(ada));
10399         }
10400         return anonymizedDevices;
10401     }
10402 
anonymizeAudioDeviceAttributesUnchecked( AudioDeviceAttributes ada)10403     private AudioDeviceAttributes anonymizeAudioDeviceAttributesUnchecked(
10404             AudioDeviceAttributes ada) {
10405         if (!AudioSystem.isBluetoothDevice(ada.getInternalType())) {
10406             return ada;
10407         }
10408         AudioDeviceAttributes res = new AudioDeviceAttributes(ada);
10409         res.setAddress(anonymizeBluetoothAddress(ada.getAddress()));
10410         return res;
10411     }
10412 
anonymizeAudioDeviceAttributes(AudioDeviceAttributes ada)10413     private AudioDeviceAttributes anonymizeAudioDeviceAttributes(AudioDeviceAttributes ada) {
10414         if (isBluetoothPrividged()) {
10415             return ada;
10416         }
10417 
10418         return anonymizeAudioDeviceAttributesUnchecked(ada);
10419     }
10420 
10421     //==========================================================================================
10422 
10423     // camera sound is forced if any of the resources corresponding to one active SIM
10424     // demands it.
readCameraSoundForced()10425     private boolean readCameraSoundForced() {
10426         if (SystemProperties.getBoolean("audio.camerasound.force", false)
10427                 || mContext.getResources().getBoolean(
10428                         com.android.internal.R.bool.config_camera_sound_forced)) {
10429             return true;
10430         }
10431 
10432         SubscriptionManager subscriptionManager = mContext.getSystemService(
10433                 SubscriptionManager.class);
10434         if (subscriptionManager == null) {
10435             Log.e(TAG, "readCameraSoundForced cannot create SubscriptionManager!");
10436             return false;
10437         }
10438         int[] subscriptionIds = subscriptionManager.getActiveSubscriptionIdList(false);
10439         for (int subId : subscriptionIds) {
10440             if (SubscriptionManager.getResourcesForSubId(mContext, subId).getBoolean(
10441                     com.android.internal.R.bool.config_camera_sound_forced)) {
10442                 return true;
10443             }
10444         }
10445         return false;
10446     }
10447 
10448     //==========================================================================================
10449     private final Object mMuteAwaitConnectionLock = new Object();
10450 
10451     /**
10452      * The device that is expected to be connected soon, and causes players to be muted until
10453      * its connection, or it times out.
10454      * Null when no active muting command, or it has timed out.
10455      */
10456     @GuardedBy("mMuteAwaitConnectionLock")
10457     private AudioDeviceAttributes mMutingExpectedDevice;
10458     @GuardedBy("mMuteAwaitConnectionLock")
10459     private @Nullable int[] mMutedUsagesAwaitingConnection;
10460 
10461     /** @see AudioManager#muteAwaitConnection */
10462     @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection
muteAwaitConnection(@onNull int[] usages, @NonNull AudioDeviceAttributes device, long timeOutMs)10463     public void muteAwaitConnection(@NonNull int[] usages,
10464             @NonNull AudioDeviceAttributes device, long timeOutMs) {
10465         Objects.requireNonNull(usages);
10466         Objects.requireNonNull(device);
10467         enforceModifyAudioRoutingPermission();
10468 
10469         final AudioDeviceAttributes ada = retrieveBluetoothAddress(device);
10470 
10471         if (timeOutMs <= 0 || usages.length == 0) {
10472             throw new IllegalArgumentException("Invalid timeOutMs/usagesToMute");
10473         }
10474         Log.i(TAG, "muteAwaitConnection dev:" + device + " timeOutMs:" + timeOutMs
10475                 + " usages:" + Arrays.toString(usages));
10476 
10477         if (mDeviceBroker.isDeviceConnected(ada)) {
10478             // not throwing an exception as there could be a race between a connection (server-side,
10479             // notification of connection in flight) and a mute operation (client-side)
10480             Log.i(TAG, "muteAwaitConnection ignored, device (" + device + ") already connected");
10481             return;
10482         }
10483         synchronized (mMuteAwaitConnectionLock) {
10484             if (mMutingExpectedDevice != null) {
10485                 Log.e(TAG, "muteAwaitConnection ignored, another in progress for device:"
10486                         + mMutingExpectedDevice);
10487                 throw new IllegalStateException("muteAwaitConnection already in progress");
10488             }
10489             mMutingExpectedDevice = ada;
10490             mMutedUsagesAwaitingConnection = usages;
10491             mPlaybackMonitor.muteAwaitConnection(usages, ada, timeOutMs);
10492         }
10493         dispatchMuteAwaitConnection((cb, isPrivileged) -> {
10494             try {
10495                 AudioDeviceAttributes dev = ada;
10496                 if (!isPrivileged) {
10497                     dev = anonymizeAudioDeviceAttributesUnchecked(ada);
10498                 }
10499                 cb.dispatchOnMutedUntilConnection(dev, usages);
10500             } catch (RemoteException e) { }
10501         });
10502     }
10503 
10504     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
10505     /** @see AudioManager#getMutingExpectedDevice */
getMutingExpectedDevice()10506     public @Nullable AudioDeviceAttributes getMutingExpectedDevice() {
10507         super.getMutingExpectedDevice_enforcePermission();
10508 
10509         synchronized (mMuteAwaitConnectionLock) {
10510             return anonymizeAudioDeviceAttributes(mMutingExpectedDevice);
10511         }
10512     }
10513 
10514     /** @see AudioManager#cancelMuteAwaitConnection */
10515     @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection
cancelMuteAwaitConnection(@onNull AudioDeviceAttributes device)10516     public void cancelMuteAwaitConnection(@NonNull AudioDeviceAttributes device) {
10517         Objects.requireNonNull(device);
10518         enforceModifyAudioRoutingPermission();
10519 
10520         final AudioDeviceAttributes ada = retrieveBluetoothAddress(device);
10521 
10522         Log.i(TAG, "cancelMuteAwaitConnection for device:" + device);
10523         final int[] mutedUsages;
10524         synchronized (mMuteAwaitConnectionLock) {
10525             if (mMutingExpectedDevice == null) {
10526                 // not throwing an exception as there could be a race between a timeout
10527                 // (server-side) and a cancel operation (client-side)
10528                 Log.i(TAG, "cancelMuteAwaitConnection ignored, no expected device");
10529                 return;
10530             }
10531             if (!ada.equalTypeAddress(mMutingExpectedDevice)) {
10532                 Log.e(TAG, "cancelMuteAwaitConnection ignored, got " + device
10533                         + "] but expected device is" + mMutingExpectedDevice);
10534                 throw new IllegalStateException("cancelMuteAwaitConnection for wrong device");
10535             }
10536             mutedUsages = mMutedUsagesAwaitingConnection;
10537             mMutingExpectedDevice = null;
10538             mMutedUsagesAwaitingConnection = null;
10539             mPlaybackMonitor.cancelMuteAwaitConnection("cancelMuteAwaitConnection dev:" + device);
10540         }
10541         dispatchMuteAwaitConnection((cb, isPrivileged) -> {
10542             try {
10543                 AudioDeviceAttributes dev = ada;
10544                 if (!isPrivileged) {
10545                     dev = anonymizeAudioDeviceAttributesUnchecked(ada);
10546                 }
10547                 cb.dispatchOnUnmutedEvent(
10548                         AudioManager.MuteAwaitConnectionCallback.EVENT_CANCEL, dev, mutedUsages);
10549             } catch (RemoteException e) { } });
10550     }
10551 
10552     final RemoteCallbackList<IMuteAwaitConnectionCallback> mMuteAwaitConnectionDispatchers =
10553             new RemoteCallbackList<IMuteAwaitConnectionCallback>();
10554 
10555     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
10556     /** @see AudioManager#registerMuteAwaitConnectionCallback */
registerMuteAwaitConnectionDispatcher(@onNull IMuteAwaitConnectionCallback cb, boolean register)10557     public void registerMuteAwaitConnectionDispatcher(@NonNull IMuteAwaitConnectionCallback cb,
10558             boolean register) {
10559         super.registerMuteAwaitConnectionDispatcher_enforcePermission();
10560 
10561         if (register) {
10562             mMuteAwaitConnectionDispatchers.register(cb, isBluetoothPrividged());
10563         } else {
10564             mMuteAwaitConnectionDispatchers.unregister(cb);
10565         }
10566     }
10567 
10568     @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection
checkMuteAwaitConnection()10569     void checkMuteAwaitConnection() {
10570         final AudioDeviceAttributes device;
10571         final int[] mutedUsages;
10572         synchronized (mMuteAwaitConnectionLock) {
10573             if (mMutingExpectedDevice == null) {
10574                 return;
10575             }
10576             device = mMutingExpectedDevice;
10577             mutedUsages = mMutedUsagesAwaitingConnection;
10578             if (!mDeviceBroker.isDeviceConnected(device)) {
10579                 return;
10580             }
10581             mMutingExpectedDevice = null;
10582             mMutedUsagesAwaitingConnection = null;
10583             mPlaybackMonitor.cancelMuteAwaitConnection(
10584                     "checkMuteAwaitConnection device " + device + " connected, unmuting");
10585         }
10586         dispatchMuteAwaitConnection((cb, isPrivileged) -> {
10587             try {
10588                 AudioDeviceAttributes ada = device;
10589                 if (!isPrivileged) {
10590                     ada = anonymizeAudioDeviceAttributesUnchecked(device);
10591                 }
10592                 cb.dispatchOnUnmutedEvent(AudioManager.MuteAwaitConnectionCallback.EVENT_CONNECTION,
10593                         ada, mutedUsages);
10594             } catch (RemoteException e) { } });
10595     }
10596 
10597     /**
10598      * Called by PlaybackActivityMonitor when the timeout hit for the mute on device connection
10599      */
10600     @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection
onMuteAwaitConnectionTimeout(@onNull AudioDeviceAttributes timedOutDevice)10601     void onMuteAwaitConnectionTimeout(@NonNull AudioDeviceAttributes timedOutDevice) {
10602         final int[] mutedUsages;
10603         synchronized (mMuteAwaitConnectionLock) {
10604             if (!timedOutDevice.equals(mMutingExpectedDevice)) {
10605                 return;
10606             }
10607             Log.i(TAG, "muteAwaitConnection timeout, clearing expected device "
10608                     + mMutingExpectedDevice);
10609             mutedUsages = mMutedUsagesAwaitingConnection;
10610             mMutingExpectedDevice = null;
10611             mMutedUsagesAwaitingConnection = null;
10612         }
10613         dispatchMuteAwaitConnection((cb, isPrivileged) -> {
10614             try {
10615                 cb.dispatchOnUnmutedEvent(
10616                         AudioManager.MuteAwaitConnectionCallback.EVENT_TIMEOUT,
10617                         timedOutDevice, mutedUsages);
10618             } catch (RemoteException e) { } });
10619     }
10620 
dispatchMuteAwaitConnection( java.util.function.BiConsumer<IMuteAwaitConnectionCallback, Boolean> callback)10621     private void dispatchMuteAwaitConnection(
10622             java.util.function.BiConsumer<IMuteAwaitConnectionCallback, Boolean> callback) {
10623         final int nbDispatchers = mMuteAwaitConnectionDispatchers.beginBroadcast();
10624         // lazy initialization as errors unlikely
10625         ArrayList<IMuteAwaitConnectionCallback> errorList = null;
10626         for (int i = 0; i < nbDispatchers; i++) {
10627             try {
10628                 callback.accept(mMuteAwaitConnectionDispatchers.getBroadcastItem(i),
10629                         (Boolean) mMuteAwaitConnectionDispatchers.getBroadcastCookie(i));
10630             } catch (Exception e) {
10631                 if (errorList == null) {
10632                     errorList = new ArrayList<>(1);
10633                 }
10634                 errorList.add(mMuteAwaitConnectionDispatchers.getBroadcastItem(i));
10635             }
10636         }
10637         if (errorList != null) {
10638             for (IMuteAwaitConnectionCallback errorItem : errorList) {
10639                 mMuteAwaitConnectionDispatchers.unregister(errorItem);
10640             }
10641         }
10642         mMuteAwaitConnectionDispatchers.finishBroadcast();
10643     }
10644 
10645     final RemoteCallbackList<IDeviceVolumeBehaviorDispatcher> mDeviceVolumeBehaviorDispatchers =
10646             new RemoteCallbackList<IDeviceVolumeBehaviorDispatcher>();
10647 
10648     /**
10649      *  @see AudioDeviceVolumeManager#addOnDeviceVolumeBehaviorChangedListener and
10650      *  AudioDeviceVolumeManager#removeOnDeviceVolumeBehaviorChangedListener
10651      */
registerDeviceVolumeBehaviorDispatcher(boolean register, @NonNull IDeviceVolumeBehaviorDispatcher dispatcher)10652     public void registerDeviceVolumeBehaviorDispatcher(boolean register,
10653             @NonNull IDeviceVolumeBehaviorDispatcher dispatcher) {
10654         enforceQueryStateOrModifyRoutingPermission();
10655         Objects.requireNonNull(dispatcher);
10656         if (register) {
10657             mDeviceVolumeBehaviorDispatchers.register(dispatcher);
10658         } else {
10659             mDeviceVolumeBehaviorDispatchers.unregister(dispatcher);
10660         }
10661     }
10662 
dispatchDeviceVolumeBehavior(AudioDeviceAttributes device, int volumeBehavior)10663     private void dispatchDeviceVolumeBehavior(AudioDeviceAttributes device, int volumeBehavior) {
10664         final int dispatchers = mDeviceVolumeBehaviorDispatchers.beginBroadcast();
10665         for (int i = 0; i < dispatchers; i++) {
10666             try {
10667                 mDeviceVolumeBehaviorDispatchers.getBroadcastItem(i)
10668                         .dispatchDeviceVolumeBehaviorChanged(device, volumeBehavior);
10669             } catch (RemoteException e) {
10670             }
10671         }
10672         mDeviceVolumeBehaviorDispatchers.finishBroadcast();
10673     }
10674 
10675     //==========================================================================================
10676     // Device orientation
10677     //==========================================================================================
10678     /**
10679      * Handles device configuration changes that may map to a change in rotation.
10680      * Monitoring rotation is optional, and is defined by the definition and value
10681      * of the "ro.audio.monitorRotation" system property.
10682      */
onConfigurationChanged()10683     private void onConfigurationChanged() {
10684         try {
10685             // reading new configuration "safely" (i.e. under try catch) in case anything
10686             // goes wrong.
10687             Configuration config = mContext.getResources().getConfiguration();
10688             mSoundDoseHelper.configureSafeMedia(/*forced*/false, TAG);
10689 
10690             boolean cameraSoundForced = readCameraSoundForced();
10691             synchronized (mSettingsLock) {
10692                 final boolean cameraSoundForcedChanged = (cameraSoundForced != mCameraSoundForced);
10693                 mCameraSoundForced = cameraSoundForced;
10694                 if (cameraSoundForcedChanged) {
10695                     if (!mIsSingleVolume) {
10696                         synchronized (VolumeStreamState.class) {
10697                             VolumeStreamState s = mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED];
10698                             if (cameraSoundForced) {
10699                                 s.setAllIndexesToMax();
10700                                 mRingerModeAffectedStreams &=
10701                                         ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
10702                             } else {
10703                                 s.setAllIndexes(mStreamStates[AudioSystem.STREAM_SYSTEM], TAG);
10704                                 mRingerModeAffectedStreams |=
10705                                         (1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
10706                             }
10707                         }
10708                         // take new state into account for streams muted by ringer mode
10709                         setRingerModeInt(getRingerModeInternal(), false);
10710                     }
10711                     mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM,
10712                             cameraSoundForced ?
10713                                     AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE,
10714                             "onConfigurationChanged");
10715                     sendMsg(mAudioHandler,
10716                             MSG_SET_ALL_VOLUMES,
10717                             SENDMSG_QUEUE,
10718                             0,
10719                             0,
10720                             mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED], 0);
10721 
10722                 }
10723             }
10724             mVolumeController.setLayoutDirection(config.getLayoutDirection());
10725         } catch (Exception e) {
10726             Log.e(TAG, "Error handling configuration change: ", e);
10727         }
10728     }
10729 
10730     @Override
setRingtonePlayer(IRingtonePlayer player)10731     public void setRingtonePlayer(IRingtonePlayer player) {
10732         mContext.enforceCallingOrSelfPermission(REMOTE_AUDIO_PLAYBACK, null);
10733         mRingtonePlayer = player;
10734     }
10735 
10736     @Override
getRingtonePlayer()10737     public IRingtonePlayer getRingtonePlayer() {
10738         return mRingtonePlayer;
10739     }
10740 
10741     @Override
startWatchingRoutes(IAudioRoutesObserver observer)10742     public AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) {
10743         return mDeviceBroker.startWatchingRoutes(observer);
10744     }
10745 
10746     @Override
disableSafeMediaVolume(String callingPackage)10747     public void disableSafeMediaVolume(String callingPackage) {
10748         enforceVolumeController("disable the safe media volume");
10749         mSoundDoseHelper.disableSafeMediaVolume(callingPackage);
10750     }
10751 
10752     @Override
lowerVolumeToRs1(String callingPackage)10753     public void lowerVolumeToRs1(String callingPackage) {
10754         enforceVolumeController("lowerVolumeToRs1");
10755         postLowerVolumeToRs1();
10756     }
10757 
postLowerVolumeToRs1()10758     /*package*/ void postLowerVolumeToRs1() {
10759         sendMsg(mAudioHandler, MSG_LOWER_VOLUME_TO_RS1, SENDMSG_QUEUE,
10760                 // no params, no delay
10761                 0, 0, null, 0);
10762     }
10763 
10764     /**
10765      * Called when handling MSG_LOWER_VOLUME_TO_RS1
10766      */
onLowerVolumeToRs1()10767     private void onLowerVolumeToRs1() {
10768         final ArrayList<AudioDeviceAttributes> devices = getDevicesForAttributesInt(
10769                 new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build(), true);
10770         final int nativeDeviceType;
10771         final AudioDeviceAttributes ada;
10772         if (!devices.isEmpty()) {
10773             ada = devices.get(0);
10774             nativeDeviceType = ada.getInternalType();
10775         } else {
10776             nativeDeviceType = AudioSystem.DEVICE_OUT_USB_HEADSET;
10777             ada = new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_USB_HEADSET, "");
10778         }
10779         final int index = mSoundDoseHelper.safeMediaVolumeIndex(nativeDeviceType);
10780         setStreamVolumeWithAttributionInt(STREAM_MUSIC, index, /*flags*/ 0, ada,
10781                 "com.android.server.audio", "AudioService");
10782     }
10783 
10784     @Override
10785     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
getOutputRs2UpperBound()10786     public float getOutputRs2UpperBound() {
10787         super.getOutputRs2UpperBound_enforcePermission();
10788         return mSoundDoseHelper.getOutputRs2UpperBound();
10789     }
10790 
10791     @Override
10792     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setOutputRs2UpperBound(float rs2Value)10793     public void setOutputRs2UpperBound(float rs2Value) {
10794         super.setOutputRs2UpperBound_enforcePermission();
10795         mSoundDoseHelper.setOutputRs2UpperBound(rs2Value);
10796     }
10797 
10798     @Override
10799     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
getCsd()10800     public float getCsd() {
10801         super.getCsd_enforcePermission();
10802         return mSoundDoseHelper.getCsd();
10803     }
10804 
10805     @Override
10806     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setCsd(float csd)10807     public void setCsd(float csd) {
10808         super.setCsd_enforcePermission();
10809         if (csd < 0.0f) {
10810             mSoundDoseHelper.resetCsdTimeouts();
10811         } else {
10812             mSoundDoseHelper.setCsd(csd);
10813         }
10814     }
10815 
10816     @Override
10817     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
forceUseFrameworkMel(boolean useFrameworkMel)10818     public void forceUseFrameworkMel(boolean useFrameworkMel) {
10819         super.forceUseFrameworkMel_enforcePermission();
10820         mSoundDoseHelper.forceUseFrameworkMel(useFrameworkMel);
10821     }
10822 
10823     @Override
10824     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
forceComputeCsdOnAllDevices(boolean computeCsdOnAllDevices)10825     public void forceComputeCsdOnAllDevices(boolean computeCsdOnAllDevices) {
10826         super.forceComputeCsdOnAllDevices_enforcePermission();
10827         mSoundDoseHelper.forceComputeCsdOnAllDevices(computeCsdOnAllDevices);
10828     }
10829 
10830     @Override
10831     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
isCsdEnabled()10832     public boolean isCsdEnabled() {
10833         super.isCsdEnabled_enforcePermission();
10834         return mSoundDoseHelper.isCsdEnabled();
10835     }
10836 
10837     @Override
10838     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
isCsdAsAFeatureAvailable()10839     public boolean isCsdAsAFeatureAvailable() {
10840         super.isCsdAsAFeatureAvailable_enforcePermission();
10841         return mSoundDoseHelper.isCsdAsAFeatureAvailable();
10842     }
10843 
10844     @Override
10845     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
isCsdAsAFeatureEnabled()10846     public boolean isCsdAsAFeatureEnabled() {
10847         super.isCsdAsAFeatureEnabled_enforcePermission();
10848         return mSoundDoseHelper.isCsdAsAFeatureEnabled();
10849     }
10850 
10851     @Override
10852     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setCsdAsAFeatureEnabled(boolean csdToggleValue)10853     public void setCsdAsAFeatureEnabled(boolean csdToggleValue) {
10854         super.setCsdAsAFeatureEnabled_enforcePermission();
10855         mSoundDoseHelper.setCsdAsAFeatureEnabled(csdToggleValue);
10856     }
10857 
10858     @Override
10859     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setBluetoothAudioDeviceCategory(@onNull String address, boolean isBle, @AudioDeviceCategory int btAudioDeviceCategory)10860     public void setBluetoothAudioDeviceCategory(@NonNull String address, boolean isBle,
10861             @AudioDeviceCategory int btAudioDeviceCategory) {
10862         super.setBluetoothAudioDeviceCategory_enforcePermission();
10863 
10864         final String addr = Objects.requireNonNull(address);
10865 
10866         AdiDeviceState deviceState = mDeviceBroker.findBtDeviceStateForAddress(addr, isBle);
10867 
10868         int internalType = !isBle ? DEVICE_OUT_BLUETOOTH_A2DP
10869                 : ((btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES)
10870                         ? DEVICE_OUT_BLE_HEADSET : DEVICE_OUT_BLE_SPEAKER);
10871         int deviceType = !isBle ? TYPE_BLUETOOTH_A2DP
10872                 : ((btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES) ? TYPE_BLE_HEADSET
10873                         : TYPE_BLE_SPEAKER);
10874 
10875         if (deviceState == null) {
10876             deviceState = new AdiDeviceState(deviceType, internalType, addr);
10877         }
10878 
10879         deviceState.setAudioDeviceCategory(btAudioDeviceCategory);
10880 
10881         mDeviceBroker.addOrUpdateBtAudioDeviceCategoryInInventory(deviceState);
10882         mDeviceBroker.persistAudioDeviceSettings();
10883 
10884         mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes());
10885         mSoundDoseHelper.setAudioDeviceCategory(addr, internalType,
10886                 btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES);
10887     }
10888 
10889     @Override
10890     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
10891     @AudioDeviceCategory
getBluetoothAudioDeviceCategory(@onNull String address, boolean isBle)10892     public int getBluetoothAudioDeviceCategory(@NonNull String address, boolean isBle) {
10893         super.getBluetoothAudioDeviceCategory_enforcePermission();
10894 
10895         final AdiDeviceState deviceState = mDeviceBroker.findBtDeviceStateForAddress(
10896                 Objects.requireNonNull(address), isBle);
10897         if (deviceState == null) {
10898             return AUDIO_DEVICE_CATEGORY_UNKNOWN;
10899         }
10900 
10901         return deviceState.getAudioDeviceCategory();
10902     }
10903 
10904     //==========================================================================================
10905     // Hdmi CEC:
10906     // - System audio mode:
10907     //     If Hdmi Cec's system audio mode is on, audio service should send the volume change
10908     //     to HdmiControlService so that the audio receiver can handle it.
10909     // - CEC sink:
10910     //     OUT_HDMI becomes a "full volume device", i.e. output is always at maximum level
10911     //     and volume changes won't be taken into account on this device. Volume adjustments
10912     //     are transformed into key events for the HDMI playback client.
10913     //==========================================================================================
10914 
10915     @GuardedBy("mHdmiClientLock")
updateHdmiCecSinkLocked(boolean hdmiCecSink)10916     private void updateHdmiCecSinkLocked(boolean hdmiCecSink) {
10917         if (!hasDeviceVolumeBehavior(AudioSystem.DEVICE_OUT_HDMI)) {
10918             if (hdmiCecSink) {
10919                 if (DEBUG_VOL) {
10920                     Log.d(TAG, "CEC sink: setting HDMI as full vol device");
10921                 }
10922                 setDeviceVolumeBehaviorInternal(
10923                         new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""),
10924                         AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL,
10925                         "AudioService.updateHdmiCecSinkLocked()");
10926             } else {
10927                 if (DEBUG_VOL) {
10928                     Log.d(TAG, "TV, no CEC: setting HDMI as regular vol device");
10929                 }
10930                 // Android TV devices without CEC service apply software volume on
10931                 // HDMI output
10932                 setDeviceVolumeBehaviorInternal(
10933                         new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""),
10934                         AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE,
10935                         "AudioService.updateHdmiCecSinkLocked()");
10936             }
10937             postUpdateVolumeStatesForAudioDevice(AudioSystem.DEVICE_OUT_HDMI,
10938                     "HdmiPlaybackClient.DisplayStatusCallback");
10939         }
10940     }
10941 
10942     private class MyHdmiControlStatusChangeListenerCallback
10943             implements HdmiControlManager.HdmiControlStatusChangeListener {
onStatusChange(@dmiControlManager.HdmiCecControl int isCecEnabled, boolean isCecAvailable)10944         public void onStatusChange(@HdmiControlManager.HdmiCecControl int isCecEnabled,
10945                 boolean isCecAvailable) {
10946             synchronized (mHdmiClientLock) {
10947                 if (mHdmiManager == null) return;
10948                 boolean cecEnabled = isCecEnabled == HdmiControlManager.HDMI_CEC_CONTROL_ENABLED;
10949                 updateHdmiCecSinkLocked(cecEnabled ? isCecAvailable : false);
10950             }
10951         }
10952     };
10953 
10954     private class MyHdmiCecVolumeControlFeatureListener
10955             implements HdmiControlManager.HdmiCecVolumeControlFeatureListener {
onHdmiCecVolumeControlFeature( @dmiControlManager.VolumeControl int hdmiCecVolumeControl)10956         public void onHdmiCecVolumeControlFeature(
10957                 @HdmiControlManager.VolumeControl int hdmiCecVolumeControl) {
10958             synchronized (mHdmiClientLock) {
10959                 if (mHdmiManager == null) return;
10960                 mHdmiCecVolumeControlEnabled =
10961                         hdmiCecVolumeControl == HdmiControlManager.VOLUME_CONTROL_ENABLED;
10962             }
10963         }
10964     };
10965 
10966     private final Object mHdmiClientLock = new Object();
10967 
10968     // If HDMI-CEC system audio is supported
10969     // Note that for CEC volume commands mHdmiCecVolumeControlEnabled will play a role on volume
10970     // commands
10971     private boolean mHdmiSystemAudioSupported = false;
10972     // Set only when device is tv.
10973     @GuardedBy("mHdmiClientLock")
10974     private HdmiTvClient mHdmiTvClient;
10975     // true if the device has system feature PackageManager.FEATURE_LEANBACK.
10976     // cached HdmiControlManager interface
10977     @GuardedBy("mHdmiClientLock")
10978     private HdmiControlManager mHdmiManager;
10979     // Set only when device is a set-top box.
10980     @GuardedBy("mHdmiClientLock")
10981     private HdmiPlaybackClient mHdmiPlaybackClient;
10982     // Set only when device is an audio system.
10983     @GuardedBy("mHdmiClientLock")
10984     private HdmiAudioSystemClient mHdmiAudioSystemClient;
10985     // True when volume control over HDMI CEC is used when CEC is enabled (meaningless otherwise)
10986     @GuardedBy("mHdmiClientLock")
10987     private boolean mHdmiCecVolumeControlEnabled;
10988 
10989     private MyHdmiControlStatusChangeListenerCallback mHdmiControlStatusChangeListenerCallback =
10990             new MyHdmiControlStatusChangeListenerCallback();
10991 
10992     private MyHdmiCecVolumeControlFeatureListener mMyHdmiCecVolumeControlFeatureListener =
10993             new MyHdmiCecVolumeControlFeatureListener();
10994 
10995     @Override
setHdmiSystemAudioSupported(boolean on)10996     public int setHdmiSystemAudioSupported(boolean on) {
10997         int device = AudioSystem.DEVICE_NONE;
10998         synchronized (mHdmiClientLock) {
10999             if (mHdmiManager != null) {
11000                 if (mHdmiTvClient == null && mHdmiAudioSystemClient == null) {
11001                     Log.w(TAG, "Only Hdmi-Cec enabled TV or audio system device supports"
11002                             + "system audio mode.");
11003                     return device;
11004                 }
11005                 if (mHdmiSystemAudioSupported != on) {
11006                     mHdmiSystemAudioSupported = on;
11007                     final int config = on ? AudioSystem.FORCE_HDMI_SYSTEM_AUDIO_ENFORCED :
11008                         AudioSystem.FORCE_NONE;
11009                     mDeviceBroker.setForceUse_Async(AudioSystem.FOR_HDMI_SYSTEM_AUDIO, config,
11010                             "setHdmiSystemAudioSupported");
11011                 }
11012                 // TODO(b/185386781): Update AudioManager API to use device list.
11013                 // So far, this value appears to be advisory for debug log.
11014                 device = getDeviceMaskForStream(AudioSystem.STREAM_MUSIC);
11015             }
11016         }
11017         return device;
11018     }
11019 
11020     @Override
isHdmiSystemAudioSupported()11021     public boolean isHdmiSystemAudioSupported() {
11022         return mHdmiSystemAudioSupported;
11023     }
11024 
11025     //==========================================================================================
11026     // Accessibility
11027 
initA11yMonitoring()11028     private void initA11yMonitoring() {
11029         final AccessibilityManager accessibilityManager =
11030                 (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
11031         updateDefaultStreamOverrideDelay(accessibilityManager.isTouchExplorationEnabled());
11032         updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive());
11033         accessibilityManager.addTouchExplorationStateChangeListener(this, null);
11034         accessibilityManager.addAccessibilityServicesStateChangeListener(this);
11035     }
11036 
11037     //---------------------------------------------------------------------------------
11038     // A11y: taking touch exploration into account for selecting the default
11039     //   stream override timeout when adjusting volume
11040     //---------------------------------------------------------------------------------
11041 
11042     // - STREAM_NOTIFICATION on tablets during this period after a notification stopped
11043     // - STREAM_RING on phones during this period after a notification stopped
11044     // - STREAM_MUSIC otherwise
11045 
11046     private static final int DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS = 0;
11047     private static final int TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS = 1000;
11048 
11049     private static int sStreamOverrideDelayMs;
11050 
11051     @Override
onTouchExplorationStateChanged(boolean enabled)11052     public void onTouchExplorationStateChanged(boolean enabled) {
11053         updateDefaultStreamOverrideDelay(enabled);
11054     }
11055 
updateDefaultStreamOverrideDelay(boolean touchExploreEnabled)11056     private void updateDefaultStreamOverrideDelay(boolean touchExploreEnabled) {
11057         if (touchExploreEnabled) {
11058             sStreamOverrideDelayMs = TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS;
11059         } else {
11060             sStreamOverrideDelayMs = DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS;
11061         }
11062         if (DEBUG_VOL) Log.d(TAG, "Touch exploration enabled=" + touchExploreEnabled
11063                 + " stream override delay is now " + sStreamOverrideDelayMs + " ms");
11064     }
11065 
11066     //---------------------------------------------------------------------------------
11067     // A11y: taking a11y state into account for the handling of a11y prompts volume
11068     //---------------------------------------------------------------------------------
11069 
11070     private static boolean sIndependentA11yVolume = false;
11071 
11072     // implementation of AccessibilityServicesStateChangeListener
11073     @Override
onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager)11074     public void onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager) {
11075         updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive());
11076     }
11077 
updateA11yVolumeAlias(boolean a11VolEnabled)11078     private void updateA11yVolumeAlias(boolean a11VolEnabled) {
11079         if (DEBUG_VOL) Log.d(TAG, "Accessibility volume enabled = " + a11VolEnabled);
11080         if (sIndependentA11yVolume != a11VolEnabled) {
11081             sIndependentA11yVolume = a11VolEnabled;
11082             // update the volume mapping scheme
11083             updateStreamVolumeAlias(true /*updateVolumes*/, TAG);
11084             // update the volume controller behavior
11085             mVolumeController.setA11yMode(sIndependentA11yVolume ?
11086                     VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME :
11087                         VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME);
11088             mVolumeController.postVolumeChanged(AudioManager.STREAM_ACCESSIBILITY, 0);
11089         }
11090     }
11091 
11092     //==========================================================================================
11093     // Camera shutter sound policy.
11094     // config_camera_sound_forced configuration option in config.xml defines if the camera shutter
11095     // sound is forced (sound even if the device is in silent mode) or not. This option is false by
11096     // default and can be overridden by country specific overlay in values-mccXXX/config.xml.
11097     //==========================================================================================
11098 
11099     // cached value of com.android.internal.R.bool.config_camera_sound_forced
11100     @GuardedBy("mSettingsLock")
11101     private boolean mCameraSoundForced;
11102 
11103     // called by android.hardware.Camera to populate CameraInfo.canDisableShutterSound
isCameraSoundForced()11104     public boolean isCameraSoundForced() {
11105         synchronized (mSettingsLock) {
11106             return mCameraSoundForced;
11107         }
11108     }
11109 
11110     //==========================================================================================
11111     // AudioService logging and dumpsys
11112     //==========================================================================================
11113     static final int LOG_NB_EVENTS_LIFECYCLE = 20;
11114     static final int LOG_NB_EVENTS_PHONE_STATE = 20;
11115     static final int LOG_NB_EVENTS_DEVICE_CONNECTION = 50;
11116     static final int LOG_NB_EVENTS_FORCE_USE = 20;
11117     static final int LOG_NB_EVENTS_VOLUME = 100;
11118     static final int LOG_NB_EVENTS_DYN_POLICY = 10;
11119     static final int LOG_NB_EVENTS_SPATIAL = 30;
11120     static final int LOG_NB_EVENTS_SOUND_DOSE = 30;
11121 
11122     static final EventLogger
11123             sLifecycleLogger = new EventLogger(LOG_NB_EVENTS_LIFECYCLE,
11124             "audio services lifecycle");
11125 
11126     static final EventLogger sMuteLogger = new EventLogger(30,
11127             "mute commands");
11128 
11129     final private EventLogger
11130             mModeLogger = new EventLogger(LOG_NB_EVENTS_PHONE_STATE,
11131             "phone state (logged after successful call to AudioSystem.setPhoneState(int, int))");
11132 
11133     // logs for wired + A2DP device connections:
11134     // - wired: logged before onSetWiredDeviceConnectionState() is executed
11135     // - A2DP: logged at reception of method call
11136     /*package*/ static final EventLogger
11137             sDeviceLogger = new EventLogger(
11138             LOG_NB_EVENTS_DEVICE_CONNECTION, "wired/A2DP/hearing aid device connection");
11139 
11140     static final EventLogger
11141             sForceUseLogger = new EventLogger(
11142             LOG_NB_EVENTS_FORCE_USE,
11143             "force use (logged before setForceUse() is executed)");
11144 
11145     static final EventLogger
11146             sVolumeLogger = new EventLogger(LOG_NB_EVENTS_VOLUME,
11147             "volume changes (logged when command received by AudioService)");
11148 
11149     static final EventLogger
11150             sSpatialLogger = new EventLogger(LOG_NB_EVENTS_SPATIAL,
11151             "spatial audio");
11152 
11153     final private EventLogger
11154             mDynPolicyLogger = new EventLogger(LOG_NB_EVENTS_DYN_POLICY,
11155             "dynamic policy events (logged when command received by AudioService)");
11156 
11157     private static final String[] RINGER_MODE_NAMES = new String[] {
11158             "SILENT",
11159             "VIBRATE",
11160             "NORMAL"
11161     };
11162 
dumpRingerMode(PrintWriter pw)11163     private void dumpRingerMode(PrintWriter pw) {
11164         pw.println("\nRinger mode: ");
11165         pw.println("- mode (internal) = " + RINGER_MODE_NAMES[mRingerMode]);
11166         pw.println("- mode (external) = " + RINGER_MODE_NAMES[mRingerModeExternal]);
11167         pw.println("- zen mode:" + Settings.Global.zenModeToString(mNm.getZenMode()));
11168         dumpRingerModeStreams(pw, "affected", mRingerModeAffectedStreams);
11169         dumpRingerModeStreams(pw, "muted", sRingerAndZenModeMutedStreams);
11170         pw.print("- delegate = "); pw.println(mRingerModeDelegate);
11171     }
11172 
dumpRingerModeStreams(PrintWriter pw, String type, int streams)11173     private void dumpRingerModeStreams(PrintWriter pw, String type, int streams) {
11174         pw.print("- ringer mode "); pw.print(type); pw.print(" streams = 0x");
11175         pw.print(Integer.toHexString(streams));
11176         if (streams != 0) {
11177             pw.print(" (");
11178             boolean first = true;
11179             for (int i = 0; i < AudioSystem.STREAM_NAMES.length; i++) {
11180                 final int stream = (1 << i);
11181                 if ((streams & stream) != 0) {
11182                     if (!first) pw.print(',');
11183                     pw.print(AudioSystem.STREAM_NAMES[i]);
11184                     streams &= ~stream;
11185                     first = false;
11186                 }
11187             }
11188             if (streams != 0) {
11189                 if (!first) pw.print(',');
11190                 pw.print(streams);
11191             }
11192             pw.print(')');
11193         }
11194         pw.println();
11195     }
11196 
getAbsoluteVolumeDevicesWithBehavior(int behavior)11197     private Set<Integer> getAbsoluteVolumeDevicesWithBehavior(int behavior) {
11198         return mAbsoluteVolumeDeviceInfoMap.entrySet().stream()
11199                 .filter(entry -> entry.getValue().mDeviceVolumeBehavior == behavior)
11200                 .map(Map.Entry::getKey)
11201                 .collect(Collectors.toSet());
11202     }
11203 
dumpDeviceTypes(@onNull Set<Integer> deviceTypes)11204     private String dumpDeviceTypes(@NonNull Set<Integer> deviceTypes) {
11205         Iterator<Integer> it = deviceTypes.iterator();
11206         if (!it.hasNext()) {
11207             return "";
11208         }
11209         final StringBuilder sb = new StringBuilder();
11210         sb.append("0x" + Integer.toHexString(it.next()));
11211         while (it.hasNext()) {
11212             sb.append("," + "0x" + Integer.toHexString(it.next()));
11213         }
11214         return sb.toString();
11215     }
11216 
11217     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)11218     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11219         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
11220 
11221         sLifecycleLogger.dump(pw);
11222         if (mAudioHandler != null) {
11223             pw.println("\nMessage handler (watch for unhandled messages):");
11224             mAudioHandler.dump(new PrintWriterPrinter(pw), "  ");
11225         } else {
11226             pw.println("\nMessage handler is null");
11227         }
11228         mMediaFocusControl.dump(pw);
11229         dumpStreamStates(pw);
11230         dumpVolumeGroups(pw);
11231         dumpRingerMode(pw);
11232         dumpAudioMode(pw);
11233         pw.println("\nAudio routes:");
11234         pw.print("  mMainType=0x"); pw.println(Integer.toHexString(
11235                 mDeviceBroker.getCurAudioRoutes().mainType));
11236         pw.print("  mBluetoothName="); pw.println(mDeviceBroker.getCurAudioRoutes().bluetoothName);
11237 
11238         pw.println("\nOther state:");
11239         pw.print("  mUseVolumeGroupAliases="); pw.println(mUseVolumeGroupAliases);
11240         pw.print("  mVolumeController="); pw.println(mVolumeController);
11241         mSoundDoseHelper.dump(pw);
11242         pw.print("  sIndependentA11yVolume="); pw.println(sIndependentA11yVolume);
11243         pw.print("  mCameraSoundForced="); pw.println(isCameraSoundForced());
11244         pw.print("  mHasVibrator="); pw.println(mHasVibrator);
11245         pw.print("  mVolumePolicy="); pw.println(mVolumePolicy);
11246         pw.print("  mAvrcpAbsVolSupported="); pw.println(mAvrcpAbsVolSupported);
11247         pw.print("  mBtScoOnByApp="); pw.println(mBtScoOnByApp);
11248         pw.print("  mIsSingleVolume="); pw.println(mIsSingleVolume);
11249         pw.print("  mUseFixedVolume="); pw.println(mUseFixedVolume);
11250         pw.print("  mNotifAliasRing="); pw.println(mNotifAliasRing);
11251         pw.print("  mFixedVolumeDevices="); pw.println(dumpDeviceTypes(mFixedVolumeDevices));
11252         pw.print("  mFullVolumeDevices="); pw.println(dumpDeviceTypes(mFullVolumeDevices));
11253         pw.print("  absolute volume devices="); pw.println(dumpDeviceTypes(
11254                 getAbsoluteVolumeDevicesWithBehavior(
11255                         AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE)));
11256         pw.print("  adjust-only absolute volume devices="); pw.println(dumpDeviceTypes(
11257                 getAbsoluteVolumeDevicesWithBehavior(
11258                         AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY)));
11259         pw.print("  mExtVolumeController="); pw.println(mExtVolumeController);
11260         pw.print("  mHdmiAudioSystemClient="); pw.println(mHdmiAudioSystemClient);
11261         pw.print("  mHdmiPlaybackClient="); pw.println(mHdmiPlaybackClient);
11262         pw.print("  mHdmiTvClient="); pw.println(mHdmiTvClient);
11263         pw.print("  mHdmiSystemAudioSupported="); pw.println(mHdmiSystemAudioSupported);
11264         synchronized (mHdmiClientLock) {
11265             pw.print("  mHdmiCecVolumeControlEnabled="); pw.println(mHdmiCecVolumeControlEnabled);
11266         }
11267         pw.print("  mIsCallScreeningModeSupported="); pw.println(mIsCallScreeningModeSupported);
11268         pw.print("  mic mute FromSwitch=" + mMicMuteFromSwitch
11269                         + " FromRestrictions=" + mMicMuteFromRestrictions
11270                         + " FromApi=" + mMicMuteFromApi
11271                         + " from system=" + mMicMuteFromSystemCached);
11272         dumpAccessibilityServiceUids(pw);
11273         dumpAssistantServicesUids(pw);
11274 
11275         pw.print("  supportsBluetoothVariableLatency=");
11276         pw.println(AudioSystem.supportsBluetoothVariableLatency());
11277         pw.print("  isBluetoothVariableLatencyEnabled=");
11278         pw.println(AudioSystem.isBluetoothVariableLatencyEnabled());
11279 
11280         dumpAudioPolicies(pw);
11281         mDynPolicyLogger.dump(pw);
11282         mPlaybackMonitor.dump(pw);
11283         mRecordMonitor.dump(pw);
11284 
11285         pw.println("\nAudioDeviceBroker:");
11286         mDeviceBroker.dump(pw, "  ");
11287         pw.println("\nSoundEffects:");
11288         mSfxHelper.dump(pw, "  ");
11289 
11290         pw.println("\n");
11291         pw.println("\nEvent logs:");
11292         mModeLogger.dump(pw);
11293         pw.println("\n");
11294         sDeviceLogger.dump(pw);
11295         pw.println("\n");
11296         sForceUseLogger.dump(pw);
11297         pw.println("\n");
11298         sVolumeLogger.dump(pw);
11299         pw.println("\n");
11300         sMuteLogger.dump(pw);
11301         pw.println("\n");
11302         dumpSupportedSystemUsage(pw);
11303 
11304         pw.println("\n");
11305         pw.println("\nSpatial audio:");
11306         pw.println("mHasSpatializerEffect:" + mHasSpatializerEffect + " (effect present)");
11307         pw.println("isSpatializerEnabled:" + isSpatializerEnabled() + " (routing dependent)");
11308         mSpatializerHelper.dump(pw);
11309         sSpatialLogger.dump(pw);
11310 
11311         mAudioSystem.dump(pw);
11312     }
11313 
dumpSupportedSystemUsage(PrintWriter pw)11314     private void dumpSupportedSystemUsage(PrintWriter pw) {
11315         pw.println("Supported System Usages:");
11316         synchronized (mSupportedSystemUsagesLock) {
11317             for (int i = 0; i < mSupportedSystemUsages.length; i++) {
11318                 pw.printf("\t%s\n", AudioAttributes.usageToString(mSupportedSystemUsages[i]));
11319             }
11320         }
11321     }
11322 
dumpAssistantServicesUids(PrintWriter pw)11323     private void dumpAssistantServicesUids(PrintWriter pw) {
11324         synchronized (mSettingsLock) {
11325             if (mAssistantUids.size() > 0) {
11326                 pw.println("  Assistant service UIDs:");
11327                 for (int uid : mAssistantUids) {
11328                     pw.println("  - " + uid);
11329                 }
11330             } else {
11331                 pw.println("  No Assistant service Uids.");
11332             }
11333         }
11334     }
11335 
dumpAccessibilityServiceUids(PrintWriter pw)11336     private void dumpAccessibilityServiceUids(PrintWriter pw) {
11337         synchronized (mSupportedSystemUsagesLock) {
11338             if (mAccessibilityServiceUids != null && mAccessibilityServiceUids.length > 0) {
11339                 pw.println("  Accessibility service Uids:");
11340                 for (int uid : mAccessibilityServiceUids) {
11341                     pw.println("  - " + uid);
11342                 }
11343             } else {
11344                 pw.println("  No accessibility service Uids.");
11345             }
11346         }
11347     }
11348 
11349     /**
11350      * Audio Analytics ids.
11351      */
11352     private static final String mMetricsId = MediaMetrics.Name.AUDIO_SERVICE
11353             + MediaMetrics.SEPARATOR;
11354 
11355     // Inform AudioFlinger of our device's low RAM attribute
readAndSetLowRamDevice()11356     private static void readAndSetLowRamDevice()
11357     {
11358         boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic();
11359         long totalMemory = 1024 * 1024 * 1024; // 1GB is the default if ActivityManager fails.
11360 
11361         try {
11362             final ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();
11363             ActivityManager.getService().getMemoryInfo(info);
11364             totalMemory = info.totalMem;
11365         } catch (RemoteException e) {
11366             Log.w(TAG, "Cannot obtain MemoryInfo from ActivityManager, assume low memory device");
11367             isLowRamDevice = true;
11368         }
11369 
11370         final int status = AudioSystem.setLowRamDevice(isLowRamDevice, totalMemory);
11371         if (status != 0) {
11372             Log.w(TAG, "AudioFlinger informed of device's low RAM attribute; status " + status);
11373         }
11374     }
11375 
enforceVolumeController(String action)11376     private void enforceVolumeController(String action) {
11377         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE,
11378                 "Only SystemUI can " + action);
11379     }
11380 
11381     @Override
setVolumeController(final IVolumeController controller)11382     public void setVolumeController(final IVolumeController controller) {
11383         enforceVolumeController("set the volume controller");
11384 
11385         // return early if things are not actually changing
11386         if (mVolumeController.isSameBinder(controller)) {
11387             return;
11388         }
11389 
11390         // dismiss the old volume controller
11391         mVolumeController.postDismiss();
11392         if (controller != null) {
11393             // we are about to register a new controller, listen for its death
11394             try {
11395                 controller.asBinder().linkToDeath(new DeathRecipient() {
11396                     @Override
11397                     public void binderDied() {
11398                         if (mVolumeController.isSameBinder(controller)) {
11399                             Log.w(TAG, "Current remote volume controller died, unregistering");
11400                             setVolumeController(null);
11401                         }
11402                     }
11403                 }, 0);
11404             } catch (RemoteException e) {
11405                 // noop
11406             }
11407         }
11408         mVolumeController.setController(controller);
11409         if (DEBUG_VOL) Log.d(TAG, "Volume controller: " + mVolumeController);
11410     }
11411 
11412     @Override
11413     @Nullable
getVolumeController()11414     public IVolumeController getVolumeController() {
11415         enforceVolumeController("get the volume controller");
11416         if (DEBUG_VOL) Log.d(TAG, "Volume controller: " + mVolumeController);
11417 
11418         return mVolumeController.getController();
11419     }
11420 
11421     @Override
notifyVolumeControllerVisible(final IVolumeController controller, boolean visible)11422     public void notifyVolumeControllerVisible(final IVolumeController controller, boolean visible) {
11423         enforceVolumeController("notify about volume controller visibility");
11424 
11425         // return early if the controller is not current
11426         if (!mVolumeController.isSameBinder(controller)) {
11427             return;
11428         }
11429 
11430         mVolumeController.setVisible(visible);
11431         if (DEBUG_VOL) Log.d(TAG, "Volume controller visible: " + visible);
11432     }
11433 
11434     @Override
setVolumePolicy(VolumePolicy policy)11435     public void setVolumePolicy(VolumePolicy policy) {
11436         enforceVolumeController("set volume policy");
11437         if (policy != null && !policy.equals(mVolumePolicy)) {
11438             mVolumePolicy = policy;
11439             if (DEBUG_VOL) Log.d(TAG, "Volume policy changed: " + mVolumePolicy);
11440         }
11441     }
11442 
11443     /** Interface used for enforcing the safe hearing standard. */
11444     public interface ISafeHearingVolumeController {
11445         /** Displays an instructional safeguard as required by the safe hearing standard. */
postDisplaySafeVolumeWarning(int flags)11446         void postDisplaySafeVolumeWarning(int flags);
11447 
11448         /** Displays a warning about transient exposure to high level playback */
postDisplayCsdWarning(@udioManager.CsdWarning int csdEvent, int displayDurationMs)11449         void postDisplayCsdWarning(@AudioManager.CsdWarning int csdEvent, int displayDurationMs);
11450     }
11451 
11452     /** Wrapper which encapsulates the {@link IVolumeController} functionality. */
11453     public class VolumeController implements ISafeHearingVolumeController {
11454         private static final String TAG = "VolumeController";
11455 
11456         private IVolumeController mController;
11457         private boolean mVisible;
11458         private long mNextLongPress;
11459         private int mLongPressTimeout;
11460 
setController(IVolumeController controller)11461         public void setController(IVolumeController controller) {
11462             mController = controller;
11463             mVisible = false;
11464         }
11465 
getController()11466         public IVolumeController getController() {
11467             return mController;
11468         }
11469 
loadSettings(ContentResolver cr)11470         public void loadSettings(ContentResolver cr) {
11471             mLongPressTimeout = mSettings.getSecureIntForUser(cr,
11472                     Settings.Secure.LONG_PRESS_TIMEOUT, 500, UserHandle.USER_CURRENT);
11473         }
11474 
suppressAdjustment(int resolvedStream, int flags, boolean isMute)11475         public boolean suppressAdjustment(int resolvedStream, int flags, boolean isMute) {
11476             if (isMute) {
11477                 return false;
11478             }
11479             boolean suppress = false;
11480             // Intended behavior:
11481             // 1/ if the stream is not the default UI stream, do not suppress (as it is not involved
11482             //    in bringing up the UI)
11483             // 2/ if the resolved and default stream is MUSIC, and media is playing, do not suppress
11484             // 3/ otherwise suppress the first adjustments that occur during the "long press
11485             //    timeout" interval. Note this is true regardless of whether this is a "real long
11486             //    press" (where the user keeps pressing on the volume button), or repeated single
11487             //    presses (here we don't know if we are in a real long press, or repeated fast
11488             //    button presses).
11489             //    Once the long press timeout occurs (mNextLongPress reset to 0), do not suppress.
11490             // Example: for a default and resolved stream of MUSIC, this allows modifying rapidly
11491             // the volume when media is playing (whether by long press or repeated individual
11492             // presses), or to bring up the volume UI when media is not playing, in order to make
11493             // another change (e.g. switch ringer modes) without changing media volume.
11494             if (resolvedStream == DEFAULT_VOL_STREAM_NO_PLAYBACK && mController != null) {
11495                 // never suppress media vol adjustement during media playback
11496                 if (resolvedStream == AudioSystem.STREAM_MUSIC
11497                         && mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, mLongPressTimeout))
11498                 {
11499                     // media is playing, adjust the volume right away
11500                     return false;
11501                 }
11502 
11503                 final long now = SystemClock.uptimeMillis();
11504                 if ((flags & AudioManager.FLAG_SHOW_UI) != 0 && !mVisible) {
11505                     // UI is not visible yet, adjustment is ignored
11506                     if (mNextLongPress < now) {
11507                         mNextLongPress = now + mLongPressTimeout;
11508                     }
11509                     suppress = true;
11510                 } else if (mNextLongPress > 0) {  // in a long-press
11511                     if (now > mNextLongPress) {
11512                         // long press triggered, no more suppression
11513                         mNextLongPress = 0;
11514                     } else {
11515                         // keep suppressing until the long press triggers
11516                         suppress = true;
11517                     }
11518                 }
11519             }
11520             return suppress;
11521         }
11522 
setVisible(boolean visible)11523         public void setVisible(boolean visible) {
11524             mVisible = visible;
11525         }
11526 
isSameBinder(IVolumeController controller)11527         public boolean isSameBinder(IVolumeController controller) {
11528             return Objects.equals(asBinder(), binder(controller));
11529         }
11530 
asBinder()11531         public IBinder asBinder() {
11532             return binder(mController);
11533         }
11534 
binder(IVolumeController controller)11535         private IBinder binder(IVolumeController controller) {
11536             return controller == null ? null : controller.asBinder();
11537         }
11538 
11539         @Override
toString()11540         public String toString() {
11541             return "VolumeController(" + asBinder() + ",mVisible=" + mVisible + ")";
11542         }
11543 
11544         @Override
postDisplaySafeVolumeWarning(int flags)11545         public void postDisplaySafeVolumeWarning(int flags) {
11546             if (mController == null)
11547                 return;
11548             flags = flags | AudioManager.FLAG_SHOW_UI;
11549             try {
11550                 mController.displaySafeVolumeWarning(flags);
11551             } catch (RemoteException e) {
11552                 Log.w(TAG, "Error calling displaySafeVolumeWarning", e);
11553             }
11554         }
11555 
11556         @Override
postDisplayCsdWarning( @udioManager.CsdWarning int csdWarning, int displayDurationMs)11557         public void postDisplayCsdWarning(
11558                 @AudioManager.CsdWarning int csdWarning, int displayDurationMs) {
11559             if (mController == null) {
11560                 Log.e(TAG, "Unable to display CSD warning, no controller");
11561                 return;
11562             }
11563             try {
11564                 mController.displayCsdWarning(csdWarning, displayDurationMs);
11565             } catch (RemoteException e) {
11566                 Log.w(TAG, "Error calling displayCsdWarning for warning " + csdWarning, e);
11567             }
11568         }
11569 
postVolumeChanged(int streamType, int flags)11570         public void postVolumeChanged(int streamType, int flags) {
11571             if (mController == null)
11572                 return;
11573             try {
11574                 mController.volumeChanged(streamType, flags);
11575             } catch (RemoteException e) {
11576                 Log.w(TAG, "Error calling volumeChanged", e);
11577             }
11578         }
11579 
postMasterMuteChanged(int flags)11580         public void postMasterMuteChanged(int flags) {
11581             if (mController == null)
11582                 return;
11583             try {
11584                 mController.masterMuteChanged(flags);
11585             } catch (RemoteException e) {
11586                 Log.w(TAG, "Error calling masterMuteChanged", e);
11587             }
11588         }
11589 
setLayoutDirection(int layoutDirection)11590         public void setLayoutDirection(int layoutDirection) {
11591             if (mController == null)
11592                 return;
11593             try {
11594                 mController.setLayoutDirection(layoutDirection);
11595             } catch (RemoteException e) {
11596                 Log.w(TAG, "Error calling setLayoutDirection", e);
11597             }
11598         }
11599 
postDismiss()11600         public void postDismiss() {
11601             if (mController == null)
11602                 return;
11603             try {
11604                 mController.dismiss();
11605             } catch (RemoteException e) {
11606                 Log.w(TAG, "Error calling dismiss", e);
11607             }
11608         }
11609 
setA11yMode(int a11yMode)11610         public void setA11yMode(int a11yMode) {
11611             if (mController == null)
11612                 return;
11613             try {
11614                 mController.setA11yMode(a11yMode);
11615             } catch (RemoteException e) {
11616                 Log.w(TAG, "Error calling setA11Mode", e);
11617             }
11618         }
11619     }
11620 
11621     /**
11622      * Interface for system components to get some extra functionality through
11623      * LocalServices.
11624      */
11625     final class AudioServiceInternal extends AudioManagerInternal {
11626         @Override
setRingerModeDelegate(RingerModeDelegate delegate)11627         public void setRingerModeDelegate(RingerModeDelegate delegate) {
11628             mRingerModeDelegate = delegate;
11629             if (mRingerModeDelegate != null) {
11630                 synchronized (mSettingsLock) {
11631                     updateRingerAndZenModeAffectedStreams();
11632                 }
11633                 setRingerModeInternal(getRingerModeInternal(), TAG + ".setRingerModeDelegate");
11634             }
11635         }
11636 
11637         @Override
getRingerModeInternal()11638         public int getRingerModeInternal() {
11639             return AudioService.this.getRingerModeInternal();
11640         }
11641 
11642         @Override
setRingerModeInternal(int ringerMode, String caller)11643         public void setRingerModeInternal(int ringerMode, String caller) {
11644             AudioService.this.setRingerModeInternal(ringerMode, caller);
11645         }
11646 
11647         @Override
silenceRingerModeInternal(String caller)11648         public void silenceRingerModeInternal(String caller) {
11649             AudioService.this.silenceRingerModeInternal(caller);
11650         }
11651 
11652         @Override
updateRingerModeAffectedStreamsInternal()11653         public void updateRingerModeAffectedStreamsInternal() {
11654             synchronized (mSettingsLock) {
11655                 if (updateRingerAndZenModeAffectedStreams()) {
11656                     setRingerModeInt(getRingerModeInternal(), false);
11657                 }
11658             }
11659         }
11660 
11661         @Override
addAssistantServiceUid(int uid)11662         public void addAssistantServiceUid(int uid) {
11663             sendMsg(mAudioHandler, MSG_ADD_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE,
11664                     uid, 0, null, 0);
11665         }
11666 
11667         @Override
removeAssistantServiceUid(int uid)11668         public void removeAssistantServiceUid(int uid) {
11669             sendMsg(mAudioHandler, MSG_REMOVE_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE,
11670                     uid, 0, null, 0);
11671         }
11672 
11673         @Override
setActiveAssistantServicesUids(IntArray activeUids)11674         public void setActiveAssistantServicesUids(IntArray activeUids) {
11675             synchronized (mSettingsLock) {
11676                 if (activeUids.size() == 0) {
11677                     mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS;
11678                 } else {
11679                     boolean changed = (mActiveAssistantServiceUids == null)
11680                             || (mActiveAssistantServiceUids.length != activeUids.size());
11681                     if (!changed) {
11682                         for (int i = 0; i < mActiveAssistantServiceUids.length; i++) {
11683                             if (activeUids.get(i) != mActiveAssistantServiceUids[i]) {
11684                                 changed = true;
11685                                 break;
11686                             }
11687                         }
11688                     }
11689                     if (changed) {
11690                         mActiveAssistantServiceUids = activeUids.toArray();
11691                     }
11692                 }
11693             }
11694             sendMsg(mAudioHandler, MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID, SENDMSG_REPLACE,
11695                     0, 0, null, 0);
11696         }
11697 
11698         @Override
setAccessibilityServiceUids(IntArray uids)11699         public void setAccessibilityServiceUids(IntArray uids) {
11700             // TODO(b/233287010): Fix voice interaction and a11y concurrency in audio policy service
11701             if (isPlatformAutomotive()) {
11702                 return;
11703             }
11704 
11705             synchronized (mAccessibilityServiceUidsLock) {
11706                 if (uids.size() == 0) {
11707                     mAccessibilityServiceUids = null;
11708                 } else {
11709                     boolean changed = (mAccessibilityServiceUids == null)
11710                             || (mAccessibilityServiceUids.length != uids.size());
11711                     if (!changed) {
11712                         for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
11713                             if (uids.get(i) != mAccessibilityServiceUids[i]) {
11714                                 changed = true;
11715                                 break;
11716                             }
11717                         }
11718                     }
11719                     if (changed) {
11720                         mAccessibilityServiceUids = uids.toArray();
11721                     }
11722                 }
11723                 sendMsg(mAudioHandler, MSG_UPDATE_A11Y_SERVICE_UIDS, SENDMSG_REPLACE,
11724                         0, 0, null, 0);
11725             }
11726         }
11727 
11728         /**
11729          * {@inheritDoc}
11730          */
11731         @Override
setInputMethodServiceUid(int uid)11732         public void setInputMethodServiceUid(int uid) {
11733             synchronized (mInputMethodServiceUidLock) {
11734                 if (mInputMethodServiceUid != uid) {
11735                     mAudioSystem.setCurrentImeUid(uid);
11736                     mInputMethodServiceUid = uid;
11737                 }
11738             }
11739         }
11740     }
11741 
onUpdateAccessibilityServiceUids()11742     private void onUpdateAccessibilityServiceUids() {
11743         int[] accessibilityServiceUids;
11744         synchronized (mAccessibilityServiceUidsLock) {
11745             accessibilityServiceUids = mAccessibilityServiceUids;
11746         }
11747         AudioSystem.setA11yServicesUids(accessibilityServiceUids);
11748     }
11749 
11750     //==========================================================================================
11751     // Audio policy management
11752     //==========================================================================================
registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection)11753     public String registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb,
11754             boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy,
11755             boolean isVolumeController, IMediaProjection projection) {
11756         AudioSystem.setDynamicPolicyCallback(mDynPolicyCallback);
11757 
11758         if (!isPolicyRegisterAllowed(policyConfig,
11759                                      isFocusPolicy || isTestFocusPolicy || hasFocusListener,
11760                                      isVolumeController,
11761                                      projection)) {
11762             Slog.w(TAG, "Permission denied to register audio policy for pid "
11763                     + Binder.getCallingPid() + " / uid " + Binder.getCallingUid()
11764                     + ", need system permission or a MediaProjection that can project audio");
11765             return null;
11766         }
11767 
11768         String regId = null;
11769         synchronized (mAudioPolicies) {
11770             if (mAudioPolicies.containsKey(pcb.asBinder())) {
11771                 Slog.e(TAG, "Cannot re-register policy");
11772                 return null;
11773             }
11774             try {
11775                 AudioPolicyProxy app = new AudioPolicyProxy(policyConfig, pcb, hasFocusListener,
11776                         isFocusPolicy, isTestFocusPolicy, isVolumeController, projection);
11777                 pcb.asBinder().linkToDeath(app, 0/*flags*/);
11778 
11779                 // logging after registration so we have the registration id
11780                 mDynPolicyLogger.enqueue((new EventLogger.StringEvent("registerAudioPolicy for "
11781                         + pcb.asBinder() + " u/pid:" + Binder.getCallingUid() + "/"
11782                         + Binder.getCallingPid() + " with config:" + app.toCompactLogString()))
11783                         .printLog(TAG));
11784 
11785                 regId = app.getRegistrationId();
11786                 mAudioPolicies.put(pcb.asBinder(), app);
11787             } catch (RemoteException e) {
11788                 // audio policy owner has already died!
11789                 Slog.w(TAG, "Audio policy registration failed, could not link to " + pcb +
11790                         " binder death", e);
11791                 return null;
11792             } catch (IllegalStateException e) {
11793                 Slog.w(TAG, "Audio policy registration failed for binder " + pcb, e);
11794                 return null;
11795             }
11796         }
11797         return regId;
11798     }
11799 
11800     /**
11801      * Called by an AudioPolicyProxy when the client dies.
11802      * Checks if an active playback for media use case is currently routed to one of the
11803      * remote submix devices owned by this dynamic policy and broadcasts a becoming noisy
11804      * intend in this case.
11805      * @param addresses list of remote submix device addresses to check.
11806      */
onPolicyClientDeath(List<String> addresses)11807     private void onPolicyClientDeath(List<String> addresses) {
11808         for (String address : addresses) {
11809             if (mPlaybackMonitor.hasActiveMediaPlaybackOnSubmixWithAddress(address)) {
11810                 mDeviceBroker.postBroadcastBecomingNoisy();
11811                 return;
11812             }
11813         }
11814     }
11815     /**
11816      * Apps with MODIFY_AUDIO_ROUTING can register any policy.
11817      * Apps with an audio capable MediaProjection are allowed to register a RENDER|LOOPBACK policy
11818      * as those policy do not modify the audio routing.
11819      */
isPolicyRegisterAllowed(AudioPolicyConfig policyConfig, boolean hasFocusAccess, boolean isVolumeController, IMediaProjection projection)11820     private boolean isPolicyRegisterAllowed(AudioPolicyConfig policyConfig,
11821                                             boolean hasFocusAccess,
11822                                             boolean isVolumeController,
11823                                             IMediaProjection projection) {
11824 
11825         boolean requireValidProjection = false;
11826         boolean requireCaptureAudioOrMediaOutputPerm = false;
11827         boolean requireModifyRouting = false;
11828         boolean requireCallAudioInterception = false;
11829         ArrayList<AudioMix> voiceCommunicationCaptureMixes = null;
11830 
11831 
11832         if (hasFocusAccess || isVolumeController) {
11833             requireModifyRouting |= true;
11834         } else if (policyConfig.getMixes().isEmpty()) {
11835             // An empty policy could be used to lock the focus or add mixes later
11836             requireModifyRouting |= true;
11837         }
11838         for (AudioMix mix : policyConfig.getMixes()) {
11839             // If mix is requesting privileged capture
11840             if (mix.getRule().allowPrivilegedMediaPlaybackCapture()) {
11841                 // then its format must be low quality enough
11842                 String privilegedMediaCaptureError =
11843                         mix.canBeUsedForPrivilegedMediaCapture(mix.getFormat());
11844                 if (privilegedMediaCaptureError != null) {
11845                     Log.e(TAG, privilegedMediaCaptureError);
11846                     return false;
11847                 }
11848                 // and it must have CAPTURE_MEDIA_OUTPUT or CAPTURE_AUDIO_OUTPUT permission
11849                 requireCaptureAudioOrMediaOutputPerm |= true;
11850 
11851             }
11852             // If mix is trying to explicitly capture USAGE_VOICE_COMMUNICATION
11853             if (mix.containsMatchAttributeRuleForUsage(
11854                     AudioAttributes.USAGE_VOICE_COMMUNICATION)
11855                     && (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER)) {
11856                 // It must have CAPTURE_USAGE_VOICE_COMMUNICATION_OUTPUT permission
11857                 // Note that for UID, USERID or EXCLDUE rules, the capture will be silenced
11858                 // in AudioPolicyMix
11859                 if (voiceCommunicationCaptureMixes == null) {
11860                     voiceCommunicationCaptureMixes = new ArrayList<AudioMix>();
11861                 }
11862                 voiceCommunicationCaptureMixes.add(mix);
11863             }
11864 
11865             // If mix is RENDER|LOOPBACK, then an audio MediaProjection is enough
11866             // otherwise MODIFY_AUDIO_ROUTING permission is required
11867             if (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER && projection != null) {
11868                 requireValidProjection |= true;
11869             } else if (mix.isForCallRedirection()) {
11870                 requireCallAudioInterception |= true;
11871             } else if (mix.containsMatchAttributeRuleForUsage(
11872                             AudioAttributes.USAGE_VOICE_COMMUNICATION)) {
11873                 requireModifyRouting |= true;
11874             }
11875         }
11876 
11877         if (requireCaptureAudioOrMediaOutputPerm
11878                 && !callerHasPermission(android.Manifest.permission.CAPTURE_MEDIA_OUTPUT)
11879                 && !callerHasPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT)) {
11880             Log.e(TAG, "Privileged audio capture requires CAPTURE_MEDIA_OUTPUT or "
11881                       + "CAPTURE_AUDIO_OUTPUT system permission");
11882             return false;
11883         }
11884 
11885         if (voiceCommunicationCaptureMixes != null && voiceCommunicationCaptureMixes.size() > 0) {
11886             if (!callerHasPermission(
11887                     android.Manifest.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT)) {
11888                 Log.e(TAG, "Audio capture for voice communication requires "
11889                         + "CAPTURE_VOICE_COMMUNICATION_OUTPUT system permission");
11890                 return false;
11891             }
11892 
11893             // If permission check succeeded, we set the flag in each of the mixing rules
11894             for (AudioMix mix : voiceCommunicationCaptureMixes) {
11895                 mix.getRule().setVoiceCommunicationCaptureAllowed(true);
11896             }
11897         }
11898 
11899         if (requireValidProjection && !canProjectAudio(projection)) {
11900             return false;
11901         }
11902 
11903         if (requireModifyRouting
11904                 && !callerHasPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)) {
11905             Log.e(TAG, "Can not capture audio without MODIFY_AUDIO_ROUTING");
11906             return false;
11907         }
11908 
11909         if (requireCallAudioInterception
11910                 && !callerHasPermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION)) {
11911             Log.e(TAG, "Can not capture audio without CALL_AUDIO_INTERCEPTION");
11912             return false;
11913         }
11914 
11915         return true;
11916     }
11917 
callerHasPermission(String permission)11918     private boolean callerHasPermission(String permission) {
11919         return mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED;
11920     }
11921 
11922     /** @return true if projection is a valid MediaProjection that can project audio. */
canProjectAudio(IMediaProjection projection)11923     private boolean canProjectAudio(IMediaProjection projection) {
11924         if (projection == null) {
11925             Log.e(TAG, "MediaProjection is null");
11926             return false;
11927         }
11928 
11929         IMediaProjectionManager projectionService = getProjectionService();
11930         if (projectionService == null) {
11931             Log.e(TAG, "Can't get service IMediaProjectionManager");
11932             return false;
11933         }
11934 
11935         final long token = Binder.clearCallingIdentity();
11936         try {
11937             if (!projectionService.isCurrentProjection(projection)) {
11938                 Log.w(TAG, "App passed invalid MediaProjection token");
11939                 return false;
11940             }
11941         } catch (RemoteException e) {
11942             Log.e(TAG, "Can't call .isCurrentProjection() on IMediaProjectionManager"
11943                     + projectionService.asBinder(), e);
11944             return false;
11945         } finally {
11946             Binder.restoreCallingIdentity(token);
11947         }
11948 
11949         try {
11950             if (!projection.canProjectAudio()) {
11951                 Log.w(TAG, "App passed MediaProjection that can not project audio");
11952                 return false;
11953             }
11954         } catch (RemoteException e) {
11955             Log.e(TAG, "Can't call .canProjectAudio() on valid IMediaProjection"
11956                     + projection.asBinder(), e);
11957             return false;
11958         }
11959 
11960         return true;
11961     }
11962 
getProjectionService()11963     private IMediaProjectionManager getProjectionService() {
11964         if (mProjectionService == null) {
11965             IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE);
11966             mProjectionService = IMediaProjectionManager.Stub.asInterface(b);
11967         }
11968         return mProjectionService;
11969     }
11970 
11971     /**
11972      * See {@link AudioManager#unregisterAudioPolicyAsync(AudioPolicy)}
11973      * Declared oneway
11974      * @param pcb nullable because on service interface
11975      */
unregisterAudioPolicyAsync(@ullable IAudioPolicyCallback pcb)11976     public void unregisterAudioPolicyAsync(@Nullable IAudioPolicyCallback pcb) {
11977         if (pcb == null) {
11978             return;
11979         }
11980         unregisterAudioPolicyInt(pcb, "unregisterAudioPolicyAsync");
11981     }
11982 
11983     /**
11984      * See {@link AudioManager#unregisterAudioPolicy(AudioPolicy)}
11985      * @param pcb nullable because on service interface
11986      */
unregisterAudioPolicy(@ullable IAudioPolicyCallback pcb)11987     public void unregisterAudioPolicy(@Nullable IAudioPolicyCallback pcb) {
11988         if (pcb == null) {
11989             return;
11990         }
11991         unregisterAudioPolicyInt(pcb, "unregisterAudioPolicy");
11992     }
11993 
11994 
unregisterAudioPolicyInt(@onNull IAudioPolicyCallback pcb, String operationName)11995     private void unregisterAudioPolicyInt(@NonNull IAudioPolicyCallback pcb, String operationName) {
11996         mDynPolicyLogger.enqueue((new EventLogger.StringEvent(operationName + " for "
11997                 + pcb.asBinder()).printLog(TAG)));
11998         synchronized (mAudioPolicies) {
11999             AudioPolicyProxy app = mAudioPolicies.remove(pcb.asBinder());
12000             if (app == null) {
12001                 Slog.w(TAG, "Trying to unregister unknown audio policy for pid "
12002                         + Binder.getCallingPid() + " / uid " + Binder.getCallingUid());
12003                 return;
12004             } else {
12005                 pcb.asBinder().unlinkToDeath(app, 0/*flags*/);
12006             }
12007             app.release();
12008         }
12009         // TODO implement clearing mix attribute matching info in native audio policy
12010     }
12011 
12012     /**
12013      * Checks whether caller has MODIFY_AUDIO_ROUTING permission, and the policy is registered.
12014      * @param errorMsg log warning if permission check failed.
12015      * @return null if the operation on the audio mixes should be cancelled.
12016      */
12017     @GuardedBy("mAudioPolicies")
checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg)12018     private AudioPolicyProxy checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg) {
12019         // permission check
12020         final boolean hasPermissionForPolicy =
12021                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
12022                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
12023         if (!hasPermissionForPolicy) {
12024             Slog.w(TAG, errorMsg + " for pid " +
12025                     + Binder.getCallingPid() + " / uid "
12026                     + Binder.getCallingUid() + ", need MODIFY_AUDIO_ROUTING");
12027             return null;
12028         }
12029         // policy registered?
12030         final AudioPolicyProxy app = mAudioPolicies.get(pcb.asBinder());
12031         if (app == null) {
12032             Slog.w(TAG, errorMsg + " for pid " +
12033                     + Binder.getCallingPid() + " / uid "
12034                     + Binder.getCallingUid() + ", unregistered policy");
12035             return null;
12036         }
12037         return app;
12038     }
12039 
addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)12040     public int addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) {
12041         if (DEBUG_AP) { Log.d(TAG, "addMixForPolicy for " + pcb.asBinder()
12042                 + " with config:" + policyConfig); }
12043         synchronized (mAudioPolicies) {
12044             final AudioPolicyProxy app =
12045                     checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy");
12046             if (app == null){
12047                 return AudioManager.ERROR;
12048             }
12049             return app.addMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS
12050                 ? AudioManager.SUCCESS : AudioManager.ERROR;
12051         }
12052     }
12053 
removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)12054     public int removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) {
12055         if (DEBUG_AP) { Log.d(TAG, "removeMixForPolicy for " + pcb.asBinder()
12056                 + " with config:" + policyConfig); }
12057         synchronized (mAudioPolicies) {
12058             final AudioPolicyProxy app =
12059                     checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy");
12060             if (app == null) {
12061                 return AudioManager.ERROR;
12062             }
12063             return app.removeMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS
12064                 ? AudioManager.SUCCESS : AudioManager.ERROR;
12065         }
12066     }
12067 
12068     /** see AudioPolicy.setUidDeviceAffinity() */
setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)12069     public int setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid,
12070             @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) {
12071         if (DEBUG_AP) {
12072             Log.d(TAG, "setUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid);
12073         }
12074         synchronized (mAudioPolicies) {
12075             final AudioPolicyProxy app =
12076                     checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy");
12077             if (app == null) {
12078                 return AudioManager.ERROR;
12079             }
12080             if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) {
12081                 return AudioManager.ERROR;
12082             }
12083             return app.setUidDeviceAffinities(uid, deviceTypes, deviceAddresses);
12084         }
12085     }
12086 
12087     /** see AudioPolicy.setUserIdDeviceAffinity() */
setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)12088     public int setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId,
12089             @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) {
12090         if (DEBUG_AP) {
12091             Log.d(TAG, "setUserIdDeviceAffinity for " + pcb.asBinder() + " user:" + userId);
12092         }
12093 
12094         synchronized (mAudioPolicies) {
12095             final AudioPolicyProxy app =
12096                     checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy");
12097             if (app == null) {
12098                 return AudioManager.ERROR;
12099             }
12100             if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) {
12101                 return AudioManager.ERROR;
12102             }
12103             return app.setUserIdDeviceAffinities(userId, deviceTypes, deviceAddresses);
12104         }
12105     }
12106 
12107     /** see AudioPolicy.removeUidDeviceAffinity() */
removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid)12108     public int removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid) {
12109         if (DEBUG_AP) {
12110             Log.d(TAG, "removeUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid);
12111         }
12112         synchronized (mAudioPolicies) {
12113             final AudioPolicyProxy app =
12114                     checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy");
12115             if (app == null) {
12116                 return AudioManager.ERROR;
12117             }
12118             return app.removeUidDeviceAffinities(uid);
12119         }
12120     }
12121 
12122     /** see AudioPolicy.removeUserIdDeviceAffinity() */
removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId)12123     public int removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId) {
12124         if (DEBUG_AP) {
12125             Log.d(TAG, "removeUserIdDeviceAffinity for " + pcb.asBinder()
12126                     + " userId:" + userId);
12127         }
12128         synchronized (mAudioPolicies) {
12129             final AudioPolicyProxy app =
12130                     checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy");
12131             if (app == null) {
12132                 return AudioManager.ERROR;
12133             }
12134             return app.removeUserIdDeviceAffinities(userId);
12135         }
12136     }
12137 
setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb)12138     public int setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb) {
12139         if (DEBUG_AP) Log.d(TAG, "setFocusPropertiesForPolicy() duck behavior=" + duckingBehavior
12140                 + " policy " +  pcb.asBinder());
12141         synchronized (mAudioPolicies) {
12142             final AudioPolicyProxy app =
12143                     checkUpdateForPolicy(pcb, "Cannot change audio policy focus properties");
12144             if (app == null){
12145                 return AudioManager.ERROR;
12146             }
12147             if (!mAudioPolicies.containsKey(pcb.asBinder())) {
12148                 Slog.e(TAG, "Cannot change audio policy focus properties, unregistered policy");
12149                 return AudioManager.ERROR;
12150             }
12151             if (duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) {
12152                 // is there already one policy managing ducking?
12153                 for (AudioPolicyProxy policy : mAudioPolicies.values()) {
12154                     if (policy.mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) {
12155                         Slog.e(TAG, "Cannot change audio policy ducking behavior, already handled");
12156                         return AudioManager.ERROR;
12157                     }
12158                 }
12159             }
12160             app.mFocusDuckBehavior = duckingBehavior;
12161             mMediaFocusControl.setDuckingInExtPolicyAvailable(
12162                     duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY);
12163         }
12164         return AudioManager.SUCCESS;
12165     }
12166 
12167     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
12168     /** @see AudioPolicy#getFocusStack() */
getFocusStack()12169     public List<AudioFocusInfo> getFocusStack() {
12170         super.getFocusStack_enforcePermission();
12171 
12172         return mMediaFocusControl.getFocusStack();
12173     }
12174 
12175     /** @see AudioPolicy#sendFocusLoss */
sendFocusLoss(@onNull AudioFocusInfo focusLoser, @NonNull IAudioPolicyCallback apcb)12176     public boolean sendFocusLoss(@NonNull AudioFocusInfo focusLoser,
12177             @NonNull IAudioPolicyCallback apcb) {
12178         Objects.requireNonNull(focusLoser);
12179         Objects.requireNonNull(apcb);
12180         enforceModifyAudioRoutingPermission();
12181         if (!mAudioPolicies.containsKey(apcb.asBinder())) {
12182             throw new IllegalStateException("Only registered AudioPolicy can change focus");
12183         }
12184         if (!mAudioPolicies.get(apcb.asBinder()).mHasFocusListener) {
12185             throw new IllegalStateException("AudioPolicy must have focus listener to change focus");
12186         }
12187         return mMediaFocusControl.sendFocusLoss(focusLoser);
12188     }
12189 
12190     /**
12191      * @see AudioManager#getHalVersion
12192      */
getHalVersion()12193     public @Nullable AudioHalVersionInfo getHalVersion() {
12194         for (AudioHalVersionInfo version : AudioHalVersionInfo.VERSIONS) {
12195             try {
12196                 // TODO: check AIDL service.
12197                 String versionStr = version.getMajorVersion() + "." + version.getMinorVersion();
12198                 HwBinder.getService(
12199                         String.format("android.hardware.audio@%s::IDevicesFactory", versionStr),
12200                         "default");
12201                 return version;
12202             } catch (NoSuchElementException e) {
12203                 // Ignore, the specified HAL interface is not found.
12204             } catch (RemoteException re) {
12205                 Log.e(TAG, "Remote exception when getting hardware audio service:", re);
12206             }
12207         }
12208         return null;
12209     }
12210 
12211     /** see AudioManager.hasRegisteredDynamicPolicy */
hasRegisteredDynamicPolicy()12212     public boolean hasRegisteredDynamicPolicy() {
12213         synchronized (mAudioPolicies) {
12214             return !mAudioPolicies.isEmpty();
12215         }
12216     }
12217 
12218     /**
12219      * @see AudioManager#setPreferredMixerAttributes(
12220      *      AudioAttributes, AudioDeviceInfo, AudioMixerAttributes)
12221      */
setPreferredMixerAttributes(AudioAttributes attributes, int portId, AudioMixerAttributes mixerAttributes)12222     public int setPreferredMixerAttributes(AudioAttributes attributes,
12223             int portId, AudioMixerAttributes mixerAttributes) {
12224         Objects.requireNonNull(attributes);
12225         Objects.requireNonNull(mixerAttributes);
12226         if (!checkAudioSettingsPermission("setPreferredMixerAttributes()")) {
12227             return AudioSystem.PERMISSION_DENIED;
12228         }
12229         final int uid = Binder.getCallingUid();
12230         final int pid = Binder.getCallingPid();
12231         int status = AudioSystem.SUCCESS;
12232         final long token = Binder.clearCallingIdentity();
12233         try {
12234             final String logString = TextUtils.formatSimple(
12235                     "setPreferredMixerAttributes u/pid:%d/%d attr:%s mixerAttributes:%s portId:%d",
12236                     uid, pid, attributes.toString(), mixerAttributes.toString(), portId);
12237             sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
12238 
12239             status = mAudioSystem.setPreferredMixerAttributes(
12240                     attributes, portId, uid, mixerAttributes);
12241             if (status == AudioSystem.SUCCESS) {
12242                 dispatchPreferredMixerAttributesChanged(attributes, portId, mixerAttributes);
12243             } else {
12244                 Log.e(TAG, TextUtils.formatSimple("Error %d in %s)", status, logString));
12245             }
12246         } finally {
12247             Binder.restoreCallingIdentity(token);
12248         }
12249         return status;
12250     }
12251 
12252     /**
12253      * @see AudioManager#clearPreferredMixerAttributes(AudioAttributes, AudioDeviceInfo)
12254      */
clearPreferredMixerAttributes(AudioAttributes attributes, int portId)12255     public int clearPreferredMixerAttributes(AudioAttributes attributes, int portId) {
12256         Objects.requireNonNull(attributes);
12257         if (!checkAudioSettingsPermission("clearPreferredMixerAttributes()")) {
12258             return AudioSystem.PERMISSION_DENIED;
12259         }
12260         final int uid = Binder.getCallingUid();
12261         final int pid = Binder.getCallingPid();
12262         int status = AudioSystem.SUCCESS;
12263         final long token = Binder.clearCallingIdentity();
12264         try {
12265             final String logString = TextUtils.formatSimple(
12266                     "clearPreferredMixerAttributes u/pid:%d/%d attr:%s",
12267                     uid, pid, attributes.toString());
12268             sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
12269 
12270             status = mAudioSystem.clearPreferredMixerAttributes(attributes, portId, uid);
12271             if (status == AudioSystem.SUCCESS) {
12272                 dispatchPreferredMixerAttributesChanged(attributes, portId, null /*mixerAttr*/);
12273             } else {
12274                 Log.e(TAG, TextUtils.formatSimple("Error %d in %s)", status, logString));
12275             }
12276         } finally {
12277             Binder.restoreCallingIdentity(token);
12278         }
12279         return status;
12280     }
12281 
dispatchPreferredMixerAttributesChanged( AudioAttributes attr, int deviceId, AudioMixerAttributes mixerAttr)12282     void dispatchPreferredMixerAttributesChanged(
12283             AudioAttributes attr, int deviceId, AudioMixerAttributes mixerAttr) {
12284         Bundle bundle = new Bundle();
12285         bundle.putParcelable(KEY_AUDIO_ATTRIBUTES, attr);
12286         bundle.putParcelable(KEY_AUDIO_MIXER_ATTRIBUTES, mixerAttr);
12287         sendBundleMsg(mAudioHandler, MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES, SENDMSG_QUEUE,
12288                 deviceId, 0, null, bundle, 0);
12289     }
12290 
12291     final RemoteCallbackList<IPreferredMixerAttributesDispatcher> mPrefMixerAttrDispatcher =
12292             new RemoteCallbackList<IPreferredMixerAttributesDispatcher>();
12293     private static final String KEY_AUDIO_ATTRIBUTES = "audio_attributes";
12294     private static final String KEY_AUDIO_MIXER_ATTRIBUTES = "audio_mixer_attributes";
12295 
12296     /** @see AudioManager#addOnPreferredMixerAttributesChangedListener(
12297      *       Executor, AudioManager.OnPreferredMixerAttributesChangedListener)
12298      */
registerPreferredMixerAttributesDispatcher( @ullable IPreferredMixerAttributesDispatcher dispatcher)12299     public void registerPreferredMixerAttributesDispatcher(
12300             @Nullable IPreferredMixerAttributesDispatcher dispatcher) {
12301         if (dispatcher == null) {
12302             return;
12303         }
12304         mPrefMixerAttrDispatcher.register(dispatcher);
12305     }
12306 
12307     /** @see AudioManager#removeOnPreferredMixerAttributesChangedListener(
12308      *       AudioManager.OnPreferredMixerAttributesChangedListener)
12309      */
unregisterPreferredMixerAttributesDispatcher( @ullable IPreferredMixerAttributesDispatcher dispatcher)12310     public void unregisterPreferredMixerAttributesDispatcher(
12311             @Nullable IPreferredMixerAttributesDispatcher dispatcher) {
12312         if (dispatcher == null) {
12313             return;
12314         }
12315         mPrefMixerAttrDispatcher.unregister(dispatcher);
12316     }
12317 
onDispatchPreferredMixerAttributesChanged(Bundle data, int deviceId)12318     protected void onDispatchPreferredMixerAttributesChanged(Bundle data, int deviceId) {
12319         final int nbDispathers = mPrefMixerAttrDispatcher.beginBroadcast();
12320         final AudioAttributes attr = data.getParcelable(
12321                 KEY_AUDIO_ATTRIBUTES, AudioAttributes.class);
12322         final AudioMixerAttributes mixerAttr = data.getParcelable(
12323                 KEY_AUDIO_MIXER_ATTRIBUTES, AudioMixerAttributes.class);
12324         for (int i = 0; i < nbDispathers; i++) {
12325             try {
12326                 mPrefMixerAttrDispatcher.getBroadcastItem(i)
12327                         .dispatchPrefMixerAttributesChanged(attr, deviceId, mixerAttr);
12328             } catch (RemoteException e) {
12329                 Log.e(TAG, "Can't call dispatchPrefMixerAttributesChanged() "
12330                         + "IPreferredMixerAttributesDispatcher "
12331                         + mPrefMixerAttrDispatcher.getBroadcastItem(i).asBinder(), e);
12332             }
12333         }
12334         mPrefMixerAttrDispatcher.finishBroadcast();
12335     }
12336 
12337 
12338     /** @see AudioManager#supportsBluetoothVariableLatency() */
12339     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
supportsBluetoothVariableLatency()12340     public boolean supportsBluetoothVariableLatency() {
12341         super.supportsBluetoothVariableLatency_enforcePermission();
12342         try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
12343             return AudioSystem.supportsBluetoothVariableLatency();
12344         }
12345     }
12346 
12347     /** @see AudioManager#setBluetoothVariableLatencyEnabled(boolean) */
12348     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
setBluetoothVariableLatencyEnabled(boolean enabled)12349     public void setBluetoothVariableLatencyEnabled(boolean enabled) {
12350         super.setBluetoothVariableLatencyEnabled_enforcePermission();
12351         try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
12352             AudioSystem.setBluetoothVariableLatencyEnabled(enabled);
12353         }
12354     }
12355 
12356     /** @see AudioManager#isBluetoothVariableLatencyEnabled(boolean) */
12357     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
isBluetoothVariableLatencyEnabled()12358     public boolean isBluetoothVariableLatencyEnabled() {
12359         super.isBluetoothVariableLatencyEnabled_enforcePermission();
12360         try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
12361             return AudioSystem.isBluetoothVariableLatencyEnabled();
12362         }
12363     }
12364 
12365     private final Object mExtVolumeControllerLock = new Object();
12366     private IAudioPolicyCallback mExtVolumeController;
setExtVolumeController(IAudioPolicyCallback apc)12367     private void setExtVolumeController(IAudioPolicyCallback apc) {
12368         if (!mContext.getResources().getBoolean(
12369                 com.android.internal.R.bool.config_handleVolumeKeysInWindowManager)) {
12370             Log.e(TAG, "Cannot set external volume controller: device not set for volume keys" +
12371                     " handled in PhoneWindowManager");
12372             return;
12373         }
12374         synchronized (mExtVolumeControllerLock) {
12375             if (mExtVolumeController != null && !mExtVolumeController.asBinder().pingBinder()) {
12376                 Log.e(TAG, "Cannot set external volume controller: existing controller");
12377             }
12378             mExtVolumeController = apc;
12379         }
12380     }
12381 
dumpAudioPolicies(PrintWriter pw)12382     private void dumpAudioPolicies(PrintWriter pw) {
12383         pw.println("\nAudio policies:");
12384         synchronized (mAudioPolicies) {
12385             for (AudioPolicyProxy policy : mAudioPolicies.values()) {
12386                 pw.println(policy.toLogFriendlyString());
12387             }
12388         }
12389     }
12390 
12391     //======================
12392     // Audio policy callbacks from AudioSystem for dynamic policies
12393     //======================
12394     private final AudioSystem.DynamicPolicyCallback mDynPolicyCallback =
12395             new AudioSystem.DynamicPolicyCallback() {
12396         public void onDynamicPolicyMixStateUpdate(String regId, int state) {
12397             if (!TextUtils.isEmpty(regId)) {
12398                 sendMsg(mAudioHandler, MSG_DYN_POLICY_MIX_STATE_UPDATE, SENDMSG_QUEUE,
12399                         state /*arg1*/, 0 /*arg2 ignored*/, regId /*obj*/, 0 /*delay*/);
12400             }
12401         }
12402     };
12403 
onDynPolicyMixStateUpdate(String regId, int state)12404     private void onDynPolicyMixStateUpdate(String regId, int state) {
12405         if (DEBUG_AP) Log.d(TAG, "onDynamicPolicyMixStateUpdate("+ regId + ", " + state +")");
12406         synchronized (mAudioPolicies) {
12407             for (AudioPolicyProxy policy : mAudioPolicies.values()) {
12408                 for (AudioMix mix : policy.getMixes()) {
12409                     if (mix.getRegistration().equals(regId)) {
12410                         try {
12411                             policy.mPolicyCallback.notifyMixStateUpdate(regId, state);
12412                         } catch (RemoteException e) {
12413                             Log.e(TAG, "Can't call notifyMixStateUpdate() on IAudioPolicyCallback "
12414                                     + policy.mPolicyCallback.asBinder(), e);
12415                         }
12416                         return;
12417                     }
12418                 }
12419             }
12420         }
12421     }
12422 
12423     //======================
12424     // Audio policy callbacks from AudioSystem for recording configuration updates
12425     //======================
12426     private final RecordingActivityMonitor mRecordMonitor;
12427 
registerRecordingCallback(IRecordingConfigDispatcher rcdb)12428     public void registerRecordingCallback(IRecordingConfigDispatcher rcdb) {
12429         final boolean isPrivileged =
12430                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
12431                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
12432         mRecordMonitor.registerRecordingCallback(rcdb, isPrivileged);
12433     }
12434 
unregisterRecordingCallback(IRecordingConfigDispatcher rcdb)12435     public void unregisterRecordingCallback(IRecordingConfigDispatcher rcdb) {
12436         mRecordMonitor.unregisterRecordingCallback(rcdb);
12437     }
12438 
getActiveRecordingConfigurations()12439     public List<AudioRecordingConfiguration> getActiveRecordingConfigurations() {
12440         final boolean isPrivileged = Binder.getCallingUid() == Process.SYSTEM_UID
12441                 || (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
12442                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
12443         return mRecordMonitor.getActiveRecordingConfigurations(isPrivileged);
12444     }
12445 
12446     //======================
12447     // Audio recording state notification from clients
12448     //======================
12449     /**
12450      * Track a recorder provided by the client
12451      */
trackRecorder(IBinder recorder)12452     public int trackRecorder(IBinder recorder) {
12453         return mRecordMonitor.trackRecorder(recorder);
12454     }
12455 
12456     /**
12457      * Receive an event from the client about a tracked recorder
12458      */
recorderEvent(int riid, int event)12459     public void recorderEvent(int riid, int event) {
12460         mRecordMonitor.recorderEvent(riid, event);
12461     }
12462 
12463     /**
12464      * Stop tracking the recorder
12465      */
releaseRecorder(int riid)12466     public void releaseRecorder(int riid) {
12467         mRecordMonitor.releaseRecorder(riid);
12468     }
12469 
12470     //======================
12471     // Audio playback notification
12472     //======================
12473     private final PlaybackActivityMonitor mPlaybackMonitor;
12474 
registerPlaybackCallback(IPlaybackConfigDispatcher pcdb)12475     public void registerPlaybackCallback(IPlaybackConfigDispatcher pcdb) {
12476         final boolean isPrivileged =
12477                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
12478                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
12479         mPlaybackMonitor.registerPlaybackCallback(pcdb, isPrivileged);
12480     }
12481 
unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb)12482     public void unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb) {
12483         mPlaybackMonitor.unregisterPlaybackCallback(pcdb);
12484     }
12485 
getActivePlaybackConfigurations()12486     public List<AudioPlaybackConfiguration> getActivePlaybackConfigurations() {
12487         final boolean isPrivileged =
12488                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
12489                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
12490         return mPlaybackMonitor.getActivePlaybackConfigurations(isPrivileged);
12491     }
12492 
trackPlayer(PlayerBase.PlayerIdCard pic)12493     public int trackPlayer(PlayerBase.PlayerIdCard pic) {
12494         if (pic != null && pic.mAttributes != null) {
12495             validateAudioAttributesUsage(pic.mAttributes);
12496         }
12497         return mPlaybackMonitor.trackPlayer(pic);
12498     }
12499 
playerAttributes(int piid, AudioAttributes attr)12500     public void playerAttributes(int piid, AudioAttributes attr) {
12501         if (attr != null) {
12502             validateAudioAttributesUsage(attr);
12503         }
12504         mPlaybackMonitor.playerAttributes(piid, attr, Binder.getCallingUid());
12505     }
12506 
12507     /**
12508      * Update player session ID
12509      * @param piid Player id to update
12510      * @param sessionId The new audio session ID
12511      */
playerSessionId(int piid, int sessionId)12512     public void playerSessionId(int piid, int sessionId) {
12513         if (sessionId <= AudioSystem.AUDIO_SESSION_ALLOCATE) {
12514             throw new IllegalArgumentException("invalid session Id " + sessionId);
12515         }
12516         mPlaybackMonitor.playerSessionId(piid, sessionId, Binder.getCallingUid());
12517     }
12518 
12519     /**
12520      * Update player event
12521      * @param piid Player id to update
12522      * @param event The new player event
12523      * @param eventValue The value associated with this event
12524      */
playerEvent(int piid, int event, int eventValue)12525     public void playerEvent(int piid, int event, int eventValue) {
12526         mPlaybackMonitor.playerEvent(piid, event, eventValue, Binder.getCallingUid());
12527     }
12528 
12529     /**
12530      * Update event for port id
12531      * @param portId Port id to update
12532      * @param event The new event for the given port
12533      * @param extras Bundle of extra values to describe the event
12534      */
portEvent(int portId, int event, @Nullable PersistableBundle extras)12535     public void portEvent(int portId, int event, @Nullable PersistableBundle extras) {
12536         mPlaybackMonitor.portEvent(portId, event, extras, Binder.getCallingUid());
12537     }
12538 
playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio)12539     public void playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio) {
12540         mPlaybackMonitor.playerHasOpPlayAudio(piid, hasOpPlayAudio, Binder.getCallingUid());
12541     }
12542 
releasePlayer(int piid)12543     public void releasePlayer(int piid) {
12544         mPlaybackMonitor.releasePlayer(piid, Binder.getCallingUid());
12545     }
12546 
12547     /**
12548      * Specifies whether the audio played by this app may or may not be captured by other apps or
12549      * the system.
12550      *
12551      * @param capturePolicy one of
12552      *     {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL},
12553      *     {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM},
12554      *     {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}.
12555      * @return AudioSystem.AUDIO_STATUS_OK if set allowed capture policy succeed.
12556      * @throws IllegalArgumentException if the argument is not a valid value.
12557      */
setAllowedCapturePolicy(int capturePolicy)12558     public int setAllowedCapturePolicy(int capturePolicy) {
12559         int callingUid = Binder.getCallingUid();
12560         int flags = AudioAttributes.capturePolicyToFlags(capturePolicy, 0x0);
12561         final long identity = Binder.clearCallingIdentity();
12562         try {
12563             synchronized (mPlaybackMonitor) {
12564                 int result = mAudioSystem.setAllowedCapturePolicy(callingUid, flags);
12565                 if (result == AudioSystem.AUDIO_STATUS_OK) {
12566                     mPlaybackMonitor.setAllowedCapturePolicy(callingUid, capturePolicy);
12567                 }
12568                 return result;
12569             }
12570         } finally {
12571             Binder.restoreCallingIdentity(identity);
12572         }
12573     }
12574 
12575     /**
12576      * Return the capture policy.
12577      * @return the cached capture policy for the calling uid.
12578      */
getAllowedCapturePolicy()12579     public int getAllowedCapturePolicy() {
12580         int callingUid = Binder.getCallingUid();
12581         final long identity = Binder.clearCallingIdentity();
12582         try {
12583             return mPlaybackMonitor.getAllowedCapturePolicy(callingUid);
12584         } finally {
12585             Binder.restoreCallingIdentity(identity);
12586         }
12587     }
12588 
12589     /* package */
isPlaybackActiveForUid(int uid)12590     boolean isPlaybackActiveForUid(int uid) {
12591         return mPlaybackMonitor.isPlaybackActiveForUid(uid);
12592     }
12593 
12594     /* package */
isRecordingActiveForUid(int uid)12595     boolean isRecordingActiveForUid(int uid) {
12596         return mRecordMonitor.isRecordingActiveForUid(uid);
12597     }
12598 
12599     //======================
12600     // Audio device management
12601     //======================
12602     private final AudioDeviceBroker mDeviceBroker;
12603 
12604     //======================
12605     // Audio policy proxy
12606     //======================
12607     private static final class AudioDeviceArray {
12608         final @NonNull int[] mDeviceTypes;
12609         final @NonNull String[] mDeviceAddresses;
AudioDeviceArray(@onNull int[] types, @NonNull String[] addresses)12610         AudioDeviceArray(@NonNull int[] types,  @NonNull String[] addresses) {
12611             mDeviceTypes = types;
12612             mDeviceAddresses = addresses;
12613         }
12614     }
12615 
12616     /**
12617      * This internal class inherits from AudioPolicyConfig, each instance contains all the
12618      * mixes of an AudioPolicy and their configurations.
12619      */
12620     public class AudioPolicyProxy extends AudioPolicyConfig implements IBinder.DeathRecipient {
12621         private static final String TAG = "AudioPolicyProxy";
12622         final IAudioPolicyCallback mPolicyCallback;
12623         final boolean mHasFocusListener;
12624         final boolean mIsVolumeController;
12625         final HashMap<Integer, AudioDeviceArray> mUidDeviceAffinities =
12626                 new HashMap<Integer, AudioDeviceArray>();
12627 
12628         final HashMap<Integer, AudioDeviceArray> mUserIdDeviceAffinities =
12629                 new HashMap<>();
12630 
12631         final IMediaProjection mProjection;
12632         private final class UnregisterOnStopCallback extends IMediaProjectionCallback.Stub {
onStop()12633             public void onStop() {
12634                 unregisterAudioPolicyAsync(mPolicyCallback);
12635             }
12636 
12637             @Override
onCapturedContentResize(int width, int height)12638             public void onCapturedContentResize(int width, int height) {
12639                 // Ignore resize of the captured content.
12640             }
12641 
12642             @Override
onCapturedContentVisibilityChanged(boolean isVisible)12643             public void onCapturedContentVisibilityChanged(boolean isVisible) {
12644                 // Ignore visibility changes of the captured content.
12645             }
12646         };
12647         UnregisterOnStopCallback mProjectionCallback;
12648 
12649         /**
12650          * Audio focus ducking behavior for an audio policy.
12651          * This variable reflects the value that was successfully set in
12652          * {@link AudioService#setFocusPropertiesForPolicy(int, IAudioPolicyCallback)}. This
12653          * implies that a value of FOCUS_POLICY_DUCKING_IN_POLICY means the corresponding policy
12654          * is handling ducking for audio focus.
12655          */
12656         int mFocusDuckBehavior = AudioPolicy.FOCUS_POLICY_DUCKING_DEFAULT;
12657         boolean mIsFocusPolicy = false;
12658         boolean mIsTestFocusPolicy = false;
12659 
AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection)12660         AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token,
12661                 boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy,
12662                 boolean isVolumeController, IMediaProjection projection) {
12663             super(config);
12664             setRegistration(new String(config.hashCode() + ":ap:" + mAudioPolicyCounter++));
12665             mPolicyCallback = token;
12666             mHasFocusListener = hasFocusListener;
12667             mIsVolumeController = isVolumeController;
12668             mProjection = projection;
12669             if (mHasFocusListener) {
12670                 mMediaFocusControl.addFocusFollower(mPolicyCallback);
12671                 // can only ever be true if there is a focus listener
12672                 if (isFocusPolicy) {
12673                     mIsFocusPolicy = true;
12674                     mIsTestFocusPolicy = isTestFocusPolicy;
12675                     mMediaFocusControl.setFocusPolicy(mPolicyCallback, mIsTestFocusPolicy);
12676                 }
12677             }
12678             if (mIsVolumeController) {
12679                 setExtVolumeController(mPolicyCallback);
12680             }
12681             if (mProjection != null) {
12682                 mProjectionCallback = new UnregisterOnStopCallback();
12683                 try {
12684                     mProjection.registerCallback(mProjectionCallback);
12685                 } catch (RemoteException e) {
12686                     release();
12687                     throw new IllegalStateException("MediaProjection callback registration failed, "
12688                             + "could not link to " + projection + " binder death", e);
12689                 }
12690             }
12691             int status = connectMixes();
12692             if (status != AudioSystem.SUCCESS) {
12693                 release();
12694                 throw new IllegalStateException("Could not connect mix, error: " + status);
12695             }
12696         }
12697 
binderDied()12698         public void binderDied() {
12699             mDynPolicyLogger.enqueue((new EventLogger.StringEvent("AudioPolicy "
12700                     + mPolicyCallback.asBinder() + " died").printLog(TAG)));
12701 
12702             List<String> addresses = new ArrayList<>();
12703             for (AudioMix mix : mMixes) {
12704                 addresses.add(mix.getRegistration());
12705             }
12706             onPolicyClientDeath(addresses);
12707 
12708             release();
12709         }
12710 
getRegistrationId()12711         String getRegistrationId() {
12712             return getRegistration();
12713         }
12714 
release()12715         void release() {
12716             if (mIsFocusPolicy) {
12717                 mMediaFocusControl.unsetFocusPolicy(mPolicyCallback, mIsTestFocusPolicy);
12718             }
12719             if (mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) {
12720                 mMediaFocusControl.setDuckingInExtPolicyAvailable(false);
12721             }
12722             if (mHasFocusListener) {
12723                 mMediaFocusControl.removeFocusFollower(mPolicyCallback);
12724             }
12725             if (mProjectionCallback != null) {
12726                 try {
12727                     mProjection.unregisterCallback(mProjectionCallback);
12728                 } catch (RemoteException e) {
12729                     Log.e(TAG, "Fail to unregister Audiopolicy callback from MediaProjection");
12730                 }
12731             }
12732             if (mIsVolumeController) {
12733                 synchronized (mExtVolumeControllerLock) {
12734                     mExtVolumeController = null;
12735                 }
12736             }
12737             final long identity = Binder.clearCallingIdentity();
12738             try {
12739                 mAudioSystem.registerPolicyMixes(mMixes, false);
12740             } finally {
12741                 Binder.restoreCallingIdentity(identity);
12742             }
12743             synchronized (mAudioPolicies) {
12744                 mAudioPolicies.remove(mPolicyCallback.asBinder());
12745             }
12746             try {
12747                 mPolicyCallback.notifyUnregistration();
12748             } catch (RemoteException e) { }
12749         }
12750 
hasMixAffectingUsage(int usage, int excludedFlags)12751         boolean hasMixAffectingUsage(int usage, int excludedFlags) {
12752             for (AudioMix mix : mMixes) {
12753                 if (mix.isAffectingUsage(usage)
12754                         && ((mix.getRouteFlags() & excludedFlags) != excludedFlags)) {
12755                     return true;
12756                 }
12757             }
12758             return false;
12759         }
12760 
12761         // Verify all the devices in the array are served by mixes defined in this policy
hasMixRoutedToDevices(@onNull int[] deviceTypes, @NonNull String[] deviceAddresses)12762         boolean hasMixRoutedToDevices(@NonNull int[] deviceTypes,
12763                 @NonNull String[] deviceAddresses) {
12764             for (int i = 0; i < deviceTypes.length; i++) {
12765                 boolean hasDevice = false;
12766                 for (AudioMix mix : mMixes) {
12767                     // this will check both that the mix has ROUTE_FLAG_RENDER and the device
12768                     // is reached by this mix
12769                     if (mix.isRoutedToDevice(deviceTypes[i], deviceAddresses[i])) {
12770                         hasDevice = true;
12771                         break;
12772                     }
12773                 }
12774                 if (!hasDevice) {
12775                     return false;
12776                 }
12777             }
12778             return true;
12779         }
12780 
addMixes(@onNull ArrayList<AudioMix> mixes)12781         int addMixes(@NonNull ArrayList<AudioMix> mixes) {
12782             synchronized (mMixes) {
12783                 this.add(mixes);
12784                 return mAudioSystem.registerPolicyMixes(mixes, true);
12785             }
12786         }
12787 
removeMixes(@onNull ArrayList<AudioMix> mixes)12788         int removeMixes(@NonNull ArrayList<AudioMix> mixes) {
12789             synchronized (mMixes) {
12790                 this.remove(mixes);
12791                 return mAudioSystem.registerPolicyMixes(mixes, false);
12792             }
12793         }
12794 
connectMixes()12795         @AudioSystem.AudioSystemError int connectMixes() {
12796             final long identity = Binder.clearCallingIdentity();
12797             try {
12798                 return mAudioSystem.registerPolicyMixes(mMixes, true);
12799             } finally {
12800                 Binder.restoreCallingIdentity(identity);
12801             }
12802 
12803         }
12804 
setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses)12805         int setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses) {
12806             final Integer Uid = new Integer(uid);
12807             if (mUidDeviceAffinities.remove(Uid) != null) {
12808                 if (removeUidDeviceAffinitiesFromSystem(uid) != AudioSystem.SUCCESS) {
12809                     Log.e(TAG, "AudioSystem. removeUidDeviceAffinities(" + uid + ") failed, "
12810                             + " cannot call AudioSystem.setUidDeviceAffinities");
12811                     return AudioManager.ERROR;
12812                 }
12813             }
12814             AudioDeviceArray deviceArray = new AudioDeviceArray(types, addresses);
12815             if (setUidDeviceAffinitiesOnSystem(uid, deviceArray) == AudioSystem.SUCCESS) {
12816                 mUidDeviceAffinities.put(Uid, deviceArray);
12817                 return AudioManager.SUCCESS;
12818             }
12819             Log.e(TAG, "AudioSystem. setUidDeviceAffinities(" + uid + ") failed");
12820             return AudioManager.ERROR;
12821         }
12822 
removeUidDeviceAffinities(int uid)12823         int removeUidDeviceAffinities(int uid) {
12824             if (mUidDeviceAffinities.remove(new Integer(uid)) != null) {
12825                 if (removeUidDeviceAffinitiesFromSystem(uid) == AudioSystem.SUCCESS) {
12826                     return AudioManager.SUCCESS;
12827                 }
12828             }
12829             Log.e(TAG, "AudioSystem. removeUidDeviceAffinities failed");
12830             return AudioManager.ERROR;
12831         }
12832 
removeUidDeviceAffinitiesFromSystem(int uid)12833         @AudioSystem.AudioSystemError private int removeUidDeviceAffinitiesFromSystem(int uid) {
12834             final long identity = Binder.clearCallingIdentity();
12835             try {
12836                 return mAudioSystem.removeUidDeviceAffinities(uid);
12837             } finally {
12838                 Binder.restoreCallingIdentity(identity);
12839             }
12840         }
12841 
setUidDeviceAffinitiesOnSystem(int uid, AudioDeviceArray deviceArray)12842         @AudioSystem.AudioSystemError private int setUidDeviceAffinitiesOnSystem(int uid,
12843                 AudioDeviceArray deviceArray) {
12844             final long identity = Binder.clearCallingIdentity();
12845             try {
12846                 return mAudioSystem.setUidDeviceAffinities(uid, deviceArray.mDeviceTypes,
12847                         deviceArray.mDeviceAddresses);
12848             } finally {
12849                 Binder.restoreCallingIdentity(identity);
12850             }
12851         }
12852 
setUserIdDeviceAffinities(int userId, @NonNull int[] types, @NonNull String[] addresses)12853         int setUserIdDeviceAffinities(int userId,
12854                 @NonNull int[] types, @NonNull String[] addresses) {
12855             final Integer UserId = new Integer(userId);
12856             if (mUserIdDeviceAffinities.remove(UserId) != null) {
12857                 if (removeUserIdDeviceAffinitiesFromSystem(userId) != AudioSystem.SUCCESS) {
12858                     Log.e(TAG, "AudioSystem. removeUserIdDeviceAffinities("
12859                             + UserId + ") failed, "
12860                             + " cannot call AudioSystem.setUserIdDeviceAffinities");
12861                     return AudioManager.ERROR;
12862                 }
12863             }
12864             AudioDeviceArray audioDeviceArray = new AudioDeviceArray(types, addresses);
12865             if (setUserIdDeviceAffinitiesOnSystem(userId, audioDeviceArray)
12866                     == AudioSystem.SUCCESS) {
12867                 mUserIdDeviceAffinities.put(UserId, audioDeviceArray);
12868                 return AudioManager.SUCCESS;
12869             }
12870             Log.e(TAG, "AudioSystem.setUserIdDeviceAffinities(" + userId + ") failed");
12871             return AudioManager.ERROR;
12872         }
12873 
removeUserIdDeviceAffinities(int userId)12874         int removeUserIdDeviceAffinities(int userId) {
12875             if (mUserIdDeviceAffinities.remove(new Integer(userId)) != null) {
12876                 if (removeUserIdDeviceAffinitiesFromSystem(userId) == AudioSystem.SUCCESS) {
12877                     return AudioManager.SUCCESS;
12878                 }
12879             }
12880             Log.e(TAG, "AudioSystem.removeUserIdDeviceAffinities failed");
12881             return AudioManager.ERROR;
12882         }
12883 
removeUserIdDeviceAffinitiesFromSystem( @serIdInt int userId)12884         @AudioSystem.AudioSystemError private int removeUserIdDeviceAffinitiesFromSystem(
12885                 @UserIdInt int userId) {
12886             final long identity = Binder.clearCallingIdentity();
12887             try {
12888                 return mAudioSystem.removeUserIdDeviceAffinities(userId);
12889             } finally {
12890                 Binder.restoreCallingIdentity(identity);
12891             }
12892         }
12893 
setUserIdDeviceAffinitiesOnSystem( @serIdInt int userId, AudioDeviceArray deviceArray)12894         @AudioSystem.AudioSystemError private int setUserIdDeviceAffinitiesOnSystem(
12895                 @UserIdInt int userId, AudioDeviceArray deviceArray) {
12896             final long identity = Binder.clearCallingIdentity();
12897             try {
12898                 return mAudioSystem.setUserIdDeviceAffinities(userId, deviceArray.mDeviceTypes,
12899                         deviceArray.mDeviceAddresses);
12900             } finally {
12901                 Binder.restoreCallingIdentity(identity);
12902             }
12903         }
12904 
setupDeviceAffinities()12905         @AudioSystem.AudioSystemError int setupDeviceAffinities() {
12906             for (Map.Entry<Integer, AudioDeviceArray> uidEntry : mUidDeviceAffinities.entrySet()) {
12907                 int uidStatus = removeUidDeviceAffinitiesFromSystem(uidEntry.getKey());
12908                 if (uidStatus != AudioSystem.SUCCESS) {
12909                     Log.e(TAG,
12910                             "setupDeviceAffinities failed to remove device affinity for uid "
12911                                     + uidEntry.getKey());
12912                     return uidStatus;
12913                 }
12914                 uidStatus = setUidDeviceAffinitiesOnSystem(uidEntry.getKey(), uidEntry.getValue());
12915                 if (uidStatus != AudioSystem.SUCCESS) {
12916                     Log.e(TAG,
12917                             "setupDeviceAffinities failed to set device affinity for uid "
12918                                     + uidEntry.getKey());
12919                     return uidStatus;
12920                 }
12921             }
12922 
12923             for (Map.Entry<Integer, AudioDeviceArray> userIdEntry :
12924                     mUserIdDeviceAffinities.entrySet()) {
12925                 int userIdStatus = removeUserIdDeviceAffinitiesFromSystem(userIdEntry.getKey());
12926                 if (userIdStatus != AudioSystem.SUCCESS) {
12927                     Log.e(TAG,
12928                             "setupDeviceAffinities failed to remove device affinity for userId "
12929                                     + userIdEntry.getKey());
12930                     return userIdStatus;
12931                 }
12932                 userIdStatus = setUserIdDeviceAffinitiesOnSystem(userIdEntry.getKey(),
12933                                 userIdEntry.getValue());
12934                 if (userIdStatus != AudioSystem.SUCCESS) {
12935                     Log.e(TAG,
12936                             "setupDeviceAffinities failed to set device affinity for userId "
12937                                     + userIdEntry.getKey());
12938                     return userIdStatus;
12939                 }
12940             }
12941             return AudioSystem.SUCCESS;
12942         }
12943 
12944         /** @return human readable debug informations summarizing the state of the object. */
toLogFriendlyString()12945         public String toLogFriendlyString() {
12946             String textDump = super.toLogFriendlyString();
12947             textDump += " Uid Device Affinities:\n";
12948             String spacer = "     ";
12949             textDump += logFriendlyAttributeDeviceArrayMap("Uid",
12950                     mUidDeviceAffinities, spacer);
12951             textDump += " UserId Device Affinities:\n";
12952             textDump += logFriendlyAttributeDeviceArrayMap("UserId",
12953                     mUserIdDeviceAffinities, spacer);
12954             textDump += " Proxy:\n";
12955             textDump += "   is focus policy= " + mIsFocusPolicy + "\n";
12956             if (mIsFocusPolicy) {
12957                 textDump += "     focus duck behaviour= " + mFocusDuckBehavior + "\n";
12958                 textDump += "     is test focus policy= " + mIsTestFocusPolicy + "\n";
12959                 textDump += "     has focus listener= " + mHasFocusListener  + "\n";
12960             }
12961             textDump += "   media projection= " + mProjection + "\n";
12962             return textDump;
12963         }
12964 
logFriendlyAttributeDeviceArrayMap(String attribute, Map<Integer, AudioDeviceArray> map, String spacer)12965         private String logFriendlyAttributeDeviceArrayMap(String attribute,
12966                 Map<Integer, AudioDeviceArray> map, String spacer) {
12967             final StringBuilder stringBuilder = new StringBuilder();
12968             for (Map.Entry<Integer, AudioDeviceArray> mapEntry : map.entrySet()) {
12969                 stringBuilder.append(spacer).append(attribute).append(": ")
12970                         .append(mapEntry.getKey()).append("\n");
12971                 AudioDeviceArray deviceArray = mapEntry.getValue();
12972                 String deviceSpacer = spacer + "   ";
12973                 for (int i = 0; i < deviceArray.mDeviceTypes.length; i++) {
12974                     stringBuilder.append(deviceSpacer).append("Type: 0x")
12975                             .append(Integer.toHexString(deviceArray.mDeviceTypes[i]))
12976                             .append(" Address: ").append(deviceArray.mDeviceAddresses[i])
12977                                     .append("\n");
12978                 }
12979             }
12980             return stringBuilder.toString();
12981         }
12982     };
12983 
12984     //======================
12985     // Audio policy: focus
12986     //======================
12987     /**  */
dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb)12988     public int dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb) {
12989         if (afi == null) {
12990             throw new IllegalArgumentException("Illegal null AudioFocusInfo");
12991         }
12992         if (pcb == null) {
12993             throw new IllegalArgumentException("Illegal null AudioPolicy callback");
12994         }
12995         synchronized (mAudioPolicies) {
12996             if (!mAudioPolicies.containsKey(pcb.asBinder())) {
12997                 throw new IllegalStateException("Unregistered AudioPolicy for focus dispatch");
12998             }
12999             return mMediaFocusControl.dispatchFocusChange(afi, focusChange);
13000         }
13001     }
13002 
setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult, IAudioPolicyCallback pcb)13003     public void setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult,
13004             IAudioPolicyCallback pcb) {
13005         if (afi == null) {
13006             throw new IllegalArgumentException("Illegal null AudioFocusInfo");
13007         }
13008         if (pcb == null) {
13009             throw new IllegalArgumentException("Illegal null AudioPolicy callback");
13010         }
13011         synchronized (mAudioPolicies) {
13012             if (!mAudioPolicies.containsKey(pcb.asBinder())) {
13013                 throw new IllegalStateException("Unregistered AudioPolicy for external focus");
13014             }
13015             mMediaFocusControl.setFocusRequestResultFromExtPolicy(afi, requestResult);
13016         }
13017     }
13018 
13019 
13020     //======================
13021     // Audioserver state dispatch
13022     //======================
13023     private class AsdProxy implements IBinder.DeathRecipient {
13024         private final IAudioServerStateDispatcher mAsd;
13025 
AsdProxy(IAudioServerStateDispatcher asd)13026         AsdProxy(IAudioServerStateDispatcher asd) {
13027             mAsd = asd;
13028         }
13029 
binderDied()13030         public void binderDied() {
13031             synchronized (mAudioServerStateListeners) {
13032                 mAudioServerStateListeners.remove(mAsd.asBinder());
13033             }
13034         }
13035 
callback()13036         IAudioServerStateDispatcher callback() {
13037             return mAsd;
13038         }
13039     }
13040 
13041     private final HashMap<IBinder, AsdProxy> mAudioServerStateListeners =
13042             new HashMap<IBinder, AsdProxy>();
13043 
checkMonitorAudioServerStatePermission()13044     private void checkMonitorAudioServerStatePermission() {
13045         if (!(mContext.checkCallingOrSelfPermission(
13046                     android.Manifest.permission.MODIFY_PHONE_STATE) ==
13047                 PackageManager.PERMISSION_GRANTED ||
13048               mContext.checkCallingOrSelfPermission(
13049                     android.Manifest.permission.MODIFY_AUDIO_ROUTING) ==
13050                 PackageManager.PERMISSION_GRANTED)) {
13051             throw new SecurityException("Not allowed to monitor audioserver state");
13052         }
13053     }
13054 
registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd)13055     public void registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd) {
13056         checkMonitorAudioServerStatePermission();
13057         synchronized (mAudioServerStateListeners) {
13058             if (mAudioServerStateListeners.containsKey(asd.asBinder())) {
13059                 Slog.w(TAG, "Cannot re-register audio server state dispatcher");
13060                 return;
13061             }
13062             AsdProxy asdp = new AsdProxy(asd);
13063             try {
13064                 asd.asBinder().linkToDeath(asdp, 0/*flags*/);
13065             } catch (RemoteException e) {
13066 
13067             }
13068             mAudioServerStateListeners.put(asd.asBinder(), asdp);
13069         }
13070     }
13071 
unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd)13072     public void unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd) {
13073         checkMonitorAudioServerStatePermission();
13074         synchronized (mAudioServerStateListeners) {
13075             AsdProxy asdp = mAudioServerStateListeners.remove(asd.asBinder());
13076             if (asdp == null) {
13077                 Slog.w(TAG, "Trying to unregister unknown audioserver state dispatcher for pid "
13078                         + Binder.getCallingPid() + " / uid " + Binder.getCallingUid());
13079                 return;
13080             } else {
13081                 asd.asBinder().unlinkToDeath(asdp, 0/*flags*/);
13082             }
13083         }
13084     }
13085 
isAudioServerRunning()13086     public boolean isAudioServerRunning() {
13087         checkMonitorAudioServerStatePermission();
13088         return (AudioSystem.checkAudioFlinger() == AudioSystem.AUDIO_STATUS_OK);
13089     }
13090 
13091     //======================
13092     // Audio HAL process dump
13093     //======================
13094 
13095     private static final String AUDIO_HAL_SERVICE_PREFIX = "android.hardware.audio";
13096 
getAudioAidlHalPids(HashSet<Integer> pids)13097     private void getAudioAidlHalPids(HashSet<Integer> pids) {
13098         try {
13099             ServiceDebugInfo[] infos = ServiceManager.getServiceDebugInfo();
13100             if (infos == null) return;
13101             for (ServiceDebugInfo info : infos) {
13102                 if (info.debugPid > 0 && info.name.startsWith(AUDIO_HAL_SERVICE_PREFIX)) {
13103                     pids.add(info.debugPid);
13104                 }
13105             }
13106         } catch (RuntimeException e) {
13107             // ignored, pid hashset does not change
13108         }
13109     }
13110 
getAudioHalHidlPids(HashSet<Integer> pids)13111     private void getAudioHalHidlPids(HashSet<Integer> pids) {
13112         try {
13113             IServiceManager serviceManager = IServiceManager.getService();
13114             ArrayList<IServiceManager.InstanceDebugInfo> dump =
13115                     serviceManager.debugDump();
13116             for (IServiceManager.InstanceDebugInfo info : dump) {
13117                 if (info.pid != IServiceManager.PidConstant.NO_PID
13118                         && info.interfaceName != null
13119                         && info.interfaceName.startsWith(AUDIO_HAL_SERVICE_PREFIX)) {
13120                     pids.add(info.pid);
13121                 }
13122             }
13123         } catch (RemoteException | RuntimeException e) {
13124             // ignored, pid hashset does not change
13125         }
13126     }
13127 
getAudioHalPids()13128     private Set<Integer> getAudioHalPids() {
13129         HashSet<Integer> pids = new HashSet<>();
13130         getAudioAidlHalPids(pids);
13131         getAudioHalHidlPids(pids);
13132         return pids;
13133     }
13134 
updateAudioHalPids()13135     private void updateAudioHalPids() {
13136         Set<Integer> pidsSet = getAudioHalPids();
13137         if (pidsSet.isEmpty()) {
13138             Slog.w(TAG, "Could not retrieve audio HAL service pids");
13139             return;
13140         }
13141         int[] pidsArray = pidsSet.stream().mapToInt(Integer::intValue).toArray();
13142         AudioSystem.setAudioHalPids(pidsArray);
13143     }
13144 
13145     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
13146     //======================
13147     // Multi Audio Focus
13148     //======================
setMultiAudioFocusEnabled(boolean enabled)13149     public void setMultiAudioFocusEnabled(boolean enabled) {
13150         super.setMultiAudioFocusEnabled_enforcePermission();
13151 
13152         if (mMediaFocusControl != null) {
13153             boolean mafEnabled = mMediaFocusControl.getMultiAudioFocusEnabled();
13154             if (mafEnabled != enabled) {
13155                 mMediaFocusControl.updateMultiAudioFocus(enabled);
13156                 if (!enabled) {
13157                     mDeviceBroker.postBroadcastBecomingNoisy();
13158                 }
13159             }
13160         }
13161     }
13162 
13163     /**
13164      * @hide
13165      * Sets an additional audio output device delay in milliseconds.
13166      *
13167      * The additional output delay is a request to the output device to
13168      * delay audio presentation (generally with respect to video presentation for better
13169      * synchronization).
13170      * It may not be supported by all output devices,
13171      * and typically increases the audio latency by the amount of additional
13172      * audio delay requested.
13173      *
13174      * If additional audio delay is supported by an audio output device,
13175      * it is expected to be supported for all output streams (and configurations)
13176      * opened on that device.
13177      *
13178      * @param deviceType
13179      * @param address
13180      * @param delayMillis delay in milliseconds desired.  This should be in range of {@code 0}
13181      *     to the value returned by {@link #getMaxAdditionalOutputDeviceDelay()}.
13182      * @return true if successful, false if the device does not support output device delay
13183      *     or the delay is not in range of {@link #getMaxAdditionalOutputDeviceDelay()}.
13184      */
13185     @Override
13186     //@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
setAdditionalOutputDeviceDelay( @onNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis)13187     public boolean setAdditionalOutputDeviceDelay(
13188             @NonNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis) {
13189         Objects.requireNonNull(device, "device must not be null");
13190         enforceModifyAudioRoutingPermission();
13191 
13192         device = retrieveBluetoothAddress(device);
13193 
13194         final String getterKey = "additional_output_device_delay="
13195                 + device.getInternalType() + "," + device.getAddress(); // "getter" key as an id.
13196         final String setterKey = getterKey + "," + delayMillis;     // append the delay for setter
13197         return mRestorableParameters.setParameters(getterKey, setterKey)
13198                 == AudioSystem.AUDIO_STATUS_OK;
13199     }
13200 
13201     /**
13202      * @hide
13203      * Returns the current additional audio output device delay in milliseconds.
13204      *
13205      * @param deviceType
13206      * @param address
13207      * @return the additional output device delay. This is a non-negative number.
13208      *     {@code 0} is returned if unsupported.
13209      */
13210     @Override
13211     @IntRange(from = 0)
getAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)13212     public long getAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) {
13213         Objects.requireNonNull(device, "device must not be null");
13214 
13215         device = retrieveBluetoothAddress(device);
13216 
13217         final String key = "additional_output_device_delay";
13218         final String reply = AudioSystem.getParameters(
13219                 key + "=" + device.getInternalType() + "," + device.getAddress());
13220         long delayMillis;
13221         try {
13222             delayMillis = Long.parseLong(reply.substring(key.length() + 1));
13223         } catch (NullPointerException e) {
13224             delayMillis = 0;
13225         }
13226         return delayMillis;
13227     }
13228 
13229     /**
13230      * @hide
13231      * Returns the maximum additional audio output device delay in milliseconds.
13232      *
13233      * @param deviceType
13234      * @param address
13235      * @return the maximum output device delay in milliseconds that can be set.
13236      *     This is a non-negative number
13237      *     representing the additional audio delay supported for the device.
13238      *     {@code 0} is returned if unsupported.
13239      */
13240     @Override
13241     @IntRange(from = 0)
getMaxAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)13242     public long getMaxAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) {
13243         Objects.requireNonNull(device, "device must not be null");
13244 
13245         device = retrieveBluetoothAddress(device);
13246 
13247         final String key = "max_additional_output_device_delay";
13248         final String reply = AudioSystem.getParameters(
13249                 key + "=" + device.getInternalType() + "," + device.getAddress());
13250         long delayMillis;
13251         try {
13252             delayMillis = Long.parseLong(reply.substring(key.length() + 1));
13253         } catch (NullPointerException e) {
13254             delayMillis = 0;
13255         }
13256         return delayMillis;
13257     }
13258 
13259     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
13260     /** @see AudioManager#addAssistantServicesUids(int []) */
13261     @Override
addAssistantServicesUids(int [] assistantUids)13262     public void addAssistantServicesUids(int [] assistantUids) {
13263         super.addAssistantServicesUids_enforcePermission();
13264 
13265         Objects.requireNonNull(assistantUids);
13266 
13267         synchronized (mSettingsLock) {
13268             addAssistantServiceUidsLocked(assistantUids);
13269         }
13270     }
13271 
13272     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
13273     /** @see AudioManager#removeAssistantServicesUids(int []) */
13274     @Override
removeAssistantServicesUids(int [] assistantUids)13275     public void removeAssistantServicesUids(int [] assistantUids) {
13276         super.removeAssistantServicesUids_enforcePermission();
13277 
13278         Objects.requireNonNull(assistantUids);
13279         synchronized (mSettingsLock) {
13280             removeAssistantServiceUidsLocked(assistantUids);
13281         }
13282     }
13283 
13284     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
13285     /** @see AudioManager#getAssistantServicesUids() */
13286     @Override
getAssistantServicesUids()13287     public int[] getAssistantServicesUids() {
13288         super.getAssistantServicesUids_enforcePermission();
13289 
13290         int [] assistantUids;
13291         synchronized (mSettingsLock) {
13292             assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray();
13293         }
13294         return assistantUids;
13295     }
13296 
13297     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
13298     /** @see AudioManager#setActiveAssistantServiceUids(int []) */
13299     @Override
setActiveAssistantServiceUids(int [] activeAssistantUids)13300     public void setActiveAssistantServiceUids(int [] activeAssistantUids) {
13301         super.setActiveAssistantServiceUids_enforcePermission();
13302 
13303         Objects.requireNonNull(activeAssistantUids);
13304         synchronized (mSettingsLock) {
13305             mActiveAssistantServiceUids = activeAssistantUids;
13306         }
13307         updateActiveAssistantServiceUids();
13308     }
13309 
13310     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
13311     /** @see AudioManager#getActiveAssistantServiceUids() */
13312     @Override
getActiveAssistantServiceUids()13313     public int[] getActiveAssistantServiceUids() {
13314         super.getActiveAssistantServiceUids_enforcePermission();
13315 
13316         int [] activeAssistantUids;
13317         synchronized (mSettingsLock) {
13318             activeAssistantUids = mActiveAssistantServiceUids.clone();
13319         }
13320         return activeAssistantUids;
13321     }
13322 
getDeviceSensorUuid(AudioDeviceAttributes device)13323     UUID getDeviceSensorUuid(AudioDeviceAttributes device) {
13324         return mDeviceBroker.getDeviceSensorUuid(device);
13325     }
13326 
13327     //======================
13328     // misc
13329     //======================
13330     private final HashMap<IBinder, AudioPolicyProxy> mAudioPolicies =
13331             new HashMap<IBinder, AudioPolicyProxy>();
13332     @GuardedBy("mAudioPolicies")
13333     private int mAudioPolicyCounter = 0;
13334 
13335     //======================
13336     // Helper functions for full and fixed volume device
13337     //======================
isFixedVolumeDevice(int deviceType)13338     private boolean isFixedVolumeDevice(int deviceType) {
13339         if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX
13340                 && mRecordMonitor.isLegacyRemoteSubmixActive()) {
13341             return false;
13342         }
13343         return mFixedVolumeDevices.contains(deviceType);
13344     }
13345 
isFullVolumeDevice(int deviceType)13346     private boolean isFullVolumeDevice(int deviceType) {
13347         if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX
13348                 && mRecordMonitor.isLegacyRemoteSubmixActive()) {
13349             return false;
13350         }
13351         return mFullVolumeDevices.contains(deviceType);
13352     }
13353 
13354     /**
13355      * Returns whether the input device uses absolute volume behavior, including its variants.
13356      * For included volume behaviors, see {@link AudioManager.AbsoluteDeviceVolumeBehavior}.
13357      *
13358      * This is distinct from Bluetooth A2DP absolute volume behavior
13359      * ({@link #isA2dpAbsoluteVolumeDevice}).
13360      */
isAbsoluteVolumeDevice(int deviceType)13361     private boolean isAbsoluteVolumeDevice(int deviceType) {
13362         return mAbsoluteVolumeDeviceInfoMap.containsKey(deviceType);
13363     }
13364 
13365     /**
13366      * Returns whether the input device is a Bluetooth A2dp device that uses absolute volume
13367      * behavior. This is distinct from the general implementation of absolute volume behavior
13368      * ({@link #isAbsoluteVolumeDevice}).
13369      */
isA2dpAbsoluteVolumeDevice(int deviceType)13370     private boolean isA2dpAbsoluteVolumeDevice(int deviceType) {
13371         return mAvrcpAbsVolSupported && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(deviceType);
13372     }
13373 
13374     //====================
13375     // Helper functions for {set,get}DeviceVolumeBehavior
13376     //====================
getSettingsNameForDeviceVolumeBehavior(int deviceType)13377     private static String getSettingsNameForDeviceVolumeBehavior(int deviceType) {
13378         return "AudioService_DeviceVolumeBehavior_" + AudioSystem.getOutputDeviceName(deviceType);
13379     }
13380 
persistDeviceVolumeBehavior(int deviceType, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior)13381     private void persistDeviceVolumeBehavior(int deviceType,
13382             @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior) {
13383         if (DEBUG_VOL) {
13384             Log.d(TAG, "Persisting Volume Behavior for DeviceType: " + deviceType);
13385         }
13386         final long callingIdentity = Binder.clearCallingIdentity();
13387         try {
13388             mSettings.putSystemIntForUser(mContentResolver,
13389                     getSettingsNameForDeviceVolumeBehavior(deviceType),
13390                     deviceVolumeBehavior,
13391                     UserHandle.USER_CURRENT);
13392         } finally {
13393             Binder.restoreCallingIdentity(callingIdentity);
13394         }
13395     }
13396 
13397     @AudioManager.DeviceVolumeBehaviorState
retrieveStoredDeviceVolumeBehavior(int deviceType)13398     private int retrieveStoredDeviceVolumeBehavior(int deviceType) {
13399         return mSettings.getSystemIntForUser(mContentResolver,
13400                 getSettingsNameForDeviceVolumeBehavior(deviceType),
13401                 AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET,
13402                 UserHandle.USER_CURRENT);
13403     }
13404 
restoreDeviceVolumeBehavior()13405     private void restoreDeviceVolumeBehavior() {
13406         for (int deviceType : AudioSystem.DEVICE_OUT_ALL_SET) {
13407             if (DEBUG_VOL) {
13408                 Log.d(TAG, "Retrieving Volume Behavior for DeviceType: " + deviceType);
13409             }
13410             int deviceVolumeBehavior = retrieveStoredDeviceVolumeBehavior(deviceType);
13411             if (deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET) {
13412                 if (DEBUG_VOL) {
13413                     Log.d(TAG, "Skipping Setting Volume Behavior for DeviceType: " + deviceType);
13414                 }
13415                 continue;
13416             }
13417 
13418             setDeviceVolumeBehaviorInternal(new AudioDeviceAttributes(deviceType, ""),
13419                     deviceVolumeBehavior, "AudioService.restoreDeviceVolumeBehavior()");
13420         }
13421     }
13422 
13423     /**
13424      * @param audioSystemDeviceOut one of AudioSystem.DEVICE_OUT_*
13425      * @return whether {@code audioSystemDeviceOut} has previously been set to a specific volume
13426      * behavior
13427      */
hasDeviceVolumeBehavior( int audioSystemDeviceOut)13428     private boolean hasDeviceVolumeBehavior(
13429             int audioSystemDeviceOut) {
13430         return retrieveStoredDeviceVolumeBehavior(audioSystemDeviceOut)
13431                 != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET;
13432     }
13433 
addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut)13434     private boolean addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut) {
13435         if (DEBUG_VOL) {
13436             Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
13437                     + " to mFixedVolumeDevices");
13438         }
13439         return mFixedVolumeDevices.add(audioSystemDeviceOut);
13440     }
13441 
removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut)13442     private boolean removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut) {
13443         if (DEBUG_VOL) {
13444             Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
13445                     + " from mFixedVolumeDevices");
13446         }
13447         return mFixedVolumeDevices.remove(audioSystemDeviceOut);
13448     }
13449 
addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut)13450     private boolean addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut) {
13451         if (DEBUG_VOL) {
13452             Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
13453                     + " to mFullVolumeDevices");
13454         }
13455         return mFullVolumeDevices.add(audioSystemDeviceOut);
13456     }
13457 
removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut)13458     private boolean removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut) {
13459         if (DEBUG_VOL) {
13460             Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
13461                     + " from mFullVolumeDevices");
13462         }
13463         return mFullVolumeDevices.remove(audioSystemDeviceOut);
13464     }
13465 
addAudioSystemDeviceOutToAbsVolumeDevices(int audioSystemDeviceOut, AbsoluteVolumeDeviceInfo info)13466     private void addAudioSystemDeviceOutToAbsVolumeDevices(int audioSystemDeviceOut,
13467             AbsoluteVolumeDeviceInfo info) {
13468         if (DEBUG_VOL) {
13469             Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
13470                     + " to mAbsoluteVolumeDeviceInfoMap with behavior "
13471                     + AudioDeviceVolumeManager.volumeBehaviorName(info.mDeviceVolumeBehavior)
13472             );
13473         }
13474         mAbsoluteVolumeDeviceInfoMap.put(audioSystemDeviceOut, info);
13475     }
13476 
removeAudioSystemDeviceOutFromAbsVolumeDevices( int audioSystemDeviceOut)13477     private AbsoluteVolumeDeviceInfo removeAudioSystemDeviceOutFromAbsVolumeDevices(
13478             int audioSystemDeviceOut) {
13479         if (DEBUG_VOL) {
13480             Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
13481                     + " from mAbsoluteVolumeDeviceInfoMap");
13482         }
13483         return mAbsoluteVolumeDeviceInfoMap.remove(audioSystemDeviceOut);
13484     }
13485 
13486     //====================
13487     // Helper functions for app ops
13488     //====================
13489     /**
13490      * Validates, and notes an app op for a given uid and package name.
13491      * Validation comes from exception catching: a security exception indicates the package
13492      * doesn't exist, an IAE indicates the uid and package don't match. The code only checks
13493      * if exception was thrown for robustness to code changes in op validation
13494      * @param op the app op to check
13495      * @param uid the uid of the caller
13496      * @param packageName the package to check
13497      * @return true if the origin of the call is valid (no uid / package mismatch) and the caller
13498      *      is allowed to perform the operation
13499      */
checkNoteAppOp(int op, int uid, String packageName, String attributionTag)13500     private boolean checkNoteAppOp(int op, int uid, String packageName, String attributionTag) {
13501         try {
13502             if (mAppOps.noteOp(op, uid, packageName, attributionTag, null)
13503                     != AppOpsManager.MODE_ALLOWED) {
13504                 return false;
13505             }
13506         } catch (Exception e) {
13507             Log.e(TAG, "Error noting op:" + op + " on uid:" + uid + " for package:"
13508                     + packageName, e);
13509             return false;
13510         }
13511         return true;
13512     }
13513 }
13514