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.BLUETOOTH_PRIVILEGED;
20 import static android.Manifest.permission.BLUETOOTH_STACK;
21 import static android.Manifest.permission.CALL_AUDIO_INTERCEPTION;
22 import static android.Manifest.permission.CAPTURE_AUDIO_HOTWORD;
23 import static android.Manifest.permission.CAPTURE_AUDIO_OUTPUT;
24 import static android.Manifest.permission.CAPTURE_MEDIA_OUTPUT;
25 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
26 import static android.Manifest.permission.MODIFY_AUDIO_ROUTING;
27 import static android.Manifest.permission.MODIFY_AUDIO_SETTINGS;
28 import static android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED;
29 import static android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS;
30 import static android.Manifest.permission.MODIFY_PHONE_STATE;
31 import static android.Manifest.permission.QUERY_AUDIO_STATE;
32 import static android.Manifest.permission.WRITE_SETTINGS;
33 import static android.app.BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT;
34 import static android.content.Intent.ACTION_PACKAGE_ADDED;
35 import static android.content.Intent.ACTION_PACKAGE_REMOVED;
36 import static android.content.Intent.EXTRA_ARCHIVAL;
37 import static android.content.Intent.EXTRA_REPLACING;
38 import static android.media.AudioDeviceInfo.TYPE_BLE_HEADSET;
39 import static android.media.AudioDeviceInfo.TYPE_BLE_SPEAKER;
40 import static android.media.AudioDeviceInfo.TYPE_BLUETOOTH_A2DP;
41 import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_HEADPHONES;
42 import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_UNKNOWN;
43 import static android.media.AudioManager.DEVICE_OUT_BLE_HEADSET;
44 import static android.media.AudioManager.DEVICE_OUT_BLE_SPEAKER;
45 import static android.media.AudioManager.DEVICE_OUT_BLUETOOTH_A2DP;
46 import static android.media.AudioManager.RINGER_MODE_NORMAL;
47 import static android.media.AudioManager.RINGER_MODE_SILENT;
48 import static android.media.AudioManager.RINGER_MODE_VIBRATE;
49 import static android.media.AudioManager.STREAM_SYSTEM;
50 import static android.media.audio.Flags.autoPublicVolumeApiHardening;
51 import static android.media.audio.Flags.automaticBtDeviceType;
52 import static android.media.audio.Flags.featureSpatialAudioHeadtrackingLowLatency;
53 import static android.media.audio.Flags.focusFreezeTestApi;
54 import static android.media.audio.Flags.roForegroundAudioControl;
55 import static android.media.audio.Flags.scoManagedByAudio;
56 import static android.media.audiopolicy.Flags.enableFadeManagerConfiguration;
57 import static android.os.Process.FIRST_APPLICATION_UID;
58 import static android.os.Process.INVALID_UID;
59 import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE;
60 import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
61 import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE;
62 
63 import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
64 import static com.android.media.audio.Flags.absVolumeIndexFix;
65 import static com.android.media.audio.Flags.alarmMinVolumeZero;
66 import static com.android.media.audio.Flags.audioserverPermissions;
67 import static com.android.media.audio.Flags.disablePrescaleAbsoluteVolume;
68 import static com.android.media.audio.Flags.ringerModeAffectsAlarm;
69 import static com.android.media.audio.Flags.setStreamVolumeOrder;
70 import static com.android.media.audio.Flags.vgsVssSyncMuteOrder;
71 import static com.android.server.audio.SoundDoseHelper.ACTION_CHECK_MUSIC_ACTIVE;
72 import static com.android.server.utils.EventLogger.Event.ALOGE;
73 import static com.android.server.utils.EventLogger.Event.ALOGI;
74 import static com.android.server.utils.EventLogger.Event.ALOGW;
75 
76 import android.Manifest;
77 import android.annotation.EnforcePermission;
78 import android.annotation.IntDef;
79 import android.annotation.IntRange;
80 import android.annotation.NonNull;
81 import android.annotation.Nullable;
82 import android.annotation.RequiresPermission;
83 import android.annotation.SuppressLint;
84 import android.annotation.UserIdInt;
85 import android.app.ActivityManager;
86 import android.app.ActivityManagerInternal;
87 import android.app.AppGlobals;
88 import android.app.AppOpsManager;
89 import android.app.BroadcastOptions;
90 import android.app.IUidObserver;
91 import android.app.NotificationManager;
92 import android.app.UidObserver;
93 import android.app.role.OnRoleHoldersChangedListener;
94 import android.app.role.RoleManager;
95 import android.bluetooth.BluetoothDevice;
96 import android.bluetooth.BluetoothHeadset;
97 import android.bluetooth.BluetoothProfile;
98 import android.content.AttributionSource;
99 import android.content.BroadcastReceiver;
100 import android.content.ComponentName;
101 import android.content.ContentResolver;
102 import android.content.Context;
103 import android.content.Intent;
104 import android.content.IntentFilter;
105 import android.content.pm.ApplicationInfo;
106 import android.content.pm.PackageInfo;
107 import android.content.pm.PackageManager;
108 import android.content.pm.UserInfo;
109 import android.content.res.Configuration;
110 import android.content.res.Resources;
111 import android.database.ContentObserver;
112 import android.hardware.SensorPrivacyManager;
113 import android.hardware.SensorPrivacyManagerInternal;
114 import android.hardware.display.DisplayManager;
115 import android.hardware.display.DisplayManager.DisplayListener;
116 import android.hardware.hdmi.HdmiAudioSystemClient;
117 import android.hardware.hdmi.HdmiClient;
118 import android.hardware.hdmi.HdmiControlManager;
119 import android.hardware.hdmi.HdmiPlaybackClient;
120 import android.hardware.hdmi.HdmiTvClient;
121 import android.hardware.input.InputManager;
122 import android.hardware.usb.UsbManager;
123 import android.hidl.manager.V1_0.IServiceManager;
124 import android.media.AudioAttributes;
125 import android.media.AudioAttributes.AttributeSystemUsage;
126 import android.media.AudioDescriptor;
127 import android.media.AudioDeviceAttributes;
128 import android.media.AudioDeviceInfo;
129 import android.media.AudioDeviceVolumeManager;
130 import android.media.AudioFocusInfo;
131 import android.media.AudioFocusRequest;
132 import android.media.AudioFormat;
133 import android.media.AudioHalVersionInfo;
134 import android.media.AudioManager;
135 import android.media.AudioManager.AudioDeviceCategory;
136 import android.media.AudioManagerInternal;
137 import android.media.AudioMixerAttributes;
138 import android.media.AudioPlaybackConfiguration;
139 import android.media.AudioProfile;
140 import android.media.AudioRecordingConfiguration;
141 import android.media.AudioRoutesInfo;
142 import android.media.AudioSystem;
143 import android.media.BluetoothProfileConnectionInfo;
144 import android.media.FadeManagerConfiguration;
145 import android.media.IAudioDeviceVolumeDispatcher;
146 import android.media.IAudioFocusDispatcher;
147 import android.media.IAudioModeDispatcher;
148 import android.media.IAudioRoutesObserver;
149 import android.media.IAudioServerStateDispatcher;
150 import android.media.IAudioService;
151 import android.media.ICapturePresetDevicesRoleDispatcher;
152 import android.media.ICommunicationDeviceDispatcher;
153 import android.media.IDeviceVolumeBehaviorDispatcher;
154 import android.media.IDevicesForAttributesCallback;
155 import android.media.ILoudnessCodecUpdatesDispatcher;
156 import android.media.IMuteAwaitConnectionCallback;
157 import android.media.IPlaybackConfigDispatcher;
158 import android.media.IPreferredMixerAttributesDispatcher;
159 import android.media.IRecordingConfigDispatcher;
160 import android.media.IRingtonePlayer;
161 import android.media.ISpatializerCallback;
162 import android.media.ISpatializerHeadToSoundStagePoseCallback;
163 import android.media.ISpatializerHeadTrackerAvailableCallback;
164 import android.media.ISpatializerHeadTrackingModeCallback;
165 import android.media.ISpatializerOutputCallback;
166 import android.media.IStrategyNonDefaultDevicesDispatcher;
167 import android.media.IStrategyPreferredDevicesDispatcher;
168 import android.media.IStreamAliasingDispatcher;
169 import android.media.IVolumeController;
170 import android.media.LoudnessCodecController;
171 import android.media.LoudnessCodecInfo;
172 import android.media.MediaCodec;
173 import android.media.MediaMetrics;
174 import android.media.MediaRecorder.AudioSource;
175 import android.media.PlayerBase;
176 import android.media.Spatializer;
177 import android.media.Utils;
178 import android.media.VolumeInfo;
179 import android.media.VolumePolicy;
180 import android.media.audiofx.AudioEffect;
181 import android.media.audiopolicy.AudioMix;
182 import android.media.audiopolicy.AudioMixingRule;
183 import android.media.audiopolicy.AudioPolicy;
184 import android.media.audiopolicy.AudioPolicyConfig;
185 import android.media.audiopolicy.AudioProductStrategy;
186 import android.media.audiopolicy.AudioVolumeGroup;
187 import android.media.audiopolicy.IAudioPolicyCallback;
188 import android.media.permission.ClearCallingIdentityContext;
189 import android.media.permission.SafeCloseable;
190 import android.media.projection.IMediaProjection;
191 import android.media.projection.IMediaProjectionCallback;
192 import android.media.projection.IMediaProjectionManager;
193 import android.media.session.MediaSessionManager;
194 import android.net.Uri;
195 import android.os.Binder;
196 import android.os.Build;
197 import android.os.Bundle;
198 import android.os.Handler;
199 import android.os.HandlerThread;
200 import android.os.HwBinder;
201 import android.os.IBinder;
202 import android.os.Looper;
203 import android.os.Message;
204 import android.os.PermissionEnforcer;
205 import android.os.PersistableBundle;
206 import android.os.PowerManager;
207 import android.os.Process;
208 import android.os.RemoteCallbackList;
209 import android.os.RemoteException;
210 import android.os.ResultReceiver;
211 import android.os.ServiceDebugInfo;
212 import android.os.ServiceManager;
213 import android.os.ShellCallback;
214 import android.os.SystemClock;
215 import android.os.SystemProperties;
216 import android.os.UserHandle;
217 import android.os.UserManager;
218 import android.os.VibrationAttributes;
219 import android.os.VibrationEffect;
220 import android.os.Vibrator;
221 import android.os.VibratorManager;
222 import android.permission.PermissionManager;
223 import android.provider.Settings;
224 import android.provider.Settings.System;
225 import android.service.notification.ZenModeConfig;
226 import android.telecom.TelecomManager;
227 import android.telephony.SubscriptionManager;
228 import android.text.TextUtils;
229 import android.util.AndroidRuntimeException;
230 import android.util.ArrayMap;
231 import android.util.ArraySet;
232 import android.util.IntArray;
233 import android.util.Log;
234 import android.util.PrintWriterPrinter;
235 import android.util.Slog;
236 import android.util.SparseArray;
237 import android.util.SparseIntArray;
238 import android.view.Display;
239 import android.view.KeyEvent;
240 import android.view.accessibility.AccessibilityManager;
241 import android.widget.Toast;
242 
243 import com.android.internal.annotations.GuardedBy;
244 import com.android.internal.annotations.VisibleForTesting;
245 import com.android.internal.os.SomeArgs;
246 import com.android.internal.util.DumpUtils;
247 import com.android.internal.util.Preconditions;
248 import com.android.server.EventLogTags;
249 import com.android.server.LocalManagerRegistry;
250 import com.android.server.LocalServices;
251 import com.android.server.SystemService;
252 import com.android.server.audio.AudioServiceEvents.DeviceVolumeEvent;
253 import com.android.server.audio.AudioServiceEvents.PhoneStateEvent;
254 import com.android.server.audio.AudioServiceEvents.VolChangedBroadcastEvent;
255 import com.android.server.audio.AudioServiceEvents.VolumeEvent;
256 import com.android.server.pm.PackageManagerLocal;
257 import com.android.server.pm.UserManagerInternal;
258 import com.android.server.pm.UserManagerInternal.UserRestrictionsListener;
259 import com.android.server.pm.UserManagerService;
260 import com.android.server.pm.permission.PermissionManagerServiceInternal;
261 import com.android.server.pm.pkg.PackageState;
262 import com.android.server.utils.EventLogger;
263 import com.android.server.wm.ActivityTaskManagerInternal;
264 
265 import java.io.FileDescriptor;
266 import java.io.PrintWriter;
267 import java.lang.annotation.Retention;
268 import java.lang.annotation.RetentionPolicy;
269 import java.text.SimpleDateFormat;
270 import java.util.ArrayList;
271 import java.util.Arrays;
272 import java.util.Collection;
273 import java.util.Collections;
274 import java.util.Date;
275 import java.util.HashMap;
276 import java.util.HashSet;
277 import java.util.Iterator;
278 import java.util.LinkedHashMap;
279 import java.util.List;
280 import java.util.Map;
281 import java.util.NoSuchElementException;
282 import java.util.Objects;
283 import java.util.Set;
284 import java.util.TreeSet;
285 import java.util.concurrent.Executor;
286 import java.util.concurrent.Executors;
287 import java.util.concurrent.atomic.AtomicBoolean;
288 import java.util.concurrent.atomic.AtomicInteger;
289 import java.util.concurrent.atomic.AtomicLong;
290 import java.util.concurrent.atomic.AtomicReference;
291 import java.util.function.BooleanSupplier;
292 import java.util.stream.Collectors;
293 
294 /**
295  * The implementation of the audio service for volume, audio focus, device management...
296  * <p>
297  * This implementation focuses on delivering a responsive UI. Most methods are
298  * asynchronous to external calls. For example, the task of setting a volume
299  * will update our internal state, but in a separate thread will set the system
300  * volume and later persist to the database. Similarly, setting the ringer mode
301  * will update the state and broadcast a change and in a separate thread later
302  * persist the ringer mode.
303  *
304  * @hide
305  */
306 public class AudioService extends IAudioService.Stub
307         implements AccessibilityManager.TouchExplorationStateChangeListener,
308             AccessibilityManager.AccessibilityServicesStateChangeListener,
309             AudioSystemAdapter.OnRoutingUpdatedListener,
310             AudioSystemAdapter.OnVolRangeInitRequestListener {
311 
312     private static final String TAG = "AS.AudioService";
313 
314     private final AudioSystemAdapter mAudioSystem;
315     private final SystemServerAdapter mSystemServer;
316     private final SettingsAdapter mSettings;
317     private final AudioPolicyFacade mAudioPolicy;
318 
319     private final AudioServerPermissionProvider mPermissionProvider;
320 
321     private final MusicFxHelper mMusicFxHelper;
322 
323     /** Debug audio mode */
324     protected static final boolean DEBUG_MODE = false;
325 
326     /** Debug audio policy feature */
327     protected static final boolean DEBUG_AP = false;
328 
329     /** Debug volumes */
330     protected static final boolean DEBUG_VOL = false;
331 
332     /** debug calls to devices APIs */
333     protected static final boolean DEBUG_DEVICES = false;
334 
335     /** Debug communication route */
336     protected static final boolean DEBUG_COMM_RTE = false;
337 
338     /** Debug log sound fx (touchsounds...) in dumpsys */
339     protected static final boolean DEBUG_LOG_SOUND_FX = false;
340 
341     /** How long to delay before persisting a change in volume/ringer mode. */
342     private static final int PERSIST_DELAY = 500;
343 
344     /** How long to delay after a volume down event before unmuting a stream */
345     private static final int UNMUTE_STREAM_DELAY = 350;
346 
347     /**
348      * Delay before disconnecting a device that would cause BECOMING_NOISY intent to be sent,
349      * to give a chance to applications to pause.
350      */
351     @VisibleForTesting
352     public static final int BECOMING_NOISY_DELAY_MS = 1000;
353 
354     /**
355      * Only used in the result from {@link #checkForRingerModeChange(int, int, int)}
356      */
357     private static final int FLAG_ADJUST_VOLUME = 1;
358 
359     final Context mContext;
360     private final ContentResolver mContentResolver;
361     private final AppOpsManager mAppOps;
362 
363     /** do not use directly, use getMediaSessionManager() which handles lazy initialization */
364     @Nullable private volatile MediaSessionManager mMediaSessionManager;
365 
366     // the platform type affects volume and silent mode behavior
367     private final int mPlatformType;
368 
369     // indicates whether the system maps all streams to a single stream.
370     private final boolean mIsSingleVolume;
371 
372     /**
373      * indicates whether STREAM_NOTIFICATION is aliased to STREAM_RING
374      *     not final due to test method, see {@link #setNotifAliasRingForTest(boolean)}.
375      */
376     private boolean mNotifAliasRing = false;
377 
378     /**
379      * Test method to temporarily override whether STREAM_NOTIFICATION is aliased to STREAM_RING,
380      * volumes will be updated in case of a change.
381      * @param alias if true, STREAM_NOTIFICATION is aliased to STREAM_RING
382      */
383     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setNotifAliasRingForTest(boolean alias)384     public void setNotifAliasRingForTest(boolean alias) {
385         super.setNotifAliasRingForTest_enforcePermission();
386         boolean update = (mNotifAliasRing != alias);
387         mNotifAliasRing = alias;
388         if (update) {
389             updateStreamVolumeAlias(true, "AudioServiceTest");
390         }
391     }
392 
isPlatformVoice()393     /*package*/ boolean isPlatformVoice() {
394         return mPlatformType == AudioSystem.PLATFORM_VOICE;
395     }
396 
isPlatformTelevision()397     /*package*/ boolean isPlatformTelevision() {
398         return mPlatformType == AudioSystem.PLATFORM_TELEVISION;
399     }
400 
isPlatformAutomotive()401     /*package*/ boolean isPlatformAutomotive() {
402         return mPlatformType == AudioSystem.PLATFORM_AUTOMOTIVE;
403     }
404 
405     /** The controller for the volume UI. */
406     private final VolumeController mVolumeController = new VolumeController();
407 
408     // sendMsg() flags
409     /** If the msg is already queued, replace it with this one. */
410     private static final int SENDMSG_REPLACE = 0;
411     /** If the msg is already queued, ignore this one and leave the old. */
412     private static final int SENDMSG_NOOP = 1;
413     /** If the msg is already queued, queue this one and leave the old. */
414     private static final int SENDMSG_QUEUE = 2;
415 
416     // AudioHandler messages
417     /*package*/ static final int MSG_SET_DEVICE_VOLUME = 0;
418     private static final int MSG_PERSIST_VOLUME = 1;
419     private static final int MSG_PERSIST_VOLUME_GROUP = 2;
420     private static final int MSG_PERSIST_RINGER_MODE = 3;
421     private static final int MSG_AUDIO_SERVER_DIED = 4;
422     private static final int MSG_PLAY_SOUND_EFFECT = 5;
423     private static final int MSG_LOAD_SOUND_EFFECTS = 7;
424     private static final int MSG_SET_FORCE_USE = 8;
425     private static final int MSG_SET_ALL_VOLUMES = 10;
426     private static final int MSG_UNLOAD_SOUND_EFFECTS = 15;
427     private static final int MSG_SYSTEM_READY = 16;
428     private static final int MSG_UNMUTE_STREAM_ON_SINGLE_VOL_DEVICE = 18;
429     private static final int MSG_DYN_POLICY_MIX_STATE_UPDATE = 19;
430     private static final int MSG_INDICATE_SYSTEM_READY = 20;
431     private static final int MSG_ACCESSORY_PLUG_MEDIA_UNMUTE = 21;
432     private static final int MSG_NOTIFY_VOL_EVENT = 22;
433     private static final int MSG_DISPATCH_AUDIO_SERVER_STATE = 23;
434     private static final int MSG_ENABLE_SURROUND_FORMATS = 24;
435     private static final int MSG_UPDATE_RINGER_MODE = 25;
436     private static final int MSG_SET_DEVICE_STREAM_VOLUME = 26;
437     private static final int MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS = 27;
438     private static final int MSG_HDMI_VOLUME_CHECK = 28;
439     private static final int MSG_PLAYBACK_CONFIG_CHANGE = 29;
440     private static final int MSG_BROADCAST_MICROPHONE_MUTE = 30;
441     private static final int MSG_CHECK_MODE_FOR_UID = 31;
442     private static final int MSG_STREAM_DEVICES_CHANGED = 32;
443     private static final int MSG_UPDATE_VOLUME_STATES_FOR_DEVICE = 33;
444     private static final int MSG_REINIT_VOLUMES = 34;
445     private static final int MSG_UPDATE_A11Y_SERVICE_UIDS = 35;
446     private static final int MSG_UPDATE_AUDIO_MODE = 36;
447     private static final int MSG_RECORDING_CONFIG_CHANGE = 37;
448     private static final int MSG_BT_DEV_CHANGED = 38;
449 
450     private static final int MSG_DISPATCH_AUDIO_MODE = 40;
451     private static final int MSG_ROUTING_UPDATED = 41;
452     private static final int MSG_INIT_HEADTRACKING_SENSORS = 42;
453     private static final int MSG_ADD_ASSISTANT_SERVICE_UID = 44;
454     private static final int MSG_REMOVE_ASSISTANT_SERVICE_UID = 45;
455     private static final int MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID = 46;
456     private static final int MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR = 47;
457     private static final int MSG_ROTATION_UPDATE = 48;
458     private static final int MSG_FOLD_UPDATE = 49;
459     private static final int MSG_RESET_SPATIALIZER = 50;
460     private static final int MSG_NO_LOG_FOR_PLAYER_I = 51;
461     private static final int MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES = 52;
462     private static final int MSG_CONFIGURATION_CHANGED = 54;
463     private static final int MSG_BROADCAST_MASTER_MUTE = 55;
464 
465     /**
466      * Messages handled by the {@link SoundDoseHelper}, do not exceed
467      * {@link MUSICFX_HELPER_MSG_START}.
468      */
469     /*package*/ static final int SAFE_MEDIA_VOLUME_MSG_START = 1000;
470 
471     /** Messages handled by the {@link MusicFxHelper}. */
472     /*package*/ static final int MUSICFX_HELPER_MSG_START = 1100;
473 
474     // start of messages handled under wakelock
475     //   these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
476     //   and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
477     private static final int MSG_DISABLE_AUDIO_FOR_UID = 100;
478     private static final int MSG_INIT_STREAMS_VOLUMES = 101;
479     private static final int MSG_INIT_SPATIALIZER = 102;
480     private static final int MSG_INIT_ADI_DEVICE_STATES = 103;
481 
482     // end of messages handled under wakelock
483 
484     // retry delay in case of failure to indicate system ready to AudioFlinger
485     private static final int INDICATE_SYSTEM_READY_RETRY_DELAY_MS = 1000;
486 
487     // List of empty UIDs used to reset the active assistant list
488     private static final int[] NO_ACTIVE_ASSISTANT_SERVICE_UIDS = new int[0];
489 
490     // check playback or record activity every 6 seconds for UIDs owning mode IN_COMMUNICATION
491     private static final int CHECK_MODE_FOR_UID_PERIOD_MS = 6000;
492 
493     /** @see AudioSystemThread */
494     private AudioSystemThread mAudioSystemThread;
495     /** @see AudioHandler */
496     private AudioHandler mAudioHandler;
497     /** @see VolumeStreamState */
498     private VolumeStreamState[] mStreamStates;
499 
getVssVolumeForDevice(int stream, int device)500     /*package*/ int getVssVolumeForDevice(int stream, int device) {
501         return mStreamStates[stream].getIndex(device);
502     }
503 
getVssVolumeForStream(int stream)504     /*package*/ VolumeStreamState getVssVolumeForStream(int stream) {
505         return mStreamStates[stream];
506     }
507 
getMaxVssVolumeForStream(int stream)508     /*package*/ int getMaxVssVolumeForStream(int stream) {
509         return mStreamStates[stream].getMaxIndex();
510     }
511 
512     private SettingsObserver mSettingsObserver;
513 
514     private AtomicInteger mMode = new AtomicInteger(AudioSystem.MODE_NORMAL);
515 
516     // protects mRingerMode
517     private final Object mSettingsLock = new Object();
518 
519    /** Maximum volume index values for audio streams */
520     protected static int[] MAX_STREAM_VOLUME = new int[] {
521         5,  // STREAM_VOICE_CALL
522         7,  // STREAM_SYSTEM
523         7,  // STREAM_RING            // configured by config_audio_ring_vol_steps
524         15, // STREAM_MUSIC
525         7,  // STREAM_ALARM
526         7,  // STREAM_NOTIFICATION    // configured by config_audio_notif_vol_steps
527         15, // STREAM_BLUETOOTH_SCO
528         7,  // STREAM_SYSTEM_ENFORCED
529         15, // STREAM_DTMF
530         15, // STREAM_TTS
531         15, // STREAM_ACCESSIBILITY
532         15  // STREAM_ASSISTANT
533     };
534 
535     /** Minimum volume index values for audio streams */
536     protected static int[] MIN_STREAM_VOLUME = new int[] {
537         1,  // STREAM_VOICE_CALL
538         0,  // STREAM_SYSTEM
539         0,  // STREAM_RING
540         0,  // STREAM_MUSIC
541         1,  // STREAM_ALARM
542         0,  // STREAM_NOTIFICATION
543         0,  // STREAM_BLUETOOTH_SCO
544         0,  // STREAM_SYSTEM_ENFORCED
545         0,  // STREAM_DTMF
546         0,  // STREAM_TTS
547         1,  // STREAM_ACCESSIBILITY
548         0   // STREAM_ASSISTANT
549     };
550 
551     /* mStreamVolumeAlias[] indicates for each stream if it uses the volume settings
552      * of another stream: This avoids multiplying the volume settings for hidden
553      * stream types that follow other stream behavior for volume settings
554      * NOTE: do not create loops in aliases!
555      * Some streams alias to different streams according to device category (phone or tablet) or
556      * use case (in call vs off call...). See updateStreamVolumeAlias() for more details.
557      *  mStreamVolumeAlias contains STREAM_VOLUME_ALIAS_VOICE aliases for a voice capable device
558      *  (phone), STREAM_VOLUME_ALIAS_TELEVISION for a television or set-top box and
559      *  STREAM_VOLUME_ALIAS_DEFAULT for other devices (e.g. tablets).*/
560     private final int[] STREAM_VOLUME_ALIAS_VOICE = new int[] {
561         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
562         AudioSystem.STREAM_RING,            // STREAM_SYSTEM
563         AudioSystem.STREAM_RING,            // STREAM_RING
564         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
565         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
566         AudioSystem.STREAM_RING,            // STREAM_NOTIFICATION
567         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
568         AudioSystem.STREAM_RING,            // STREAM_SYSTEM_ENFORCED
569         AudioSystem.STREAM_RING,            // STREAM_DTMF
570         AudioSystem.STREAM_MUSIC,           // STREAM_TTS
571         AudioSystem.STREAM_MUSIC,           // STREAM_ACCESSIBILITY
572         AudioSystem.STREAM_MUSIC            // STREAM_ASSISTANT
573     };
574     private final int[] STREAM_VOLUME_ALIAS_TELEVISION = new int[] {
575         AudioSystem.STREAM_MUSIC,       // STREAM_VOICE_CALL
576         AudioSystem.STREAM_MUSIC,       // STREAM_SYSTEM
577         AudioSystem.STREAM_MUSIC,       // STREAM_RING
578         AudioSystem.STREAM_MUSIC,       // STREAM_MUSIC
579         AudioSystem.STREAM_MUSIC,       // STREAM_ALARM
580         AudioSystem.STREAM_MUSIC,       // STREAM_NOTIFICATION
581         AudioSystem.STREAM_BLUETOOTH_SCO,       // STREAM_BLUETOOTH_SCO
582         AudioSystem.STREAM_MUSIC,       // STREAM_SYSTEM_ENFORCED
583         AudioSystem.STREAM_MUSIC,       // STREAM_DTMF
584         AudioSystem.STREAM_MUSIC,       // STREAM_TTS
585         AudioSystem.STREAM_MUSIC,       // STREAM_ACCESSIBILITY
586         AudioSystem.STREAM_MUSIC        // STREAM_ASSISTANT
587     };
588     /**
589      * Using Volume groups configuration allows to control volume per attributes
590      * and group definition may differ from stream aliases.
591      * So, do not alias any stream on one another when using volume groups.
592      * TODO(b/181140246): volume group definition hosting alias definition.
593      */
594     private final int[] STREAM_VOLUME_ALIAS_NONE = new int[] {
595         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
596         AudioSystem.STREAM_SYSTEM,          // STREAM_SYSTEM
597         AudioSystem.STREAM_RING,            // STREAM_RING
598         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
599         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
600         AudioSystem.STREAM_NOTIFICATION,    // STREAM_NOTIFICATION
601         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
602         AudioSystem.STREAM_SYSTEM_ENFORCED, // STREAM_SYSTEM_ENFORCED
603         AudioSystem.STREAM_DTMF,            // STREAM_DTMF
604         AudioSystem.STREAM_TTS,             // STREAM_TTS
605         AudioSystem.STREAM_ACCESSIBILITY,   // STREAM_ACCESSIBILITY
606         AudioSystem.STREAM_ASSISTANT        // STREAM_ASSISTANT
607     };
608     private final int[] STREAM_VOLUME_ALIAS_DEFAULT = new int[] {
609         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
610         AudioSystem.STREAM_RING,            // STREAM_SYSTEM
611         AudioSystem.STREAM_RING,            // STREAM_RING
612         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
613         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
614         AudioSystem.STREAM_RING,            // STREAM_NOTIFICATION
615         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
616         AudioSystem.STREAM_RING,            // STREAM_SYSTEM_ENFORCED
617         AudioSystem.STREAM_RING,            // STREAM_DTMF
618         AudioSystem.STREAM_MUSIC,           // STREAM_TTS
619         AudioSystem.STREAM_MUSIC,           // STREAM_ACCESSIBILITY
620         AudioSystem.STREAM_MUSIC            // STREAM_ASSISTANT
621     };
622     protected static int[] mStreamVolumeAlias;
623     private static final int UNSET_INDEX = -1;
624 
625     /**
626      * Map AudioSystem.STREAM_* constants to app ops.  This should be used
627      * after mapping through mStreamVolumeAlias.
628      */
629     private static final int[] STREAM_VOLUME_OPS = new int[] {
630         AppOpsManager.OP_AUDIO_VOICE_VOLUME,            // STREAM_VOICE_CALL
631         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_SYSTEM
632         AppOpsManager.OP_AUDIO_RING_VOLUME,             // STREAM_RING
633         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_MUSIC
634         AppOpsManager.OP_AUDIO_ALARM_VOLUME,            // STREAM_ALARM
635         AppOpsManager.OP_AUDIO_NOTIFICATION_VOLUME,     // STREAM_NOTIFICATION
636         AppOpsManager.OP_AUDIO_BLUETOOTH_VOLUME,        // STREAM_BLUETOOTH_SCO
637         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_SYSTEM_ENFORCED
638         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_DTMF
639         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_TTS
640         AppOpsManager.OP_AUDIO_ACCESSIBILITY_VOLUME,    // STREAM_ACCESSIBILITY
641         AppOpsManager.OP_AUDIO_MEDIA_VOLUME             // STREAM_ASSISTANT
642     };
643 
644     private final boolean mUseFixedVolume;
645     private final boolean mRingerModeAffectsAlarm;
646     private final boolean mUseVolumeGroupAliases;
647 
648     // If absolute volume is supported in AVRCP device
649     private volatile boolean mAvrcpAbsVolSupported = false;
650 
651     private final Object mCachedAbsVolDrivingStreamsLock = new Object();
652     // Contains for all the device types which support absolute volume the current streams that
653     // are driving the volume changes
654     @GuardedBy("mCachedAbsVolDrivingStreamsLock")
655     private final HashMap<Integer, Integer> mCachedAbsVolDrivingStreams = new HashMap<>(
656             Map.of(AudioSystem.DEVICE_OUT_BLE_HEADSET, AudioSystem.STREAM_MUSIC,
657                     AudioSystem.DEVICE_OUT_BLE_SPEAKER, AudioSystem.STREAM_MUSIC,
658                     AudioSystem.DEVICE_OUT_BLE_BROADCAST, AudioSystem.STREAM_MUSIC,
659                     AudioSystem.DEVICE_OUT_HEARING_AID, AudioSystem.STREAM_MUSIC
660             ));
661 
662     /**
663     * Default stream type used for volume control in the absence of playback
664     * e.g. user on homescreen, no app playing anything, presses hardware volume buttons, this
665     *    stream type is controlled.
666     */
667     protected static final int DEFAULT_VOL_STREAM_NO_PLAYBACK = AudioSystem.STREAM_MUSIC;
668 
669     private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() {
670         public void onError(int error) {
671             switch (error) {
672                 case AudioSystem.AUDIO_STATUS_SERVER_DIED:
673                     // check for null in case error callback is called during instance creation
674                     if (mRecordMonitor != null) {
675                         mRecordMonitor.onAudioServerDied();
676                     }
677                     // Notify the playback monitor that the audio server has died
678                     if (mPlaybackMonitor != null) {
679                         mPlaybackMonitor.onAudioServerDied();
680                     }
681                     sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED,
682                             SENDMSG_NOOP, 0, 0, null, 0);
683                     sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE,
684                             SENDMSG_QUEUE, 0, 0, null, 0);
685                     break;
686                 default:
687                     break;
688             }
689         }
690     };
691 
692     /**
693      * Current ringer mode from one of {@link AudioManager#RINGER_MODE_NORMAL},
694      * {@link AudioManager#RINGER_MODE_SILENT}, or
695      * {@link AudioManager#RINGER_MODE_VIBRATE}.
696      */
697     @GuardedBy("mSettingsLock")
698     private int mRingerMode;  // internal ringer mode, affects muting of underlying streams
699     @GuardedBy("mSettingsLock")
700     private int mRingerModeExternal = -1;  // reported ringer mode to outside clients (AudioManager)
701 
702     /** @see System#MODE_RINGER_STREAMS_AFFECTED */
703     private int mRingerModeAffectedStreams = 0;
704 
705     private int mZenModeAffectedStreams = 0;
706 
707     // Streams currently muted by ringer mode and dnd
708     protected static volatile int sRingerAndZenModeMutedStreams;
709 
710     /** Streams that can be muted by system. Do not resolve to aliases when checking.
711      * @see System#MUTE_STREAMS_AFFECTED */
712     private int mMuteAffectedStreams;
713 
714     /** Streams that can be muted by user. Do not resolve to aliases when checking.
715      * @see System#MUTE_STREAMS_AFFECTED */
716     private int mUserMutableStreams;
717 
718     @NonNull
719     private SoundEffectsHelper mSfxHelper;
720 
721     /**
722      * NOTE: setVibrateSetting(), getVibrateSetting(), shouldVibrate() are deprecated.
723      * mVibrateSetting is just maintained during deprecation period but vibration policy is
724      * now only controlled by mHasVibrator and mRingerMode
725      */
726     private int mVibrateSetting;
727 
728     // Is there a vibrator
729     private final boolean mHasVibrator;
730     // Used to play vibrations
731     private Vibrator mVibrator;
732     private static final VibrationAttributes TOUCH_VIBRATION_ATTRIBUTES =
733             VibrationAttributes.createForUsage(VibrationAttributes.USAGE_TOUCH);
734 
735     // Handler for broadcast receiver
736     // TODO(b/335513647) combine handlers
737     private final HandlerThread mBroadcastHandlerThread;
738     // Broadcast receiver for device connections intent broadcasts
739     private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver();
740 
741     private IMediaProjectionManager mProjectionService; // to validate projection token
742 
743     /** Interface for UserManagerService. */
744     private final UserManagerInternal mUserManagerInternal;
745     private final ActivityManagerInternal mActivityManagerInternal;
746     private final SensorPrivacyManagerInternal mSensorPrivacyManagerInternal;
747 
748     private final UserRestrictionsListener mUserRestrictionsListener =
749             new AudioServiceUserRestrictionsListener();
750 
751     // List of binder death handlers for setMode() client processes.
752     // The last process to have called setMode() is at the top of the list.
753     // package-private so it can be accessed in AudioDeviceBroker.getSetModeDeathHandlers
754     //TODO candidate to be moved to separate class that handles synchronization
755     @GuardedBy("mDeviceBroker.mSetModeLock")
756     /*package*/ final ArrayList<SetModeDeathHandler> mSetModeDeathHandlers =
757             new ArrayList<SetModeDeathHandler>();
758 
759     // true if boot sequence has been completed
760     private boolean mSystemReady;
761     // true if Intent.ACTION_USER_SWITCHED has ever been received
762     private boolean mUserSwitchedReceived;
763     // previous volume adjustment direction received by checkForRingerModeChange()
764     private int mPrevVolDirection = AudioManager.ADJUST_SAME;
765     // mVolumeControlStream is set by VolumePanel to temporarily force the stream type which volume
766     // is controlled by Vol keys.
767     private int mVolumeControlStream = -1;
768     // interpretation of whether the volume stream has been selected by the user by clicking on a
769     // volume slider to change which volume is controlled by the volume keys. Is false
770     // when mVolumeControlStream is -1.
771     private boolean mUserSelectedVolumeControlStream = false;
772     private final Object mForceControlStreamLock = new Object();
773     // VolumePanel is currently the only client of forceVolumeControlStream() and runs in system
774     // server process so in theory it is not necessary to monitor the client death.
775     // However it is good to be ready for future evolutions.
776     private ForceControlStreamClient mForceControlStreamClient = null;
777     // Used to play ringtones outside system_server
778     private volatile IRingtonePlayer mRingtonePlayer;
779 
780     // Devices for which the volume is fixed (volume is either max or muted)
781     Set<Integer> mFixedVolumeDevices = new HashSet<>(Arrays.asList(
782             AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET,
783             AudioSystem.DEVICE_OUT_AUX_LINE));
784     // Devices for which the volume is always max, no volume panel
785     Set<Integer> mFullVolumeDevices = new HashSet<>(Arrays.asList(
786             AudioSystem.DEVICE_OUT_HDMI_ARC,
787             AudioSystem.DEVICE_OUT_HDMI_EARC
788     ));
789 
790     // Devices where the framework sends a full scale audio signal, and controls the volume of
791     // the external audio system separately.
792     // For possible volume behaviors, see {@link AudioManager.AbsoluteDeviceVolumeBehavior}.
793     Map<Integer, AbsoluteVolumeDeviceInfo> mAbsoluteVolumeDeviceInfoMap = new ArrayMap<>();
794 
795     /**
796      * Stores information about a device using absolute volume behavior.
797      */
798     private static final class AbsoluteVolumeDeviceInfo {
799         private final AudioDeviceAttributes mDevice;
800         private final List<VolumeInfo> mVolumeInfos;
801         private final IAudioDeviceVolumeDispatcher mCallback;
802         private final boolean mHandlesVolumeAdjustment;
803         private @AudioManager.AbsoluteDeviceVolumeBehavior int mDeviceVolumeBehavior;
804 
AbsoluteVolumeDeviceInfo( AudioDeviceAttributes device, List<VolumeInfo> volumeInfos, IAudioDeviceVolumeDispatcher callback, boolean handlesVolumeAdjustment, @AudioManager.AbsoluteDeviceVolumeBehavior int behavior)805         private AbsoluteVolumeDeviceInfo(
806                 AudioDeviceAttributes device,
807                 List<VolumeInfo> volumeInfos,
808                 IAudioDeviceVolumeDispatcher callback,
809                 boolean handlesVolumeAdjustment,
810                 @AudioManager.AbsoluteDeviceVolumeBehavior int behavior) {
811             this.mDevice = device;
812             this.mVolumeInfos = volumeInfos;
813             this.mCallback = callback;
814             this.mHandlesVolumeAdjustment = handlesVolumeAdjustment;
815             this.mDeviceVolumeBehavior = behavior;
816         }
817 
818         /**
819          * Given a stream type, returns a matching VolumeInfo.
820          */
821         @Nullable
getMatchingVolumeInfoForStream(int streamType)822         private VolumeInfo getMatchingVolumeInfoForStream(int streamType) {
823             for (VolumeInfo volumeInfo : mVolumeInfos) {
824                 boolean streamTypeMatches = volumeInfo.hasStreamType()
825                         && volumeInfo.getStreamType() == streamType;
826                 boolean volumeGroupMatches = volumeInfo.hasVolumeGroup()
827                         && Arrays.stream(volumeInfo.getVolumeGroup().getLegacyStreamTypes())
828                         .anyMatch(s -> s == streamType);
829                 if (streamTypeMatches || volumeGroupMatches) {
830                     return volumeInfo;
831                 }
832             }
833             return null;
834         }
835     }
836 
837     // Devices for the which use the "absolute volume" concept (framework sends audio signal
838     // full scale, and volume control separately) and can be used for multiple use cases reflected
839     // by the audio mode (e.g. media playback in MODE_NORMAL, and phone calls in MODE_IN_CALL).
840     Set<Integer> mAbsVolumeMultiModeCaseDevices = new HashSet<>(
841             Arrays.asList(AudioSystem.DEVICE_OUT_HEARING_AID));
842 
843     private final boolean mMonitorRotation;
844 
845     private boolean mDockAudioMediaEnabled = true;
846 
847     /**
848      * RestorableParameters is a thread-safe class used to store a
849      * first-in first-out history of parameters for replay / restoration.
850      *
851      * The idealized implementation of restoration would have a list of setting methods and
852      * values to be called for restoration.  Explicitly managing such setters and
853      * values would be tedious - a simpler method is to store the values and the
854      * method implicitly by lambda capture (the values must be immutable or synchronization
855      * needs to be taken).
856      *
857      * We provide queueRestoreWithRemovalIfTrue() to allow
858      * the caller to provide a BooleanSupplier lambda, which conveniently packages
859      * the setter and its parameters needed for restoration.  If during restoration,
860      * the BooleanSupplier returns true, e.g. on error, it is removed from the mMap
861      * so as not to be called on a subsequent restore.
862      *
863      * We provide a setParameters() method as an example helper method.
864      */
865     private static class RestorableParameters {
866         /**
867          * Sets a parameter and queues for restoration if successful.
868          *
869          * @param id a string handle associated with this parameter.
870          * @param parameter the actual parameter string.
871          * @return the result of AudioSystem.setParameters
872          */
setParameters(@onNull String id, @NonNull String parameter)873         public int setParameters(@NonNull String id, @NonNull String parameter) {
874             Objects.requireNonNull(id, "id must not be null");
875             Objects.requireNonNull(parameter, "parameter must not be null");
876             synchronized (mMap) {
877                 final int status = AudioSystem.setParameters(parameter);
878                 if (status == AudioSystem.AUDIO_STATUS_OK) { // Java uses recursive mutexes.
879                     queueRestoreWithRemovalIfTrue(id, () -> { // remove me if set fails.
880                         return AudioSystem.setParameters(parameter) != AudioSystem.AUDIO_STATUS_OK;
881                     });
882                 }
883                 // Implementation detail: We do not mMap.remove(id); on failure.
884                 return status;
885             }
886         }
887 
888         /**
889          * Queues a restore method which is executed on restoreAll().
890          *
891          * If the supplier null, the id is removed from the restore map.
892          *
893          * Note: When the BooleanSupplier restore method is executed
894          * during restoreAll, if it returns true, it is removed from the
895          * restore map.
896          *
897          * @param id a unique tag associated with the restore method.
898          * @param supplier is a BooleanSupplier lambda.
899          */
queueRestoreWithRemovalIfTrue( @onNull String id, @Nullable BooleanSupplier supplier)900         public void queueRestoreWithRemovalIfTrue(
901                 @NonNull String id, @Nullable BooleanSupplier supplier) {
902             Objects.requireNonNull(id, "id must not be null");
903             synchronized (mMap) {
904                 if (supplier != null) {
905                     mMap.put(id, supplier);
906                 } else {
907                     mMap.remove(id);
908                 }
909             }
910         }
911 
912         /**
913          * Restore all parameters
914          *
915          * During restoration after audioserver death, any BooleanSupplier that returns
916          * true, for example on parameter restoration error, will be removed from mMap
917          * so as not to be executed on a subsequent restoreAll().
918          */
restoreAll()919         public void restoreAll() {
920             synchronized (mMap) {
921                 // Note: removing from values() also removes from the backing map.
922                 // TODO: Consider catching exceptions?
923                 mMap.values().removeIf(v -> {
924                     return v.getAsBoolean(); // this iterates the setters().
925                 });
926             }
927         }
928 
929         /**
930          * mMap is a LinkedHashMap<Key, Value> of parameters restored by restore().
931          * The Key is a unique id tag for identification.
932          * The Value is a lambda expression which returns true if the entry is to
933          *     be removed.
934          *
935          * 1) For memory limitation purposes, mMap keeps the latest MAX_ENTRIES
936          *    accessed in the map.
937          * 2) Parameters are restored in order of queuing, first in first out,
938          *    from earliest to latest.
939          */
940         @GuardedBy("mMap")
941         private Map</* @NonNull */ String, /* @NonNull */ BooleanSupplier> mMap =
942                 new LinkedHashMap<>() {
943             // TODO: do we need this memory limitation?
944             private static final int MAX_ENTRIES = 1000;  // limit our memory for now.
945             @Override
946             protected boolean removeEldestEntry(Map.Entry eldest) {
947                 if (size() <= MAX_ENTRIES) return false;
948                 Log.w(TAG, "Parameter map exceeds "
949                         + MAX_ENTRIES + " removing " + eldest.getKey()); // don't silently remove.
950                 return true;
951             }
952         };
953     }
954 
955     // We currently have one instance for mRestorableParameters used for
956     // setAdditionalOutputDeviceDelay().  Other methods requiring restoration could share this
957     // or use their own instance.
958     private RestorableParameters mRestorableParameters = new RestorableParameters();
959 
960     private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
961 
962     private PowerManager.WakeLock mAudioEventWakeLock;
963 
964     private final MediaFocusControl mMediaFocusControl;
965 
966     // Pre-scale for Bluetooth Absolute Volume
967     private float[] mPrescaleAbsoluteVolume = new float[] {
968         0.6f,    // Pre-scale for index 1
969         0.8f,    // Pre-scale for index 2
970         0.9f,   // Pre-scale for index 3
971     };
972 
973     private NotificationManager mNm;
974     private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate;
975     private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT;
976     private long mLoweredFromNormalToVibrateTime;
977 
978     // Array of Uids of valid assistant services to check if caller is one of them
979     @GuardedBy("mSettingsLock")
980     private final ArraySet<Integer> mAssistantUids = new ArraySet<>();
981     @GuardedBy("mSettingsLock")
982     private int mPrimaryAssistantUid = INVALID_UID;
983 
984     // Array of Uids of valid active assistant service to check if caller is one of them
985     @GuardedBy("mSettingsLock")
986     private int[] mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS;
987 
988     // Array of Uids of valid accessibility services to check if caller is one of them
989     private final Object mAccessibilityServiceUidsLock = new Object();
990     @GuardedBy("mAccessibilityServiceUidsLock")
991     private int[] mAccessibilityServiceUids;
992 
993     // Uid of the active input method service to check if caller is the one or not.
994     private int mInputMethodServiceUid = android.os.Process.INVALID_UID;
995     private final Object mInputMethodServiceUidLock = new Object();
996 
997     private int mEncodedSurroundMode;
998     private String mEnabledSurroundFormats;
999     private boolean mSurroundModeChanged;
1000 
1001     private boolean mSupportsMicPrivacyToggle;
1002 
1003     private boolean mMicMuteFromSwitch;
1004     private boolean mMicMuteFromApi;
1005     private boolean mMicMuteFromRestrictions;
1006     private boolean mMicMuteFromPrivacyToggle;
1007     // caches the value returned by AudioSystem.isMicrophoneMuted()
1008     private boolean mMicMuteFromSystemCached;
1009 
1010     private boolean mNavigationRepeatSoundEffectsEnabled;
1011     private boolean mHomeSoundEffectEnabled;
1012 
1013     private final SoundDoseHelper mSoundDoseHelper;
1014 
1015     private final LoudnessCodecHelper mLoudnessCodecHelper;
1016 
1017     private final HardeningEnforcer mHardeningEnforcer;
1018 
1019     private final AudioVolumeGroupHelperBase mAudioVolumeGroupHelper;
1020 
1021     private final Object mSupportedSystemUsagesLock = new Object();
1022     @GuardedBy("mSupportedSystemUsagesLock")
1023     private @AttributeSystemUsage int[] mSupportedSystemUsages =
1024             new int[]{AudioAttributes.USAGE_CALL_ASSISTANT};
1025 
1026     // Defines the format for the connection "address" for ALSA devices
makeAlsaAddressString(int card, int device)1027     public static String makeAlsaAddressString(int card, int device) {
1028         return "card=" + card + ";device=" + device;
1029     }
1030 
1031     private static class AudioVolumeGroupHelper extends AudioVolumeGroupHelperBase {
1032         @Override
getAudioVolumeGroups()1033         public List<AudioVolumeGroup> getAudioVolumeGroups() {
1034             return AudioVolumeGroup.getAudioVolumeGroups();
1035         }
1036     }
1037 
1038     public static final class Lifecycle extends SystemService {
1039         private AudioService mService;
1040 
Lifecycle(Context context)1041         public Lifecycle(Context context) {
1042             super(context);
1043             var audioserverLifecycleExecutor = Executors.newSingleThreadExecutor();
1044             var audioPolicyFacade = new DefaultAudioPolicyFacade(audioserverLifecycleExecutor);
1045             mService = new AudioService(context,
1046                               AudioSystemAdapter.getDefaultAdapter(),
1047                               SystemServerAdapter.getDefaultAdapter(context),
1048                               SettingsAdapter.getDefaultAdapter(),
1049                               new AudioVolumeGroupHelper(),
1050                               audioPolicyFacade,
1051                               null,
1052                               context.getSystemService(AppOpsManager.class),
1053                               PermissionEnforcer.fromContext(context),
1054                               audioserverPermissions() ?
1055                                 initializeAudioServerPermissionProvider(
1056                                     context, audioPolicyFacade, audioserverLifecycleExecutor) :
1057                                     null
1058                               );
1059         }
1060 
1061         @Override
onStart()1062         public void onStart() {
1063             publishBinderService(Context.AUDIO_SERVICE, mService);
1064         }
1065 
1066         @Override
onBootPhase(int phase)1067         public void onBootPhase(int phase) {
1068             if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
1069                 mService.systemReady();
1070             }
1071         }
1072     }
1073 
1074     final private IUidObserver mUidObserver = new UidObserver() {
1075         @Override public void onUidGone(int uid, boolean disabled) {
1076             // Once the uid is no longer running, no need to keep trying to disable its audio.
1077             disableAudioForUid(false, uid);
1078         }
1079 
1080         @Override public void onUidCachedChanged(int uid, boolean cached) {
1081             disableAudioForUid(cached, uid);
1082         }
1083 
1084         private void disableAudioForUid(boolean disable, int uid) {
1085             queueMsgUnderWakeLock(mAudioHandler, MSG_DISABLE_AUDIO_FOR_UID,
1086                     disable ? 1 : 0 /* arg1 */,  uid /* arg2 */,
1087                     null /* obj */,  0 /* delay */);
1088         }
1089     };
1090 
1091     @GuardedBy("mSettingsLock")
1092     private boolean mRttEnabled = false;
1093 
1094     private AtomicBoolean mMasterMute = new AtomicBoolean(false);
1095 
1096     private DisplayManager mDisplayManager;
1097 
1098     private DisplayListener mDisplayListener =
1099       new DisplayListener() {
1100         @Override
1101         public void onDisplayAdded(int displayId) {}
1102 
1103         @Override
1104         public void onDisplayRemoved(int displayId) {}
1105 
1106         @Override
1107         public void onDisplayChanged(int displayId) {
1108             if (displayId != Display.DEFAULT_DISPLAY) {
1109                 return;
1110             }
1111             int displayState = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY).getState();
1112             if (displayState == Display.STATE_ON) {
1113                 if (mMonitorRotation) {
1114                     RotationHelper.enable();
1115                 }
1116                 AudioSystem.setParameters("screen_state=on");
1117             } else {
1118                 if (mMonitorRotation) {
1119                     //reduce wakeups (save current) by only listening when display is on
1120                     RotationHelper.disable();
1121                 }
1122                 AudioSystem.setParameters("screen_state=off");
1123             }
1124         }
1125       };
1126 
1127     ///////////////////////////////////////////////////////////////////////////
1128     // Construction
1129     ///////////////////////////////////////////////////////////////////////////
1130 
1131 
1132     /**
1133      * @param context
1134      * @param audioSystem Adapter for {@link AudioSystem}
1135      * @param systemServer Adapter for privilieged functionality for system server components
1136      * @param settings Adapter for {@link Settings}
1137      * @param audioVolumeGroupHelper Adapter for {@link AudioVolumeGroup}
1138      * @param audioPolicy Interface of a facade to IAudioPolicyManager
1139      * @param looper Looper to use for the service's message handler. If this is null, an
1140      *               {@link AudioSystemThread} is created as the messaging thread instead.
1141      * @param appOps {@link AppOpsManager} system service
1142      * @param enforcer Used for permission enforcing
1143      */
1144     @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
AudioService(Context context, AudioSystemAdapter audioSystem, SystemServerAdapter systemServer, SettingsAdapter settings, AudioVolumeGroupHelperBase audioVolumeGroupHelper, AudioPolicyFacade audioPolicy, @Nullable Looper looper, AppOpsManager appOps, @NonNull PermissionEnforcer enforcer, AudioServerPermissionProvider permissionProvider)1145     public AudioService(Context context, AudioSystemAdapter audioSystem,
1146             SystemServerAdapter systemServer, SettingsAdapter settings,
1147             AudioVolumeGroupHelperBase audioVolumeGroupHelper, AudioPolicyFacade audioPolicy,
1148             @Nullable Looper looper, AppOpsManager appOps, @NonNull PermissionEnforcer enforcer,
1149             /* @NonNull */ AudioServerPermissionProvider permissionProvider) {
1150         super(enforcer);
1151         sLifecycleLogger.enqueue(new EventLogger.StringEvent("AudioService()"));
1152         mContext = context;
1153         mContentResolver = context.getContentResolver();
1154         mAppOps = appOps;
1155 
1156         mPermissionProvider = permissionProvider;
1157 
1158         mAudioSystem = audioSystem;
1159         mSystemServer = systemServer;
1160         mAudioVolumeGroupHelper = audioVolumeGroupHelper;
1161         mSettings = settings;
1162         mAudioPolicy = audioPolicy;
1163         mPlatformType = AudioSystem.getPlatformType(context);
1164 
1165         mBroadcastHandlerThread = new HandlerThread("AudioService Broadcast");
1166         mBroadcastHandlerThread.start();
1167 
1168         mDeviceBroker = new AudioDeviceBroker(mContext, this, mAudioSystem);
1169 
1170         mIsSingleVolume = AudioSystem.isSingleVolume(context);
1171 
1172         mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
1173         mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
1174         mSensorPrivacyManagerInternal =
1175                 LocalServices.getService(SensorPrivacyManagerInternal.class);
1176 
1177         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
1178         mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent");
1179 
1180         mSfxHelper = new SoundEffectsHelper(mContext, playerBase -> ignorePlayerLogs(playerBase));
1181 
1182         boolean binauralEnabledDefault = SystemProperties.getBoolean(
1183                 "ro.audio.spatializer_binaural_enabled_default", true);
1184         boolean transauralEnabledDefault = SystemProperties.getBoolean(
1185                 "ro.audio.spatializer_transaural_enabled_default", true);
1186         boolean headTrackingEnabledDefault = mContext.getResources().getBoolean(
1187                 com.android.internal.R.bool.config_spatial_audio_head_tracking_enabled_default);
1188 
1189         mSpatializerHelper = new SpatializerHelper(this, mAudioSystem, mDeviceBroker,
1190                 binauralEnabledDefault, transauralEnabledDefault, headTrackingEnabledDefault);
1191 
1192         mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
1193         mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator();
1194 
1195         mSupportsMicPrivacyToggle = context.getSystemService(SensorPrivacyManager.class)
1196                 .supportsSensorToggle(SensorPrivacyManager.Sensors.MICROPHONE);
1197 
1198         mUseVolumeGroupAliases = mContext.getResources().getBoolean(
1199                 com.android.internal.R.bool.config_handleVolumeAliasesUsingVolumeGroups);
1200 
1201         // Initialize volume
1202         // Priority 1 - Android Property
1203         // Priority 2 - Audio Policy Service
1204         // Priority 3 - Default Value
1205         if (AudioProductStrategy.getAudioProductStrategies().size() > 0) {
1206             int numStreamTypes = AudioSystem.getNumStreamTypes();
1207 
1208             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
1209                 AudioAttributes attr =
1210                         AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(
1211                                 streamType);
1212                 int maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr);
1213                 if (maxVolume != -1) {
1214                     MAX_STREAM_VOLUME[streamType] = maxVolume;
1215                 }
1216                 int minVolume = AudioSystem.getMinVolumeIndexForAttributes(attr);
1217                 if (minVolume != -1) {
1218                     MIN_STREAM_VOLUME[streamType] = minVolume;
1219                 }
1220             }
1221             if (mUseVolumeGroupAliases) {
1222                 // Set all default to uninitialized.
1223                 for (int stream = 0; stream < AudioSystem.DEFAULT_STREAM_VOLUME.length; stream++) {
1224                     AudioSystem.DEFAULT_STREAM_VOLUME[stream] = UNSET_INDEX;
1225                 }
1226             }
1227         }
1228 
1229         int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1);
1230         if (maxCallVolume != -1) {
1231             MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxCallVolume;
1232         }
1233 
1234         int defaultCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_default", -1);
1235         if (defaultCallVolume != -1 &&
1236                 defaultCallVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] &&
1237                 defaultCallVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]) {
1238             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = defaultCallVolume;
1239         } else {
1240             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] =
1241                     (MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] * 3) / 4;
1242         }
1243 
1244         int maxMusicVolume = SystemProperties.getInt("ro.config.media_vol_steps", -1);
1245         if (maxMusicVolume != -1) {
1246             MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxMusicVolume;
1247         }
1248 
1249         int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", -1);
1250         if (defaultMusicVolume != -1 &&
1251                 defaultMusicVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] &&
1252                 defaultMusicVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) {
1253             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = defaultMusicVolume;
1254         } else {
1255             if (isPlatformTelevision()) {
1256                 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] =
1257                         MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 4;
1258             } else {
1259                 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] =
1260                         MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 3;
1261             }
1262         }
1263 
1264         int maxAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_steps", -1);
1265         if (maxAlarmVolume != -1) {
1266             MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = maxAlarmVolume;
1267         }
1268 
1269         if (alarmMinVolumeZero()) {
1270             try {
1271                 int minAlarmVolume = mContext.getResources().getInteger(
1272                         com.android.internal.R.integer.config_audio_alarm_min_vol);
1273                 if (minAlarmVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]) {
1274                     MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = minAlarmVolume;
1275                 } else {
1276                     Log.e(TAG, "Error min alarm volume greater than max alarm volume");
1277                 }
1278             } catch (Resources.NotFoundException e) {
1279                 Log.e(TAG, "Error querying for alarm min volume ", e);
1280             }
1281         }
1282         int defaultAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_default", -1);
1283         if (defaultAlarmVolume != -1 &&
1284                 defaultAlarmVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]) {
1285             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = defaultAlarmVolume;
1286         } else {
1287             // Default is 6 out of 7 (default maximum), so scale accordingly.
1288             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] =
1289                         6 * MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] / 7;
1290         }
1291 
1292         int maxSystemVolume = SystemProperties.getInt("ro.config.system_vol_steps", -1);
1293         if (maxSystemVolume != -1) {
1294             MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = maxSystemVolume;
1295         }
1296 
1297         int defaultSystemVolume = SystemProperties.getInt("ro.config.system_vol_default", -1);
1298         if (defaultSystemVolume != -1 &&
1299                 defaultSystemVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]) {
1300             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = defaultSystemVolume;
1301         } else {
1302             // Default is to use maximum.
1303             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] =
1304                         MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM];
1305         }
1306 
1307         int minAssistantVolume = SystemProperties.getInt("ro.config.assistant_vol_min", -1);
1308         if (minAssistantVolume != -1) {
1309             MIN_STREAM_VOLUME[AudioSystem.STREAM_ASSISTANT] = minAssistantVolume;
1310         }
1311 
1312         // Read following properties to configure max volume (number of steps) and default volume
1313         //   for STREAM_NOTIFICATION and STREAM_RING:
1314         //      config_audio_notif_vol_default
1315         //      config_audio_notif_vol_steps
1316         //      config_audio_ring_vol_default
1317         //      config_audio_ring_vol_steps
1318         int[] streams = { AudioSystem.STREAM_NOTIFICATION, AudioSystem.STREAM_RING };
1319         int[] stepsResId = { com.android.internal.R.integer.config_audio_notif_vol_steps,
1320                 com.android.internal.R.integer.config_audio_ring_vol_steps };
1321         int[] defaultResId = { com.android.internal.R.integer.config_audio_notif_vol_default,
1322                 com.android.internal.R.integer.config_audio_ring_vol_default };
1323         for (int s = 0; s < streams.length; s++) {
1324             try {
1325                 final int maxVol = mContext.getResources().getInteger(stepsResId[s]);
1326                 if (maxVol <= 0) {
1327                     throw new IllegalArgumentException("Invalid negative max volume for stream "
1328                             + streams[s]);
1329                 }
1330                 Log.i(TAG, "Stream " + streams[s] + ": using max vol of " + maxVol);
1331                 MAX_STREAM_VOLUME[streams[s]] = maxVol;
1332             } catch (Resources.NotFoundException e) {
1333                 Log.e(TAG, "Error querying max vol for stream type " + streams[s], e);
1334             }
1335             try {
1336                 final int defaultVol = mContext.getResources().getInteger(defaultResId[s]);
1337                 if (defaultVol > MAX_STREAM_VOLUME[streams[s]]) {
1338                     throw new IllegalArgumentException("Invalid default volume (" + defaultVol
1339                             + ") for stream " + streams[s] + ", greater than max volume of "
1340                             + MAX_STREAM_VOLUME[streams[s]]);
1341                 }
1342                 if (defaultVol < MIN_STREAM_VOLUME[streams[s]]) {
1343                     throw new IllegalArgumentException("Invalid default volume (" + defaultVol
1344                             + ") for stream " + streams[s] + ", lower than min volume of "
1345                             + MIN_STREAM_VOLUME[streams[s]]);
1346                 }
1347                 Log.i(TAG, "Stream " + streams[s] + ": using default vol of " + defaultVol);
1348                 AudioSystem.DEFAULT_STREAM_VOLUME[streams[s]] = defaultVol;
1349             } catch (Resources.NotFoundException e) {
1350                 Log.e(TAG, "Error querying default vol for stream type " + streams[s], e);
1351             }
1352         }
1353 
1354         if (looper == null) {
1355             createAudioSystemThread();
1356         } else {
1357             mAudioHandler = new AudioHandler(looper);
1358         }
1359 
1360         mSoundDoseHelper = new SoundDoseHelper(this, mContext, mAudioHandler, mSettings,
1361                 mVolumeController);
1362 
1363         AudioSystem.setErrorCallback(mAudioSystemCallback);
1364 
1365         updateAudioHalPids();
1366 
1367         mUseFixedVolume = mContext.getResources().getBoolean(
1368                 com.android.internal.R.bool.config_useFixedVolume);
1369 
1370         mRingerModeAffectsAlarm = mContext.getResources().getBoolean(
1371                 com.android.internal.R.bool.config_audio_ringer_mode_affects_alarm_stream);
1372 
1373         mRecordMonitor = new RecordingActivityMonitor(mContext);
1374         mRecordMonitor.registerRecordingCallback(mVoiceRecordingActivityMonitor, true);
1375 
1376         // must be called before readPersistedSettings() which needs a valid mStreamVolumeAlias[]
1377         // array initialized by updateStreamVolumeAlias()
1378         updateStreamVolumeAlias(false /*updateVolumes*/, TAG);
1379         readPersistedSettings();
1380         readUserRestrictions();
1381 
1382         mLoudnessCodecHelper = new LoudnessCodecHelper(this);
1383 
1384         mPlaybackMonitor =
1385                 new PlaybackActivityMonitor(context, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM],
1386                         device -> onMuteAwaitConnectionTimeout(device));
1387         mPlaybackMonitor.registerPlaybackCallback(mPlaybackActivityMonitor, true);
1388 
1389         mMediaFocusControl = new MediaFocusControl(mContext, mPlaybackMonitor);
1390 
1391         readAndSetLowRamDevice();
1392 
1393         mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported();
1394 
1395         if (mSystemServer.isPrivileged()) {
1396             LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal());
1397 
1398             mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
1399 
1400             mRecordMonitor.initMonitor();
1401         }
1402 
1403         mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false);
1404 
1405         mHasSpatializerEffect = SystemProperties.getBoolean("ro.audio.spatializer_enabled", false);
1406 
1407         // monitor routing updates coming from native
1408         mAudioSystem.setRoutingListener(this);
1409         // monitor requests for volume range initialization coming from native (typically when
1410         // errors are found by AudioPolicyManager
1411         mAudioSystem.setVolRangeInitReqListener(this);
1412 
1413         // done with service initialization, continue additional work in our Handler thread
1414         queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_STREAMS_VOLUMES,
1415                 0 /* arg1 */,  0 /* arg2 */, null /* obj */,  0 /* delay */);
1416         queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_ADI_DEVICE_STATES,
1417                 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */);
1418         queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_SPATIALIZER,
1419                 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */);
1420 
1421         mDisplayManager = context.getSystemService(DisplayManager.class);
1422 
1423         mMusicFxHelper = new MusicFxHelper(mContext, mAudioHandler);
1424 
1425         mHardeningEnforcer = new HardeningEnforcer(mContext, isPlatformAutomotive(), mAppOps,
1426                 context.getPackageManager());
1427     }
1428 
initVolumeStreamStates()1429     private void initVolumeStreamStates() {
1430         int numStreamTypes = AudioSystem.getNumStreamTypes();
1431         synchronized (VolumeStreamState.class) {
1432             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
1433                 VolumeStreamState streamState = mStreamStates[streamType];
1434                 int groupId = getVolumeGroupForStreamType(streamType);
1435                 if (groupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP
1436                         && sVolumeGroupStates.indexOfKey(groupId) >= 0) {
1437                     streamState.setVolumeGroupState(sVolumeGroupStates.get(groupId));
1438                 }
1439             }
1440         }
1441     }
1442 
1443     /**
1444      * Called by handling of MSG_INIT_STREAMS_VOLUMES
1445      */
onInitStreamsAndVolumes()1446     private void onInitStreamsAndVolumes() {
1447         synchronized (mSettingsLock) {
1448             mCameraSoundForced = readCameraSoundForced();
1449             sendMsg(mAudioHandler,
1450                     MSG_SET_FORCE_USE,
1451                     SENDMSG_QUEUE,
1452                     AudioSystem.FOR_SYSTEM,
1453                     mCameraSoundForced
1454                             ? AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE,
1455                     new String("AudioService ctor"),
1456                     0);
1457         }
1458 
1459         createStreamStates();
1460 
1461         // must be called after createStreamStates() as it uses MUSIC volume as default if no
1462         // persistent data
1463         initVolumeGroupStates();
1464 
1465         mSoundDoseHelper.initSafeMediaVolumeIndex();
1466         // Link VGS on VSS
1467         initVolumeStreamStates();
1468 
1469         // Call setRingerModeInt() to apply correct mute
1470         // state on streams affected by ringer mode.
1471         sRingerAndZenModeMutedStreams = 0;
1472         sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent(
1473                 sRingerAndZenModeMutedStreams, "onInitStreamsAndVolumes"));
1474         setRingerModeInt(getRingerModeInternal(), false);
1475 
1476         if (!disablePrescaleAbsoluteVolume()) {
1477             final float[] preScale = new float[3];
1478             preScale[0] = mContext.getResources().getFraction(
1479                     com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index1,
1480                     1, 1);
1481             preScale[1] = mContext.getResources().getFraction(
1482                     com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index2,
1483                     1, 1);
1484             preScale[2] = mContext.getResources().getFraction(
1485                     com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index3,
1486                     1, 1);
1487             for (int i = 0; i < preScale.length; i++) {
1488                 if (0.0f <= preScale[i] && preScale[i] <= 1.0f) {
1489                     mPrescaleAbsoluteVolume[i] = preScale[i];
1490                 }
1491             }
1492         }
1493 
1494         initExternalEventReceivers();
1495 
1496         // check on volume initialization
1497         checkVolumeRangeInitialization("AudioService()");
1498 
1499         synchronized (mCachedAbsVolDrivingStreamsLock) {
1500             mCachedAbsVolDrivingStreams.forEach((dev, stream) -> {
1501                 mAudioSystem.setDeviceAbsoluteVolumeEnabled(dev, /*address=*/"", /*enabled=*/true,
1502                         stream);
1503             });
1504         }
1505     }
1506 
1507     private SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionChangedListener =
1508             new SubscriptionManager.OnSubscriptionsChangedListener() {
1509                 @Override
1510                 public void onSubscriptionsChanged() {
1511                     Log.i(TAG, "onSubscriptionsChanged()");
1512                     sendMsg(mAudioHandler, MSG_CONFIGURATION_CHANGED, SENDMSG_REPLACE,
1513                             0, 0, null, 0);
1514                 }
1515             };
1516 
getMediaSessionManager()1517     private MediaSessionManager getMediaSessionManager() {
1518         if (mMediaSessionManager == null) {
1519             mMediaSessionManager = (MediaSessionManager) mContext
1520                     .getSystemService(Context.MEDIA_SESSION_SERVICE);
1521         }
1522         return mMediaSessionManager;
1523     }
1524 
1525     /**
1526      * Initialize intent receives and settings observers for this service.
1527      * Must be called after createStreamStates() as the handling of some events
1528      * may affect or need volumes, e.g. BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED
1529      * (for intent receiver), or Settings.Global.ZEN_MODE (for settings observer)
1530      */
initExternalEventReceivers()1531     private void initExternalEventReceivers() {
1532         mSettingsObserver = new SettingsObserver();
1533 
1534         // Register for device connection intent broadcasts.
1535         IntentFilter intentFilter =
1536                 new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
1537         if (!mDeviceBroker.isScoManagedByAudio()) {
1538             intentFilter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED);
1539         }
1540         intentFilter.addAction(Intent.ACTION_DOCK_EVENT);
1541         if (mDisplayManager == null) {
1542             intentFilter.addAction(Intent.ACTION_SCREEN_ON);
1543             intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
1544         }
1545         intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
1546         intentFilter.addAction(Intent.ACTION_USER_BACKGROUND);
1547         intentFilter.addAction(Intent.ACTION_USER_FOREGROUND);
1548         intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
1549         intentFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
1550 
1551         intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
1552         if (mMonitorRotation) {
1553             RotationHelper.init(mContext, mAudioHandler,
1554                     rotation -> onRotationUpdate(rotation),
1555                     foldState -> onFoldStateUpdate(foldState));
1556         }
1557 
1558         intentFilter.addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION);
1559         intentFilter.addAction(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION);
1560         intentFilter.addAction(ACTION_CHECK_MUSIC_ACTIVE);
1561         intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
1562 
1563         mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null,
1564                 mBroadcastHandlerThread.getThreadHandler(),
1565                 Context.RECEIVER_EXPORTED);
1566 
1567         SubscriptionManager subscriptionManager = mContext.getSystemService(
1568                 SubscriptionManager.class);
1569         if (subscriptionManager == null) {
1570             Log.e(TAG, "initExternalEventReceivers cannot create SubscriptionManager!");
1571         } else {
1572             subscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionChangedListener);
1573         }
1574 
1575         if (mDisplayManager != null) {
1576             mDisplayManager.registerDisplayListener(mDisplayListener, mAudioHandler);
1577         }
1578     }
1579 
systemReady()1580     public void systemReady() {
1581         sendMsg(mAudioHandler, MSG_SYSTEM_READY, SENDMSG_QUEUE,
1582                 0, 0, null, 0);
1583         if (false) {
1584             // This is turned off for now, because it is racy and thus causes apps to break.
1585             // Currently banning a uid means that if an app tries to start playing an audio
1586             // stream, that will be preventing, and unbanning it will not allow that stream
1587             // to resume.  However these changes in uid state are racy with what the app is doing,
1588             // so that after taking a process out of the cached state we can't guarantee that
1589             // we will unban the uid before the app actually tries to start playing audio.
1590             // (To do that, the activity manager would need to wait until it knows for sure
1591             // that the ban has been removed, before telling the app to do whatever it is
1592             // supposed to do that caused it to go out of the cached state.)
1593             try {
1594                 ActivityManager.getService().registerUidObserver(mUidObserver,
1595                         ActivityManager.UID_OBSERVER_CACHED | ActivityManager.UID_OBSERVER_GONE,
1596                         ActivityManager.PROCESS_STATE_UNKNOWN, null);
1597             } catch (RemoteException e) {
1598                 // ignored; both services live in system_server
1599             }
1600         }
1601     }
1602 
updateVibratorInfos()1603     private void updateVibratorInfos() {
1604         VibratorManager vibratorManager = mContext.getSystemService(VibratorManager.class);
1605         if (vibratorManager == null) {
1606             Slog.e(TAG, "Vibrator manager is not found");
1607             return;
1608         }
1609         int[] vibratorIds = vibratorManager.getVibratorIds();
1610         if (vibratorIds.length == 0) {
1611             Slog.d(TAG, "No vibrator found");
1612             return;
1613         }
1614         List<Vibrator> vibrators = new ArrayList<>(vibratorIds.length);
1615         for (int id : vibratorIds) {
1616             Vibrator vibrator = vibratorManager.getVibrator(id);
1617             if (vibrator != null) {
1618                 vibrators.add(vibrator);
1619             } else {
1620                 Slog.w(TAG, "Vibrator(" + id + ") is not found");
1621             }
1622         }
1623         if (vibrators.isEmpty()) {
1624             Slog.w(TAG, "Cannot find any available vibrator");
1625             return;
1626         }
1627         AudioSystem.setVibratorInfos(vibrators);
1628     }
1629 
onSystemReady()1630     public void onSystemReady() {
1631         mSystemReady = true;
1632         scheduleLoadSoundEffects();
1633 
1634         mDeviceBroker.onSystemReady();
1635 
1636         if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_HDMI_CEC)) {
1637             synchronized (mHdmiClientLock) {
1638                 mHdmiManager = mContext.getSystemService(HdmiControlManager.class);
1639                 if (mHdmiManager != null) {
1640                     mHdmiManager.addHdmiControlStatusChangeListener(
1641                             mHdmiControlStatusChangeListenerCallback);
1642                     mHdmiManager.addHdmiCecVolumeControlFeatureListener(mContext.getMainExecutor(),
1643                             mMyHdmiCecVolumeControlFeatureListener);
1644                 }
1645                 mHdmiTvClient = mHdmiManager.getTvClient();
1646                 if (mHdmiTvClient != null) {
1647                     mFixedVolumeDevices.removeAll(
1648                             AudioSystem.DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET);
1649                 }
1650                 mHdmiPlaybackClient = mHdmiManager.getPlaybackClient();
1651                 mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient();
1652             }
1653         }
1654 
1655         if (mSupportsMicPrivacyToggle) {
1656             mSensorPrivacyManagerInternal.addSensorPrivacyListenerForAllUsers(
1657                     SensorPrivacyManager.Sensors.MICROPHONE, (userId, enabled) -> {
1658                         if (userId == getCurrentUserId()) {
1659                             mMicMuteFromPrivacyToggle = enabled;
1660                             setMicrophoneMuteNoCallerCheck(getCurrentUserId());
1661                         }
1662                     });
1663         }
1664 
1665         mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
1666 
1667         mSoundDoseHelper.configureSafeMedia(/*forced=*/true, TAG);
1668 
1669         initA11yMonitoring();
1670 
1671         mRoleObserver = new RoleObserver();
1672         mRoleObserver.register();
1673 
1674         onIndicateSystemReady();
1675 
1676         mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted();
1677         setMicMuteFromSwitchInput();
1678 
1679         initMinStreamVolumeWithoutModifyAudioSettings();
1680 
1681         updateVibratorInfos();
1682 
1683         synchronized (mSupportedSystemUsagesLock) {
1684             AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages);
1685         }
1686     }
1687 
1688     //-----------------------------------------------------------------
1689     // routing monitoring from AudioSystemAdapter
1690     @Override
onRoutingUpdatedFromNative()1691     public void onRoutingUpdatedFromNative() {
1692         sendMsg(mAudioHandler,
1693                 MSG_ROUTING_UPDATED,
1694                 SENDMSG_REPLACE, 0, 0, null,
1695                 /*delay*/ 0);
1696     }
1697 
1698     /**
1699      * called when handling MSG_ROUTING_UPDATED
1700      */
onRoutingUpdatedFromAudioThread()1701     void onRoutingUpdatedFromAudioThread() {
1702         if (mHasSpatializerEffect) {
1703             mSpatializerHelper.onRoutingUpdated();
1704         }
1705         checkMuteAwaitConnection();
1706     }
1707 
1708     //-----------------------------------------------------------------
1709     // rotation/fold updates coming from RotationHelper
onRotationUpdate(Integer rotation)1710     void onRotationUpdate(Integer rotation) {
1711         mSpatializerHelper.setDisplayOrientation((float) (rotation * Math.PI / 180.));
1712         // use REPLACE as only the last rotation matters
1713         final String rotationParameter = "rotation=" + rotation;
1714         sendMsg(mAudioHandler, MSG_ROTATION_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0,
1715                 /*obj*/ rotationParameter, /*delay*/ 0);
1716     }
1717 
onFoldStateUpdate(Boolean foldState)1718     void onFoldStateUpdate(Boolean foldState) {
1719         mSpatializerHelper.setFoldState(foldState);
1720         // use REPLACE as only the last fold state matters
1721         final String foldStateParameter = "device_folded=" + (foldState ? "on" : "off");
1722         sendMsg(mAudioHandler, MSG_FOLD_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0,
1723                 /*obj*/ foldStateParameter, /*delay*/ 0);
1724     }
1725 
1726     //-----------------------------------------------------------------
1727     // Communicate to PlayackActivityMonitor whether to log or not
1728     // the sound FX activity (useful for removing touch sounds in the activity logs)
ignorePlayerLogs(@onNull PlayerBase playerToIgnore)1729     void ignorePlayerLogs(@NonNull PlayerBase playerToIgnore) {
1730         if (DEBUG_LOG_SOUND_FX) {
1731             return;
1732         }
1733         sendMsg(mAudioHandler, MSG_NO_LOG_FOR_PLAYER_I, SENDMSG_REPLACE,
1734                 /*arg1, piid of the player*/ playerToIgnore.getPlayerIId(),
1735                 /*arg2 ignored*/ 0, /*obj ignored*/ null, /*delay*/ 0);
1736     }
1737 
1738     //-----------------------------------------------------------------
1739     // monitoring requests for volume range initialization
1740     @Override // AudioSystemAdapter.OnVolRangeInitRequestListener
onVolumeRangeInitRequestFromNative()1741     public void onVolumeRangeInitRequestFromNative() {
1742         sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_REPLACE, 0, 0,
1743                 "onVolumeRangeInitRequestFromNative" /*obj: caller, for dumpsys*/, /*delay*/ 0);
1744     }
1745 
1746     //-----------------------------------------------------------------
1747     RoleObserver mRoleObserver;
1748 
1749     class RoleObserver implements OnRoleHoldersChangedListener {
1750         private RoleManager mRm;
1751         private final Executor mExecutor;
1752 
RoleObserver()1753         RoleObserver() {
1754             mExecutor = mContext.getMainExecutor();
1755         }
1756 
register()1757         public void register() {
1758             mRm = (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE);
1759             if (mRm != null) {
1760                 mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.ALL);
1761                 synchronized (mSettingsLock) {
1762                     updateAssistantUIdLocked(/* forceUpdate= */ true);
1763                 }
1764             }
1765         }
1766 
1767         @Override
onRoleHoldersChanged(@onNull String roleName, @NonNull UserHandle user)1768         public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
1769             if (RoleManager.ROLE_ASSISTANT.equals(roleName)) {
1770                 synchronized (mSettingsLock) {
1771                     updateAssistantUIdLocked(/* forceUpdate= */ false);
1772                 }
1773             }
1774         }
1775 
getAssistantRoleHolder()1776         public String getAssistantRoleHolder() {
1777             String assitantPackage = "";
1778             if (mRm != null) {
1779                 List<String> assistants = mRm.getRoleHolders(RoleManager.ROLE_ASSISTANT);
1780                 assitantPackage = assistants.size() == 0 ? "" : assistants.get(0);
1781             }
1782             return assitantPackage;
1783         }
1784     }
1785 
onIndicateSystemReady()1786     void onIndicateSystemReady() {
1787         if (AudioSystem.systemReady() == AudioSystem.SUCCESS) {
1788             return;
1789         }
1790         sendMsg(mAudioHandler,
1791                 MSG_INDICATE_SYSTEM_READY,
1792                 SENDMSG_REPLACE,
1793                 0,
1794                 0,
1795                 null,
1796                 INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
1797     }
1798 
onAudioServerDied()1799     public void onAudioServerDied() {
1800         if (!mSystemReady ||
1801                 (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) {
1802             Log.e(TAG, "Audioserver died.");
1803             sLifecycleLogger.enqueue(new EventLogger.StringEvent(
1804                     "onAudioServerDied() audioserver died"));
1805             sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, SENDMSG_NOOP, 0, 0,
1806                     null, 500);
1807             return;
1808         }
1809         Log.i(TAG, "Audioserver started.");
1810         sLifecycleLogger.enqueue(new EventLogger.StringEvent(
1811                 "onAudioServerDied() audioserver started"));
1812 
1813         updateAudioHalPids();
1814 
1815         // indicate to audio HAL that we start the reconfiguration phase after a media
1816         // server crash
1817         // Note that we only execute this when the media server
1818         // process restarts after a crash, not the first time it is started.
1819         AudioSystem.setParameters("restarting=true");
1820 
1821         readAndSetLowRamDevice();
1822 
1823         mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported();
1824 
1825         // Restore device connection states, BT state
1826         mDeviceBroker.onAudioServerDied();
1827 
1828         // Restore call state
1829         synchronized (mDeviceBroker.mSetModeLock) {
1830             onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(),
1831                     mContext.getPackageName(), true /*force*/);
1832         }
1833         final int forSys;
1834         synchronized (mSettingsLock) {
1835             forSys = mCameraSoundForced ?
1836                     AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE;
1837         }
1838 
1839         mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, forSys, "onAudioServerDied");
1840 
1841         // Restore stream volumes
1842         onReinitVolumes("after audioserver restart");
1843 
1844         // Restore audio volume groups
1845         restoreVolumeGroups();
1846 
1847         // Restore mono mode
1848         updateMasterMono(mContentResolver);
1849 
1850         // Restore audio balance
1851         updateMasterBalance(mContentResolver);
1852 
1853         // Restore ringer mode
1854         setRingerModeInt(getRingerModeInternal(), false);
1855 
1856         // Reset device rotation (if monitored for this device)
1857         if (mMonitorRotation) {
1858             RotationHelper.updateOrientation();
1859         }
1860 
1861         // Restore setParameters and other queued setters.
1862         mRestorableParameters.restoreAll();
1863 
1864         synchronized (mSettingsLock) {
1865             final int forDock = mDockAudioMediaEnabled ?
1866                     AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE;
1867             mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, forDock, "onAudioServerDied");
1868             sendEncodedSurroundMode(mContentResolver, "onAudioServerDied");
1869             sendEnabledSurroundFormats(mContentResolver, true);
1870             AudioSystem.setRttEnabled(mRttEnabled);
1871             resetAssistantServicesUidsLocked();
1872         }
1873 
1874         synchronized (mAccessibilityServiceUidsLock) {
1875             AudioSystem.setA11yServicesUids(mAccessibilityServiceUids);
1876         }
1877         synchronized (mInputMethodServiceUidLock) {
1878             mAudioSystem.setCurrentImeUid(mInputMethodServiceUid);
1879         }
1880         synchronized (mHdmiClientLock) {
1881             if (mHdmiManager != null && mHdmiTvClient != null) {
1882                 setHdmiSystemAudioSupported(mHdmiSystemAudioSupported);
1883             }
1884         }
1885 
1886         synchronized (mSupportedSystemUsagesLock) {
1887             AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages);
1888         }
1889 
1890         synchronized (mAudioPolicies) {
1891             ArrayList<AudioPolicyProxy> invalidProxies = new ArrayList<>();
1892             for (AudioPolicyProxy policy : mAudioPolicies.values()) {
1893                 final int status = policy.connectMixes();
1894                 if (status != AudioSystem.SUCCESS) {
1895                     // note that PERMISSION_DENIED may also indicate trouble getting to APService
1896                     Log.e(TAG, "onAudioServerDied: error "
1897                             + AudioSystem.audioSystemErrorToString(status)
1898                             + " when connecting mixes for policy " + policy.toLogFriendlyString());
1899                     invalidProxies.add(policy);
1900                 } else {
1901                     final int deviceAffinitiesStatus = policy.setupDeviceAffinities();
1902                     if (deviceAffinitiesStatus != AudioSystem.SUCCESS) {
1903                         Log.e(TAG, "onAudioServerDied: error "
1904                                 + AudioSystem.audioSystemErrorToString(deviceAffinitiesStatus)
1905                                 + " when connecting device affinities for policy "
1906                                 + policy.toLogFriendlyString());
1907                         invalidProxies.add(policy);
1908                     }
1909                 }
1910             }
1911             invalidProxies.forEach((policy) -> policy.release());
1912 
1913         }
1914 
1915         // Restore capture policies
1916         synchronized (mPlaybackMonitor) {
1917             HashMap<Integer, Integer> allowedCapturePolicies =
1918                     mPlaybackMonitor.getAllAllowedCapturePolicies();
1919             for (HashMap.Entry<Integer, Integer> entry : allowedCapturePolicies.entrySet()) {
1920                 int result = mAudioSystem.setAllowedCapturePolicy(
1921                         entry.getKey(),
1922                         AudioAttributes.capturePolicyToFlags(entry.getValue(), 0x0));
1923                 if (result != AudioSystem.AUDIO_STATUS_OK) {
1924                     Log.e(TAG, "Failed to restore capture policy, uid: "
1925                             + entry.getKey() + ", capture policy: " + entry.getValue()
1926                             + ", result: " + result);
1927                     // When restoring capture policy failed, set the capture policy as
1928                     // ALLOW_CAPTURE_BY_ALL, which will result in removing the cached
1929                     // capture policy in PlaybackActivityMonitor.
1930                     mPlaybackMonitor.setAllowedCapturePolicy(
1931                             entry.getKey(), AudioAttributes.ALLOW_CAPTURE_BY_ALL);
1932                 }
1933             }
1934         }
1935 
1936         mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect);
1937 
1938         // Restore rotation information.
1939         if (mMonitorRotation) {
1940             RotationHelper.forceUpdate();
1941         }
1942 
1943         onIndicateSystemReady();
1944 
1945         synchronized (mCachedAbsVolDrivingStreamsLock) {
1946             mCachedAbsVolDrivingStreams.forEach((dev, stream) -> {
1947                 mAudioSystem.setDeviceAbsoluteVolumeEnabled(dev, /*address=*/"", /*enabled=*/true,
1948                         stream);
1949             });
1950         }
1951 
1952         // indicate the end of reconfiguration phase to audio HAL
1953         AudioSystem.setParameters("restarting=false");
1954 
1955         mSoundDoseHelper.reset(/*resetISoundDose=*/true);
1956 
1957         sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE,
1958                 SENDMSG_QUEUE, 1, 0, null, 0);
1959 
1960         setMicrophoneMuteNoCallerCheck(getCurrentUserId()); // will also update the mic mute cache
1961         setMicMuteFromSwitchInput();
1962 
1963         // Restore vibrator info
1964         updateVibratorInfos();
1965     }
1966 
onRemoveAssistantServiceUids(int[] uids)1967     private void onRemoveAssistantServiceUids(int[] uids) {
1968         synchronized (mSettingsLock) {
1969             removeAssistantServiceUidsLocked(uids);
1970         }
1971     }
1972 
1973     @GuardedBy("mSettingsLock")
removeAssistantServiceUidsLocked(int[] uids)1974     private void removeAssistantServiceUidsLocked(int[] uids) {
1975         boolean changed = false;
1976         for (int index = 0; index < uids.length; index++) {
1977             if (!mAssistantUids.remove(uids[index])) {
1978                 Slog.e(TAG, TextUtils.formatSimple(
1979                         "Cannot remove assistant service, uid(%d) not present", uids[index]));
1980                 continue;
1981             }
1982             changed = true;
1983         }
1984         if (changed) {
1985             updateAssistantServicesUidsLocked();
1986         }
1987     }
1988 
onAddAssistantServiceUids(int[] uids)1989     private void onAddAssistantServiceUids(int[] uids) {
1990         synchronized (mSettingsLock) {
1991             addAssistantServiceUidsLocked(uids);
1992         }
1993     }
1994 
1995     @GuardedBy("mSettingsLock")
addAssistantServiceUidsLocked(int[] uids)1996     private void addAssistantServiceUidsLocked(int[] uids) {
1997         boolean changed = false;
1998         for (int index = 0; index < uids.length; index++) {
1999             if (uids[index] == INVALID_UID) {
2000                 continue;
2001             }
2002             if (!mAssistantUids.add(uids[index])) {
2003                 Slog.e(TAG, TextUtils.formatSimple(
2004                                 "Cannot add assistant service, uid(%d) already present",
2005                                 uids[index]));
2006                 continue;
2007             }
2008             changed = true;
2009         }
2010         if (changed) {
2011             updateAssistantServicesUidsLocked();
2012         }
2013     }
2014 
2015     @GuardedBy("mSettingsLock")
resetAssistantServicesUidsLocked()2016     private void resetAssistantServicesUidsLocked() {
2017         mAssistantUids.clear();
2018         updateAssistantUIdLocked(/* forceUpdate= */ true);
2019     }
2020 
2021     @GuardedBy("mSettingsLock")
updateAssistantServicesUidsLocked()2022     private void updateAssistantServicesUidsLocked() {
2023         int[] assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray();
2024         AudioSystem.setAssistantServicesUids(assistantUids);
2025     }
2026 
updateActiveAssistantServiceUids()2027     private void updateActiveAssistantServiceUids() {
2028         int [] activeAssistantServiceUids;
2029         synchronized (mSettingsLock) {
2030             activeAssistantServiceUids = mActiveAssistantServiceUids;
2031         }
2032         AudioSystem.setActiveAssistantServicesUids(activeAssistantServiceUids);
2033     }
2034 
onReinitVolumes(@onNull String caller)2035     private void onReinitVolumes(@NonNull String caller) {
2036         final int numStreamTypes = AudioSystem.getNumStreamTypes();
2037         // keep track of any error during stream volume initialization
2038         int status = AudioSystem.AUDIO_STATUS_OK;
2039         for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
2040             VolumeStreamState streamState = mStreamStates[streamType];
2041             final int res = AudioSystem.initStreamVolume(
2042                     streamType, streamState.mIndexMin / 10, streamState.mIndexMax / 10);
2043             if (res != AudioSystem.AUDIO_STATUS_OK) {
2044                 status = res;
2045                 Log.e(TAG, "Failed to initStreamVolume (" + res + ") for stream " + streamType);
2046                 // stream volume initialization failed, no need to try the others, it will be
2047                 // attempted again when MSG_REINIT_VOLUMES is handled
2048                 break;
2049             }
2050             streamState.applyAllVolumes();
2051         }
2052 
2053         // did it work? check based on status
2054         if (status != AudioSystem.AUDIO_STATUS_OK) {
2055             sLifecycleLogger.enqueue(new EventLogger.StringEvent(
2056                     caller + ": initStreamVolume failed with " + status + " will retry")
2057                     .printLog(ALOGE, TAG));
2058             sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0,
2059                     caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
2060             return;
2061         }
2062 
2063         // did it work? check based on min/max values of some basic streams
2064         if (!checkVolumeRangeInitialization(caller)) {
2065             return;
2066         }
2067 
2068         // success
2069         sLifecycleLogger.enqueue(new EventLogger.StringEvent(
2070                 caller + ": initStreamVolume succeeded").printLog(ALOGI, TAG));
2071     }
2072 
2073     /**
2074      * Check volume ranges were properly initialized
2075      * @return true if volume ranges were successfully initialized
2076      */
checkVolumeRangeInitialization(String caller)2077     private boolean checkVolumeRangeInitialization(String caller) {
2078         boolean success = true;
2079         final int[] basicStreams = { AudioSystem.STREAM_ALARM, AudioSystem.STREAM_RING,
2080                 AudioSystem.STREAM_MUSIC, AudioSystem.STREAM_VOICE_CALL,
2081                 AudioSystem.STREAM_ACCESSIBILITY };
2082         for (int streamType : basicStreams) {
2083             final AudioAttributes aa = new AudioAttributes.Builder()
2084                     .setInternalLegacyStreamType(streamType).build();
2085             if (AudioSystem.getMaxVolumeIndexForAttributes(aa) < 0
2086                     || AudioSystem.getMinVolumeIndexForAttributes(aa) < 0) {
2087                 success = false;
2088                 break;
2089             }
2090         }
2091         if (!success) {
2092             sLifecycleLogger.enqueue(new EventLogger.StringEvent(
2093                     caller + ": initStreamVolume succeeded but invalid mix/max levels, will retry")
2094                     .printLog(ALOGW, TAG));
2095             sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0,
2096                     caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
2097         }
2098         return success;
2099     }
2100 
onDispatchAudioServerStateChange(boolean state)2101     private void onDispatchAudioServerStateChange(boolean state) {
2102         synchronized (mAudioServerStateListeners) {
2103             for (AsdProxy asdp : mAudioServerStateListeners.values()) {
2104                 try {
2105                     asdp.callback().dispatchAudioServerStateChange(state);
2106                 } catch (RemoteException e) {
2107                     Log.w(TAG, "Could not call dispatchAudioServerStateChange()", e);
2108                 }
2109             }
2110         }
2111     }
2112 
createAudioSystemThread()2113     private void createAudioSystemThread() {
2114         mAudioSystemThread = new AudioSystemThread();
2115         mAudioSystemThread.start();
2116         waitForAudioHandlerCreation();
2117     }
2118 
2119     /** Waits for the volume handler to be created by the other thread. */
waitForAudioHandlerCreation()2120     private void waitForAudioHandlerCreation() {
2121         synchronized(this) {
2122             while (mAudioHandler == null) {
2123                 try {
2124                     // Wait for mAudioHandler to be set by the other thread
2125                     wait();
2126                 } catch (InterruptedException e) {
2127                     Log.e(TAG, "Interrupted while waiting on volume handler.");
2128                 }
2129             }
2130         }
2131     }
2132 
2133     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
2134     /**
2135      * @see AudioManager#setSupportedSystemUsages(int[])
2136      */
setSupportedSystemUsages(@onNull @ttributeSystemUsage int[] systemUsages)2137     public void setSupportedSystemUsages(@NonNull @AttributeSystemUsage int[] systemUsages) {
2138         super.setSupportedSystemUsages_enforcePermission();
2139 
2140         verifySystemUsages(systemUsages);
2141 
2142         synchronized (mSupportedSystemUsagesLock) {
2143             AudioSystem.setSupportedSystemUsages(systemUsages);
2144             mSupportedSystemUsages = systemUsages;
2145         }
2146     }
2147 
2148     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
2149     /**
2150      * @see AudioManager#getSupportedSystemUsages()
2151      */
getSupportedSystemUsages()2152     public @NonNull @AttributeSystemUsage int[] getSupportedSystemUsages() {
2153         super.getSupportedSystemUsages_enforcePermission();
2154 
2155         synchronized (mSupportedSystemUsagesLock) {
2156             return Arrays.copyOf(mSupportedSystemUsages, mSupportedSystemUsages.length);
2157         }
2158     }
2159 
verifySystemUsages(@onNull int[] systemUsages)2160     private void verifySystemUsages(@NonNull int[] systemUsages) {
2161         for (int i = 0; i < systemUsages.length; i++) {
2162             if (!AudioAttributes.isSystemUsage(systemUsages[i])) {
2163                 throw new IllegalArgumentException("Non-system usage provided: " + systemUsages[i]);
2164             }
2165         }
2166     }
2167 
2168     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
2169     /**
2170      * @return the {@link android.media.audiopolicy.AudioProductStrategy} discovered from the
2171      * platform configuration file.
2172      */
2173     @NonNull
getAudioProductStrategies()2174     public List<AudioProductStrategy> getAudioProductStrategies() {
2175         // verify permissions
2176         super.getAudioProductStrategies_enforcePermission();
2177 
2178         return AudioProductStrategy.getAudioProductStrategies();
2179     }
2180 
2181     @android.annotation.EnforcePermission(anyOf = {
2182             MODIFY_AUDIO_SETTINGS_PRIVILEGED, MODIFY_AUDIO_ROUTING })
2183     /**
2184      * @return the List of {@link android.media.audiopolicy.AudioVolumeGroup} discovered from the
2185      * platform configuration file.
2186      */
2187     @NonNull
getAudioVolumeGroups()2188     public List<AudioVolumeGroup> getAudioVolumeGroups() {
2189         // verify permissions
2190         super.getAudioVolumeGroups_enforcePermission();
2191 
2192         return mAudioVolumeGroupHelper.getAudioVolumeGroups();
2193     }
2194 
checkAllAliasStreamVolumes()2195     private void checkAllAliasStreamVolumes() {
2196         synchronized (mSettingsLock) {
2197             synchronized (VolumeStreamState.class) {
2198                 int numStreamTypes = AudioSystem.getNumStreamTypes();
2199                 for (int streamType = 0; streamType < numStreamTypes; streamType++) {
2200                     mStreamStates[streamType]
2201                             .setAllIndexes(mStreamStates[mStreamVolumeAlias[streamType]], TAG);
2202                     // apply stream volume
2203                     if (!mStreamStates[streamType].mIsMuted) {
2204                         mStreamStates[streamType].applyAllVolumes();
2205                     }
2206                 }
2207             }
2208         }
2209     }
2210 
2211 
2212     /**
2213      * Called from AudioDeviceBroker when DEVICE_OUT_HDMI is connected or disconnected.
2214      */
postCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)2215     /*package*/ void postCheckVolumeCecOnHdmiConnection(
2216             @AudioService.ConnectionState  int state, String caller) {
2217         sendMsg(mAudioHandler, MSG_HDMI_VOLUME_CHECK, SENDMSG_REPLACE,
2218                 state /*arg1*/, 0 /*arg2 ignored*/, caller /*obj*/, 0 /*delay*/);
2219     }
2220 
onCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)2221     private void onCheckVolumeCecOnHdmiConnection(
2222             @AudioService.ConnectionState int state, String caller) {
2223         if (state == AudioService.CONNECTION_STATE_CONNECTED) {
2224             // DEVICE_OUT_HDMI is now connected
2225             if (mSoundDoseHelper.safeDevicesContains(AudioSystem.DEVICE_OUT_HDMI)) {
2226                 mSoundDoseHelper.scheduleMusicActiveCheck();
2227             }
2228 
2229             if (isPlatformTelevision()) {
2230                 synchronized (mHdmiClientLock) {
2231                     if (mHdmiManager != null && mHdmiPlaybackClient != null) {
2232                         updateHdmiCecSinkLocked(
2233                                 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI));
2234                     }
2235                 }
2236             }
2237             sendEnabledSurroundFormats(mContentResolver, true);
2238         } else {
2239             // DEVICE_OUT_HDMI disconnected
2240             if (isPlatformTelevision()) {
2241                 synchronized (mHdmiClientLock) {
2242                     if (mHdmiManager != null) {
2243                         updateHdmiCecSinkLocked(
2244                                 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI));
2245                     }
2246                 }
2247             }
2248         }
2249     }
2250 
2251     /**
2252      * Asynchronously update volume states for the given device.
2253      *
2254      * @param device a single audio device, ensure that this is not a devices bitmask
2255      * @param caller caller of this method
2256      */
postUpdateVolumeStatesForAudioDevice(int device, String caller)2257     private void postUpdateVolumeStatesForAudioDevice(int device, String caller) {
2258         sendMsg(mAudioHandler,
2259                 MSG_UPDATE_VOLUME_STATES_FOR_DEVICE,
2260                 SENDMSG_QUEUE, device /*arg1*/, 0 /*arg2*/, caller /*obj*/,
2261                 0 /*delay*/);
2262     }
2263 
2264     /**
2265      * Update volume states for the given device.
2266      *
2267      * This will initialize the volume index if no volume index is available.
2268      * If the device is the currently routed device, fixed/full volume policies will be applied.
2269      *
2270      * @param device a single audio device, ensure that this is not a devices bitmask
2271      * @param caller caller of this method
2272      */
onUpdateVolumeStatesForAudioDevice(int device, String caller)2273     private void onUpdateVolumeStatesForAudioDevice(int device, String caller) {
2274         final int numStreamTypes = AudioSystem.getNumStreamTypes();
2275         synchronized (mSettingsLock) {
2276             synchronized (VolumeStreamState.class) {
2277                 for (int streamType = 0; streamType < numStreamTypes; streamType++) {
2278                     updateVolumeStates(device, streamType, caller);
2279                 }
2280             }
2281         }
2282     }
2283 
2284     /**
2285      * Update volume states for the given device and given stream.
2286      *
2287      * This will initialize the volume index if no volume index is available.
2288      * If the device is the currently routed device, fixed/full volume policies will be applied.
2289      *
2290      * @param device a single audio device, ensure that this is not a devices bitmask
2291      * @param streamType streamType to be updated
2292      * @param caller caller of this method
2293      */
updateVolumeStates(int device, int streamType, String caller)2294     private void updateVolumeStates(int device, int streamType, String caller) {
2295         // Handle device volume aliasing of SPEAKER_SAFE.
2296         if (device == AudioSystem.DEVICE_OUT_SPEAKER_SAFE) {
2297             device = AudioSystem.DEVICE_OUT_SPEAKER;
2298         }
2299         if (!mStreamStates[streamType].hasIndexForDevice(device)) {
2300             // set the default value, if device is affected by a full/fix/abs volume rule, it
2301             // will taken into account in checkFixedVolumeDevices()
2302             mStreamStates[streamType].setIndex(
2303                     mStreamStates[mStreamVolumeAlias[streamType]]
2304                             .getIndex(AudioSystem.DEVICE_OUT_DEFAULT),
2305                     device, caller, true /*hasModifyAudioSettings*/);
2306         }
2307 
2308         // Check if device to be updated is routed for the given audio stream
2309         // This may include devices such as SPEAKER_SAFE.
2310         List<AudioDeviceAttributes> devicesForAttributes = getDevicesForAttributesInt(
2311                 new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build(),
2312                 true /* forVolume */);
2313         for (AudioDeviceAttributes deviceAttributes : devicesForAttributes) {
2314             if (deviceAttributes.getType() == AudioDeviceInfo.convertInternalDeviceToDeviceType(
2315                     device)) {
2316                 mStreamStates[streamType].checkFixedVolumeDevices();
2317 
2318                 // Unmute streams if required and device is full volume
2319                 if (isStreamMute(streamType) && mFullVolumeDevices.contains(device)) {
2320                     mStreamStates[streamType].mute(false, "updateVolumeStates(" + caller);
2321                 }
2322             }
2323         }
2324     }
2325 
checkAllFixedVolumeDevices()2326     private void checkAllFixedVolumeDevices()
2327     {
2328         int numStreamTypes = AudioSystem.getNumStreamTypes();
2329         for (int streamType = 0; streamType < numStreamTypes; streamType++) {
2330             mStreamStates[streamType].checkFixedVolumeDevices();
2331         }
2332     }
2333 
checkAllFixedVolumeDevices(int streamType)2334     private void checkAllFixedVolumeDevices(int streamType) {
2335         mStreamStates[streamType].checkFixedVolumeDevices();
2336     }
2337 
checkMuteAffectedStreams()2338     private void checkMuteAffectedStreams() {
2339         // any stream with a min level > 0 is not muteable by definition
2340         // STREAM_VOICE_CALL and STREAM_BLUETOOTH_SCO can be muted by applications
2341         // that has the the MODIFY_PHONE_STATE permission.
2342         for (int i = 0; i < mStreamStates.length; i++) {
2343             final VolumeStreamState vss = mStreamStates[i];
2344             if (vss.mIndexMin > 0 &&
2345                 (vss.mStreamType != AudioSystem.STREAM_VOICE_CALL &&
2346                 vss.mStreamType != AudioSystem.STREAM_BLUETOOTH_SCO)) {
2347                 mMuteAffectedStreams &= ~(1 << vss.mStreamType);
2348             }
2349         }
2350         updateUserMutableStreams();
2351     }
2352 
createStreamStates()2353     private void createStreamStates() {
2354         int numStreamTypes = AudioSystem.getNumStreamTypes();
2355         VolumeStreamState[] streams = mStreamStates = new VolumeStreamState[numStreamTypes];
2356 
2357         for (int i = 0; i < numStreamTypes; i++) {
2358             streams[i] =
2359                     new VolumeStreamState(System.VOLUME_SETTINGS_INT[mStreamVolumeAlias[i]], i);
2360         }
2361 
2362         checkAllFixedVolumeDevices();
2363         checkAllAliasStreamVolumes();
2364         checkMuteAffectedStreams();
2365         updateDefaultVolumes();
2366     }
2367 
2368     /**
2369      * Update default indexes from aliased streams. Must be called after mStreamStates is created
2370      * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for default
2371      * index. Need to make default index configurable and independent of streams.
2372      * Fallback on music stream for default initialization to take benefit of property based default
2373      * initialization.
2374      * For other volume groups not linked to any streams, default music stream index is considered.
2375      */
updateDefaultVolumes()2376     private void updateDefaultVolumes() {
2377         for (int stream = 0; stream < mStreamStates.length; stream++) {
2378             int streamVolumeAlias = mStreamVolumeAlias[stream];
2379             if (mUseVolumeGroupAliases) {
2380                 if (AudioSystem.DEFAULT_STREAM_VOLUME[stream] != UNSET_INDEX) {
2381                     // Already initialized through default property based mecanism.
2382                     continue;
2383                 }
2384                 streamVolumeAlias = AudioSystem.STREAM_MUSIC;
2385                 int defaultAliasVolume = getUiDefaultRescaledIndex(streamVolumeAlias, stream);
2386                 if ((defaultAliasVolume >= MIN_STREAM_VOLUME[stream])
2387                         && (defaultAliasVolume <= MAX_STREAM_VOLUME[stream])) {
2388                     AudioSystem.DEFAULT_STREAM_VOLUME[stream] = defaultAliasVolume;
2389                     continue;
2390                 }
2391             }
2392             if (stream != streamVolumeAlias) {
2393                 AudioSystem.DEFAULT_STREAM_VOLUME[stream] =
2394                         getUiDefaultRescaledIndex(streamVolumeAlias, stream);
2395             }
2396         }
2397     }
2398 
getUiDefaultRescaledIndex(int srcStream, int dstStream)2399     private int getUiDefaultRescaledIndex(int srcStream, int dstStream) {
2400         return (rescaleIndex(AudioSystem.DEFAULT_STREAM_VOLUME[srcStream] * 10,
2401                 srcStream, dstStream) + 5) / 10;
2402     }
2403 
dumpStreamStates(PrintWriter pw)2404     private void dumpStreamStates(PrintWriter pw) {
2405         pw.println("\nStream volumes (device: index)");
2406         int numStreamTypes = AudioSystem.getNumStreamTypes();
2407         for (int i = 0; i < numStreamTypes; i++) {
2408             StringBuilder alias = new StringBuilder();
2409             if (mStreamVolumeAlias[i] != i) {
2410                 alias.append(" (aliased to: ")
2411                         .append(AudioSystem.STREAM_NAMES[mStreamVolumeAlias[i]])
2412                         .append(")");
2413             }
2414             pw.println("- " + AudioSystem.STREAM_NAMES[i] + alias + ":");
2415             mStreamStates[i].dump(pw);
2416             pw.println("");
2417         }
2418         pw.print("\n- mute affected streams = 0x");
2419         pw.println(Integer.toHexString(mMuteAffectedStreams));
2420         pw.print("\n- user mutable streams = 0x");
2421         pw.println(Integer.toHexString(mUserMutableStreams));
2422     }
2423 
updateStreamVolumeAlias(boolean updateVolumes, String caller)2424     private void updateStreamVolumeAlias(boolean updateVolumes, String caller) {
2425         int dtmfStreamAlias;
2426         final int a11yStreamAlias = sIndependentA11yVolume ?
2427                 AudioSystem.STREAM_ACCESSIBILITY : AudioSystem.STREAM_MUSIC;
2428         final int assistantStreamAlias = mContext.getResources().getBoolean(
2429                 com.android.internal.R.bool.config_useAssistantVolume) ?
2430                 AudioSystem.STREAM_ASSISTANT : AudioSystem.STREAM_MUSIC;
2431 
2432         if (mIsSingleVolume) {
2433             mStreamVolumeAlias = STREAM_VOLUME_ALIAS_TELEVISION.clone();
2434             dtmfStreamAlias = AudioSystem.STREAM_MUSIC;
2435         } else if (mUseVolumeGroupAliases) {
2436             mStreamVolumeAlias = STREAM_VOLUME_ALIAS_NONE.clone();
2437             dtmfStreamAlias = AudioSystem.STREAM_DTMF;
2438         } else {
2439             switch (mPlatformType) {
2440                 case AudioSystem.PLATFORM_VOICE:
2441                     mStreamVolumeAlias = STREAM_VOLUME_ALIAS_VOICE.clone();
2442                     dtmfStreamAlias = AudioSystem.STREAM_RING;
2443                     break;
2444                 default:
2445                     mStreamVolumeAlias = STREAM_VOLUME_ALIAS_DEFAULT.clone();
2446                     dtmfStreamAlias = AudioSystem.STREAM_MUSIC;
2447             }
2448             if (!mNotifAliasRing) {
2449                 mStreamVolumeAlias[AudioSystem.STREAM_NOTIFICATION] =
2450                         AudioSystem.STREAM_NOTIFICATION;
2451             }
2452         }
2453 
2454         if (mIsSingleVolume) {
2455             mRingerModeAffectedStreams = 0;
2456         } else {
2457             if (isInCommunication()) {
2458                 dtmfStreamAlias = AudioSystem.STREAM_VOICE_CALL;
2459                 mRingerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF);
2460             } else {
2461                 mRingerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF);
2462             }
2463         }
2464 
2465         mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias;
2466         mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY] = a11yStreamAlias;
2467         mStreamVolumeAlias[AudioSystem.STREAM_ASSISTANT] = assistantStreamAlias;
2468 
2469         if (updateVolumes && mStreamStates != null) {
2470             updateDefaultVolumes();
2471 
2472             synchronized (mSettingsLock) {
2473                 synchronized (VolumeStreamState.class) {
2474                     mStreamStates[AudioSystem.STREAM_DTMF]
2475                             .setAllIndexes(mStreamStates[dtmfStreamAlias], caller);
2476                     mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setSettingName(
2477                             System.VOLUME_SETTINGS_INT[a11yStreamAlias]);
2478                     mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setAllIndexes(
2479                             mStreamStates[a11yStreamAlias], caller);
2480                 }
2481             }
2482             if (sIndependentA11yVolume) {
2483                 // restore the a11y values from the settings
2484                 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].readSettings();
2485             }
2486 
2487             // apply stream mute states according to new value of mRingerModeAffectedStreams
2488             setRingerModeInt(getRingerModeInternal(), false);
2489             sendMsg(mAudioHandler,
2490                     MSG_SET_ALL_VOLUMES,
2491                     SENDMSG_QUEUE,
2492                     0,
2493                     0,
2494                     mStreamStates[AudioSystem.STREAM_DTMF], 0);
2495             sendMsg(mAudioHandler,
2496                     MSG_SET_ALL_VOLUMES,
2497                     SENDMSG_QUEUE,
2498                     0,
2499                     0,
2500                     mStreamStates[AudioSystem.STREAM_ACCESSIBILITY], 0);
2501         }
2502         dispatchStreamAliasingUpdate();
2503     }
2504 
readDockAudioSettings(ContentResolver cr)2505     private void readDockAudioSettings(ContentResolver cr)
2506     {
2507         mDockAudioMediaEnabled = mSettings.getGlobalInt(
2508                                         cr, Settings.Global.DOCK_AUDIO_MEDIA_ENABLED, 0) == 1;
2509 
2510         sendMsg(mAudioHandler,
2511                 MSG_SET_FORCE_USE,
2512                 SENDMSG_QUEUE,
2513                 AudioSystem.FOR_DOCK,
2514                 mDockAudioMediaEnabled ?
2515                         AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE,
2516                 new String("readDockAudioSettings"),
2517                 0);
2518 
2519     }
2520 
2521 
updateMasterMono(ContentResolver cr)2522     private void updateMasterMono(ContentResolver cr)
2523     {
2524         final boolean masterMono = mSettings.getSystemIntForUser(
2525                 cr, System.MASTER_MONO, 0 /* default */, UserHandle.USER_CURRENT) == 1;
2526         if (DEBUG_VOL) {
2527             Log.d(TAG, String.format("Master mono %b", masterMono));
2528         }
2529         AudioSystem.setMasterMono(masterMono);
2530     }
2531 
updateMasterBalance(ContentResolver cr)2532     private void updateMasterBalance(ContentResolver cr) {
2533         final float masterBalance = System.getFloatForUser(
2534                 cr, System.MASTER_BALANCE, 0.f /* default */, UserHandle.USER_CURRENT);
2535         if (DEBUG_VOL) {
2536             Log.d(TAG, String.format("Master balance %f", masterBalance));
2537         }
2538         if (AudioSystem.setMasterBalance(masterBalance) != 0) {
2539             Log.e(TAG, String.format("setMasterBalance failed for %f", masterBalance));
2540         }
2541     }
2542 
sendEncodedSurroundMode(ContentResolver cr, String eventSource)2543     private void sendEncodedSurroundMode(ContentResolver cr, String eventSource)
2544     {
2545         final int encodedSurroundMode = mSettings.getGlobalInt(
2546                 cr, Settings.Global.ENCODED_SURROUND_OUTPUT,
2547                 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
2548         sendEncodedSurroundMode(encodedSurroundMode, eventSource);
2549     }
2550 
sendEncodedSurroundMode(int encodedSurroundMode, String eventSource)2551     private void sendEncodedSurroundMode(int encodedSurroundMode, String eventSource)
2552     {
2553         // initialize to guaranteed bad value
2554         int forceSetting = AudioSystem.NUM_FORCE_CONFIG;
2555         switch (encodedSurroundMode) {
2556             case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO:
2557                 forceSetting = AudioSystem.FORCE_NONE;
2558                 break;
2559             case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER:
2560                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_NEVER;
2561                 break;
2562             case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS:
2563                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_ALWAYS;
2564                 break;
2565             case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL:
2566                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_MANUAL;
2567                 break;
2568             default:
2569                 Log.e(TAG, "updateSurroundSoundSettings: illegal value "
2570                         + encodedSurroundMode);
2571                 break;
2572         }
2573         if (forceSetting != AudioSystem.NUM_FORCE_CONFIG) {
2574             mDeviceBroker.setForceUse_Async(AudioSystem.FOR_ENCODED_SURROUND, forceSetting,
2575                     eventSource);
2576         }
2577     }
2578 
2579     @Override // Binder call
onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)2580     public void onShellCommand(FileDescriptor in, FileDescriptor out,
2581             FileDescriptor err, String[] args, ShellCallback callback,
2582             ResultReceiver resultReceiver) {
2583         if (mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_AUDIO_POLICY)
2584                 != PackageManager.PERMISSION_GRANTED) {
2585             throw new SecurityException("Missing MANAGE_AUDIO_POLICY permission");
2586         }
2587         new AudioManagerShellCommand(AudioService.this).exec(this, in, out, err,
2588                 args, callback, resultReceiver);
2589     }
2590 
2591     /** @see AudioManager#getSurroundFormats() */
2592     @Override
getSurroundFormats()2593     public Map<Integer, Boolean> getSurroundFormats() {
2594         Map<Integer, Boolean> surroundFormats = new HashMap<>();
2595         int status = AudioSystem.getSurroundFormats(surroundFormats);
2596         if (status != AudioManager.SUCCESS) {
2597             // fail and bail!
2598             Log.e(TAG, "getSurroundFormats failed:" + status);
2599             return new HashMap<>(); // Always return a map.
2600         }
2601         return surroundFormats;
2602     }
2603 
2604     /** @see AudioManager#getReportedSurroundFormats() */
2605     @Override
getReportedSurroundFormats()2606     public List<Integer> getReportedSurroundFormats() {
2607         ArrayList<Integer> reportedSurroundFormats = new ArrayList<>();
2608         int status = AudioSystem.getReportedSurroundFormats(reportedSurroundFormats);
2609         if (status != AudioManager.SUCCESS) {
2610             // fail and bail!
2611             Log.e(TAG, "getReportedSurroundFormats failed:" + status);
2612             return new ArrayList<>(); // Always return a list.
2613         }
2614         return reportedSurroundFormats;
2615     }
2616 
2617     /** @see AudioManager#isSurroundFormatEnabled(int) */
2618     @Override
isSurroundFormatEnabled(int audioFormat)2619     public boolean isSurroundFormatEnabled(int audioFormat) {
2620         if (!isSurroundFormat(audioFormat)) {
2621             Log.w(TAG, "audioFormat to enable is not a surround format.");
2622             return false;
2623         }
2624 
2625         final long token = Binder.clearCallingIdentity();
2626         try {
2627             synchronized (mSettingsLock) {
2628                 HashSet<Integer> enabledFormats = getEnabledFormats();
2629                 return enabledFormats.contains(audioFormat);
2630             }
2631         } finally {
2632             Binder.restoreCallingIdentity(token);
2633         }
2634     }
2635 
2636     /** @see AudioManager#setSurroundFormatEnabled(int, boolean) */
2637     @Override
setSurroundFormatEnabled(int audioFormat, boolean enabled)2638     public boolean setSurroundFormatEnabled(int audioFormat, boolean enabled) {
2639         if (!isSurroundFormat(audioFormat)) {
2640             Log.w(TAG, "audioFormat to enable is not a surround format.");
2641             return false;
2642         }
2643         if (mContext.checkCallingOrSelfPermission(WRITE_SETTINGS)
2644                 != PackageManager.PERMISSION_GRANTED) {
2645             throw new SecurityException("Missing WRITE_SETTINGS permission");
2646         }
2647 
2648         HashSet<Integer> enabledFormats = getEnabledFormats();
2649         if (enabled) {
2650             enabledFormats.add(audioFormat);
2651         } else {
2652             enabledFormats.remove(audioFormat);
2653         }
2654         final long token = Binder.clearCallingIdentity();
2655         try {
2656             synchronized (mSettingsLock) {
2657                 mSettings.putGlobalString(mContentResolver,
2658                         Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
2659                         TextUtils.join(",", enabledFormats));
2660             }
2661         } finally {
2662             Binder.restoreCallingIdentity(token);
2663         }
2664         return true;
2665     }
2666 
2667     @android.annotation.EnforcePermission(WRITE_SETTINGS)
2668     /** @see AudioManager#setEncodedSurroundMode(int) */
2669     @Override
setEncodedSurroundMode(@udioManager.EncodedSurroundOutputMode int mode)2670     public boolean setEncodedSurroundMode(@AudioManager.EncodedSurroundOutputMode int mode) {
2671         setEncodedSurroundMode_enforcePermission();
2672 
2673         final long token = Binder.clearCallingIdentity();
2674         try {
2675             synchronized (mSettingsLock) {
2676                 mSettings.putGlobalInt(mContentResolver,
2677                         Settings.Global.ENCODED_SURROUND_OUTPUT,
2678                         toEncodedSurroundSetting(mode));
2679             }
2680         } finally {
2681             Binder.restoreCallingIdentity(token);
2682         }
2683         return true;
2684     }
2685 
2686     /** @see AudioManager#getEncodedSurroundMode() */
2687     @Override
getEncodedSurroundMode(int targetSdkVersion)2688     public int getEncodedSurroundMode(int targetSdkVersion) {
2689         final long token = Binder.clearCallingIdentity();
2690         try {
2691             synchronized (mSettingsLock) {
2692                 int encodedSurroundSetting = mSettings.getGlobalInt(mContentResolver,
2693                         Settings.Global.ENCODED_SURROUND_OUTPUT,
2694                         AudioManager.ENCODED_SURROUND_OUTPUT_AUTO);
2695                 return toEncodedSurroundOutputMode(encodedSurroundSetting, targetSdkVersion);
2696             }
2697         } finally {
2698             Binder.restoreCallingIdentity(token);
2699         }
2700     }
2701 
2702     /** @return the formats that are enabled in global settings */
getEnabledFormats()2703     private HashSet<Integer> getEnabledFormats() {
2704         HashSet<Integer> formats = new HashSet<>();
2705         String enabledFormats = mSettings.getGlobalString(mContentResolver,
2706                 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
2707         if (enabledFormats != null) {
2708             try {
2709                 Arrays.stream(TextUtils.split(enabledFormats, ","))
2710                         .mapToInt(Integer::parseInt)
2711                         .forEach(formats::add);
2712             } catch (NumberFormatException e) {
2713                 Log.w(TAG, "ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS misformatted.", e);
2714             }
2715         }
2716         return formats;
2717     }
2718 
2719     @SuppressWarnings("AndroidFrameworkCompatChange")
2720     @AudioManager.EncodedSurroundOutputMode
toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion)2721     private int toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion) {
2722         if (targetSdkVersion <= Build.VERSION_CODES.S
2723                 && encodedSurroundSetting > Settings.Global.ENCODED_SURROUND_SC_MAX) {
2724             return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN;
2725         }
2726         switch (encodedSurroundSetting) {
2727             case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO:
2728                 return AudioManager.ENCODED_SURROUND_OUTPUT_AUTO;
2729             case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER:
2730                 return AudioManager.ENCODED_SURROUND_OUTPUT_NEVER;
2731             case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS:
2732                 return AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS;
2733             case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL:
2734                 return AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL;
2735             default:
2736                 return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN;
2737         }
2738     }
2739 
toEncodedSurroundSetting( @udioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode)2740     private int toEncodedSurroundSetting(
2741             @AudioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode) {
2742         switch (encodedSurroundOutputMode) {
2743             case AudioManager.ENCODED_SURROUND_OUTPUT_NEVER:
2744                 return Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER;
2745             case AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS:
2746                 return Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS;
2747             case AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL:
2748                 return Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL;
2749             default:
2750                 return Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO;
2751         }
2752     }
2753 
isSurroundFormat(int audioFormat)2754     private boolean isSurroundFormat(int audioFormat) {
2755         for (int sf : AudioFormat.SURROUND_SOUND_ENCODING) {
2756             if (sf == audioFormat) {
2757                 return true;
2758             }
2759         }
2760         return false;
2761     }
2762 
sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate)2763     private void sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate) {
2764         if (mEncodedSurroundMode != Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL) {
2765             // Manually enable surround formats only when the setting is in manual mode.
2766             return;
2767         }
2768         String enabledSurroundFormats = mSettings.getGlobalString(
2769                 cr, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
2770         if (enabledSurroundFormats == null) {
2771             // Never allow enabledSurroundFormats as a null, which could happen when
2772             // ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS is not appear in settings DB.
2773             enabledSurroundFormats = "";
2774         }
2775         if (!forceUpdate && TextUtils.equals(enabledSurroundFormats, mEnabledSurroundFormats)) {
2776             // Update enabled surround formats to AudioPolicyManager only when forceUpdate
2777             // is true or enabled surround formats changed.
2778             return;
2779         }
2780 
2781         mEnabledSurroundFormats = enabledSurroundFormats;
2782         String[] surroundFormats = TextUtils.split(enabledSurroundFormats, ",");
2783         ArrayList<Integer> formats = new ArrayList<>();
2784         for (String format : surroundFormats) {
2785             try {
2786                 int audioFormat = Integer.valueOf(format);
2787                 if (isSurroundFormat(audioFormat) && !formats.contains(audioFormat)) {
2788                     formats.add(audioFormat);
2789                 }
2790             } catch (Exception e) {
2791                 Log.e(TAG, "Invalid enabled surround format:" + format);
2792             }
2793         }
2794         // Set filtered surround formats to settings DB in case
2795         // there are invalid surround formats in original settings.
2796         mSettings.putGlobalString(mContext.getContentResolver(),
2797                 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
2798                 TextUtils.join(",", formats));
2799         sendMsg(mAudioHandler, MSG_ENABLE_SURROUND_FORMATS, SENDMSG_QUEUE, 0, 0, formats, 0);
2800     }
2801 
onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats)2802     private void onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats) {
2803         // Set surround format enabled accordingly.
2804         for (int surroundFormat : AudioFormat.SURROUND_SOUND_ENCODING) {
2805             boolean enabled = enabledSurroundFormats.contains(surroundFormat);
2806             int ret = AudioSystem.setSurroundFormatEnabled(surroundFormat, enabled);
2807             Log.i(TAG, "enable surround format:" + surroundFormat + " " + enabled + " " + ret);
2808         }
2809     }
2810 
2811     @GuardedBy("mSettingsLock")
updateAssistantUIdLocked(boolean forceUpdate)2812     private void updateAssistantUIdLocked(boolean forceUpdate) {
2813         int assistantUid = INVALID_UID;
2814         // Consider assistants in the following order of priority:
2815         // 1) apk in assistant role
2816         // 2) voice interaction service
2817         // 3) assistant service
2818 
2819         String packageName = "";
2820         if (mRoleObserver != null) {
2821             packageName = mRoleObserver.getAssistantRoleHolder();
2822         }
2823         if (TextUtils.isEmpty(packageName)) {
2824             String assistantName = mSettings.getSecureStringForUser(
2825                             mContentResolver,
2826                             Settings.Secure.VOICE_INTERACTION_SERVICE, UserHandle.USER_CURRENT);
2827             if (TextUtils.isEmpty(assistantName)) {
2828                 assistantName = mSettings.getSecureStringForUser(
2829                         mContentResolver,
2830                         Settings.Secure.ASSISTANT, UserHandle.USER_CURRENT);
2831             }
2832             if (!TextUtils.isEmpty(assistantName)) {
2833                 ComponentName componentName = ComponentName.unflattenFromString(assistantName);
2834                 if (componentName == null) {
2835                     Slog.w(TAG, "Invalid service name for "
2836                             + Settings.Secure.VOICE_INTERACTION_SERVICE + ": " + assistantName);
2837                     return;
2838                 }
2839                 packageName = componentName.getPackageName();
2840             }
2841         }
2842         if (!TextUtils.isEmpty(packageName)) {
2843             PackageManager pm = mContext.getPackageManager();
2844 
2845             if (pm.checkPermission(CAPTURE_AUDIO_HOTWORD, packageName)
2846                     == PackageManager.PERMISSION_GRANTED) {
2847                 try {
2848                     assistantUid = pm.getPackageUidAsUser(packageName, getCurrentUserId());
2849                 } catch (PackageManager.NameNotFoundException e) {
2850                     Log.e(TAG,
2851                             "updateAssistantUId() could not find UID for package: " + packageName);
2852                 }
2853             }
2854         }
2855         if ((mPrimaryAssistantUid != assistantUid) || forceUpdate) {
2856             mAssistantUids.remove(mPrimaryAssistantUid);
2857             mPrimaryAssistantUid = assistantUid;
2858             addAssistantServiceUidsLocked(new int[]{mPrimaryAssistantUid});
2859         }
2860     }
2861 
readPersistedSettings()2862     private void readPersistedSettings() {
2863         if (!mSystemServer.isPrivileged()) {
2864             return;
2865         }
2866         final ContentResolver cr = mContentResolver;
2867 
2868         int ringerModeFromSettings =
2869                 mSettings.getGlobalInt(
2870                         cr, Settings.Global.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
2871         int ringerMode = ringerModeFromSettings;
2872         // validity check in case the settings are restored from a device with incompatible
2873         // ringer modes
2874         if (!isValidRingerMode(ringerMode)) {
2875             ringerMode = AudioManager.RINGER_MODE_NORMAL;
2876         }
2877         if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) {
2878             ringerMode = AudioManager.RINGER_MODE_SILENT;
2879         }
2880         if (ringerMode != ringerModeFromSettings) {
2881             mSettings.putGlobalInt(cr, Settings.Global.MODE_RINGER, ringerMode);
2882         }
2883         if (mUseFixedVolume || mIsSingleVolume) {
2884             ringerMode = AudioManager.RINGER_MODE_NORMAL;
2885         }
2886         synchronized(mSettingsLock) {
2887             mRingerMode = ringerMode;
2888             if (mRingerModeExternal == -1) {
2889                 mRingerModeExternal = mRingerMode;
2890             }
2891 
2892             // System.VIBRATE_ON is not used any more but defaults for mVibrateSetting
2893             // are still needed while setVibrateSetting() and getVibrateSetting() are being
2894             // deprecated.
2895             mVibrateSetting = AudioSystem.getValueForVibrateSetting(0,
2896                                             AudioManager.VIBRATE_TYPE_NOTIFICATION,
2897                                             mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT
2898                                                             : AudioManager.VIBRATE_SETTING_OFF);
2899             mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting,
2900                                             AudioManager.VIBRATE_TYPE_RINGER,
2901                                             mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT
2902                                                             : AudioManager.VIBRATE_SETTING_OFF);
2903 
2904             updateRingerAndZenModeAffectedStreams();
2905             readDockAudioSettings(cr);
2906             sendEncodedSurroundMode(cr, "readPersistedSettings");
2907             sendEnabledSurroundFormats(cr, true);
2908             updateAssistantUIdLocked(/* forceUpdate= */ true);
2909             resetActiveAssistantUidsLocked();
2910             AudioSystem.setRttEnabled(mRttEnabled);
2911         }
2912 
2913         mMuteAffectedStreams = mSettings.getSystemIntForUser(cr,
2914                 System.MUTE_STREAMS_AFFECTED, AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED,
2915                 UserHandle.USER_CURRENT);
2916         updateUserMutableStreams();
2917 
2918         updateMasterMono(cr);
2919 
2920         updateMasterBalance(cr);
2921 
2922         // Each stream will read its own persisted settings
2923 
2924         // Broadcast the sticky intents
2925         broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, mRingerModeExternal);
2926         broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, mRingerMode);
2927 
2928         // Broadcast vibrate settings
2929         broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
2930         broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION);
2931 
2932         // Load settings for the volume controller
2933         mVolumeController.loadSettings(cr);
2934     }
2935 
updateUserMutableStreams()2936     private void updateUserMutableStreams() {
2937         mUserMutableStreams = mMuteAffectedStreams;
2938         mUserMutableStreams &= ~(1 << AudioSystem.STREAM_VOICE_CALL);
2939         mUserMutableStreams &= ~(1 << AudioSystem.STREAM_BLUETOOTH_SCO);
2940     }
2941 
2942     @GuardedBy("mSettingsLock")
resetActiveAssistantUidsLocked()2943     private void resetActiveAssistantUidsLocked() {
2944         mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS;
2945         updateActiveAssistantServiceUids();
2946     }
2947 
readUserRestrictions()2948     private void readUserRestrictions() {
2949         if (!mSystemServer.isPrivileged()) {
2950             return;
2951         }
2952         final int currentUser = getCurrentUserId();
2953 
2954         if (mUseFixedVolume) {
2955             AudioSystem.setMasterVolume(1.0f);
2956         }
2957 
2958         // Check the current user restriction.
2959         boolean masterMute =
2960                 mUserManagerInternal.getUserRestriction(currentUser,
2961                         UserManager.DISALLOW_UNMUTE_DEVICE)
2962                         || mUserManagerInternal.getUserRestriction(currentUser,
2963                         UserManager.DISALLOW_ADJUST_VOLUME);
2964         setMasterMuteInternalNoCallerCheck(
2965                 masterMute, /* flags =*/ 0, currentUser, "readUserRestrictions");
2966 
2967         mMicMuteFromRestrictions = mUserManagerInternal.getUserRestriction(
2968                 currentUser, UserManager.DISALLOW_UNMUTE_MICROPHONE);
2969         if (DEBUG_VOL) {
2970             Log.d(TAG, String.format("Mic mute %b, user=%d", mMicMuteFromRestrictions,
2971                     currentUser));
2972         }
2973         setMicrophoneMuteNoCallerCheck(currentUser);
2974     }
2975 
getIndexRange(int streamType)2976     private int getIndexRange(int streamType) {
2977         return (mStreamStates[streamType].getMaxIndex() - mStreamStates[streamType].getMinIndex());
2978     }
2979 
rescaleIndex(VolumeInfo volumeInfo, int dstStream)2980     private int rescaleIndex(VolumeInfo volumeInfo, int dstStream) {
2981         if (volumeInfo.getVolumeIndex() == VolumeInfo.INDEX_NOT_SET
2982                 || volumeInfo.getMinVolumeIndex() == VolumeInfo.INDEX_NOT_SET
2983                 || volumeInfo.getMaxVolumeIndex() == VolumeInfo.INDEX_NOT_SET) {
2984             Log.e(TAG, "rescaleIndex: volumeInfo has invalid index or range");
2985             return mStreamStates[dstStream].getMinIndex();
2986         }
2987         return rescaleIndex(volumeInfo.getVolumeIndex(),
2988                 volumeInfo.getMinVolumeIndex(), volumeInfo.getMaxVolumeIndex(),
2989                 mStreamStates[dstStream].getMinIndex(), mStreamStates[dstStream].getMaxIndex());
2990     }
2991 
rescaleIndex(int index, int srcStream, VolumeInfo dstVolumeInfo)2992     private int rescaleIndex(int index, int srcStream, VolumeInfo dstVolumeInfo) {
2993         int dstMin = dstVolumeInfo.getMinVolumeIndex();
2994         int dstMax = dstVolumeInfo.getMaxVolumeIndex();
2995         // Don't rescale index if the VolumeInfo is missing a min or max index
2996         if (dstMin == VolumeInfo.INDEX_NOT_SET || dstMax == VolumeInfo.INDEX_NOT_SET) {
2997             return index;
2998         }
2999         return rescaleIndex(index,
3000                 mStreamStates[srcStream].getMinIndex(), mStreamStates[srcStream].getMaxIndex(),
3001                 dstMin, dstMax);
3002     }
3003 
rescaleIndex(int index, int srcStream, int dstStream)3004     private int rescaleIndex(int index, int srcStream, int dstStream) {
3005         return rescaleIndex(index,
3006                 mStreamStates[srcStream].getMinIndex(), mStreamStates[srcStream].getMaxIndex(),
3007                 mStreamStates[dstStream].getMinIndex(), mStreamStates[dstStream].getMaxIndex());
3008     }
3009 
rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax)3010     private int rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax) {
3011         int srcRange = srcMax - srcMin;
3012         int dstRange = dstMax - dstMin;
3013         if (srcRange == 0) {
3014             Log.e(TAG, "rescaleIndex : index range should not be zero");
3015             return dstMin;
3016         }
3017         return dstMin + ((index - srcMin) * dstRange + srcRange / 2) / srcRange;
3018     }
3019 
rescaleStep(int step, int srcStream, int dstStream)3020     private int rescaleStep(int step, int srcStream, int dstStream) {
3021         int srcRange = getIndexRange(srcStream);
3022         int dstRange = getIndexRange(dstStream);
3023         if (srcRange == 0) {
3024             Log.e(TAG, "rescaleStep : index range should not be zero");
3025             return 0;
3026         }
3027 
3028         return ((step * dstRange + srcRange / 2) / srcRange);
3029     }
3030 
3031     ///////////////////////////////////////////////////////////////////////////
3032     // IPC methods
3033     ///////////////////////////////////////////////////////////////////////////
3034     /**
3035      * @see AudioManager#setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes)
3036      * @see AudioManager#setPreferredDevicesForStrategy(AudioProductStrategy,
3037      *                                                  List<AudioDeviceAttributes>)
3038      */
3039     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices)3040     public int setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices) {
3041         super.setPreferredDevicesForStrategy_enforcePermission();
3042         if (devices == null) {
3043             return AudioSystem.ERROR;
3044         }
3045 
3046         devices = retrieveBluetoothAddresses(devices);
3047 
3048         final String logString = String.format(
3049                 "setPreferredDevicesForStrategy u/pid:%d/%d strat:%d dev:%s",
3050                 Binder.getCallingUid(), Binder.getCallingPid(), strategy,
3051                 devices.stream().map(e -> e.toString()).collect(Collectors.joining(",")));
3052         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
3053         if (devices.stream().anyMatch(device ->
3054                 device.getRole() == AudioDeviceAttributes.ROLE_INPUT)) {
3055             Log.e(TAG, "Unsupported input routing in " + logString);
3056             return AudioSystem.ERROR;
3057         }
3058 
3059         final int status = mDeviceBroker.setPreferredDevicesForStrategySync(strategy, devices);
3060         if (status != AudioSystem.SUCCESS) {
3061             Log.e(TAG, String.format("Error %d in %s)", status, logString));
3062         }
3063 
3064         return status;
3065     }
3066 
3067     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
3068     /** @see AudioManager#removePreferredDeviceForStrategy(AudioProductStrategy) */
removePreferredDevicesForStrategy(int strategy)3069     public int removePreferredDevicesForStrategy(int strategy) {
3070         super.removePreferredDevicesForStrategy_enforcePermission();
3071 
3072         final String logString =
3073                 String.format("removePreferredDevicesForStrategy strat:%d", strategy);
3074         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
3075 
3076         final int status = mDeviceBroker.removePreferredDevicesForStrategySync(strategy);
3077         if (status != AudioSystem.SUCCESS && status != AudioSystem.BAD_VALUE) {
3078             Log.e(TAG, String.format("Error %d in %s)", status, logString));
3079         }
3080         return status;
3081     }
3082 
3083     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
3084     /**
3085      * @see AudioManager#getPreferredDeviceForStrategy(AudioProductStrategy)
3086      * @see AudioManager#getPreferredDevicesForStrategy(AudioProductStrategy)
3087      */
getPreferredDevicesForStrategy(int strategy)3088     public List<AudioDeviceAttributes> getPreferredDevicesForStrategy(int strategy) {
3089         super.getPreferredDevicesForStrategy_enforcePermission();
3090 
3091         List<AudioDeviceAttributes> devices = new ArrayList<>();
3092         int status = AudioSystem.SUCCESS;
3093         final long identity = Binder.clearCallingIdentity();
3094         try {
3095             status = AudioSystem.getDevicesForRoleAndStrategy(
3096                     strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
3097         } finally {
3098             Binder.restoreCallingIdentity(identity);
3099         }
3100         if (status != AudioSystem.SUCCESS) {
3101             Log.e(TAG, String.format("Error %d in getPreferredDeviceForStrategy(%d)",
3102                     status, strategy));
3103             return new ArrayList<AudioDeviceAttributes>();
3104         } else {
3105             return anonymizeAudioDeviceAttributesList(devices);
3106         }
3107     }
3108 
3109     /**
3110      * @see AudioManager#setDeviceAsNonDefaultForStrategy(AudioProductStrategy,
3111      *                                                    AudioDeviceAttributes)
3112      * @see AudioManager#setDeviceAsNonDefaultForStrategy(AudioProductStrategy,
3113      *                                                     List<AudioDeviceAttributes>)
3114      */
3115     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
setDeviceAsNonDefaultForStrategy(int strategy, @NonNull AudioDeviceAttributes device)3116     public int setDeviceAsNonDefaultForStrategy(int strategy,
3117                                                 @NonNull AudioDeviceAttributes device) {
3118         super.setDeviceAsNonDefaultForStrategy_enforcePermission();
3119         Objects.requireNonNull(device);
3120 
3121         device = retrieveBluetoothAddress(device);
3122 
3123         final String logString = String.format(
3124                 "setDeviceAsNonDefaultForStrategy u/pid:%d/%d strat:%d dev:%s",
3125                 Binder.getCallingUid(), Binder.getCallingPid(), strategy, device.toString());
3126         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
3127         if (device.getRole() == AudioDeviceAttributes.ROLE_INPUT) {
3128             Log.e(TAG, "Unsupported input routing in " + logString);
3129             return AudioSystem.ERROR;
3130         }
3131 
3132         final int status = mDeviceBroker.setDeviceAsNonDefaultForStrategySync(strategy, device);
3133         if (status != AudioSystem.SUCCESS) {
3134             Log.e(TAG, String.format("Error %d in %s)", status, logString));
3135         }
3136 
3137         return status;
3138     }
3139 
3140     /**
3141      * @see AudioManager#removeDeviceAsNonDefaultForStrategy(AudioProductStrategy,
3142      *                                                       AudioDeviceAttributes)
3143      */
3144     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
removeDeviceAsNonDefaultForStrategy(int strategy, AudioDeviceAttributes device)3145     public int removeDeviceAsNonDefaultForStrategy(int strategy,
3146                                                    AudioDeviceAttributes device) {
3147         super.removeDeviceAsNonDefaultForStrategy_enforcePermission();
3148         Objects.requireNonNull(device);
3149 
3150         device = retrieveBluetoothAddress(device);
3151 
3152         final String logString = String.format(
3153                 "removeDeviceAsNonDefaultForStrategy strat:%d dev:%s", strategy, device.toString());
3154         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
3155         if (device.getRole() == AudioDeviceAttributes.ROLE_INPUT) {
3156             Log.e(TAG, "Unsupported input routing in " + logString);
3157             return AudioSystem.ERROR;
3158         }
3159 
3160         final int status = mDeviceBroker.removeDeviceAsNonDefaultForStrategySync(strategy, device);
3161         if (status != AudioSystem.SUCCESS && status != AudioSystem.BAD_VALUE) {
3162             Log.e(TAG, String.format("Error %d in %s)", status, logString));
3163         }
3164         return status;
3165     }
3166 
3167     /**
3168      * @see AudioManager#getNonDefaultDevicesForStrategy(AudioProductStrategy)
3169      */
3170     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
getNonDefaultDevicesForStrategy(int strategy)3171     public List<AudioDeviceAttributes> getNonDefaultDevicesForStrategy(int strategy) {
3172         super.getNonDefaultDevicesForStrategy_enforcePermission();
3173         List<AudioDeviceAttributes> devices = new ArrayList<>();
3174         int status = AudioSystem.ERROR;
3175 
3176         try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
3177             status = AudioSystem.getDevicesForRoleAndStrategy(
3178                     strategy, AudioSystem.DEVICE_ROLE_DISABLED, devices);
3179         }
3180 
3181         if (status != AudioSystem.SUCCESS) {
3182             Log.e(TAG, String.format("Error %d in getNonDefaultDeviceForStrategy(%d)",
3183                     status, strategy));
3184             return new ArrayList<AudioDeviceAttributes>();
3185         } else {
3186             return anonymizeAudioDeviceAttributesList(devices);
3187         }
3188     }
3189 
3190     /** @see AudioManager#addOnPreferredDevicesForStrategyChangedListener(
3191      *               Executor, AudioManager.OnPreferredDevicesForStrategyChangedListener)
3192      */
registerStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)3193     public void registerStrategyPreferredDevicesDispatcher(
3194             @Nullable IStrategyPreferredDevicesDispatcher dispatcher) {
3195         if (dispatcher == null) {
3196             return;
3197         }
3198         enforceModifyAudioRoutingPermission();
3199         mDeviceBroker.registerStrategyPreferredDevicesDispatcher(
3200                 dispatcher, isBluetoothPrividged());
3201     }
3202 
3203     /** @see AudioManager#removeOnPreferredDevicesForStrategyChangedListener(
3204      *               AudioManager.OnPreferredDevicesForStrategyChangedListener)
3205      */
unregisterStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)3206     public void unregisterStrategyPreferredDevicesDispatcher(
3207             @Nullable IStrategyPreferredDevicesDispatcher dispatcher) {
3208         if (dispatcher == null) {
3209             return;
3210         }
3211         enforceModifyAudioRoutingPermission();
3212         mDeviceBroker.unregisterStrategyPreferredDevicesDispatcher(dispatcher);
3213     }
3214 
3215     /** @see AudioManager#addOnNonDefaultDevicesForStrategyChangedListener(
3216      *               Executor, AudioManager.OnNonDefaultDevicesForStrategyChangedListener)
3217      */
registerStrategyNonDefaultDevicesDispatcher( @ullable IStrategyNonDefaultDevicesDispatcher dispatcher)3218     public void registerStrategyNonDefaultDevicesDispatcher(
3219             @Nullable IStrategyNonDefaultDevicesDispatcher dispatcher) {
3220         if (dispatcher == null) {
3221             return;
3222         }
3223         enforceModifyAudioRoutingPermission();
3224         mDeviceBroker.registerStrategyNonDefaultDevicesDispatcher(
3225                 dispatcher, isBluetoothPrividged());
3226     }
3227 
3228     /** @see AudioManager#removeOnNonDefaultDevicesForStrategyChangedListener(
3229      *               AudioManager.OnNonDefaultDevicesForStrategyChangedListener)
3230      */
unregisterStrategyNonDefaultDevicesDispatcher( @ullable IStrategyNonDefaultDevicesDispatcher dispatcher)3231     public void unregisterStrategyNonDefaultDevicesDispatcher(
3232             @Nullable IStrategyNonDefaultDevicesDispatcher dispatcher) {
3233         if (dispatcher == null) {
3234             return;
3235         }
3236         enforceModifyAudioRoutingPermission();
3237         mDeviceBroker.unregisterStrategyNonDefaultDevicesDispatcher(dispatcher);
3238     }
3239 
3240     /**
3241      * @see AudioManager#setPreferredDevicesForCapturePreset(int, AudioDeviceAttributes)
3242      */
setPreferredDevicesForCapturePreset( int capturePreset, List<AudioDeviceAttributes> devices)3243     public int setPreferredDevicesForCapturePreset(
3244             int capturePreset, List<AudioDeviceAttributes> devices) {
3245         if (devices == null) {
3246             return AudioSystem.ERROR;
3247         }
3248         enforceModifyAudioRoutingPermission();
3249         final String logString = String.format(
3250                 "setPreferredDevicesForCapturePreset u/pid:%d/%d source:%d dev:%s",
3251                 Binder.getCallingUid(), Binder.getCallingPid(), capturePreset,
3252                 devices.stream().map(e -> e.toString()).collect(Collectors.joining(",")));
3253         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
3254         if (devices.stream().anyMatch(device ->
3255                 device.getRole() == AudioDeviceAttributes.ROLE_OUTPUT)) {
3256             Log.e(TAG, "Unsupported output routing in " + logString);
3257             return AudioSystem.ERROR;
3258         }
3259 
3260         devices = retrieveBluetoothAddresses(devices);
3261 
3262         final int status = mDeviceBroker.setPreferredDevicesForCapturePresetSync(
3263                 capturePreset, devices);
3264         if (status != AudioSystem.SUCCESS) {
3265             Log.e(TAG, String.format("Error %d in %s)", status, logString));
3266         }
3267 
3268         return status;
3269     }
3270 
3271     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
3272     /** @see AudioManager#clearPreferredDevicesForCapturePreset(int) */
clearPreferredDevicesForCapturePreset(int capturePreset)3273     public int clearPreferredDevicesForCapturePreset(int capturePreset) {
3274         super.clearPreferredDevicesForCapturePreset_enforcePermission();
3275 
3276         final String logString = String.format(
3277                 "removePreferredDeviceForCapturePreset source:%d", capturePreset);
3278         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
3279 
3280         final int status = mDeviceBroker.clearPreferredDevicesForCapturePresetSync(capturePreset);
3281         if (status != AudioSystem.SUCCESS && status != AudioSystem.BAD_VALUE) {
3282             Log.e(TAG, String.format("Error %d in %s", status, logString));
3283         }
3284         return status;
3285     }
3286 
3287     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
3288     /**
3289      * @see AudioManager#getPreferredDevicesForCapturePreset(int)
3290      */
getPreferredDevicesForCapturePreset(int capturePreset)3291     public List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int capturePreset) {
3292         super.getPreferredDevicesForCapturePreset_enforcePermission();
3293 
3294         List<AudioDeviceAttributes> devices = new ArrayList<>();
3295         int status = AudioSystem.SUCCESS;
3296         final long identity = Binder.clearCallingIdentity();
3297         try {
3298             status = AudioSystem.getDevicesForRoleAndCapturePreset(
3299                     capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
3300         } finally {
3301             Binder.restoreCallingIdentity(identity);
3302         }
3303         if (status != AudioSystem.SUCCESS) {
3304             Log.e(TAG, String.format("Error %d in getPreferredDeviceForCapturePreset(%d)",
3305                     status, capturePreset));
3306             return new ArrayList<AudioDeviceAttributes>();
3307         } else {
3308             return anonymizeAudioDeviceAttributesList(devices);
3309         }
3310     }
3311 
3312     /**
3313      * @see AudioManager#addOnPreferredDevicesForCapturePresetChangedListener(
3314      *              Executor, OnPreferredDevicesForCapturePresetChangedListener)
3315      */
registerCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)3316     public void registerCapturePresetDevicesRoleDispatcher(
3317             @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) {
3318         if (dispatcher == null) {
3319             return;
3320         }
3321         enforceModifyAudioRoutingPermission();
3322         mDeviceBroker.registerCapturePresetDevicesRoleDispatcher(
3323                 dispatcher, isBluetoothPrividged());
3324     }
3325 
3326     /**
3327      * @see AudioManager#removeOnPreferredDevicesForCapturePresetChangedListener(
3328      *              AudioManager.OnPreferredDevicesForCapturePresetChangedListener)
3329      */
unregisterCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)3330     public void unregisterCapturePresetDevicesRoleDispatcher(
3331             @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) {
3332         if (dispatcher == null) {
3333             return;
3334         }
3335         enforceModifyAudioRoutingPermission();
3336         mDeviceBroker.unregisterCapturePresetDevicesRoleDispatcher(dispatcher);
3337     }
3338 
3339     /** @see AudioManager#getDevicesForAttributes(AudioAttributes) */
getDevicesForAttributes( @onNull AudioAttributes attributes)3340     public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes(
3341             @NonNull AudioAttributes attributes) {
3342         enforceQueryStateOrModifyRoutingPermission();
3343 
3344         return new ArrayList<AudioDeviceAttributes>(anonymizeAudioDeviceAttributesList(
3345                 getDevicesForAttributesInt(attributes, false /* forVolume */)));
3346     }
3347 
3348     /** @see AudioManager#getAudioDevicesForAttributes(AudioAttributes)
3349      * This method is similar with AudioService#getDevicesForAttributes,
3350      * only it doesn't enforce permissions because it is used by an unprivileged public API
3351      * instead of the system API.
3352      */
getDevicesForAttributesUnprotected( @onNull AudioAttributes attributes)3353     public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesUnprotected(
3354             @NonNull AudioAttributes attributes) {
3355         return new ArrayList<AudioDeviceAttributes>(anonymizeAudioDeviceAttributesList(
3356                 getDevicesForAttributesInt(attributes, false /* forVolume */)));
3357     }
3358 
3359     /**
3360      * @see AudioManager#isMusicActive()
3361      * @param remotely true if query is for remote playback (cast), false for local playback.
3362      */
isMusicActive(boolean remotely)3363     public boolean isMusicActive(boolean remotely) {
3364         // no permission required
3365         final long token = Binder.clearCallingIdentity();
3366         try {
3367             if (remotely) {
3368                 return AudioSystem.isStreamActiveRemotely(AudioSystem.STREAM_MUSIC, 0);
3369             } else {
3370                 return AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0);
3371             }
3372         } finally {
3373             Binder.restoreCallingIdentity(token);
3374         }
3375     }
3376 
getDevicesForAttributesInt( @onNull AudioAttributes attributes, boolean forVolume)3377     protected @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesInt(
3378             @NonNull AudioAttributes attributes, boolean forVolume) {
3379         Objects.requireNonNull(attributes);
3380         return mAudioSystem.getDevicesForAttributes(attributes, forVolume);
3381     }
3382 
3383     /**
3384      * @see AudioManager#addOnDevicesForAttributesChangedListener(
3385      *      AudioAttributes, Executor, OnDevicesForAttributesChangedListener)
3386      */
addOnDevicesForAttributesChangedListener(AudioAttributes attributes, IDevicesForAttributesCallback callback)3387     public void addOnDevicesForAttributesChangedListener(AudioAttributes attributes,
3388             IDevicesForAttributesCallback callback) {
3389         mAudioSystem.addOnDevicesForAttributesChangedListener(
3390                 attributes, false /* forVolume */, callback);
3391     }
3392 
3393     /**
3394      * @see AudioManager#removeOnDevicesForAttributesChangedListener(
3395      *      OnDevicesForAttributesChangedListener)
3396      */
removeOnDevicesForAttributesChangedListener( IDevicesForAttributesCallback callback)3397     public void removeOnDevicesForAttributesChangedListener(
3398             IDevicesForAttributesCallback callback) {
3399         mAudioSystem.removeOnDevicesForAttributesChangedListener(callback);
3400     }
3401 
3402     // pre-condition: event.getKeyCode() is one of KeyEvent.KEYCODE_VOLUME_UP,
3403     //                                   KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_MUTE
handleVolumeKey(@onNull KeyEvent event, boolean isOnTv, @NonNull String callingPackage, @NonNull String caller)3404     public void handleVolumeKey(@NonNull KeyEvent event, boolean isOnTv,
3405             @NonNull String callingPackage, @NonNull String caller) {
3406         int keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_NORMAL;
3407         if (isOnTv) {
3408             if (event.getAction() == KeyEvent.ACTION_DOWN) {
3409                 keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_START;
3410             } else { // may catch more than ACTION_UP, but will end vol adjustement
3411                 // the vol key is either released (ACTION_UP), or multiple keys are pressed
3412                 // (ACTION_MULTIPLE) and we don't know what to do for volume control on CEC, end
3413                 // the repeated volume adjustement
3414                 keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_END;
3415             }
3416         } else if (event.getAction() != KeyEvent.ACTION_DOWN) {
3417             return;
3418         }
3419 
3420         int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND
3421                 | AudioManager.FLAG_FROM_KEY;
3422 
3423         switch (event.getKeyCode()) {
3424             case KeyEvent.KEYCODE_VOLUME_UP:
3425                     adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE,
3426                             AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller,
3427                             Binder.getCallingUid(), Binder.getCallingPid(), true, keyEventMode);
3428                 break;
3429             case KeyEvent.KEYCODE_VOLUME_DOWN:
3430                     adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER,
3431                             AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller,
3432                             Binder.getCallingUid(), Binder.getCallingPid(), true, keyEventMode);
3433                 break;
3434             case KeyEvent.KEYCODE_VOLUME_MUTE:
3435                 if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
3436                     adjustSuggestedStreamVolume(AudioManager.ADJUST_TOGGLE_MUTE,
3437                             AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller,
3438                             Binder.getCallingUid(), Binder.getCallingPid(),
3439                             true, AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
3440                 }
3441                 break;
3442             default:
3443                 Log.e(TAG, "Invalid key code " + event.getKeyCode() + " sent by " + callingPackage);
3444                 return; // not needed but added if code gets added below this switch statement
3445         }
3446     }
3447 
setNavigationRepeatSoundEffectsEnabled(boolean enabled)3448     public void setNavigationRepeatSoundEffectsEnabled(boolean enabled) {
3449         mNavigationRepeatSoundEffectsEnabled = enabled;
3450     }
3451 
3452     /**
3453      * @return true if the fast scroll sound effects are enabled
3454      */
areNavigationRepeatSoundEffectsEnabled()3455     public boolean areNavigationRepeatSoundEffectsEnabled() {
3456         return mNavigationRepeatSoundEffectsEnabled;
3457     }
3458 
setHomeSoundEffectEnabled(boolean enabled)3459     public void setHomeSoundEffectEnabled(boolean enabled) {
3460         mHomeSoundEffectEnabled = enabled;
3461     }
3462 
3463     /**
3464      * @return true if the home sound effect is enabled
3465      */
isHomeSoundEffectEnabled()3466     public boolean isHomeSoundEffectEnabled() {
3467         return mHomeSoundEffectEnabled;
3468     }
3469 
3470     /** 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)3471     private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
3472             String callingPackage, String caller, int uid, int pid, boolean hasModifyAudioSettings,
3473             int keyEventMode) {
3474         if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream=" + suggestedStreamType
3475                 + ", flags=" + flags + ", caller=" + caller
3476                 + ", volControlStream=" + mVolumeControlStream
3477                 + ", userSelect=" + mUserSelectedVolumeControlStream);
3478         if (direction != AudioManager.ADJUST_SAME) {
3479             sVolumeLogger.enqueue(
3480                     new VolumeEvent(VolumeEvent.VOL_ADJUST_SUGG_VOL, suggestedStreamType,
3481                             direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage)
3482                             .append("/").append(caller).append(" uid:").append(uid).toString()));
3483         }
3484 
3485         boolean hasExternalVolumeController = notifyExternalVolumeController(direction);
3486 
3487         new MediaMetrics.Item(mMetricsId + "adjustSuggestedStreamVolume")
3488                 .setUid(Binder.getCallingUid())
3489                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage)
3490                 .set(MediaMetrics.Property.CLIENT_NAME, caller)
3491                 .set(MediaMetrics.Property.DIRECTION, direction > 0
3492                         ? MediaMetrics.Value.UP : MediaMetrics.Value.DOWN)
3493                 .set(MediaMetrics.Property.EXTERNAL, hasExternalVolumeController
3494                         ? MediaMetrics.Value.YES : MediaMetrics.Value.NO)
3495                 .set(MediaMetrics.Property.FLAGS, flags)
3496                 .record();
3497 
3498         if (hasExternalVolumeController) {
3499             return;
3500         }
3501 
3502         final int streamType;
3503         synchronized (mForceControlStreamLock) {
3504             // Request lock in case mVolumeControlStream is changed by other thread.
3505             if (mUserSelectedVolumeControlStream) { // implies mVolumeControlStream != -1
3506                 streamType = mVolumeControlStream;
3507             } else {
3508                 // TODO discard activity on a muted stream?
3509                 final int maybeActiveStreamType = getActiveStreamType(suggestedStreamType);
3510                 final boolean activeForReal;
3511                 if (maybeActiveStreamType == AudioSystem.STREAM_RING
3512                         || maybeActiveStreamType == AudioSystem.STREAM_NOTIFICATION) {
3513                     activeForReal = wasStreamActiveRecently(maybeActiveStreamType, 0);
3514                 } else {
3515                     activeForReal = mAudioSystem.isStreamActive(maybeActiveStreamType, 0);
3516                 }
3517                 if (activeForReal || mVolumeControlStream == -1) {
3518                     streamType = maybeActiveStreamType;
3519                 } else {
3520                     streamType = mVolumeControlStream;
3521                 }
3522             }
3523         }
3524 
3525         final boolean isMute = isMuteAdjust(direction);
3526 
3527         ensureValidStreamType(streamType);
3528         final int resolvedStream = mStreamVolumeAlias[streamType];
3529 
3530         // Play sounds on STREAM_RING only.
3531         if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 &&
3532                 resolvedStream != AudioSystem.STREAM_RING) {
3533             flags &= ~AudioManager.FLAG_PLAY_SOUND;
3534         }
3535 
3536         // For notifications/ring, show the ui before making any adjustments
3537         // Don't suppress mute/unmute requests
3538         // Don't suppress adjustments for single volume device
3539         if (mVolumeController.suppressAdjustment(resolvedStream, flags, isMute)
3540                 && !mIsSingleVolume) {
3541             direction = 0;
3542             flags &= ~AudioManager.FLAG_PLAY_SOUND;
3543             flags &= ~AudioManager.FLAG_VIBRATE;
3544             if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment");
3545         }
3546 
3547         adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid, pid,
3548                 null, hasModifyAudioSettings, keyEventMode);
3549     }
3550 
notifyExternalVolumeController(int direction)3551     private boolean notifyExternalVolumeController(int direction) {
3552         final IAudioPolicyCallback externalVolumeController;
3553         synchronized (mExtVolumeControllerLock) {
3554             externalVolumeController = mExtVolumeController;
3555         }
3556         if (externalVolumeController == null) {
3557             return false;
3558         }
3559 
3560         sendMsg(mAudioHandler, MSG_NOTIFY_VOL_EVENT, SENDMSG_QUEUE,
3561                 direction, 0 /*ignored*/,
3562                 externalVolumeController, 0 /*delay*/);
3563         return true;
3564     }
3565 
3566     /** Retain API for unsupported app usage */
adjustStreamVolume(int streamType, int direction, int flags, String callingPackage)3567     public void adjustStreamVolume(int streamType, int direction, int flags,
3568             String callingPackage) {
3569         adjustStreamVolumeWithAttribution(streamType, direction, flags, callingPackage, null);
3570     }
3571 
3572     /** @see AudioManager#adjustStreamVolume(int, int, int)
3573      * Part of service interface, check permissions here */
adjustStreamVolumeWithAttribution(int streamType, int direction, int flags, String callingPackage, String attributionTag)3574     public void adjustStreamVolumeWithAttribution(int streamType, int direction, int flags,
3575             String callingPackage, String attributionTag) {
3576         if (mHardeningEnforcer.blockVolumeMethod(
3577                 HardeningEnforcer.METHOD_AUDIO_MANAGER_ADJUST_STREAM_VOLUME)) {
3578             return;
3579         }
3580         if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {
3581             Log.w(TAG, "Trying to call adjustStreamVolume() for a11y without"
3582                     + "CHANGE_ACCESSIBILITY_VOLUME / callingPackage=" + callingPackage);
3583             return;
3584         }
3585 
3586         final VolumeEvent evt = new VolumeEvent(VolumeEvent.VOL_ADJUST_STREAM_VOL, streamType,
3587                 direction/*val1*/, flags/*val2*/, callingPackage);
3588         sVolumeLogger.enqueue(evt);
3589         // also logging mute/unmute calls to the dedicated logger
3590         if (isMuteAdjust(direction)) {
3591             sMuteLogger.enqueue(evt);
3592         }
3593         adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage,
3594                 Binder.getCallingUid(), Binder.getCallingPid(), attributionTag,
3595                 callingHasAudioSettingsPermission(), AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
3596     }
3597 
adjustStreamVolume(int streamType, int direction, int flags, String callingPackage, String caller, int uid, int pid, String attributionTag, boolean hasModifyAudioSettings, int keyEventMode)3598     protected void adjustStreamVolume(int streamType, int direction, int flags,
3599             String callingPackage, String caller, int uid, int pid, String attributionTag,
3600             boolean hasModifyAudioSettings, int keyEventMode) {
3601         if (mUseFixedVolume) {
3602             return;
3603         }
3604         if (DEBUG_VOL) Log.d(TAG, "adjustStreamVolume() stream=" + streamType + ", dir=" + direction
3605                 + ", flags=" + flags + ", caller=" + caller);
3606 
3607         ensureValidDirection(direction);
3608         ensureValidStreamType(streamType);
3609 
3610         boolean isMuteAdjust = isMuteAdjust(direction);
3611 
3612         if (isMuteAdjust && !isStreamAffectedByMute(streamType)) {
3613             return;
3614         }
3615 
3616         // If adjust is mute and the stream is STREAM_VOICE_CALL or STREAM_BLUETOOTH_SCO, make sure
3617         // that the calling app have the MODIFY_PHONE_STATE permission.
3618         if (isMuteAdjust &&
3619             (streamType == AudioSystem.STREAM_VOICE_CALL ||
3620                 streamType == AudioSystem.STREAM_BLUETOOTH_SCO) &&
3621                 mContext.checkPermission(MODIFY_PHONE_STATE, pid, uid)
3622                     != PackageManager.PERMISSION_GRANTED) {
3623             Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: adjustStreamVolume from pid="
3624                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
3625             return;
3626         }
3627 
3628         // If the stream is STREAM_ASSISTANT,
3629         // make sure that the calling app have the MODIFY_AUDIO_ROUTING permission.
3630         if (streamType == AudioSystem.STREAM_ASSISTANT &&
3631                 mContext.checkPermission(
3632                 MODIFY_AUDIO_ROUTING, pid, uid)
3633                     != PackageManager.PERMISSION_GRANTED) {
3634             Log.w(TAG, "MODIFY_AUDIO_ROUTING Permission Denial: adjustStreamVolume from pid="
3635                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
3636             return;
3637         }
3638 
3639         // use stream type alias here so that streams with same alias have the same behavior,
3640         // including with regard to silent mode control (e.g the use of STREAM_RING below and in
3641         // checkForRingerModeChange() in place of STREAM_RING or STREAM_NOTIFICATION)
3642         int streamTypeAlias = mStreamVolumeAlias[streamType];
3643 
3644         VolumeStreamState streamState = mStreamStates[streamTypeAlias];
3645 
3646         final int device = getDeviceForStream(streamTypeAlias);
3647 
3648         int aliasIndex = streamState.getIndex(device);
3649         boolean adjustVolume = true;
3650         int step;
3651 
3652         // skip a2dp absolute volume control request when the device
3653         // is neither an a2dp device nor BLE device
3654         if ((!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
3655                 && !AudioSystem.DEVICE_OUT_ALL_BLE_SET.contains(device))
3656                 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) {
3657             return;
3658         }
3659 
3660         // If we are being called by the system (e.g. hardware keys) check for current user
3661         // so we handle user restrictions correctly.
3662         if (uid == android.os.Process.SYSTEM_UID) {
3663             uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid));
3664         }
3665         // validate calling package and app op
3666         if (!checkNoteAppOp(
3667                 STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage, attributionTag)) {
3668             return;
3669         }
3670 
3671         mSoundDoseHelper.invalidatePendingVolumeCommand();
3672 
3673         flags &= ~AudioManager.FLAG_FIXED_VOLUME;
3674         if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) {
3675             flags |= AudioManager.FLAG_FIXED_VOLUME;
3676 
3677             // Always toggle between max safe volume and 0 for fixed volume devices where safe
3678             // volume is enforced, and max and 0 for the others.
3679             // This is simulated by stepping by the full allowed volume range
3680             step = mSoundDoseHelper.getSafeMediaVolumeIndex(device);
3681             if (step < 0) {
3682                 step = streamState.getMaxIndex();
3683             }
3684             if (aliasIndex != 0) {
3685                 aliasIndex = step;
3686             }
3687         } else {
3688             // convert one UI step (+/-1) into a number of internal units on the stream alias
3689             step = rescaleStep(10, streamType, streamTypeAlias);
3690         }
3691 
3692         // If either the client forces allowing ringer modes for this adjustment,
3693         // or stream is used for UI sonification
3694         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
3695                 (isUiSoundsStreamType(streamTypeAlias))) {
3696             int ringerMode = getRingerModeInternal();
3697             // do not vibrate if already in vibrate mode
3698             if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
3699                 flags &= ~AudioManager.FLAG_VIBRATE;
3700             }
3701             // Check if the ringer mode handles this adjustment. If it does we don't
3702             // need to adjust the volume further.
3703             final int result = checkForRingerModeChange(aliasIndex, direction, step,
3704                     streamState.mIsMuted, callingPackage, flags);
3705             adjustVolume = (result & FLAG_ADJUST_VOLUME) != 0;
3706             // If suppressing a volume adjustment in silent mode, display the UI hint
3707             if ((result & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) {
3708                 flags |= AudioManager.FLAG_SHOW_SILENT_HINT;
3709             }
3710             // If suppressing a volume down adjustment in vibrate mode, display the UI hint
3711             if ((result & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) {
3712                 flags |= AudioManager.FLAG_SHOW_VIBRATE_HINT;
3713             }
3714         } else if (isStreamMutedByRingerOrZenMode(streamTypeAlias) && streamState.mIsMuted) {
3715             // if the stream is currently muted streams by ringer/zen mode
3716             // then it cannot be unmuted (without FLAG_ALLOW_RINGER_MODES) with an unmute or raise
3717             if (direction == AudioManager.ADJUST_TOGGLE_MUTE
3718                     || direction == AudioManager.ADJUST_UNMUTE
3719                     || direction == AudioManager.ADJUST_RAISE) {
3720                 adjustVolume = false;
3721             }
3722         }
3723 
3724         // If the ringer mode or zen is muting the stream, do not change stream unless
3725         // it'll cause us to exit dnd
3726         if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) {
3727             adjustVolume = false;
3728         }
3729         int oldIndex = mStreamStates[streamType].getIndex(device);
3730 
3731         // Check if the volume adjustment should be handled by an absolute volume controller instead
3732         if (isAbsoluteVolumeDevice(device)
3733                 && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) {
3734             AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device);
3735             if (info.mHandlesVolumeAdjustment) {
3736                 dispatchAbsoluteVolumeAdjusted(streamType, info, oldIndex, direction,
3737                         keyEventMode);
3738                 return;
3739             }
3740         }
3741 
3742         if (adjustVolume && (direction != AudioManager.ADJUST_SAME)
3743                 && (keyEventMode != AudioDeviceVolumeManager.ADJUST_MODE_END)) {
3744             mAudioHandler.removeMessages(MSG_UNMUTE_STREAM_ON_SINGLE_VOL_DEVICE);
3745 
3746             if (isMuteAdjust && !mFullVolumeDevices.contains(device)) {
3747                 boolean state;
3748                 if (direction == AudioManager.ADJUST_TOGGLE_MUTE) {
3749                     state = !streamState.mIsMuted;
3750                 } else {
3751                     state = direction == AudioManager.ADJUST_MUTE;
3752                 }
3753                 muteAliasStreams(streamTypeAlias, state);
3754             } else if ((direction == AudioManager.ADJUST_RAISE)
3755                     && mSoundDoseHelper.raiseVolumeDisplaySafeMediaVolume(streamTypeAlias,
3756                             aliasIndex + step, device, flags)) {
3757                 Log.e(TAG, "adjustStreamVolume() safe volume index = " + oldIndex);
3758             } else if (!isFullVolumeDevice(device)
3759                     && (streamState.adjustIndex(direction * step, device, caller,
3760                             hasModifyAudioSettings)
3761                             || streamState.mIsMuted)) {
3762                 // Post message to set system volume (it in turn will post a
3763                 // message to persist).
3764                 if (streamState.mIsMuted) {
3765                     // Unmute the stream if it was previously muted
3766                     if (direction == AudioManager.ADJUST_RAISE) {
3767                         // unmute immediately for volume up
3768                         muteAliasStreams(streamTypeAlias, false);
3769                     } else if (direction == AudioManager.ADJUST_LOWER) {
3770                         if (mIsSingleVolume) {
3771                             sendMsg(mAudioHandler, MSG_UNMUTE_STREAM_ON_SINGLE_VOL_DEVICE,
3772                                     SENDMSG_QUEUE, streamTypeAlias, flags, null,
3773                                     UNMUTE_STREAM_DELAY);
3774                         }
3775                     }
3776                 }
3777                 sendMsg(mAudioHandler,
3778                         MSG_SET_DEVICE_VOLUME,
3779                         SENDMSG_QUEUE,
3780                         device,
3781                         0,
3782                         streamState,
3783                         0);
3784             }
3785 
3786             int newIndex = mStreamStates[streamType].getIndex(device);
3787 
3788             int streamToDriveAbsVol = absVolumeIndexFix() ? getBluetoothContextualVolumeStream() :
3789                     AudioSystem.STREAM_MUSIC;
3790             // Check if volume update should be send to AVRCP
3791             if (streamTypeAlias == streamToDriveAbsVol
3792                     && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
3793                     && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
3794                 if (DEBUG_VOL) {
3795                     Log.d(TAG, "adjustStreamVolume: postSetAvrcpAbsoluteVolumeIndex index="
3796                             + newIndex + "stream=" + streamType);
3797                 }
3798                 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(newIndex / 10);
3799             } else if (isAbsoluteVolumeDevice(device)
3800                     && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) {
3801                 AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device);
3802                 dispatchAbsoluteVolumeChanged(streamType, info, newIndex);
3803             }
3804 
3805             if (AudioSystem.isLeAudioDeviceType(device)
3806                     && streamType == getBluetoothContextualVolumeStream()
3807                     && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
3808                 if (DEBUG_VOL) {
3809                     Log.d(TAG, "adjustStreamVolume postSetLeAudioVolumeIndex index="
3810                             + newIndex + " stream=" + streamType);
3811                 }
3812                 mDeviceBroker.postSetLeAudioVolumeIndex(newIndex,
3813                     mStreamStates[streamType].getMaxIndex(), streamType);
3814             }
3815 
3816             // Check if volume update should be send to Hearing Aid
3817             if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
3818                 // only modify the hearing aid attenuation when the stream to modify matches
3819                 // the one expected by the hearing aid
3820                 if (streamType == getBluetoothContextualVolumeStream()) {
3821                     if (DEBUG_VOL) {
3822                         Log.d(TAG, "adjustStreamVolume postSetHearingAidVolumeIndex index="
3823                                 + newIndex + " stream=" + streamType);
3824                     }
3825                     mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType);
3826                 }
3827             }
3828         }
3829 
3830         final int newIndex = mStreamStates[streamType].getIndex(device);
3831 
3832         if (adjustVolume) {
3833             synchronized (mHdmiClientLock) {
3834                 if (mHdmiManager != null) {
3835                     // At most one of mHdmiPlaybackClient and mHdmiTvClient should be non-null
3836                     HdmiClient hdmiClient = mHdmiPlaybackClient;
3837                     if (mHdmiTvClient != null) {
3838                         hdmiClient = mHdmiTvClient;
3839                     }
3840 
3841                     boolean playbackDeviceConditions = mHdmiPlaybackClient != null
3842                             && isFullVolumeDevice(device);
3843                     boolean tvConditions = mHdmiTvClient != null
3844                             && mHdmiSystemAudioSupported
3845                             && !isAbsoluteVolumeDevice(device)
3846                             && !isA2dpAbsoluteVolumeDevice(device);
3847 
3848                     if ((playbackDeviceConditions || tvConditions)
3849                             && mHdmiCecVolumeControlEnabled
3850                             && streamTypeAlias == AudioSystem.STREAM_MUSIC) {
3851                         int keyCode = KeyEvent.KEYCODE_UNKNOWN;
3852                         switch (direction) {
3853                             case AudioManager.ADJUST_RAISE:
3854                                 keyCode = KeyEvent.KEYCODE_VOLUME_UP;
3855                                 break;
3856                             case AudioManager.ADJUST_LOWER:
3857                                 keyCode = KeyEvent.KEYCODE_VOLUME_DOWN;
3858                                 break;
3859                             case AudioManager.ADJUST_TOGGLE_MUTE:
3860                             case AudioManager.ADJUST_MUTE:
3861                             case AudioManager.ADJUST_UNMUTE:
3862                                 // Many CEC devices only support toggle mute. Therefore, we send the
3863                                 // same keycode for all three mute options.
3864                                 keyCode = KeyEvent.KEYCODE_VOLUME_MUTE;
3865                                 break;
3866                             default:
3867                                 break;
3868                         }
3869                         if (keyCode != KeyEvent.KEYCODE_UNKNOWN) {
3870                             final long ident = Binder.clearCallingIdentity();
3871                             try {
3872                                 switch (keyEventMode) {
3873                                     case AudioDeviceVolumeManager.ADJUST_MODE_NORMAL:
3874                                         hdmiClient.sendVolumeKeyEvent(keyCode, true);
3875                                         hdmiClient.sendVolumeKeyEvent(keyCode, false);
3876                                         break;
3877                                     case AudioDeviceVolumeManager.ADJUST_MODE_START:
3878                                         hdmiClient.sendVolumeKeyEvent(keyCode, true);
3879                                         break;
3880                                     case AudioDeviceVolumeManager.ADJUST_MODE_END:
3881                                         hdmiClient.sendVolumeKeyEvent(keyCode, false);
3882                                         break;
3883                                     default:
3884                                         Log.e(TAG, "Invalid keyEventMode " + keyEventMode);
3885                                 }
3886                             } finally {
3887                                 Binder.restoreCallingIdentity(ident);
3888                             }
3889                         }
3890                     }
3891 
3892                     if (streamTypeAlias == AudioSystem.STREAM_MUSIC
3893                             && (oldIndex != newIndex || isMuteAdjust)) {
3894                         maybeSendSystemAudioStatusCommand(isMuteAdjust);
3895                     }
3896                 }
3897             }
3898         }
3899         sendVolumeUpdate(streamType, oldIndex, newIndex, flags, device);
3900     }
3901 
3902     /**
3903      * Loops on aliased stream, update the mute cache attribute of each
3904      * {@see AudioService#VolumeStreamState}, and then apply the change.
3905      * It prevents to unnecessary {@see AudioSystem#setStreamVolume} done for each stream
3906      * and aliases before mute change changed and after.
3907      */
muteAliasStreams(int streamAlias, boolean state)3908     private void muteAliasStreams(int streamAlias, boolean state) {
3909         // Locking mSettingsLock to avoid inversion when calling doMute -> updateVolumeGroupIndex
3910         synchronized (mSettingsLock) {
3911             synchronized (VolumeStreamState.class) {
3912                 List<Integer> streamsToMute = new ArrayList<>();
3913                 for (int stream = 0; stream < mStreamStates.length; stream++) {
3914                     VolumeStreamState vss = mStreamStates[stream];
3915                     if (streamAlias == mStreamVolumeAlias[stream] && vss.isMutable()) {
3916                         if (!(mCameraSoundForced
3917                                 && (vss.getStreamType()
3918                                 == AudioSystem.STREAM_SYSTEM_ENFORCED))) {
3919                             boolean changed = vss.mute(state, /* apply= */ false,
3920                                     "muteAliasStreams");
3921                             if (changed) {
3922                                 streamsToMute.add(stream);
3923                             }
3924                         }
3925                     }
3926                 }
3927                 streamsToMute.forEach(streamToMute -> {
3928                     mStreamStates[streamToMute].doMute();
3929                     broadcastMuteSetting(streamToMute, state);
3930                 });
3931             }
3932         }
3933     }
3934 
broadcastMuteSetting(int streamType, boolean isMuted)3935     private void broadcastMuteSetting(int streamType, boolean isMuted) {
3936         // Stream mute changed, fire the intent.
3937         Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION);
3938         intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, streamType);
3939         intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, isMuted);
3940         sendBroadcastToAll(intent, null /* options */);
3941     }
3942 
3943     // Called after a delay when volume down is pressed while muted
onUnmuteStreamOnSingleVolDevice(int streamAlias, int flags)3944     private void onUnmuteStreamOnSingleVolDevice(int streamAlias, int flags) {
3945         boolean wasMuted;
3946         // Locking mSettingsLock to avoid inversion when calling vss.mute -> vss.doMute ->
3947         // vss.updateVolumeGroupIndex
3948         synchronized (mSettingsLock) {
3949             synchronized (VolumeStreamState.class) {
3950                 final VolumeStreamState streamState = mStreamStates[streamAlias];
3951                 // if unmuting causes a change, it was muted
3952                 wasMuted = streamState.mute(false, "onUnmuteStreamOnSingleVolDevice");
3953                 if (wasMuted) {
3954                     // Unmute all aliasted streams
3955                     muteAliasStreams(streamAlias, false);
3956                 }
3957                 final int device = getDeviceForStream(streamAlias);
3958                 final int index = streamState.getIndex(device);
3959                 sendVolumeUpdate(streamAlias, index, index, flags, device);
3960             }
3961             if (streamAlias == AudioSystem.STREAM_MUSIC && wasMuted) {
3962                 synchronized (mHdmiClientLock) {
3963                     maybeSendSystemAudioStatusCommand(true);
3964                 }
3965             }
3966         }
3967     }
3968 
3969     @GuardedBy("mHdmiClientLock")
maybeSendSystemAudioStatusCommand(boolean isMuteAdjust)3970     private void maybeSendSystemAudioStatusCommand(boolean isMuteAdjust) {
3971         if (mHdmiAudioSystemClient == null
3972                 || !mHdmiSystemAudioSupported
3973                 || !mHdmiCecVolumeControlEnabled) {
3974             return;
3975         }
3976 
3977         final long identity = Binder.clearCallingIdentity();
3978         try {
3979             mHdmiAudioSystemClient.sendReportAudioStatusCecCommand(
3980                     isMuteAdjust, getStreamVolume(AudioSystem.STREAM_MUSIC),
3981                     getStreamMaxVolume(AudioSystem.STREAM_MUSIC),
3982                     isStreamMute(AudioSystem.STREAM_MUSIC));
3983         } finally {
3984             Binder.restoreCallingIdentity(identity);
3985         }
3986     }
3987 
getNewRingerMode(int stream, int index, int flags)3988     private int getNewRingerMode(int stream, int index, int flags) {
3989         // setRingerMode does nothing if the device is single volume,so the value would be unchanged
3990         if (mIsSingleVolume) {
3991             return getRingerModeExternal();
3992         }
3993 
3994         // setting volume on ui sounds stream type also controls silent mode
3995         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
3996                 (stream == getUiSoundsStreamType())) {
3997             int newRingerMode;
3998             if (index == 0) {
3999                 newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE
4000                         : mVolumePolicy.volumeDownToEnterSilent ? AudioManager.RINGER_MODE_SILENT
4001                                 : AudioManager.RINGER_MODE_NORMAL;
4002             } else {
4003                 newRingerMode = AudioManager.RINGER_MODE_NORMAL;
4004             }
4005             return newRingerMode;
4006         }
4007         return getRingerModeExternal();
4008     }
4009 
isAndroidNPlus(String caller)4010     private boolean isAndroidNPlus(String caller) {
4011         try {
4012             final ApplicationInfo applicationInfo =
4013                     mContext.getPackageManager().getApplicationInfoAsUser(
4014                             caller, 0, UserHandle.getUserId(Binder.getCallingUid()));
4015             if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N) {
4016                 return true;
4017             }
4018             return false;
4019         } catch (PackageManager.NameNotFoundException e) {
4020             return true;
4021         }
4022     }
4023 
wouldToggleZenMode(int newMode)4024     private boolean wouldToggleZenMode(int newMode) {
4025         if (getRingerModeExternal() == AudioManager.RINGER_MODE_SILENT
4026                 && newMode != AudioManager.RINGER_MODE_SILENT) {
4027             return true;
4028         } else if (getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT
4029                 && newMode == AudioManager.RINGER_MODE_SILENT) {
4030             return true;
4031         }
4032         return false;
4033     }
4034 
4035     /**
4036      * Update stream volume, ringer mode and mute status after a volume index change
4037      * @param streamType
4038      * @param index
4039      * @param flags
4040      * @param device the device for which the volume is changed
4041      * @param caller
4042      * @param hasModifyAudioSettings
4043      * @param canChangeMute true if the origin of this event is one where the mute state should be
4044      *                      updated following the change in volume index
4045      */
onSetStreamVolume(int streamType, int index, int flags, int device, String caller, boolean hasModifyAudioSettings, boolean canChangeMute)4046     /*package*/ void onSetStreamVolume(int streamType, int index, int flags, int device,
4047             String caller, boolean hasModifyAudioSettings, boolean canChangeMute) {
4048         final int stream = mStreamVolumeAlias[streamType];
4049         // setting volume on ui sounds stream type also controls silent mode
4050         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
4051                 (stream == getUiSoundsStreamType())) {
4052             setRingerMode(getNewRingerMode(stream, index, flags),
4053                     TAG + ".onSetStreamVolume", false /*external*/);
4054         }
4055         setStreamVolumeInt(stream, index, device, false, caller, hasModifyAudioSettings);
4056         // setting non-zero volume for a muted stream unmutes the stream and vice versa
4057         // except for BT SCO stream where only explicit mute is allowed to comply to BT requirements
4058         if ((streamType != AudioSystem.STREAM_BLUETOOTH_SCO) && canChangeMute) {
4059             // As adjustStreamVolume with muteAdjust flags mute/unmutes stream and aliased streams.
4060             muteAliasStreams(stream, index == 0);
4061         }
4062     }
4063 
enforceModifyAudioRoutingPermission()4064     private void enforceModifyAudioRoutingPermission() {
4065         if (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING)
4066                 != PackageManager.PERMISSION_GRANTED) {
4067             throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission");
4068         }
4069     }
4070 
enforceQueryStateOrModifyRoutingPermission()4071     private void enforceQueryStateOrModifyRoutingPermission() {
4072         if (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING)
4073                 != PackageManager.PERMISSION_GRANTED
4074                 && mContext.checkCallingOrSelfPermission(QUERY_AUDIO_STATE)
4075                 != PackageManager.PERMISSION_GRANTED) {
4076             throw new SecurityException(
4077                     "Missing MODIFY_AUDIO_ROUTING or QUERY_AUDIO_STATE permissions");
4078         }
4079     }
4080 
4081     @Override
4082     @android.annotation.EnforcePermission(anyOf = {
4083             MODIFY_AUDIO_SETTINGS_PRIVILEGED, MODIFY_AUDIO_ROUTING })
4084     /** @see AudioManager#setVolumeGroupVolumeIndex(int, int, int) */
setVolumeGroupVolumeIndex(int groupId, int index, int flags, String callingPackage, String attributionTag)4085     public void setVolumeGroupVolumeIndex(int groupId, int index, int flags,
4086             String callingPackage, String attributionTag) {
4087         super.setVolumeGroupVolumeIndex_enforcePermission();
4088         if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
4089             Log.e(TAG, ": no volume group found for id " + groupId);
4090             return;
4091         }
4092         VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
4093 
4094         sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_GROUP_VOL, vgs.name(),
4095                 index, flags, callingPackage + ", user " + getCurrentUserId()));
4096 
4097         vgs.setVolumeIndex(index, flags);
4098 
4099         // For legacy reason, propagate to all streams associated to this volume group
4100         for (int groupedStream : vgs.getLegacyStreamTypes()) {
4101             try {
4102                 ensureValidStreamType(groupedStream);
4103             } catch (IllegalArgumentException e) {
4104                 Log.d(TAG, "volume group " + groupId + " has internal streams (" + groupedStream
4105                         + "), do not change associated stream volume");
4106                 continue;
4107             }
4108             setStreamVolume(groupedStream, index, flags, /*device*/ null,
4109                     callingPackage, callingPackage,
4110                     attributionTag, Binder.getCallingUid(), true /*hasModifyAudioSettings*/,
4111                     true /*canChangeMuteAndUpdateController*/);
4112         }
4113     }
4114 
4115     @Override
4116     @android.annotation.EnforcePermission(anyOf = {
4117             MODIFY_AUDIO_SETTINGS_PRIVILEGED, MODIFY_AUDIO_ROUTING })
4118     /** @see AudioManager#getVolumeGroupVolumeIndex(int) */
getVolumeGroupVolumeIndex(int groupId)4119     public int getVolumeGroupVolumeIndex(int groupId) {
4120         super.getVolumeGroupVolumeIndex_enforcePermission();
4121         synchronized (VolumeStreamState.class) {
4122             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
4123                 throw new IllegalArgumentException("No volume group for id " + groupId);
4124             }
4125             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
4126             // Return 0 when muted, not min index since for e.g. Voice Call, it has a non zero
4127             // min but it mutable on permission condition.
4128             return vgs.isMuted() ? 0 : vgs.getVolumeIndex();
4129         }
4130     }
4131 
4132     /** @see AudioManager#getVolumeGroupMaxVolumeIndex(int) */
4133     @android.annotation.EnforcePermission(anyOf = {
4134             MODIFY_AUDIO_SETTINGS_PRIVILEGED, MODIFY_AUDIO_ROUTING })
getVolumeGroupMaxVolumeIndex(int groupId)4135     public int getVolumeGroupMaxVolumeIndex(int groupId) {
4136         super.getVolumeGroupMaxVolumeIndex_enforcePermission();
4137         synchronized (VolumeStreamState.class) {
4138             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
4139                 throw new IllegalArgumentException("No volume group for id " + groupId);
4140             }
4141             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
4142             return vgs.getMaxIndex();
4143         }
4144     }
4145 
4146     /** @see AudioManager#getVolumeGroupMinVolumeIndex(int) */
4147     @android.annotation.EnforcePermission(anyOf = {
4148             MODIFY_AUDIO_SETTINGS_PRIVILEGED, MODIFY_AUDIO_ROUTING })
getVolumeGroupMinVolumeIndex(int groupId)4149     public int getVolumeGroupMinVolumeIndex(int groupId) {
4150         super.getVolumeGroupMinVolumeIndex_enforcePermission();
4151         synchronized (VolumeStreamState.class) {
4152             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
4153                 throw new IllegalArgumentException("No volume group for id " + groupId);
4154             }
4155             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
4156             return vgs.getMinIndex();
4157         }
4158     }
4159 
4160     @Override
4161     @android.annotation.EnforcePermission(anyOf = {
4162             MODIFY_AUDIO_ROUTING, MODIFY_AUDIO_SETTINGS_PRIVILEGED })
4163     /** @see AudioDeviceVolumeManager#setDeviceVolume(VolumeInfo, AudioDeviceAttributes)
4164      * Part of service interface, check permissions and parameters here
4165      * Note calling package is for logging purposes only, not to be trusted
4166      */
setDeviceVolume(@onNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage)4167     public void setDeviceVolume(@NonNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada,
4168             @NonNull String callingPackage) {
4169         super.setDeviceVolume_enforcePermission();
4170         Objects.requireNonNull(vi);
4171         Objects.requireNonNull(ada);
4172         Objects.requireNonNull(callingPackage);
4173 
4174         if (!vi.hasStreamType()) {
4175             Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception());
4176             return;
4177         }
4178 
4179         int index = vi.getVolumeIndex();
4180         if (index == VolumeInfo.INDEX_NOT_SET && !vi.hasMuteCommand()) {
4181             throw new IllegalArgumentException(
4182                     "changing device volume requires a volume index or mute command");
4183         }
4184 
4185         // force a cache clear to force reevaluating stream type to audio device selection
4186         // that can interfere with the sending of the VOLUME_CHANGED_ACTION intent
4187         mAudioSystem.clearRoutingCache();
4188 
4189         // log the current device that will be used when evaluating the sending of the
4190         // VOLUME_CHANGED_ACTION intent to see if the current device is the one being modified
4191         final int currDev = getDeviceForStream(vi.getStreamType());
4192 
4193         final boolean skipping = (currDev == ada.getInternalType());
4194 
4195         AudioService.sVolumeLogger.enqueue(new DeviceVolumeEvent(vi.getStreamType(), index, ada,
4196                 currDev, callingPackage, skipping));
4197 
4198         if (skipping) {
4199             // setDeviceVolume was called on a device currently being used
4200             return;
4201         }
4202 
4203         // TODO handle unmuting of current audio device
4204         // if a stream is not muted but the VolumeInfo is for muting, set the volume index
4205         // for the device to min volume
4206         if (vi.hasMuteCommand() && vi.isMuted() && !isStreamMute(vi.getStreamType())) {
4207             setStreamVolumeWithAttributionInt(vi.getStreamType(),
4208                     mStreamStates[vi.getStreamType()].getMinIndex(),
4209                     /*flags*/ 0,
4210                     ada, callingPackage, null,
4211                     //TODO handle unmuting of current audio device
4212                     false /*canChangeMuteAndUpdateController*/);
4213             return;
4214         }
4215 
4216         AudioService.sVolumeLogger.enqueueAndLog("setDeviceVolume" + " from:" + callingPackage
4217                 + " " + vi + " " + ada, EventLogger.Event.ALOGI, TAG);
4218 
4219         if (vi.getMinVolumeIndex() == VolumeInfo.INDEX_NOT_SET
4220                 || vi.getMaxVolumeIndex() == VolumeInfo.INDEX_NOT_SET) {
4221             // assume index meant to be in stream type range, validate
4222             if ((index * 10) < mStreamStates[vi.getStreamType()].getMinIndex()
4223                     || (index * 10) > mStreamStates[vi.getStreamType()].getMaxIndex()) {
4224                 throw new IllegalArgumentException("invalid volume index " + index
4225                         + " not between min/max for stream " + vi.getStreamType());
4226             }
4227         } else {
4228             // check if index needs to be rescaled
4229             final int min = (mStreamStates[vi.getStreamType()].getMinIndex() + 5) / 10;
4230             final int max = (mStreamStates[vi.getStreamType()].getMaxIndex() + 5) / 10;
4231             if (vi.getMinVolumeIndex() != min || vi.getMaxVolumeIndex() != max) {
4232                 index = rescaleIndex(index,
4233                         /*srcMin*/ vi.getMinVolumeIndex(), /*srcMax*/ vi.getMaxVolumeIndex(),
4234                         /*dstMin*/ min, /*dstMax*/ max);
4235             }
4236         }
4237         setStreamVolumeWithAttributionInt(vi.getStreamType(), index, /*flags*/ 0,
4238                 ada, callingPackage, null,
4239                 false /*canChangeMuteAndUpdateController*/);
4240     }
4241 
4242     /** Retain API for unsupported app usage */
setStreamVolume(int streamType, int index, int flags, String callingPackage)4243     public void setStreamVolume(int streamType, int index, int flags, String callingPackage) {
4244         setStreamVolumeWithAttribution(streamType, index, flags,
4245                 callingPackage, /*attributionTag*/ null);
4246     }
4247 
4248     /** @see AudioManager#adjustVolumeGroupVolume(int, int, int) */
adjustVolumeGroupVolume(int groupId, int direction, int flags, String callingPackage)4249     public void adjustVolumeGroupVolume(int groupId, int direction, int flags,
4250                                         String callingPackage) {
4251         ensureValidDirection(direction);
4252         if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
4253             Log.e(TAG, ": no volume group found for id " + groupId);
4254             return;
4255         }
4256         VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
4257         // For compatibility reason, use stream API if group linked to a valid stream
4258         boolean fallbackOnStream = false;
4259         for (int stream : vgs.getLegacyStreamTypes()) {
4260             try {
4261                 ensureValidStreamType(stream);
4262             } catch (IllegalArgumentException e) {
4263                 Log.d(TAG, "volume group " + groupId + " has internal streams (" + stream
4264                         + "), do not change associated stream volume");
4265                 continue;
4266             }
4267             // Note: Group and Stream does not share same convention, 0 is mute for stream,
4268             // min index is acting as mute for Groups
4269             if (vgs.isVssMuteBijective(stream)) {
4270                 adjustStreamVolume(stream, direction, flags, callingPackage);
4271                 if (isMuteAdjust(direction)) {
4272                     // will be propagated to all aliased streams
4273                     return;
4274                 }
4275                 fallbackOnStream = true;
4276             }
4277         }
4278         if (fallbackOnStream) {
4279             // Handled by at least one stream, will be propagated to group, bailing out.
4280             return;
4281         }
4282         sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_ADJUST_GROUP_VOL, vgs.name(),
4283                 direction, flags, callingPackage));
4284         vgs.adjustVolume(direction, flags);
4285     }
4286 
4287     /** @see AudioManager#getLastAudibleVolumeForVolumeGroup(int) */
4288     @android.annotation.EnforcePermission(QUERY_AUDIO_STATE)
getLastAudibleVolumeForVolumeGroup(int groupId)4289     public int getLastAudibleVolumeForVolumeGroup(int groupId) {
4290         super.getLastAudibleVolumeForVolumeGroup_enforcePermission();
4291         synchronized (VolumeStreamState.class) {
4292             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
4293                 Log.e(TAG, ": no volume group found for id " + groupId);
4294                 return 0;
4295             }
4296             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
4297             return vgs.getVolumeIndex();
4298         }
4299     }
4300 
4301     /** @see AudioManager#isVolumeGroupMuted(int) */
isVolumeGroupMuted(int groupId)4302     public boolean isVolumeGroupMuted(int groupId) {
4303         synchronized (VolumeStreamState.class) {
4304             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
4305                 Log.e(TAG, ": no volume group found for id " + groupId);
4306                 return false;
4307             }
4308             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
4309             return vgs.isMuted();
4310         }
4311     }
4312 
4313     /** @see AudioManager#setStreamVolume(int, int, int)
4314      * Part of service interface, check permissions here */
setStreamVolumeWithAttribution(int streamType, int index, int flags, String callingPackage, String attributionTag)4315     public void setStreamVolumeWithAttribution(int streamType, int index, int flags,
4316             String callingPackage, String attributionTag) {
4317         if (mHardeningEnforcer.blockVolumeMethod(
4318                 HardeningEnforcer.METHOD_AUDIO_MANAGER_SET_STREAM_VOLUME)) {
4319             return;
4320         }
4321         setStreamVolumeWithAttributionInt(streamType, index, flags, /*device*/ null,
4322                 callingPackage, attributionTag, true /*canChangeMuteAndUpdateController*/);
4323     }
4324 
4325     /**
4326      * Internal method for a stream type volume change. Can be used to change the volume on a
4327      * given device only
4328      * @param streamType the stream type whose volume is to be changed
4329      * @param index the volume index
4330      * @param flags options for volume handling
4331      * @param device null when controlling volume for the current routing, otherwise the device
4332      *               for which volume is being changed
4333      * @param callingPackage client side-provided package name of caller, not to be trusted
4334      * @param attributionTag client side-provided attribution name, not to be trusted
4335      * @param canChangeMuteAndUpdateController true if the calling method is a path where
4336      *          the volume change is allowed to update the mute state as well as update
4337      *          the volume controller (the UI). This is intended to be true for a call coming
4338      *          from AudioManager.setStreamVolume (which is here
4339      *          {@link #setStreamVolumeForUid(int, int, int, String, int, int, UserHandle, int)},
4340      *          and false when coming from AudioDeviceVolumeManager.setDeviceVolume (which is here
4341      *          {@link #setDeviceVolume(VolumeInfo, AudioDeviceAttributes, String)}
4342      */
setStreamVolumeWithAttributionInt(int streamType, int index, int flags, @Nullable AudioDeviceAttributes ada, String callingPackage, String attributionTag, boolean canChangeMuteAndUpdateController)4343     protected void setStreamVolumeWithAttributionInt(int streamType, int index, int flags,
4344             @Nullable AudioDeviceAttributes ada,
4345             String callingPackage, String attributionTag,
4346             boolean canChangeMuteAndUpdateController) {
4347         if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {
4348             Log.w(TAG, "Trying to call setStreamVolume() for a11y without"
4349                     + " CHANGE_ACCESSIBILITY_VOLUME  callingPackage=" + callingPackage);
4350             return;
4351         }
4352         if ((streamType == AudioManager.STREAM_VOICE_CALL) && (index == 0)
4353                 && (mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE)
4354                     != PackageManager.PERMISSION_GRANTED)) {
4355             Log.w(TAG, "Trying to call setStreamVolume() for STREAM_VOICE_CALL and index 0 without"
4356                     + " MODIFY_PHONE_STATE  callingPackage=" + callingPackage);
4357             return;
4358         }
4359         if ((streamType == AudioManager.STREAM_ASSISTANT)
4360                 && (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING)
4361                     != PackageManager.PERMISSION_GRANTED)) {
4362             Log.w(TAG, "Trying to call setStreamVolume() for STREAM_ASSISTANT without"
4363                     + " MODIFY_AUDIO_ROUTING  callingPackage=" + callingPackage);
4364             return;
4365         }
4366 
4367         if (ada == null) {
4368             // call was already logged in setDeviceVolume()
4369             final int deviceType = getDeviceForStream(streamType);
4370             sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType,
4371                     index/*val1*/, flags/*val2*/, getStreamVolume(streamType, deviceType) /*val3*/,
4372                     callingPackage));
4373             ada = new AudioDeviceAttributes(deviceType /*nativeType*/, "" /*address*/);
4374         }
4375         setStreamVolume(streamType, index, flags, ada,
4376                 callingPackage, callingPackage, attributionTag,
4377                 Binder.getCallingUid(), callingOrSelfHasAudioSettingsPermission(),
4378                 canChangeMuteAndUpdateController);
4379     }
4380 
4381     @android.annotation.EnforcePermission(Manifest.permission.ACCESS_ULTRASOUND)
4382     /** @see AudioManager#isUltrasoundSupported() */
isUltrasoundSupported()4383     public boolean isUltrasoundSupported() {
4384         super.isUltrasoundSupported_enforcePermission();
4385 
4386         return AudioSystem.isUltrasoundSupported();
4387     }
4388 
4389     /** @see AudioManager#isHotwordStreamSupported(boolean)  */
4390     @android.annotation.EnforcePermission(CAPTURE_AUDIO_HOTWORD)
isHotwordStreamSupported(boolean lookbackAudio)4391     public boolean isHotwordStreamSupported(boolean lookbackAudio) {
4392         super.isHotwordStreamSupported_enforcePermission();
4393         try {
4394             return mAudioPolicy.isHotwordStreamSupported(lookbackAudio);
4395         } catch (IllegalStateException e) {
4396             // Suppress connection failure to APM, since the method is purely informative
4397             Log.e(TAG, "Suppressing exception calling into AudioPolicy", e);
4398             return false;
4399         }
4400     }
4401 
4402 
canChangeAccessibilityVolume()4403     private boolean canChangeAccessibilityVolume() {
4404         synchronized (mAccessibilityServiceUidsLock) {
4405             if (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
4406                     Manifest.permission.CHANGE_ACCESSIBILITY_VOLUME)) {
4407                 return true;
4408             }
4409             if (mAccessibilityServiceUids != null) {
4410                 int callingUid = Binder.getCallingUid();
4411                 for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
4412                     if (mAccessibilityServiceUids[i] == callingUid) {
4413                         return true;
4414                     }
4415                 }
4416             }
4417             return false;
4418         }
4419     }
4420 
4421     /** only public for mocking/spying, do not call outside of AudioService */
4422     @VisibleForTesting
getBluetoothContextualVolumeStream()4423     public int getBluetoothContextualVolumeStream() {
4424         return getBluetoothContextualVolumeStream(mMode.get());
4425     }
4426 
getBluetoothContextualVolumeStream(int mode)4427     private int getBluetoothContextualVolumeStream(int mode) {
4428         boolean voiceActivityCanOverride = true;
4429         switch (mode) {
4430             case AudioSystem.MODE_IN_COMMUNICATION:
4431             case AudioSystem.MODE_IN_CALL:
4432                 return AudioSystem.STREAM_VOICE_CALL;
4433             case AudioSystem.MODE_CALL_SCREENING:
4434             case AudioSystem.MODE_COMMUNICATION_REDIRECT:
4435             case AudioSystem.MODE_CALL_REDIRECT:
4436                 voiceActivityCanOverride = false;
4437                 // intended fallthrough
4438             case AudioSystem.MODE_NORMAL:
4439             default:
4440                 // other conditions will influence the stream type choice, read on...
4441                 break;
4442         }
4443         if (voiceActivityCanOverride
4444                 && mVoicePlaybackActive.get()) {
4445             return AudioSystem.STREAM_VOICE_CALL;
4446         }
4447         return AudioSystem.STREAM_MUSIC;
4448     }
4449 
4450     private AtomicBoolean mVoicePlaybackActive = new AtomicBoolean(false);
4451     private AtomicBoolean mMediaPlaybackActive = new AtomicBoolean(false);
4452 
4453     private final IPlaybackConfigDispatcher mPlaybackActivityMonitor =
4454             new IPlaybackConfigDispatcher.Stub() {
4455         @Override
4456         public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs,
4457                                                  boolean flush) {
4458             sendMsg(mAudioHandler, MSG_PLAYBACK_CONFIG_CHANGE, SENDMSG_REPLACE,
4459                     0 /*arg1 ignored*/, 0 /*arg2 ignored*/,
4460                     configs /*obj*/, 0 /*delay*/);
4461         }
4462     };
4463 
onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs)4464     private void onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) {
4465         boolean voiceActive = false;
4466         boolean mediaActive = false;
4467         for (AudioPlaybackConfiguration config : configs) {
4468             final int usage = config.getAudioAttributes().getUsage();
4469             if (!config.isActive()) {
4470                 continue;
4471             }
4472             if (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION
4473                     || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING) {
4474                 voiceActive = true;
4475             }
4476             if (usage == AudioAttributes.USAGE_MEDIA || usage == AudioAttributes.USAGE_GAME
4477                     || usage == AudioAttributes.USAGE_UNKNOWN) {
4478                 mediaActive = true;
4479             }
4480         }
4481         if (mVoicePlaybackActive.getAndSet(voiceActive) != voiceActive) {
4482             updateHearingAidVolumeOnVoiceActivityUpdate();
4483         }
4484         if (mMediaPlaybackActive.getAndSet(mediaActive) != mediaActive && mediaActive) {
4485             mSoundDoseHelper.scheduleMusicActiveCheck();
4486         }
4487 
4488         mLoudnessCodecHelper.updateCodecParameters(configs);
4489 
4490         // Update playback active state for all apps in audio mode stack.
4491         // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE
4492         // and request an audio mode update immediately. Upon any other change, queue the message
4493         // and request an audio mode update after a grace period.
4494         updateAudioModeHandlers(
4495                 configs /* playbackConfigs */, null /* recordConfigs */);
4496         mDeviceBroker.updateCommunicationRouteClientsActivity(
4497                 configs /* playbackConfigs */, null /* recordConfigs */);
4498     }
4499 
updateAudioModeHandlers(List<AudioPlaybackConfiguration> playbackConfigs, List<AudioRecordingConfiguration> recordConfigs)4500     void updateAudioModeHandlers(List<AudioPlaybackConfiguration> playbackConfigs,
4501                                  List<AudioRecordingConfiguration> recordConfigs) {
4502         synchronized (mDeviceBroker.mSetModeLock) {
4503             boolean updateAudioMode = false;
4504             int existingMsgPolicy = SENDMSG_QUEUE;
4505             int delay = CHECK_MODE_FOR_UID_PERIOD_MS;
4506             for (SetModeDeathHandler h : mSetModeDeathHandlers) {
4507                 boolean wasActive = h.isActive();
4508                 if (playbackConfigs != null) {
4509                     h.setPlaybackActive(false);
4510                     for (AudioPlaybackConfiguration config : playbackConfigs) {
4511                         final int usage = config.getAudioAttributes().getUsage();
4512                         if (config.getClientUid() == h.getUid()
4513                                 && (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION
4514                                 || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING)
4515                                 && config.isActive()) {
4516                             h.setPlaybackActive(true);
4517                             break;
4518                         }
4519                     }
4520                 }
4521                 if (recordConfigs != null) {
4522                     h.setRecordingActive(false);
4523                     for (AudioRecordingConfiguration config : recordConfigs) {
4524                         if (config.getClientUid() == h.getUid() && !config.isClientSilenced()
4525                                 && config.getAudioSource() == AudioSource.VOICE_COMMUNICATION) {
4526                             h.setRecordingActive(true);
4527                             break;
4528                         }
4529                     }
4530                 }
4531                 if (wasActive != h.isActive()) {
4532                     updateAudioMode = true;
4533                     if (h.isActive() && h == getAudioModeOwnerHandler()) {
4534                         existingMsgPolicy = SENDMSG_REPLACE;
4535                         delay = 0;
4536                     }
4537                 }
4538             }
4539             if (updateAudioMode) {
4540                 sendMsg(mAudioHandler,
4541                         MSG_UPDATE_AUDIO_MODE,
4542                         existingMsgPolicy,
4543                         AudioSystem.MODE_CURRENT,
4544                         android.os.Process.myPid(),
4545                         mContext.getPackageName(),
4546                         delay);
4547             }
4548         }
4549     }
4550 
4551     private final IRecordingConfigDispatcher mVoiceRecordingActivityMonitor =
4552             new IRecordingConfigDispatcher.Stub() {
4553         @Override
4554         public void dispatchRecordingConfigChange(List<AudioRecordingConfiguration> configs) {
4555             sendMsg(mAudioHandler, MSG_RECORDING_CONFIG_CHANGE, SENDMSG_REPLACE,
4556                     0 /*arg1 ignored*/, 0 /*arg2 ignored*/,
4557                     configs /*obj*/, 0 /*delay*/);
4558         }
4559     };
4560 
onRecordingConfigChange(List<AudioRecordingConfiguration> configs)4561     private void onRecordingConfigChange(List<AudioRecordingConfiguration> configs) {
4562         // Update recording active state for all apps in audio mode stack.
4563         // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE
4564         // and request an audio mode update immediately. Upon any other change, queue the message
4565         // and request an audio mode update after a grace period.
4566         updateAudioModeHandlers(
4567                 null /* playbackConfigs */, configs /* recordConfigs */);
4568         mDeviceBroker.updateCommunicationRouteClientsActivity(
4569                 null /* playbackConfigs */, configs /* recordConfigs */);
4570     }
4571 
dumpFlags(PrintWriter pw)4572     private void dumpFlags(PrintWriter pw) {
4573 
4574         pw.println("\nFun with Flags:");
4575         pw.println("\tandroid.media.audio.autoPublicVolumeApiHardening:"
4576                 + autoPublicVolumeApiHardening());
4577         pw.println("\tandroid.media.audio.Flags.automaticBtDeviceType:"
4578                 + automaticBtDeviceType());
4579         pw.println("\tandroid.media.audio.featureSpatialAudioHeadtrackingLowLatency:"
4580                 + featureSpatialAudioHeadtrackingLowLatency());
4581         pw.println("\tandroid.media.audio.focusFreezeTestApi:"
4582                 + focusFreezeTestApi());
4583         pw.println("\tcom.android.media.audio.audioserverPermissions:"
4584                 + audioserverPermissions());
4585         pw.println("\tcom.android.media.audio.disablePrescaleAbsoluteVolume:"
4586                 + disablePrescaleAbsoluteVolume());
4587         pw.println("\tcom.android.media.audio.setStreamVolumeOrder:"
4588                 + setStreamVolumeOrder());
4589         pw.println("\tandroid.media.audio.roForegroundAudioControl:"
4590                 + roForegroundAudioControl());
4591         pw.println("\tandroid.media.audio.scoManagedByAudio:"
4592                 + scoManagedByAudio());
4593         pw.println("\tcom.android.media.audio.vgsVssSyncMuteOrder:"
4594                 + vgsVssSyncMuteOrder());
4595         pw.println("\tcom.android.media.audio.absVolumeIndexFix:"
4596                 + absVolumeIndexFix());
4597     }
4598 
dumpAudioMode(PrintWriter pw)4599     private void dumpAudioMode(PrintWriter pw) {
4600         pw.println("\nAudio mode: ");
4601         pw.println("- Requested mode = " + AudioSystem.modeToString(getMode()));
4602         pw.println("- Actual mode = " + AudioSystem.modeToString(mMode.get()));
4603         pw.println("- Mode owner: ");
4604         SetModeDeathHandler hdlr = getAudioModeOwnerHandler();
4605         if (hdlr != null) {
4606             hdlr.dump(pw, -1);
4607         } else {
4608             pw.println("   None");
4609         }
4610         pw.println("- Mode owner stack: ");
4611         if (mSetModeDeathHandlers.isEmpty()) {
4612             pw.println("   Empty");
4613         } else {
4614             for (int i = 0; i < mSetModeDeathHandlers.size(); i++) {
4615                 mSetModeDeathHandlers.get(i).dump(pw, i);
4616             }
4617         }
4618     }
4619 
updateHearingAidVolumeOnVoiceActivityUpdate()4620     private void updateHearingAidVolumeOnVoiceActivityUpdate() {
4621         final int streamType = getBluetoothContextualVolumeStream();
4622         final int index = getStreamVolume(streamType);
4623         sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_HEARING_AID,
4624                 mVoicePlaybackActive.get(), streamType, index));
4625         mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
4626 
4627     }
4628 
4629     /**
4630      * Manage an audio mode change for audio devices that use an "absolute volume" model,
4631      * i.e. the framework sends the full scale signal, and the actual volume for the use case
4632      * is communicated separately.
4633      */
updateAbsVolumeMultiModeDevices(int oldMode, int newMode)4634     void updateAbsVolumeMultiModeDevices(int oldMode, int newMode) {
4635         if (oldMode == newMode) {
4636             return;
4637         }
4638         switch (newMode) {
4639             case AudioSystem.MODE_IN_COMMUNICATION:
4640             case AudioSystem.MODE_IN_CALL:
4641             case AudioSystem.MODE_NORMAL:
4642             case AudioSystem.MODE_CALL_SCREENING:
4643             case AudioSystem.MODE_CALL_REDIRECT:
4644             case AudioSystem.MODE_COMMUNICATION_REDIRECT:
4645                 break;
4646             default:
4647                 // no-op is enough for all other values
4648                 return;
4649         }
4650 
4651         int streamType = getBluetoothContextualVolumeStream(newMode);
4652 
4653         final Set<Integer> deviceTypes = getDeviceSetForStreamDirect(streamType);
4654         final Set<Integer> absVolumeMultiModeCaseDevices = AudioSystem.intersectionAudioDeviceTypes(
4655                 mAbsVolumeMultiModeCaseDevices, deviceTypes);
4656         if (absVolumeMultiModeCaseDevices.isEmpty()) {
4657             return;
4658         }
4659 
4660         // handling of specific interfaces goes here:
4661         if (AudioSystem.isSingleAudioDeviceType(
4662                 absVolumeMultiModeCaseDevices, AudioSystem.DEVICE_OUT_HEARING_AID)) {
4663             final int index = getStreamVolume(streamType);
4664             sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_MODE_CHANGE_HEARING_AID,
4665                     newMode, streamType, index));
4666             mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
4667         }
4668     }
4669 
setLeAudioVolumeOnModeUpdate(int mode, int device, int streamType, int index, int maxIndex)4670     private void setLeAudioVolumeOnModeUpdate(int mode, int device, int streamType, int index,
4671             int maxIndex) {
4672         switch (mode) {
4673             case AudioSystem.MODE_IN_COMMUNICATION:
4674             case AudioSystem.MODE_IN_CALL:
4675             case AudioSystem.MODE_NORMAL:
4676             case AudioSystem.MODE_CALL_SCREENING:
4677             case AudioSystem.MODE_CALL_REDIRECT:
4678             case AudioSystem.MODE_COMMUNICATION_REDIRECT:
4679             case AudioSystem.MODE_RINGTONE:
4680                 break;
4681             default:
4682                 // no-op is enough for all other values
4683                 return;
4684         }
4685 
4686         // In some cases (like the outgoing or rejected call) the value of 'device' is not
4687         // DEVICE_OUT_BLE_* even when BLE is connected. Changing the volume level in such case
4688         // may cuase the other devices volume level leaking into the LeAudio device settings.
4689         if (!AudioSystem.isLeAudioDeviceType(device)) {
4690             Log.w(TAG, "setLeAudioVolumeOnModeUpdate ignoring invalid device="
4691                     + device + ", mode=" + mode + ", index=" + index + " maxIndex=" + maxIndex
4692                     + " streamType=" + streamType);
4693             return;
4694         }
4695 
4696         if (DEBUG_VOL) {
4697             Log.d(TAG, "setLeAudioVolumeOnModeUpdate postSetLeAudioVolumeIndex device="
4698                     + device + ", mode=" + mode + ", index=" + index + " maxIndex=" + maxIndex
4699                     + " streamType=" + streamType);
4700         }
4701         mDeviceBroker.postSetLeAudioVolumeIndex(index, maxIndex, streamType);
4702         mDeviceBroker.postApplyVolumeOnDevice(streamType, device, "setLeAudioVolumeOnModeUpdate");
4703     }
4704 
setStreamVolume(int streamType, int index, int flags, @Nullable AudioDeviceAttributes ada, String callingPackage, String caller, String attributionTag, int uid, boolean hasModifyAudioSettings, boolean canChangeMuteAndUpdateController)4705     private void setStreamVolume(int streamType, int index, int flags,
4706             @Nullable AudioDeviceAttributes ada,
4707             String callingPackage, String caller, String attributionTag, int uid,
4708             boolean hasModifyAudioSettings,
4709             boolean canChangeMuteAndUpdateController) {
4710 
4711         if (DEBUG_VOL) {
4712             Log.d(TAG, "setStreamVolume(stream=" + streamType+", index=" + index
4713                     + ", dev=" + ada
4714                     + ", calling=" + callingPackage + ")");
4715         }
4716         if (mUseFixedVolume) {
4717             return;
4718         }
4719 
4720         ensureValidStreamType(streamType);
4721         int streamTypeAlias = mStreamVolumeAlias[streamType];
4722         VolumeStreamState streamState = mStreamStates[streamTypeAlias];
4723 
4724         if ((streamType == AudioManager.STREAM_VOICE_CALL)
4725                 && isInCommunication() && mDeviceBroker.isBluetoothScoActive()) {
4726             Log.i(TAG, "setStreamVolume for STREAM_VOICE_CALL, switching to STREAM_BLUETOOTH_SCO");
4727             streamType = AudioManager.STREAM_BLUETOOTH_SCO;
4728         }
4729 
4730         final int device = (ada == null)
4731                 ? getDeviceForStream(streamType)
4732                 : ada.getInternalType();
4733         int oldIndex;
4734 
4735         // skip a2dp absolute volume control request when the device
4736         // is neither an a2dp device nor BLE device
4737         if ((!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
4738                 && !AudioSystem.DEVICE_OUT_ALL_BLE_SET.contains(device))
4739                 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) {
4740             return;
4741         }
4742         // If we are being called by the system (e.g. hardware keys) check for current user
4743         // so we handle user restrictions correctly.
4744         if (uid == android.os.Process.SYSTEM_UID) {
4745             uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid));
4746         }
4747         if (!checkNoteAppOp(
4748                 STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage, attributionTag)) {
4749             return;
4750         }
4751 
4752         if (isAndroidNPlus(callingPackage)
4753                 && wouldToggleZenMode(getNewRingerMode(streamTypeAlias, index, flags))
4754                 && !mNm.isNotificationPolicyAccessGrantedForPackage(callingPackage)) {
4755             throw new SecurityException("Not allowed to change Do Not Disturb state");
4756         }
4757 
4758         if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) {
4759             return;
4760         }
4761 
4762         mSoundDoseHelper.invalidatePendingVolumeCommand();
4763 
4764         oldIndex = streamState.getIndex(device);
4765 
4766         index = rescaleIndex(index * 10, streamType, streamTypeAlias);
4767 
4768         if (setStreamVolumeOrder()) {
4769             flags &= ~AudioManager.FLAG_FIXED_VOLUME;
4770             if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) {
4771                 flags |= AudioManager.FLAG_FIXED_VOLUME;
4772 
4773                 // volume is either 0 or max allowed for fixed volume devices
4774                 if (index != 0) {
4775                     index = mSoundDoseHelper.getSafeMediaVolumeIndex(device);
4776                     if (index < 0) {
4777                         index = streamState.getMaxIndex();
4778                     }
4779                 }
4780             }
4781 
4782             if (!mSoundDoseHelper.willDisplayWarningAfterCheckVolume(streamType, index, device,
4783                     flags)) {
4784                 onSetStreamVolume(streamType, index, flags, device, caller, hasModifyAudioSettings,
4785                         // ada is non-null when called from setDeviceVolume,
4786                         // which shouldn't update the mute state
4787                         canChangeMuteAndUpdateController /*canChangeMute*/);
4788                 index = mStreamStates[streamType].getIndex(device);
4789             }
4790         }
4791 
4792         int streamToDriveAbsVol = absVolumeIndexFix() ? getBluetoothContextualVolumeStream() :
4793                 AudioSystem.STREAM_MUSIC;
4794         if (streamTypeAlias == streamToDriveAbsVol
4795                 && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
4796                 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
4797             if (DEBUG_VOL) {
4798                 Log.d(TAG, "setStreamVolume postSetAvrcpAbsoluteVolumeIndex index=" + index
4799                         + "stream=" + streamType);
4800             }
4801             mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index / 10);
4802         } else if (isAbsoluteVolumeDevice(device)
4803                 && ((flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0)) {
4804             AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device);
4805 
4806             dispatchAbsoluteVolumeChanged(streamType, info, index);
4807         }
4808 
4809         if (AudioSystem.isLeAudioDeviceType(device)
4810                 && streamType == getBluetoothContextualVolumeStream()
4811                 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
4812             if (DEBUG_VOL) {
4813                 Log.d(TAG, "setStreamVolume postSetLeAudioVolumeIndex index="
4814                         + index + " stream=" + streamType);
4815             }
4816             mDeviceBroker.postSetLeAudioVolumeIndex(index, mStreamStates[streamType].getMaxIndex(),
4817                     streamType);
4818         }
4819 
4820         if (device == AudioSystem.DEVICE_OUT_HEARING_AID
4821                 && streamType == getBluetoothContextualVolumeStream()) {
4822             Log.i(TAG, "setStreamVolume postSetHearingAidVolumeIndex index=" + index
4823                     + " stream=" + streamType);
4824             mDeviceBroker.postSetHearingAidVolumeIndex(index, streamType);
4825         }
4826 
4827         if (!setStreamVolumeOrder()) {
4828             flags &= ~AudioManager.FLAG_FIXED_VOLUME;
4829             if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) {
4830                 flags |= AudioManager.FLAG_FIXED_VOLUME;
4831 
4832                 // volume is either 0 or max allowed for fixed volume devices
4833                 if (index != 0) {
4834                     index = mSoundDoseHelper.getSafeMediaVolumeIndex(device);
4835                     if (index < 0) {
4836                         index = streamState.getMaxIndex();
4837                     }
4838                 }
4839             }
4840 
4841             if (!mSoundDoseHelper.willDisplayWarningAfterCheckVolume(streamType, index, device,
4842                     flags)) {
4843                 onSetStreamVolume(streamType, index, flags, device, caller, hasModifyAudioSettings,
4844                         // ada is non-null when called from setDeviceVolume,
4845                         // which shouldn't update the mute state
4846                         canChangeMuteAndUpdateController /*canChangeMute*/);
4847                 index = mStreamStates[streamType].getIndex(device);
4848             }
4849         }
4850 
4851         synchronized (mHdmiClientLock) {
4852             if (streamTypeAlias == AudioSystem.STREAM_MUSIC
4853                     && (oldIndex != index)) {
4854                 maybeSendSystemAudioStatusCommand(false);
4855             }
4856         }
4857         if (canChangeMuteAndUpdateController) {
4858             // only non-null when coming here from setDeviceVolume
4859             // TODO change test to check early if device is current device or not
4860             sendVolumeUpdate(streamType, oldIndex, index, flags, device);
4861         }
4862     }
4863 
dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, int index)4864     private void dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo,
4865             int index) {
4866         VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType);
4867         if (volumeInfo != null) {
4868             try {
4869                 deviceInfo.mCallback.dispatchDeviceVolumeChanged(deviceInfo.mDevice,
4870                         new VolumeInfo.Builder(volumeInfo)
4871                                 .setVolumeIndex(rescaleIndex(index, streamType, volumeInfo))
4872                                 .build());
4873             } catch (RemoteException e) {
4874                 Log.w(TAG, "Couldn't dispatch absolute volume behavior volume change");
4875             }
4876         }
4877     }
4878 
dispatchAbsoluteVolumeAdjusted(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, int index, int direction, int mode)4879     private void dispatchAbsoluteVolumeAdjusted(int streamType,
4880             AbsoluteVolumeDeviceInfo deviceInfo, int index, int direction, int mode) {
4881         VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType);
4882         if (volumeInfo != null) {
4883             try {
4884                 deviceInfo.mCallback.dispatchDeviceVolumeAdjusted(deviceInfo.mDevice,
4885                         new VolumeInfo.Builder(volumeInfo)
4886                                 .setVolumeIndex(rescaleIndex(index, streamType, volumeInfo))
4887                                 .build(),
4888                         direction,
4889                         mode);
4890             } catch (RemoteException e) {
4891                 Log.w(TAG, "Couldn't dispatch absolute volume behavior volume adjustment");
4892             }
4893         }
4894     }
4895 
4896     // No ringer or zen muted stream volumes can be changed unless it'll exit dnd
volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags)4897     private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) {
4898         switch (mNm.getZenMode()) {
4899             case Settings.Global.ZEN_MODE_OFF:
4900                 return true;
4901             case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
4902             case Settings.Global.ZEN_MODE_ALARMS:
4903             case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
4904                 return !isStreamMutedByRingerOrZenMode(streamTypeAlias)
4905                         || isUiSoundsStreamType(streamTypeAlias)
4906                         || (flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0;
4907         }
4908 
4909         return true;
4910     }
4911 
4912     /** @see AudioManager#forceVolumeControlStream(int) */
forceVolumeControlStream(int streamType, IBinder cb)4913     public void forceVolumeControlStream(int streamType, IBinder cb) {
4914         if (mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE)
4915                 != PackageManager.PERMISSION_GRANTED) {
4916             return;
4917         }
4918         if (DEBUG_VOL) { Log.d(TAG, String.format("forceVolumeControlStream(%d)", streamType)); }
4919         synchronized(mForceControlStreamLock) {
4920             if (mVolumeControlStream != -1 && streamType != -1) {
4921                 mUserSelectedVolumeControlStream = true;
4922             }
4923             mVolumeControlStream = streamType;
4924             if (mVolumeControlStream == -1) {
4925                 if (mForceControlStreamClient != null) {
4926                     mForceControlStreamClient.release();
4927                     mForceControlStreamClient = null;
4928                 }
4929                 mUserSelectedVolumeControlStream = false;
4930             } else {
4931                 if (null == mForceControlStreamClient) {
4932                     mForceControlStreamClient = new ForceControlStreamClient(cb);
4933                 } else {
4934                     if (mForceControlStreamClient.getBinder() == cb) {
4935                         Log.d(TAG, "forceVolumeControlStream cb:" + cb + " is already linked.");
4936                     } else {
4937                         mForceControlStreamClient.release();
4938                         mForceControlStreamClient = new ForceControlStreamClient(cb);
4939                     }
4940                 }
4941             }
4942         }
4943     }
4944 
4945     private class ForceControlStreamClient implements IBinder.DeathRecipient {
4946         private IBinder mCb; // To be notified of client's death
4947 
ForceControlStreamClient(IBinder cb)4948         ForceControlStreamClient(IBinder cb) {
4949             if (cb != null) {
4950                 try {
4951                     cb.linkToDeath(this, 0);
4952                 } catch (RemoteException e) {
4953                     // Client has died!
4954                     Log.w(TAG, "ForceControlStreamClient() could not link to "+cb+" binder death");
4955                     cb = null;
4956                 }
4957             }
4958             mCb = cb;
4959         }
4960 
binderDied()4961         public void binderDied() {
4962             synchronized(mForceControlStreamLock) {
4963                 Log.w(TAG, "SCO client died");
4964                 if (mForceControlStreamClient != this) {
4965                     Log.w(TAG, "unregistered control stream client died");
4966                 } else {
4967                     mForceControlStreamClient = null;
4968                     mVolumeControlStream = -1;
4969                     mUserSelectedVolumeControlStream = false;
4970                 }
4971             }
4972         }
4973 
release()4974         public void release() {
4975             if (mCb != null) {
4976                 mCb.unlinkToDeath(this, 0);
4977                 mCb = null;
4978             }
4979         }
4980 
getBinder()4981         public IBinder getBinder() {
4982             return mCb;
4983         }
4984     }
4985 
sendBroadcastToAll(Intent intent, Bundle options)4986     private void sendBroadcastToAll(Intent intent, Bundle options) {
4987         if (!mSystemServer.isPrivileged()) {
4988             return;
4989         }
4990         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
4991         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
4992         final long ident = Binder.clearCallingIdentity();
4993         try {
4994             mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
4995                     null /* receiverPermission */, options);
4996         } finally {
4997             Binder.restoreCallingIdentity(ident);
4998         }
4999     }
5000 
sendStickyBroadcastToAll(Intent intent)5001     private void sendStickyBroadcastToAll(Intent intent) {
5002         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
5003         final long ident = Binder.clearCallingIdentity();
5004         try {
5005             mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
5006         } finally {
5007             Binder.restoreCallingIdentity(ident);
5008         }
5009     }
5010 
getCurrentUserId()5011     private int getCurrentUserId() {
5012         final long ident = Binder.clearCallingIdentity();
5013         try {
5014             UserInfo currentUser = ActivityManager.getService().getCurrentUser();
5015             return currentUser.id;
5016         } catch (RemoteException e) {
5017             // Activity manager not running, nothing we can do assume user 0.
5018         } finally {
5019             Binder.restoreCallingIdentity(ident);
5020         }
5021         return UserHandle.USER_SYSTEM;
5022     }
5023 
5024     // UI update and Broadcast Intent
sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device)5025     protected void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device)
5026     {
5027         streamType = mStreamVolumeAlias[streamType];
5028 
5029         if (streamType == AudioSystem.STREAM_MUSIC && isFullVolumeDevice(device)) {
5030             flags &= ~AudioManager.FLAG_SHOW_UI;
5031         }
5032         mVolumeController.postVolumeChanged(streamType, flags);
5033     }
5034 
5035     // Don't show volume UI when:
5036     //  - Hdmi-CEC system audio mode is on and we are a TV panel
updateFlagsForTvPlatform(int flags)5037     private int updateFlagsForTvPlatform(int flags) {
5038         synchronized (mHdmiClientLock) {
5039             if (mHdmiTvClient != null && mHdmiSystemAudioSupported
5040                     && mHdmiCecVolumeControlEnabled) {
5041                 flags &= ~AudioManager.FLAG_SHOW_UI;
5042             }
5043         }
5044         return flags;
5045     }
5046     // UI update and Broadcast Intent
sendMasterMuteUpdate(boolean muted, int flags)5047     private void sendMasterMuteUpdate(boolean muted, int flags) {
5048         mVolumeController.postMasterMuteChanged(updateFlagsForTvPlatform(flags));
5049         sendMsg(mAudioHandler, MSG_BROADCAST_MASTER_MUTE,
5050                 SENDMSG_QUEUE, muted ? 1 : 0, 0, null, 0);
5051     }
5052 
5053 
5054     /**
5055      * Sets the stream state's index, and posts a message to set system volume.
5056      * This will not call out to the UI. Assumes a valid stream type.
5057      *
5058      * @param streamType Type of the stream
5059      * @param index Desired volume index of the stream
5060      * @param device the device whose volume must be changed
5061      * @param force If true, set the volume even if the desired volume is same
5062      * @param caller
5063      * @param hasModifyAudioSettings true if the caller is granted MODIFY_AUDIO_SETTINGS or
5064      *                              MODIFY_AUDIO_ROUTING permission
5065      * as the current volume.
5066      */
setStreamVolumeInt(int streamType, int index, int device, boolean force, String caller, boolean hasModifyAudioSettings)5067     private void setStreamVolumeInt(int streamType,
5068                                     int index,
5069                                     int device,
5070                                     boolean force,
5071                                     String caller, boolean hasModifyAudioSettings) {
5072         if (isFullVolumeDevice(device)) {
5073             return;
5074         }
5075         VolumeStreamState streamState = mStreamStates[streamType];
5076 
5077         if (streamState.setIndex(index, device, caller, hasModifyAudioSettings) || force) {
5078             // Post message to set system volume (it in turn will post a message
5079             // to persist).
5080             sendMsg(mAudioHandler,
5081                     MSG_SET_DEVICE_VOLUME,
5082                     SENDMSG_QUEUE,
5083                     device,
5084                     0,
5085                     streamState,
5086                     0);
5087         }
5088     }
5089 
5090     /** get stream mute state. */
isStreamMute(int streamType)5091     public boolean isStreamMute(int streamType) {
5092         if (streamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
5093             streamType = getActiveStreamType(streamType);
5094         }
5095         synchronized (VolumeStreamState.class) {
5096             ensureValidStreamType(streamType);
5097             return mStreamStates[streamType].mIsMuted;
5098         }
5099     }
5100 
5101     private class RmtSbmxFullVolDeathHandler implements IBinder.DeathRecipient {
5102         private IBinder mICallback; // To be notified of client's death
5103 
RmtSbmxFullVolDeathHandler(IBinder cb)5104         RmtSbmxFullVolDeathHandler(IBinder cb) {
5105             mICallback = cb;
5106             try {
5107                 cb.linkToDeath(this, 0/*flags*/);
5108             } catch (RemoteException e) {
5109                 Log.e(TAG, "can't link to death", e);
5110             }
5111         }
5112 
isHandlerFor(IBinder cb)5113         boolean isHandlerFor(IBinder cb) {
5114             return mICallback.equals(cb);
5115         }
5116 
forget()5117         void forget() {
5118             try {
5119                 mICallback.unlinkToDeath(this, 0/*flags*/);
5120             } catch (NoSuchElementException e) {
5121                 Log.e(TAG, "error unlinking to death", e);
5122             }
5123         }
5124 
binderDied()5125         public void binderDied() {
5126             Log.w(TAG, "Recorder with remote submix at full volume died " + mICallback);
5127             forceRemoteSubmixFullVolume(false, mICallback);
5128         }
5129     }
5130 
5131     /**
5132      * call must be synchronized on mRmtSbmxFullVolDeathHandlers
5133      * @return true if there is a registered death handler, false otherwise */
discardRmtSbmxFullVolDeathHandlerFor(IBinder cb)5134     private boolean discardRmtSbmxFullVolDeathHandlerFor(IBinder cb) {
5135         Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator();
5136         while (it.hasNext()) {
5137             final RmtSbmxFullVolDeathHandler handler = it.next();
5138             if (handler.isHandlerFor(cb)) {
5139                 handler.forget();
5140                 mRmtSbmxFullVolDeathHandlers.remove(handler);
5141                 return true;
5142             }
5143         }
5144         return false;
5145     }
5146 
5147     /** call synchronized on mRmtSbmxFullVolDeathHandlers */
hasRmtSbmxFullVolDeathHandlerFor(IBinder cb)5148     private boolean hasRmtSbmxFullVolDeathHandlerFor(IBinder cb) {
5149         Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator();
5150         while (it.hasNext()) {
5151             if (it.next().isHandlerFor(cb)) {
5152                 return true;
5153             }
5154         }
5155         return false;
5156     }
5157 
5158     private int mRmtSbmxFullVolRefCount = 0;
5159     private final ArrayList<RmtSbmxFullVolDeathHandler> mRmtSbmxFullVolDeathHandlers =
5160             new ArrayList<RmtSbmxFullVolDeathHandler>();
5161 
forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb)5162     public void forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb) {
5163         if (cb == null) {
5164             return;
5165         }
5166         if ((PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
5167                         CAPTURE_AUDIO_OUTPUT))) {
5168             Log.w(TAG, "Trying to call forceRemoteSubmixFullVolume() without CAPTURE_AUDIO_OUTPUT");
5169             return;
5170         }
5171         synchronized(mRmtSbmxFullVolDeathHandlers) {
5172             boolean applyRequired = false;
5173             if (startForcing) {
5174                 if (!hasRmtSbmxFullVolDeathHandlerFor(cb)) {
5175                     mRmtSbmxFullVolDeathHandlers.add(new RmtSbmxFullVolDeathHandler(cb));
5176                     if (mRmtSbmxFullVolRefCount == 0) {
5177                         mFullVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
5178                         mFixedVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
5179                         applyRequired = true;
5180                     }
5181                     mRmtSbmxFullVolRefCount++;
5182                 }
5183             } else {
5184                 if (discardRmtSbmxFullVolDeathHandlerFor(cb) && (mRmtSbmxFullVolRefCount > 0)) {
5185                     mRmtSbmxFullVolRefCount--;
5186                     if (mRmtSbmxFullVolRefCount == 0) {
5187                         mFullVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
5188                         mFixedVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
5189                         applyRequired = true;
5190                     }
5191                 }
5192             }
5193             if (applyRequired) {
5194                 // Assumes only STREAM_MUSIC going through DEVICE_OUT_REMOTE_SUBMIX
5195                 checkAllFixedVolumeDevices(AudioSystem.STREAM_MUSIC);
5196                 mStreamStates[AudioSystem.STREAM_MUSIC].applyAllVolumes();
5197             }
5198         }
5199     }
5200 
setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, int userId, int pid, String attributionTag)5201     private void setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid,
5202             int userId, int pid, String attributionTag) {
5203         // If we are being called by the system check for user we are going to change
5204         // so we handle user restrictions correctly.
5205         if (uid == android.os.Process.SYSTEM_UID) {
5206             uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
5207         }
5208         // If OP_AUDIO_MASTER_VOLUME is set, disallow unmuting.
5209         if (!mute && !checkNoteAppOp(
5210                 AppOpsManager.OP_AUDIO_MASTER_VOLUME, uid, callingPackage, attributionTag)) {
5211             return;
5212         }
5213         if (userId != UserHandle.getCallingUserId() &&
5214                 mContext.checkPermission(INTERACT_ACROSS_USERS_FULL, pid, uid)
5215                 != PackageManager.PERMISSION_GRANTED) {
5216             return;
5217         }
5218         setMasterMuteInternalNoCallerCheck(mute, flags, userId, "setMasterMute");
5219     }
5220 
setMasterMuteInternalNoCallerCheck( boolean mute, int flags, int userId, String eventSource)5221     private void setMasterMuteInternalNoCallerCheck(
5222             boolean mute, int flags, int userId, String eventSource) {
5223         if (DEBUG_VOL) {
5224             Log.d(TAG, TextUtils.formatSimple("Master mute %s, flags 0x%x, userId=%d from %s",
5225                     mute, flags, userId, eventSource));
5226         }
5227 
5228         if (!isPlatformAutomotive() && mUseFixedVolume) {
5229             // If using fixed volume, we don't mute.
5230             // TODO: remove the isPlatformAutomotive check here.
5231             // The isPlatformAutomotive check is added for safety but may not be necessary.
5232             mute = false;
5233         }
5234         // For automotive,
5235         // - the car service is always running as system user
5236         // - foreground users are non-system users
5237         // Car service is in charge of dispatching the key event include global mute to Android.
5238         // Therefore, the getCurrentUser() is always different to the foreground user.
5239         if ((isPlatformAutomotive() && userId == UserHandle.USER_SYSTEM)
5240                 || (getCurrentUserId() == userId)) {
5241             if (mute != mMasterMute.getAndSet(mute)) {
5242                 sVolumeLogger.enqueue(new VolumeEvent(
5243                         VolumeEvent.VOL_MASTER_MUTE, mute));
5244                 mAudioSystem.setMasterMute(mute);
5245                 sendMasterMuteUpdate(mute, flags);
5246             }
5247         }
5248     }
5249 
5250     /** get global mute state. */
isMasterMute()5251     public boolean isMasterMute() {
5252         return mMasterMute.get();
5253     }
5254 
5255     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
5256     /** @see AudioManager#setMasterMute(boolean, int) */
setMasterMute(boolean mute, int flags, String callingPackage, int userId, String attributionTag)5257     public void setMasterMute(boolean mute, int flags, String callingPackage, int userId,
5258             String attributionTag) {
5259 
5260         super.setMasterMute_enforcePermission();
5261 
5262         setMasterMuteInternal(mute, flags, callingPackage,
5263                 Binder.getCallingUid(), userId, Binder.getCallingPid(), attributionTag);
5264     }
5265 
5266     /** @see AudioManager#getStreamVolume(int) */
getStreamVolume(int streamType)5267     public int getStreamVolume(int streamType) {
5268         ensureValidStreamType(streamType);
5269         int device = getDeviceForStream(streamType);
5270         return getStreamVolume(streamType, device);
5271     }
5272 
getStreamVolume(int streamType, int device)5273     private int getStreamVolume(int streamType, int device) {
5274         synchronized (VolumeStreamState.class) {
5275             int index = mStreamStates[streamType].getIndex(device);
5276 
5277             // by convention getStreamVolume() returns 0 when a stream is muted.
5278             if (mStreamStates[streamType].mIsMuted) {
5279                 index = 0;
5280             }
5281             if (index != 0 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
5282                     isFixedVolumeDevice(device)) {
5283                 index = mStreamStates[streamType].getMaxIndex();
5284             }
5285             return (index + 5) / 10;
5286         }
5287     }
5288 
5289     @Override
5290     @android.annotation.EnforcePermission(anyOf = {
5291             MODIFY_AUDIO_ROUTING, MODIFY_AUDIO_SETTINGS_PRIVILEGED })
5292     /**
5293      * @see AudioDeviceVolumeManager#getDeviceVolume(VolumeInfo, AudioDeviceAttributes)
5294      */
getDeviceVolume(@onNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage)5295     public @NonNull VolumeInfo getDeviceVolume(@NonNull VolumeInfo vi,
5296             @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage) {
5297         super.getDeviceVolume_enforcePermission();
5298         Objects.requireNonNull(vi);
5299         Objects.requireNonNull(ada);
5300         Objects.requireNonNull(callingPackage);
5301         if (!vi.hasStreamType()) {
5302             Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception());
5303             return getDefaultVolumeInfo();
5304         }
5305 
5306         int streamType = vi.getStreamType();
5307         final VolumeInfo.Builder vib = new VolumeInfo.Builder(vi);
5308         vib.setMinVolumeIndex((mStreamStates[streamType].mIndexMin + 5) / 10);
5309         vib.setMaxVolumeIndex((mStreamStates[streamType].mIndexMax + 5) / 10);
5310         synchronized (VolumeStreamState.class) {
5311             final int index;
5312             if (isFixedVolumeDevice(ada.getInternalType())) {
5313                 index = (mStreamStates[streamType].mIndexMax + 5) / 10;
5314             } else {
5315                 index = (mStreamStates[streamType].getIndex(ada.getInternalType()) + 5) / 10;
5316             }
5317             vib.setVolumeIndex(index);
5318             // only set as a mute command if stream muted
5319             if (mStreamStates[streamType].mIsMuted) {
5320                 vib.setMuted(true);
5321             }
5322             return vib.build();
5323         }
5324     }
5325 
5326     /** @see AudioManager#getStreamMaxVolume(int) */
getStreamMaxVolume(int streamType)5327     public int getStreamMaxVolume(int streamType) {
5328         ensureValidStreamType(streamType);
5329         return (mStreamStates[streamType].getMaxIndex() + 5) / 10;
5330     }
5331 
5332     /** @see AudioManager#getStreamMinVolumeInt(int)
5333      * Part of service interface, check permissions here */
getStreamMinVolume(int streamType)5334     public int getStreamMinVolume(int streamType) {
5335         ensureValidStreamType(streamType);
5336         final boolean isPrivileged =
5337                 Binder.getCallingUid() == Process.SYSTEM_UID
5338                  || callingHasAudioSettingsPermission()
5339                  || (mContext.checkCallingPermission(MODIFY_AUDIO_ROUTING)
5340                         == PackageManager.PERMISSION_GRANTED);
5341         return (mStreamStates[streamType].getMinIndex(isPrivileged) + 5) / 10;
5342     }
5343 
5344     @android.annotation.EnforcePermission(QUERY_AUDIO_STATE)
5345     /** Get last audible volume before stream was muted. */
getLastAudibleStreamVolume(int streamType)5346     public int getLastAudibleStreamVolume(int streamType) {
5347         super.getLastAudibleStreamVolume_enforcePermission();
5348 
5349         ensureValidStreamType(streamType);
5350         int device = getDeviceForStream(streamType);
5351         return (mStreamStates[streamType].getIndex(device) + 5) / 10;
5352     }
5353 
5354     /**
5355      * Default VolumeInfo returned by {@link VolumeInfo#getDefaultVolumeInfo()}
5356      * Lazily initialized in {@link #getDefaultVolumeInfo()}
5357      */
5358     static VolumeInfo sDefaultVolumeInfo;
5359 
5360     /** @see VolumeInfo#getDefaultVolumeInfo() */
getDefaultVolumeInfo()5361     public VolumeInfo getDefaultVolumeInfo() {
5362         if (sDefaultVolumeInfo == null) {
5363             sDefaultVolumeInfo = new VolumeInfo.Builder(AudioSystem.STREAM_MUSIC)
5364                     .setMinVolumeIndex(getStreamMinVolume(AudioSystem.STREAM_MUSIC))
5365                     .setMaxVolumeIndex(getStreamMaxVolume(AudioSystem.STREAM_MUSIC))
5366                     .build();
5367         }
5368         return sDefaultVolumeInfo;
5369     }
5370 
5371     /**
5372      * list of callback dispatchers for stream aliasing updates
5373      */
5374     final RemoteCallbackList<IStreamAliasingDispatcher> mStreamAliasingDispatchers =
5375             new RemoteCallbackList<IStreamAliasingDispatcher>();
5376 
5377     /**
5378      * Register/unregister a callback for stream aliasing updates
5379      * @param isad the callback dispatcher
5380      * @param register whether this for a registration or unregistration
5381      * @see AudioManager#addOnStreamAliasingChangedListener(Executor, Runnable)
5382      * @see AudioManager#removeOnStreamAliasingChangedListener(Runnable)
5383      */
5384     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
registerStreamAliasingDispatcher(IStreamAliasingDispatcher isad, boolean register)5385     public void registerStreamAliasingDispatcher(IStreamAliasingDispatcher isad, boolean register) {
5386         super.registerStreamAliasingDispatcher_enforcePermission();
5387         Objects.requireNonNull(isad);
5388 
5389         if (register) {
5390             mStreamAliasingDispatchers.register(isad);
5391         } else {
5392             mStreamAliasingDispatchers.unregister(isad);
5393         }
5394     }
5395 
dispatchStreamAliasingUpdate()5396     protected void dispatchStreamAliasingUpdate() {
5397         final int nbDispatchers = mStreamAliasingDispatchers.beginBroadcast();
5398         for (int i = 0; i < nbDispatchers; i++) {
5399             try {
5400                 mStreamAliasingDispatchers.getBroadcastItem(i).dispatchStreamAliasingChanged();
5401             } catch (RemoteException e) {
5402                 Log.e(TAG, "Error on stream alias update dispatch", e);
5403             }
5404         }
5405         mStreamAliasingDispatchers.finishBroadcast();
5406     }
5407 
5408     /**
5409      * @see AudioManager#getIndependentStreamTypes()
5410      * @return the list of non-aliased stream types
5411      */
5412     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
getIndependentStreamTypes()5413     public ArrayList<Integer> getIndependentStreamTypes() {
5414         super.getIndependentStreamTypes_enforcePermission();
5415 
5416         if (mUseVolumeGroupAliases) {
5417             return new ArrayList<>(Arrays.stream(AudioManager.getPublicStreamTypes())
5418                     .boxed().toList());
5419         }
5420         ArrayList<Integer> res = new ArrayList(1);
5421         for (int stream : mStreamVolumeAlias) {
5422             if (!res.contains(stream)) {
5423                 res.add(stream);
5424             }
5425         }
5426         return res;
5427     }
5428 
5429     /**
5430      * @see AudioManager#getStreamTypeAlias(int)
5431      * @param sourceStreamType the stream type for which the alias is queried
5432      * @return the stream alias
5433      */
5434     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
5435     public @AudioManager.PublicStreamTypes
getStreamTypeAlias(@udioManager.PublicStreamTypes int sourceStreamType)5436     int getStreamTypeAlias(@AudioManager.PublicStreamTypes int sourceStreamType) {
5437         super.getStreamTypeAlias_enforcePermission();
5438         // verify parameters
5439         ensureValidStreamType(sourceStreamType);
5440 
5441         return mStreamVolumeAlias[sourceStreamType];
5442     }
5443 
5444     /**
5445      * @see AudioManager#isVolumeControlUsingVolumeGroups()
5446      * @return true when volume control is performed through volume groups, false if it uses
5447      *     stream types.
5448      */
5449     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
isVolumeControlUsingVolumeGroups()5450     public boolean isVolumeControlUsingVolumeGroups() {
5451         super.isVolumeControlUsingVolumeGroups_enforcePermission();
5452 
5453         return mUseVolumeGroupAliases;
5454     }
5455 
5456     /** @see AudioManager#getUiSoundsStreamType()
5457      * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for
5458      * UI Sounds identification.
5459      * Fallback on Voice configuration to ensure correct behavior of DnD feature.
5460      */
getUiSoundsStreamType()5461     public int getUiSoundsStreamType() {
5462         return mUseVolumeGroupAliases ? STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM]
5463                 : mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM];
5464     }
5465 
5466     /**
5467      * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for
5468      * UI Sounds identification.
5469      * Fallback on Voice configuration to ensure correct behavior of DnD feature.
5470      */
isUiSoundsStreamType(int aliasStreamType)5471     private boolean isUiSoundsStreamType(int aliasStreamType) {
5472         return mUseVolumeGroupAliases
5473                 ? STREAM_VOLUME_ALIAS_VOICE[aliasStreamType]
5474                         == STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM]
5475                 : aliasStreamType == mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM];
5476     }
5477 
5478     /** @see AudioManager#setMicrophoneMute(boolean) */
5479     @Override
setMicrophoneMute(boolean on, String callingPackage, int userId, String attributionTag)5480     public void setMicrophoneMute(boolean on, String callingPackage, int userId,
5481             String attributionTag) {
5482         // If we are being called by the system check for user we are going to change
5483         // so we handle user restrictions correctly.
5484         int uid = Binder.getCallingUid();
5485         if (uid == android.os.Process.SYSTEM_UID) {
5486             uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
5487         }
5488         MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
5489                 .setUid(uid)
5490                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage)
5491                 .set(MediaMetrics.Property.EVENT, "setMicrophoneMute")
5492                 .set(MediaMetrics.Property.REQUEST, on
5493                         ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE);
5494 
5495         // If OP_MUTE_MICROPHONE is set, disallow unmuting.
5496         if (!on && !checkNoteAppOp(
5497                 AppOpsManager.OP_MUTE_MICROPHONE, uid, callingPackage, attributionTag)) {
5498             mmi.set(MediaMetrics.Property.EARLY_RETURN, "disallow unmuting").record();
5499             return;
5500         }
5501         if (!checkAudioSettingsPermission("setMicrophoneMute()")) {
5502             mmi.set(MediaMetrics.Property.EARLY_RETURN, "!checkAudioSettingsPermission").record();
5503             return;
5504         }
5505         if (userId != UserHandle.getCallingUserId() &&
5506                 mContext.checkCallingOrSelfPermission(INTERACT_ACROSS_USERS_FULL)
5507                 != PackageManager.PERMISSION_GRANTED) {
5508             mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission").record();
5509             return;
5510         }
5511         mMicMuteFromApi = on;
5512         mmi.record(); // record now, the no caller check will set the mute state.
5513         setMicrophoneMuteNoCallerCheck(userId);
5514     }
5515 
5516     /** @see AudioManager#setMicrophoneMuteFromSwitch(boolean) */
setMicrophoneMuteFromSwitch(boolean on)5517     public void setMicrophoneMuteFromSwitch(boolean on) {
5518         int callingUid = Binder.getCallingUid();
5519         if (callingUid != android.os.Process.SYSTEM_UID) {
5520             Log.e(TAG, "setMicrophoneMuteFromSwitch() called from non system user!");
5521             return;
5522         }
5523         mMicMuteFromSwitch = on;
5524         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
5525                 .setUid(callingUid)
5526                 .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteFromSwitch")
5527                 .set(MediaMetrics.Property.REQUEST, on
5528                         ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE)
5529                 .record();
5530         setMicrophoneMuteNoCallerCheck(UserHandle.getCallingUserId());
5531     }
5532 
setMicMuteFromSwitchInput()5533     private void setMicMuteFromSwitchInput() {
5534         InputManager im = mContext.getSystemService(InputManager.class);
5535         final int isMicMuted = im.isMicMuted();
5536         if (isMicMuted != InputManager.SWITCH_STATE_UNKNOWN) {
5537             setMicrophoneMuteFromSwitch(im.isMicMuted() != InputManager.SWITCH_STATE_OFF);
5538         }
5539     }
5540 
5541     /**
5542      * Returns the microphone mute state as seen from the native audio system
5543      * @return true if microphone is reported as muted by primary HAL
5544      */
isMicrophoneMuted()5545     public boolean isMicrophoneMuted() {
5546         return mMicMuteFromSystemCached
5547                 && (!mMicMuteFromPrivacyToggle
5548                         || mMicMuteFromApi || mMicMuteFromRestrictions || mMicMuteFromSwitch);
5549     }
5550 
isMicrophoneSupposedToBeMuted()5551     private boolean isMicrophoneSupposedToBeMuted() {
5552         return mMicMuteFromSwitch || mMicMuteFromRestrictions || mMicMuteFromApi
5553                 || mMicMuteFromPrivacyToggle;
5554     }
5555 
setMicrophoneMuteNoCallerCheck(int userId)5556     private void setMicrophoneMuteNoCallerCheck(int userId) {
5557         final boolean muted = isMicrophoneSupposedToBeMuted();
5558         if (DEBUG_VOL) {
5559             Log.d(TAG, String.format("Mic mute %b, user=%d", muted, userId));
5560         }
5561         // only mute for the current user or for the system user.
5562         if (getCurrentUserId() == userId || userId == UserHandle.USER_SYSTEM) {
5563             final boolean currentMute = mAudioSystem.isMicrophoneMuted();
5564             int callingUid = Binder.getCallingUid();
5565             final long identity = Binder.clearCallingIdentity();
5566             try {
5567                 final int ret = mAudioSystem.muteMicrophone(muted);
5568 
5569                 // update cache with the real state independently from what was set
5570                 mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted();
5571                 if (ret != AudioSystem.AUDIO_STATUS_OK) {
5572                     Log.e(TAG, "Error changing mic mute state to " + muted + " current:"
5573                             + mMicMuteFromSystemCached);
5574                 }
5575 
5576                 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
5577                         .setUid(callingUid)
5578                         .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteNoCallerCheck")
5579                         .set(MediaMetrics.Property.MUTE, mMicMuteFromSystemCached
5580                                 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
5581                         .set(MediaMetrics.Property.REQUEST, muted
5582                                 ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE)
5583                         .set(MediaMetrics.Property.STATUS, ret)
5584                         .record();
5585 
5586                 // send the intent even if there was a failure to change the actual mute state:
5587                 // the AudioManager.setMicrophoneMute API doesn't have a return value to
5588                 // indicate if the call failed to successfully change the mute state, and receiving
5589                 // the intent may be the only time an application can resynchronize its mic mute
5590                 // state with the actual system mic mute state
5591                 if (muted != currentMute) {
5592                     sendMsg(mAudioHandler, MSG_BROADCAST_MICROPHONE_MUTE,
5593                                 SENDMSG_NOOP, 0, 0, null, 0);
5594                 }
5595             } finally {
5596                 Binder.restoreCallingIdentity(identity);
5597             }
5598         }
5599     }
5600 
5601     @Override
getRingerModeExternal()5602     public int getRingerModeExternal() {
5603         synchronized(mSettingsLock) {
5604             return mRingerModeExternal;
5605         }
5606     }
5607 
5608     @Override
getRingerModeInternal()5609     public int getRingerModeInternal() {
5610         synchronized(mSettingsLock) {
5611             return mRingerMode;
5612         }
5613     }
5614 
ensureValidRingerMode(int ringerMode)5615     private void ensureValidRingerMode(int ringerMode) {
5616         if (!isValidRingerMode(ringerMode)) {
5617             throw new IllegalArgumentException("Bad ringer mode " + ringerMode);
5618         }
5619     }
5620 
5621     /** @see AudioManager#isValidRingerMode(int) */
isValidRingerMode(int ringerMode)5622     public boolean isValidRingerMode(int ringerMode) {
5623         return ringerMode >= 0 && ringerMode <= AudioManager.RINGER_MODE_MAX;
5624     }
5625 
setRingerModeExternal(int ringerMode, String caller)5626     public void setRingerModeExternal(int ringerMode, String caller) {
5627         if (mHardeningEnforcer.blockVolumeMethod(
5628                 HardeningEnforcer.METHOD_AUDIO_MANAGER_SET_RINGER_MODE)) {
5629             return;
5630         }
5631         if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode)
5632                 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)) {
5633             throw new SecurityException("Not allowed to change Do Not Disturb state");
5634         }
5635 
5636         setRingerMode(ringerMode, caller, true /*external*/);
5637     }
5638 
setRingerModeInternal(int ringerMode, String caller)5639     public void setRingerModeInternal(int ringerMode, String caller) {
5640         enforceVolumeController("setRingerModeInternal");
5641         setRingerMode(ringerMode, caller, false /*external*/);
5642     }
5643 
silenceRingerModeInternal(String reason)5644     public void silenceRingerModeInternal(String reason) {
5645         VibrationEffect effect = null;
5646         int ringerMode = AudioManager.RINGER_MODE_SILENT;
5647         int toastText = 0;
5648 
5649         int silenceRingerSetting = Settings.Secure.VOLUME_HUSH_OFF;
5650         if (mContext.getResources()
5651                 .getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled)) {
5652             silenceRingerSetting = mSettings.getSecureIntForUser(mContentResolver,
5653                     Settings.Secure.VOLUME_HUSH_GESTURE, VOLUME_HUSH_OFF,
5654                     UserHandle.USER_CURRENT);
5655         }
5656 
5657         switch(silenceRingerSetting) {
5658             case VOLUME_HUSH_MUTE:
5659                 effect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK);
5660                 ringerMode = AudioManager.RINGER_MODE_SILENT;
5661                 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_silent;
5662                 break;
5663             case VOLUME_HUSH_VIBRATE:
5664                 effect = VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK);
5665                 ringerMode = AudioManager.RINGER_MODE_VIBRATE;
5666                 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_vibrate;
5667                 break;
5668         }
5669         maybeVibrate(effect, reason);
5670         setRingerModeInternal(ringerMode, reason);
5671         Toast.makeText(mContext, toastText, Toast.LENGTH_SHORT).show();
5672     }
5673 
maybeVibrate(VibrationEffect effect, String reason)5674     private boolean maybeVibrate(VibrationEffect effect, String reason) {
5675         if (!mHasVibrator) {
5676             return false;
5677         }
5678         if (effect == null) {
5679             return false;
5680         }
5681         mVibrator.vibrate(Binder.getCallingUid(), mContext.getOpPackageName(), effect,
5682                 reason, TOUCH_VIBRATION_ATTRIBUTES);
5683         return true;
5684     }
5685 
setRingerMode(int ringerMode, String caller, boolean external)5686     private void setRingerMode(int ringerMode, String caller, boolean external) {
5687         if (mUseFixedVolume || mIsSingleVolume || mUseVolumeGroupAliases) {
5688             return;
5689         }
5690         if (caller == null || caller.length() == 0) {
5691             throw new IllegalArgumentException("Bad caller: " + caller);
5692         }
5693         ensureValidRingerMode(ringerMode);
5694         if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) {
5695             ringerMode = AudioManager.RINGER_MODE_SILENT;
5696         }
5697         final long identity = Binder.clearCallingIdentity();
5698         try {
5699             synchronized (mSettingsLock) {
5700                 final int ringerModeInternal = getRingerModeInternal();
5701                 final int ringerModeExternal = getRingerModeExternal();
5702                 if (external) {
5703                     setRingerModeExt(ringerMode);
5704                     if (mRingerModeDelegate != null) {
5705                         ringerMode = mRingerModeDelegate.onSetRingerModeExternal(ringerModeExternal,
5706                                 ringerMode, caller, ringerModeInternal, mVolumePolicy);
5707                     }
5708                     if (ringerMode != ringerModeInternal) {
5709                         setRingerModeInt(ringerMode, true /*persist*/);
5710                     }
5711                 } else /*internal*/ {
5712                     if (ringerMode != ringerModeInternal) {
5713                         setRingerModeInt(ringerMode, true /*persist*/);
5714                     }
5715                     if (mRingerModeDelegate != null) {
5716                         ringerMode = mRingerModeDelegate.onSetRingerModeInternal(ringerModeInternal,
5717                                 ringerMode, caller, ringerModeExternal, mVolumePolicy);
5718                     }
5719                     setRingerModeExt(ringerMode);
5720                 }
5721             }
5722         } finally {
5723             Binder.restoreCallingIdentity(identity);
5724         }
5725     }
5726 
setRingerModeExt(int ringerMode)5727     private void setRingerModeExt(int ringerMode) {
5728         synchronized(mSettingsLock) {
5729             if (ringerMode == mRingerModeExternal) return;
5730             mRingerModeExternal = ringerMode;
5731         }
5732         // Send sticky broadcast
5733         broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, ringerMode);
5734     }
5735 
5736     @GuardedBy("mSettingsLock")
muteRingerModeStreams()5737     private void muteRingerModeStreams() {
5738         // Mute stream if not previously muted by ringer mode and (ringer mode
5739         // is not RINGER_MODE_NORMAL OR stream is zen muted) and stream is affected by ringer mode.
5740         // Unmute stream if previously muted by ringer/zen mode and ringer mode
5741         // is RINGER_MODE_NORMAL or stream is not affected by ringer mode.
5742         int numStreamTypes = AudioSystem.getNumStreamTypes();
5743 
5744         if (mNm == null) {
5745             mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
5746         }
5747 
5748         final int ringerMode = mRingerMode; // Read ringer mode as reading primitives is atomic
5749         final boolean ringerModeMute = ringerMode == AudioManager.RINGER_MODE_VIBRATE
5750                 || ringerMode == AudioManager.RINGER_MODE_SILENT;
5751         final boolean shouldRingSco = ringerMode == AudioManager.RINGER_MODE_VIBRATE
5752                 && mDeviceBroker.isBluetoothScoActive();
5753         // Ask audio policy engine to force use Bluetooth SCO channel if needed
5754         final String eventSource = "muteRingerModeStreams() from u/pid:" + Binder.getCallingUid()
5755                 + "/" + Binder.getCallingPid();
5756         sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, AudioSystem.FOR_VIBRATE_RINGING,
5757                 shouldRingSco ? AudioSystem.FORCE_BT_SCO : AudioSystem.FORCE_NONE, eventSource, 0);
5758 
5759         for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
5760             final boolean isMuted = isStreamMutedByRingerOrZenMode(streamType);
5761             final boolean muteAllowedBySco =
5762                     !(shouldRingSco && streamType == AudioSystem.STREAM_RING);
5763             final boolean shouldZenMute = isStreamAffectedByCurrentZen(streamType);
5764             final boolean shouldMute = shouldZenMute || (ringerModeMute
5765                     && isStreamAffectedByRingerMode(streamType) && muteAllowedBySco);
5766             if (isMuted == shouldMute) continue;
5767             if (!shouldMute) {
5768                 // unmute
5769                 // ring and notifications volume should never be 0 when not silenced
5770                 if (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING
5771                         || mStreamVolumeAlias[streamType] == AudioSystem.STREAM_NOTIFICATION) {
5772                     synchronized (VolumeStreamState.class) {
5773                         final VolumeStreamState vss = mStreamStates[streamType];
5774                         for (int i = 0; i < vss.mIndexMap.size(); i++) {
5775                             int device = vss.mIndexMap.keyAt(i);
5776                             int value = vss.mIndexMap.valueAt(i);
5777                             if (value == 0) {
5778                                 vss.setIndex(10, device, TAG, true /*hasModifyAudioSettings*/);
5779                             }
5780                         }
5781                         // Persist volume for stream ring when it is changed here
5782                       final int device = getDeviceForStream(streamType);
5783                       sendMsg(mAudioHandler,
5784                               MSG_PERSIST_VOLUME,
5785                               SENDMSG_QUEUE,
5786                               device,
5787                               0,
5788                               mStreamStates[streamType],
5789                               PERSIST_DELAY);
5790                     }
5791                 }
5792                 sRingerAndZenModeMutedStreams &= ~(1 << streamType);
5793                 sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent(
5794                         sRingerAndZenModeMutedStreams, "muteRingerModeStreams"));
5795                 mStreamStates[streamType].mute(false, "muteRingerModeStreams");
5796             } else {
5797                 // mute
5798                 sRingerAndZenModeMutedStreams |= (1 << streamType);
5799                 sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent(
5800                         sRingerAndZenModeMutedStreams, "muteRingerModeStreams"));
5801                 mStreamStates[streamType].mute(true, "muteRingerModeStreams");
5802             }
5803         }
5804     }
5805 
isAlarm(int streamType)5806     private boolean isAlarm(int streamType) {
5807         return streamType == AudioSystem.STREAM_ALARM;
5808     }
5809 
isNotificationOrRinger(int streamType)5810     private boolean isNotificationOrRinger(int streamType) {
5811         return streamType == AudioSystem.STREAM_NOTIFICATION
5812                 || streamType == AudioSystem.STREAM_RING;
5813     }
5814 
isMedia(int streamType)5815     private boolean isMedia(int streamType) {
5816         return streamType == AudioSystem.STREAM_MUSIC;
5817     }
5818 
5819 
isSystem(int streamType)5820     private boolean isSystem(int streamType) {
5821         return streamType == AudioSystem.STREAM_SYSTEM;
5822     }
5823 
setRingerModeInt(int ringerMode, boolean persist)5824     private void setRingerModeInt(int ringerMode, boolean persist) {
5825         final boolean change;
5826         synchronized(mSettingsLock) {
5827             change = mRingerMode != ringerMode;
5828             mRingerMode = ringerMode;
5829             muteRingerModeStreams();
5830         }
5831 
5832         // Post a persist ringer mode msg
5833         if (persist) {
5834             sendMsg(mAudioHandler, MSG_PERSIST_RINGER_MODE,
5835                     SENDMSG_REPLACE, 0, 0, null, PERSIST_DELAY);
5836         }
5837         if (change) {
5838             // Send sticky broadcast
5839             broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, ringerMode);
5840         }
5841     }
5842 
postUpdateRingerModeServiceInt()5843     /*package*/ void postUpdateRingerModeServiceInt() {
5844         sendMsg(mAudioHandler, MSG_UPDATE_RINGER_MODE, SENDMSG_QUEUE, 0, 0, null, 0);
5845     }
5846 
onUpdateRingerModeServiceInt()5847     private void onUpdateRingerModeServiceInt() {
5848         setRingerModeInt(getRingerModeInternal(), false);
5849     }
5850 
5851     /** @see AudioManager#shouldVibrate(int) */
shouldVibrate(int vibrateType)5852     public boolean shouldVibrate(int vibrateType) {
5853         if (!mHasVibrator) return false;
5854 
5855         switch (getVibrateSetting(vibrateType)) {
5856 
5857             case AudioManager.VIBRATE_SETTING_ON:
5858                 return getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT;
5859 
5860             case AudioManager.VIBRATE_SETTING_ONLY_SILENT:
5861                 return getRingerModeExternal() == AudioManager.RINGER_MODE_VIBRATE;
5862 
5863             case AudioManager.VIBRATE_SETTING_OFF:
5864                 // return false, even for incoming calls
5865                 return false;
5866 
5867             default:
5868                 return false;
5869         }
5870     }
5871 
5872     /** @see AudioManager#getVibrateSetting(int) */
getVibrateSetting(int vibrateType)5873     public int getVibrateSetting(int vibrateType) {
5874         if (!mHasVibrator) return AudioManager.VIBRATE_SETTING_OFF;
5875         return (mVibrateSetting >> (vibrateType * 2)) & 3;
5876     }
5877 
5878     /** @see AudioManager#setVibrateSetting(int, int) */
setVibrateSetting(int vibrateType, int vibrateSetting)5879     public void setVibrateSetting(int vibrateType, int vibrateSetting) {
5880 
5881         if (!mHasVibrator) return;
5882 
5883         mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, vibrateType,
5884                 vibrateSetting);
5885 
5886         // Broadcast change
5887         broadcastVibrateSetting(vibrateType);
5888 
5889     }
5890 
5891     private class SetModeDeathHandler implements IBinder.DeathRecipient {
5892         private final IBinder mCb; // To be notified of client's death
5893         private final int mPid;
5894         private final int mUid;
5895         private final boolean mIsPrivileged;
5896         private final String mPackage;
5897         private int mMode;
5898         private long mUpdateTime;
5899         private boolean mPlaybackActive = false;
5900         private boolean mRecordingActive = false;
5901 
SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged, String caller, int mode)5902         SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged,
5903                             String caller, int mode) {
5904             mMode = mode;
5905             mCb = cb;
5906             mPid = pid;
5907             mUid = uid;
5908             mPackage = caller;
5909             mIsPrivileged = isPrivileged;
5910             mUpdateTime = java.lang.System.currentTimeMillis();
5911         }
5912 
binderDied()5913         public void binderDied() {
5914             synchronized (mDeviceBroker.mSetModeLock) {
5915                 Log.w(TAG, "SetModeDeathHandler client died");
5916                 int index = mSetModeDeathHandlers.indexOf(this);
5917                 if (index < 0) {
5918                     Log.w(TAG, "unregistered SetModeDeathHandler client died");
5919                 } else {
5920                     SetModeDeathHandler h = mSetModeDeathHandlers.get(index);
5921                     mSetModeDeathHandlers.remove(index);
5922                     sendMsg(mAudioHandler,
5923                             MSG_UPDATE_AUDIO_MODE,
5924                             SENDMSG_QUEUE,
5925                             AudioSystem.MODE_CURRENT,
5926                             android.os.Process.myPid(),
5927                             mContext.getPackageName(),
5928                             0);
5929                 }
5930             }
5931         }
5932 
getPid()5933         public int getPid() {
5934             return mPid;
5935         }
5936 
setMode(int mode)5937         public void setMode(int mode) {
5938             mMode = mode;
5939             mUpdateTime = java.lang.System.currentTimeMillis();
5940         }
5941 
getMode()5942         public int getMode() {
5943             return mMode;
5944         }
5945 
getBinder()5946         public IBinder getBinder() {
5947             return mCb;
5948         }
5949 
getUid()5950         public int getUid() {
5951             return mUid;
5952         }
5953 
getPackage()5954         public String getPackage() {
5955             return mPackage;
5956         }
5957 
isPrivileged()5958         public boolean isPrivileged() {
5959             return mIsPrivileged;
5960         }
5961 
getUpdateTime()5962         public long getUpdateTime() {
5963             return mUpdateTime;
5964         }
5965 
setPlaybackActive(boolean active)5966         public void setPlaybackActive(boolean active) {
5967             mPlaybackActive = active;
5968         }
5969 
setRecordingActive(boolean active)5970         public void setRecordingActive(boolean active) {
5971             mRecordingActive = active;
5972         }
5973 
5974         /**
5975          * An app is considered active if:
5976          * - It is privileged (has MODIFY_PHONE_STATE permission)
5977          *  or
5978          * - It requests mode MODE_IN_COMMUNICATION, and it is either playing
5979          * or recording for VOICE_COMMUNICATION.
5980          *   or
5981          * - It requests a mode different from MODE_IN_COMMUNICATION or MODE_NORMAL
5982          * Note: only privileged apps can request MODE_IN_CALL, MODE_CALL_REDIRECT
5983          * or MODE_COMMUNICATION_REDIRECT.
5984          */
isActive()5985         public boolean isActive() {
5986             return mIsPrivileged
5987                     || ((mMode == AudioSystem.MODE_IN_COMMUNICATION)
5988                         && (mRecordingActive || mPlaybackActive))
5989                     || mMode == AudioSystem.MODE_RINGTONE
5990                     || mMode == AudioSystem.MODE_CALL_SCREENING;
5991         }
5992 
dump(PrintWriter pw, int index)5993         public void dump(PrintWriter pw, int index) {
5994             SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm:ss:SSS");
5995 
5996             if (index >= 0) {
5997                 pw.println("  Requester # " + (index + 1) + ":");
5998             }
5999             pw.println("  - Mode: " + AudioSystem.modeToString(mMode));
6000             pw.println("  - Binder: " + mCb);
6001             pw.println("  - Pid: " + mPid);
6002             pw.println("  - Uid: " + mUid);
6003             pw.println("  - Package: " + mPackage);
6004             pw.println("  - Privileged: " + mIsPrivileged);
6005             pw.println("  - Active: " + isActive());
6006             pw.println("    Playback active: " + mPlaybackActive);
6007             pw.println("    Recording active: " + mRecordingActive);
6008             pw.println("  - update time: " + format.format(new Date(mUpdateTime)));
6009         }
6010     }
6011 
6012     @GuardedBy("mDeviceBroker.mSetModeLock")
getAudioModeOwnerHandler()6013     private SetModeDeathHandler getAudioModeOwnerHandler() {
6014         // The Audio mode owner is:
6015         // 1) the most recent privileged app in the stack
6016         // 2) the most recent active app in the tack
6017         SetModeDeathHandler modeOwner = null;
6018         SetModeDeathHandler privilegedModeOwner = null;
6019         for (SetModeDeathHandler h : mSetModeDeathHandlers) {
6020             if (h.isActive()) {
6021                 // privileged apps are always active
6022                 if (h.isPrivileged()) {
6023                     if (privilegedModeOwner == null
6024                             || h.getUpdateTime() > privilegedModeOwner.getUpdateTime()) {
6025                         privilegedModeOwner = h;
6026                     }
6027                 } else {
6028                     if (modeOwner == null
6029                             || h.getUpdateTime() > modeOwner.getUpdateTime()) {
6030                         modeOwner = h;
6031                     }
6032                 }
6033             }
6034         }
6035         return privilegedModeOwner != null ? privilegedModeOwner :  modeOwner;
6036     }
6037 
6038     /**
6039      * Return information on the current audio mode owner
6040      * @return 0 if nobody owns the mode
6041      */
6042     @GuardedBy("mDeviceBroker.mSetModeLock")
getAudioModeOwner()6043     /*package*/ AudioDeviceBroker.AudioModeInfo getAudioModeOwner() {
6044         SetModeDeathHandler hdlr = getAudioModeOwnerHandler();
6045         if (hdlr != null) {
6046             return new AudioDeviceBroker.AudioModeInfo(
6047                     hdlr.getMode(), hdlr.getPid(), hdlr.getUid());
6048         }
6049         return new AudioDeviceBroker.AudioModeInfo(AudioSystem.MODE_NORMAL, 0 , 0);
6050     }
6051 
6052     /**
6053      * Return the uid of the current audio mode owner
6054      * @return 0 if nobody owns the mode
6055      */
6056     @GuardedBy("mDeviceBroker.mSetModeLock")
getModeOwnerUid()6057     /*package*/ int getModeOwnerUid() {
6058         SetModeDeathHandler hdlr = getAudioModeOwnerHandler();
6059         if (hdlr != null) {
6060             return hdlr.getUid();
6061         }
6062         return 0;
6063     }
6064 
6065     /** @see AudioManager#setMode(int) */
setMode(int mode, IBinder cb, String callingPackage)6066     public void setMode(int mode, IBinder cb, String callingPackage) {
6067         int pid = Binder.getCallingPid();
6068         int uid = Binder.getCallingUid();
6069         if (DEBUG_MODE) {
6070             Log.v(TAG, "setMode(mode=" + mode + ", pid=" + pid
6071                     + ", uid=" + uid + ", caller=" + callingPackage + ")");
6072         }
6073         if (!checkAudioSettingsPermission("setMode()")) {
6074             return;
6075         }
6076         if (cb == null) {
6077             Log.e(TAG, "setMode() called with null binder");
6078             return;
6079         }
6080         if (mode < AudioSystem.MODE_CURRENT || mode >= AudioSystem.NUM_MODES) {
6081             Log.w(TAG, "setMode() invalid mode: " + mode);
6082             return;
6083         }
6084 
6085         if (mode == AudioSystem.MODE_CURRENT) {
6086             mode = getMode();
6087         }
6088 
6089         if (mode == AudioSystem.MODE_CALL_SCREENING && !mIsCallScreeningModeSupported) {
6090             Log.w(TAG, "setMode(MODE_CALL_SCREENING) not permitted "
6091                     + "when call screening is not supported");
6092             return;
6093         }
6094 
6095         final boolean hasModifyPhoneStatePermission = mContext.checkCallingOrSelfPermission(
6096                 MODIFY_PHONE_STATE)
6097                 == PackageManager.PERMISSION_GRANTED;
6098         if ((mode == AudioSystem.MODE_IN_CALL
6099                 || mode == AudioSystem.MODE_CALL_REDIRECT
6100                 || mode == AudioSystem.MODE_COMMUNICATION_REDIRECT)
6101                 && !hasModifyPhoneStatePermission) {
6102             Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setMode("
6103                     + AudioSystem.modeToString(mode) + ") from pid=" + pid
6104                     + ", uid=" + Binder.getCallingUid());
6105             return;
6106         }
6107 
6108         SetModeDeathHandler currentModeHandler = null;
6109         synchronized (mDeviceBroker.mSetModeLock) {
6110             for (SetModeDeathHandler h : mSetModeDeathHandlers) {
6111                 if (h.getPid() == pid) {
6112                     currentModeHandler = h;
6113                     break;
6114                 }
6115             }
6116 
6117             if (mode == AudioSystem.MODE_NORMAL) {
6118                 if (currentModeHandler != null) {
6119                     if (!currentModeHandler.isPrivileged()
6120                             && currentModeHandler.getMode() == AudioSystem.MODE_IN_COMMUNICATION) {
6121                         mAudioHandler.removeEqualMessages(
6122                                 MSG_CHECK_MODE_FOR_UID, currentModeHandler);
6123                     }
6124                     mSetModeDeathHandlers.remove(currentModeHandler);
6125                     if (DEBUG_MODE) {
6126                         Log.v(TAG, "setMode(" + mode + ") removing hldr for pid: " + pid);
6127                     }
6128                     try {
6129                         currentModeHandler.getBinder().unlinkToDeath(currentModeHandler, 0);
6130                     } catch (NoSuchElementException e) {
6131                         Log.w(TAG, "setMode link does not exist ...");
6132                     }
6133                 }
6134             } else {
6135                 if (currentModeHandler != null) {
6136                     currentModeHandler.setMode(mode);
6137                     if (DEBUG_MODE) {
6138                         Log.v(TAG, "setMode(" + mode + ") updating hldr for pid: " + pid);
6139                     }
6140                 } else {
6141                     currentModeHandler = new SetModeDeathHandler(cb, pid, uid,
6142                             hasModifyPhoneStatePermission, callingPackage, mode);
6143                     // Register for client death notification
6144                     try {
6145                         cb.linkToDeath(currentModeHandler, 0);
6146                     } catch (RemoteException e) {
6147                         // Client has died!
6148                         Log.w(TAG, "setMode() could not link to " + cb + " binder death");
6149                         return;
6150                     }
6151                     mSetModeDeathHandlers.add(currentModeHandler);
6152                     if (DEBUG_MODE) {
6153                         Log.v(TAG, "setMode(" + mode + ") adding handler for pid=" + pid);
6154                     }
6155                 }
6156                 if (mode == AudioSystem.MODE_IN_COMMUNICATION) {
6157                     // Force active state when entering/updating the stack to avoid glitches when
6158                     // an app starts playing/recording after settng the audio mode,
6159                     // and send a reminder to check activity after a grace period.
6160                     if (!currentModeHandler.isPrivileged()) {
6161                         currentModeHandler.setPlaybackActive(true);
6162                         currentModeHandler.setRecordingActive(true);
6163                         sendMsg(mAudioHandler,
6164                                 MSG_CHECK_MODE_FOR_UID,
6165                                 SENDMSG_QUEUE,
6166                                 0,
6167                                 0,
6168                                 currentModeHandler,
6169                                 CHECK_MODE_FOR_UID_PERIOD_MS);
6170                     }
6171                 }
6172             }
6173 
6174             sendMsg(mAudioHandler,
6175                     MSG_UPDATE_AUDIO_MODE,
6176                     SENDMSG_REPLACE,
6177                     mode,
6178                     pid,
6179                     callingPackage,
6180                     0);
6181         }
6182     }
6183 
6184     @GuardedBy("mDeviceBroker.mSetModeLock")
onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage, boolean force)6185     void onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage,
6186                            boolean force) {
6187         if (requestedMode == AudioSystem.MODE_CURRENT) {
6188             requestedMode = getMode();
6189         }
6190         int mode = AudioSystem.MODE_NORMAL;
6191         int uid = 0;
6192         int pid = 0;
6193         SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler();
6194         if (currentModeHandler != null) {
6195             mode = currentModeHandler.getMode();
6196             uid = currentModeHandler.getUid();
6197             pid = currentModeHandler.getPid();
6198         }
6199         if (DEBUG_MODE) {
6200             Log.v(TAG, "onUpdateAudioMode() new mode: " + mode + ", current mode: "
6201                     + mMode.get() + " requested mode: " + requestedMode);
6202         }
6203         if (mode != mMode.get() || force) {
6204             int status = AudioSystem.SUCCESS;
6205             final long identity = Binder.clearCallingIdentity();
6206             try {
6207                 status = mAudioSystem.setPhoneState(mode, uid);
6208             } finally {
6209                 Binder.restoreCallingIdentity(identity);
6210             }
6211             if (status == AudioSystem.AUDIO_STATUS_OK) {
6212                 if (DEBUG_MODE) {
6213                     Log.v(TAG, "onUpdateAudioMode: mode successfully set to " + mode);
6214                 }
6215                 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_MODE, SENDMSG_REPLACE, mode, 0,
6216                         /*obj*/ null, /*delay*/ 0);
6217                 int previousMode = mMode.getAndSet(mode);
6218                 // Note: newModeOwnerPid is always 0 when actualMode is MODE_NORMAL
6219                 mModeLogger.enqueue(new PhoneStateEvent(requesterPackage, requesterPid,
6220                         requestedMode, pid, mode));
6221 
6222                 final int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
6223                 final int device = getDeviceForStream(streamType);
6224                 final int streamAlias = mStreamVolumeAlias[streamType];
6225 
6226                 if (DEBUG_MODE) {
6227                     Log.v(TAG, "onUpdateAudioMode: streamType=" + streamType
6228                             + ", streamAlias=" + streamAlias);
6229                 }
6230 
6231                 final int index = mStreamStates[streamAlias].getIndex(device);
6232                 final int maxIndex = mStreamStates[streamAlias].getMaxIndex();
6233                 setStreamVolumeInt(streamAlias, index, device, true,
6234                         requesterPackage, true /*hasModifyAudioSettings*/);
6235 
6236                 updateStreamVolumeAlias(true /*updateVolumes*/, requesterPackage);
6237 
6238                 // change of mode may require volume to be re-applied on some devices
6239                 updateAbsVolumeMultiModeDevices(previousMode, mode);
6240 
6241                 setLeAudioVolumeOnModeUpdate(mode, device, streamAlias, index, maxIndex);
6242 
6243                 synchronized (mCachedAbsVolDrivingStreamsLock) {
6244                     mCachedAbsVolDrivingStreams.replaceAll((absDev, stream) -> {
6245                         int streamToDriveAbs = getBluetoothContextualVolumeStream();
6246                         if (stream != streamToDriveAbs) {
6247                             mAudioSystem.setDeviceAbsoluteVolumeEnabled(absDev, /*address=*/
6248                                     "", /*enabled*/true, streamToDriveAbs);
6249                         }
6250                         return streamToDriveAbs;
6251                     });
6252                 }
6253 
6254                 // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all SCO
6255                 // connections not started by the application changing the mode when pid changes
6256                 mDeviceBroker.postSetModeOwner(mode, pid, uid);
6257             } else {
6258                 Log.w(TAG, "onUpdateAudioMode: failed to set audio mode to: " + mode);
6259             }
6260         }
6261     }
6262 
6263     /** @see AudioManager#getMode() */
getMode()6264     public int getMode() {
6265         synchronized (mDeviceBroker.mSetModeLock) {
6266             SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler();
6267             if (currentModeHandler != null) {
6268                 return currentModeHandler.getMode();
6269             }
6270             return AudioSystem.MODE_NORMAL;
6271         }
6272     }
6273 
6274     /** cached value read from audiopolicy manager after initialization. */
6275     private boolean mIsCallScreeningModeSupported = false;
6276 
6277     /** @see AudioManager#isCallScreeningModeSupported() */
isCallScreeningModeSupported()6278     public boolean isCallScreeningModeSupported() {
6279         return mIsCallScreeningModeSupported;
6280     }
6281 
dispatchMode(int mode)6282     protected void dispatchMode(int mode) {
6283         final int nbDispatchers = mModeDispatchers.beginBroadcast();
6284         for (int i = 0; i < nbDispatchers; i++) {
6285             try {
6286                 mModeDispatchers.getBroadcastItem(i).dispatchAudioModeChanged(mode);
6287             } catch (RemoteException e) {
6288             }
6289         }
6290         mModeDispatchers.finishBroadcast();
6291     }
6292 
6293     final RemoteCallbackList<IAudioModeDispatcher> mModeDispatchers =
6294             new RemoteCallbackList<IAudioModeDispatcher>();
6295 
6296     /**
6297      * @see {@link AudioManager#addOnModeChangedListener(Executor, AudioManager.OnModeChangedListener)}
6298      * @param dispatcher
6299      */
registerModeDispatcher( @onNull IAudioModeDispatcher dispatcher)6300     public void registerModeDispatcher(
6301             @NonNull IAudioModeDispatcher dispatcher) {
6302         mModeDispatchers.register(dispatcher);
6303     }
6304 
6305     /**
6306      * @see {@link AudioManager#removeOnModeChangedListener(AudioManager.OnModeChangedListener)}
6307      * @param dispatcher
6308      */
unregisterModeDispatcher( @onNull IAudioModeDispatcher dispatcher)6309     public void unregisterModeDispatcher(
6310             @NonNull IAudioModeDispatcher dispatcher) {
6311         mModeDispatchers.unregister(dispatcher);
6312     }
6313 
6314     @android.annotation.EnforcePermission(CALL_AUDIO_INTERCEPTION)
6315     /** @see AudioManager#isPstnCallAudioInterceptable() */
isPstnCallAudioInterceptable()6316     public boolean isPstnCallAudioInterceptable() {
6317 
6318         super.isPstnCallAudioInterceptable_enforcePermission();
6319 
6320         boolean uplinkDeviceFound = false;
6321         boolean downlinkDeviceFound = false;
6322         AudioDeviceInfo[] devices = AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_ALL);
6323         for (AudioDeviceInfo device : devices) {
6324             if (device.getInternalType() == AudioSystem.DEVICE_OUT_TELEPHONY_TX) {
6325                 uplinkDeviceFound = true;
6326             } else if (device.getInternalType() == AudioSystem.DEVICE_IN_TELEPHONY_RX) {
6327                 downlinkDeviceFound = true;
6328             }
6329             if (uplinkDeviceFound && downlinkDeviceFound) {
6330                 return true;
6331             }
6332         }
6333         return false;
6334     }
6335 
6336     /** @see AudioManager#setRttEnabled() */
6337     @Override
setRttEnabled(boolean rttEnabled)6338     public void setRttEnabled(boolean rttEnabled) {
6339         if (mContext.checkCallingOrSelfPermission(
6340                 MODIFY_PHONE_STATE)
6341                 != PackageManager.PERMISSION_GRANTED) {
6342             Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setRttEnabled from pid="
6343                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
6344             return;
6345         }
6346         synchronized (mSettingsLock) {
6347             mRttEnabled = rttEnabled;
6348             final long identity = Binder.clearCallingIdentity();
6349             try {
6350                 AudioSystem.setRttEnabled(rttEnabled);
6351             } finally {
6352                 Binder.restoreCallingIdentity(identity);
6353             }
6354         }
6355     }
6356 
6357     /** @see AudioManager#adjustSuggestedStreamVolumeForUid(int, int, int, String, int, int, int) */
6358     @Override
adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6359     public void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags,
6360             @NonNull String packageName, int uid, int pid, UserHandle userHandle,
6361             int targetSdkVersion) {
6362         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
6363             throw new SecurityException("Should only be called from system process");
6364         }
6365 
6366         // direction and stream type swap here because the public
6367         // adjustSuggested has a different order than the other methods.
6368         adjustSuggestedStreamVolume(direction, streamType, flags, packageName, packageName,
6369                 uid, pid, hasAudioSettingsPermission(uid, pid),
6370                 AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
6371     }
6372 
6373     /** @see AudioManager#adjustStreamVolumeForUid(int, int, int, String, int, int, int) */
6374     @Override
adjustStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6375     public void adjustStreamVolumeForUid(int streamType, int direction, int flags,
6376             @NonNull String packageName, int uid, int pid, UserHandle userHandle,
6377             int targetSdkVersion) {
6378         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
6379             throw new SecurityException("Should only be called from system process");
6380         }
6381 
6382         if (direction != AudioManager.ADJUST_SAME) {
6383             sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_ADJUST_VOL_UID, streamType,
6384                     direction/*val1*/, flags/*val2*/,
6385                     new StringBuilder(packageName).append(" uid:").append(uid)
6386                     .toString()));
6387         }
6388 
6389         adjustStreamVolume(streamType, direction, flags, packageName, packageName, uid, pid,
6390                 null, hasAudioSettingsPermission(uid, pid),
6391                 AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
6392     }
6393 
6394     /**
6395       * @see AudioManager#adjustVolume(int, int)
6396       * This method is redirected from AudioManager to AudioService for API hardening rules
6397       * enforcement then to MediaSession for implementation.
6398       */
6399     @Override
adjustVolume(int direction, int flags)6400     public void adjustVolume(int direction, int flags) {
6401         if (mHardeningEnforcer.blockVolumeMethod(
6402                 HardeningEnforcer.METHOD_AUDIO_MANAGER_ADJUST_VOLUME)) {
6403             return;
6404         }
6405         getMediaSessionManager().dispatchAdjustVolume(AudioManager.USE_DEFAULT_STREAM_TYPE,
6406                     direction, flags);
6407     }
6408 
6409     /**
6410      * @see AudioManager#adjustSuggestedStreamVolume(int, int, int)
6411      * This method is redirected from AudioManager to AudioService for API hardening rules
6412      * enforcement then to MediaSession for implementation.
6413      */
6414     @Override
adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags)6415     public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags) {
6416         if (mHardeningEnforcer.blockVolumeMethod(
6417                 HardeningEnforcer.METHOD_AUDIO_MANAGER_ADJUST_SUGGESTED_STREAM_VOLUME)) {
6418             return;
6419         }
6420         getMediaSessionManager().dispatchAdjustVolume(suggestedStreamType, direction, flags);
6421     }
6422 
6423     /** @see AudioManager#setStreamVolumeForUid(int, int, int, String, int, int, int) */
6424     @Override
setStreamVolumeForUid(int streamType, int index, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6425     public void setStreamVolumeForUid(int streamType, int index, int flags,
6426             @NonNull String packageName, int uid, int pid, UserHandle userHandle,
6427             int targetSdkVersion) {
6428         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
6429             throw new SecurityException("Should only be called from system process");
6430         }
6431 
6432         setStreamVolume(streamType, index, flags, /*device*/ null,
6433                 packageName, packageName, null, uid,
6434                 hasAudioSettingsPermission(uid, pid),
6435                 true /*canChangeMuteAndUpdateController*/);
6436     }
6437 
6438     //==========================================================================================
6439     // Sound Effects
6440     //==========================================================================================
6441     private static final class LoadSoundEffectReply
6442             implements SoundEffectsHelper.OnEffectsLoadCompleteHandler {
6443         private static final int SOUND_EFFECTS_LOADING = 1;
6444         private static final int SOUND_EFFECTS_LOADED = 0;
6445         private static final int SOUND_EFFECTS_ERROR = -1;
6446         private static final int SOUND_EFFECTS_LOAD_TIMEOUT_MS = 5000;
6447 
6448         private int mStatus = SOUND_EFFECTS_LOADING;
6449 
6450         @Override
run(boolean success)6451         public synchronized void run(boolean success) {
6452             mStatus = success ? SOUND_EFFECTS_LOADED : SOUND_EFFECTS_ERROR;
6453             notify();
6454         }
6455 
waitForLoaded(int attempts)6456         public synchronized boolean waitForLoaded(int attempts) {
6457             while ((mStatus == SOUND_EFFECTS_LOADING) && (attempts-- > 0)) {
6458                 try {
6459                     wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS);
6460                 } catch (InterruptedException e) {
6461                     Log.w(TAG, "Interrupted while waiting sound pool loaded.");
6462                 }
6463             }
6464             return mStatus == SOUND_EFFECTS_LOADED;
6465         }
6466     }
6467 
6468     /** @see AudioManager#playSoundEffect(int, int) */
playSoundEffect(int effectType, int userId)6469     public void playSoundEffect(int effectType, int userId) {
6470         if (querySoundEffectsEnabled(userId)) {
6471             playSoundEffectVolume(effectType, -1.0f);
6472         }
6473     }
6474 
6475     /**
6476      * Settings has an in memory cache, so this is fast.
6477      */
querySoundEffectsEnabled(int user)6478     private boolean querySoundEffectsEnabled(int user) {
6479         return mSettings.getSystemIntForUser(getContentResolver(),
6480                 Settings.System.SOUND_EFFECTS_ENABLED, 0, user) != 0;
6481     }
6482 
6483     /** @see AudioManager#playSoundEffect(int, float) */
playSoundEffectVolume(int effectType, float volume)6484     public void playSoundEffectVolume(int effectType, float volume) {
6485         // do not try to play the sound effect if the system stream is muted
6486         if (isStreamMute(STREAM_SYSTEM)) {
6487             return;
6488         }
6489 
6490         if (effectType >= AudioManager.NUM_SOUND_EFFECTS || effectType < 0) {
6491             Log.w(TAG, "AudioService effectType value " + effectType + " out of range");
6492             return;
6493         }
6494 
6495         sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SENDMSG_QUEUE,
6496                 effectType, (int) (volume * 1000), null, 0);
6497     }
6498 
6499     /**
6500      * Loads samples into the soundpool.
6501      * This method must be called at first when sound effects are enabled
6502      */
loadSoundEffects()6503     public boolean loadSoundEffects() {
6504         LoadSoundEffectReply reply = new LoadSoundEffectReply();
6505         sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, reply, 0);
6506         return reply.waitForLoaded(3 /*attempts*/);
6507     }
6508 
6509     /**
6510      * Schedule loading samples into the soundpool.
6511      * This method can be overridden to schedule loading at a later time.
6512      */
scheduleLoadSoundEffects()6513     protected void scheduleLoadSoundEffects() {
6514         sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0);
6515     }
6516 
6517     /**
6518      *  Unloads samples from the sound pool.
6519      *  This method can be called to free some memory when
6520      *  sound effects are disabled.
6521      */
unloadSoundEffects()6522     public void unloadSoundEffects() {
6523         sendMsg(mAudioHandler, MSG_UNLOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0);
6524     }
6525 
6526     /** @see AudioManager#reloadAudioSettings() */
reloadAudioSettings()6527     public void reloadAudioSettings() {
6528         readAudioSettings(false /*userSwitch*/);
6529     }
6530 
readAudioSettings(boolean userSwitch)6531     private void readAudioSettings(boolean userSwitch) {
6532         // restore ringer mode, ringer mode affected streams, mute affected streams and vibrate settings
6533         readPersistedSettings();
6534         readUserRestrictions();
6535 
6536         // restore volume settings
6537         int numStreamTypes = AudioSystem.getNumStreamTypes();
6538         for (int streamType = 0; streamType < numStreamTypes; streamType++) {
6539             VolumeStreamState streamState = mStreamStates[streamType];
6540 
6541             if (userSwitch && mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) {
6542                 continue;
6543             }
6544 
6545             streamState.readSettings();
6546             synchronized (VolumeStreamState.class) {
6547                 // unmute stream that was muted but is not affect by mute anymore
6548                 if (streamState.mIsMuted && ((!isStreamAffectedByMute(streamType) &&
6549                         !isStreamMutedByRingerOrZenMode(streamType)) || mUseFixedVolume)) {
6550                     streamState.mIsMuted = false;
6551                 }
6552             }
6553         }
6554 
6555         readVolumeGroupsSettings(userSwitch);
6556 
6557         // apply new ringer mode before checking volume for alias streams so that streams
6558         // muted by ringer mode have the correct volume
6559         setRingerModeInt(getRingerModeInternal(), false);
6560 
6561         checkAllFixedVolumeDevices();
6562         checkAllAliasStreamVolumes();
6563         checkMuteAffectedStreams();
6564 
6565         mSoundDoseHelper.restoreMusicActiveMs();
6566         mSoundDoseHelper.enforceSafeMediaVolumeIfActive(TAG);
6567 
6568         if (DEBUG_VOL) {
6569             Log.d(TAG, "Restoring device volume behavior");
6570         }
6571         restoreDeviceVolumeBehavior();
6572     }
6573 
6574     /** @see AudioManager#getAvailableCommunicationDevices(int) */
getAvailableCommunicationDeviceIds()6575     public int[] getAvailableCommunicationDeviceIds() {
6576         List<AudioDeviceInfo> commDevices = AudioDeviceBroker.getAvailableCommunicationDevices();
6577         return commDevices.stream().mapToInt(AudioDeviceInfo::getId).toArray();
6578     }
6579 
6580     /**
6581      * @see AudioManager#setCommunicationDevice(int)
6582      * @see AudioManager#clearCommunicationDevice()
6583      */
setCommunicationDevice(IBinder cb, int portId)6584     public boolean setCommunicationDevice(IBinder cb, int portId) {
6585         final int uid = Binder.getCallingUid();
6586         final int pid = Binder.getCallingPid();
6587 
6588         AudioDeviceInfo device = null;
6589         if (portId != 0) {
6590             device = AudioManager.getDeviceForPortId(portId, AudioManager.GET_DEVICES_OUTPUTS);
6591             if (device == null) {
6592                 Log.w(TAG, "setCommunicationDevice: invalid portID " + portId);
6593                 return false;
6594             }
6595             if (!AudioDeviceBroker.isValidCommunicationDevice(device)) {
6596                 if (!device.isSink()) {
6597                     throw new IllegalArgumentException("device must have sink role");
6598                 } else {
6599                     throw new IllegalArgumentException("invalid device type: " + device.getType());
6600                 }
6601             }
6602         }
6603         final String eventSource = new StringBuilder()
6604                 .append(device == null ? "clearCommunicationDevice(" : "setCommunicationDevice(")
6605                 .append(") from u/pid:").append(uid).append("/")
6606                 .append(pid).toString();
6607 
6608         int deviceType = AudioSystem.DEVICE_OUT_DEFAULT;
6609         String deviceAddress = null;
6610         if (device != null) {
6611             deviceType = device.getPort().type();
6612             deviceAddress = device.getAddress();
6613         } else {
6614             AudioDeviceInfo curDevice = mDeviceBroker.getCommunicationDevice();
6615             if (curDevice != null) {
6616                 deviceType = curDevice.getPort().type();
6617                 deviceAddress = curDevice.getAddress();
6618             }
6619         }
6620         // do not log metrics if clearing communication device while no communication device
6621         // was selected
6622         if (deviceType != AudioSystem.DEVICE_OUT_DEFAULT) {
6623             new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
6624                     + MediaMetrics.SEPARATOR + "setCommunicationDevice")
6625                     .set(MediaMetrics.Property.DEVICE,
6626                             AudioSystem.getDeviceName(deviceType))
6627                     .set(MediaMetrics.Property.ADDRESS, deviceAddress)
6628                     .set(MediaMetrics.Property.STATE, device != null
6629                             ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED)
6630                     .record();
6631         }
6632         final boolean isPrivileged = mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE)
6633                 == PackageManager.PERMISSION_GRANTED;
6634         final long ident = Binder.clearCallingIdentity();
6635         try {
6636             return mDeviceBroker.setCommunicationDevice(cb, uid, device, isPrivileged, eventSource);
6637         } finally {
6638             Binder.restoreCallingIdentity(ident);
6639         }
6640     }
6641 
6642     /** @see AudioManager#getCommunicationDevice() */
getCommunicationDevice()6643     public int getCommunicationDevice() {
6644         int deviceId = 0;
6645         final long ident = Binder.clearCallingIdentity();
6646         try {
6647             AudioDeviceInfo device = mDeviceBroker.getCommunicationDevice();
6648             deviceId = device != null ? device.getId() : 0;
6649         } finally {
6650             Binder.restoreCallingIdentity(ident);
6651         }
6652         return deviceId;
6653     }
6654 
6655     /** @see AudioManager#addOnCommunicationDeviceChangedListener(
6656      *               Executor, AudioManager.OnCommunicationDeviceChangedListener)
6657      */
registerCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)6658     public void registerCommunicationDeviceDispatcher(
6659             @Nullable ICommunicationDeviceDispatcher dispatcher) {
6660         if (dispatcher == null) {
6661             return;
6662         }
6663         mDeviceBroker.registerCommunicationDeviceDispatcher(dispatcher);
6664     }
6665 
6666     /** @see AudioManager#removeOnCommunicationDeviceChangedListener(
6667      *               AudioManager.OnCommunicationDeviceChangedListener)
6668      */
unregisterCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)6669     public void unregisterCommunicationDeviceDispatcher(
6670             @Nullable ICommunicationDeviceDispatcher dispatcher) {
6671         if (dispatcher == null) {
6672             return;
6673         }
6674         mDeviceBroker.unregisterCommunicationDeviceDispatcher(dispatcher);
6675     }
6676 
6677     /** @see AudioManager#setSpeakerphoneOn(boolean) */
setSpeakerphoneOn(IBinder cb, boolean on)6678     public void setSpeakerphoneOn(IBinder cb, boolean on) {
6679         if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) {
6680             return;
6681         }
6682         final boolean isPrivileged = mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE)
6683                 == PackageManager.PERMISSION_GRANTED;
6684 
6685         // for logging only
6686         final int uid = Binder.getCallingUid();
6687         final int pid = Binder.getCallingPid();
6688 
6689         final String eventSource = new StringBuilder("setSpeakerphoneOn(").append(on)
6690                 .append(") from u/pid:").append(uid).append("/")
6691                 .append(pid).toString();
6692         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
6693                 + MediaMetrics.SEPARATOR + "setSpeakerphoneOn")
6694                 .setUid(uid)
6695                 .setPid(pid)
6696                 .set(MediaMetrics.Property.STATE, on
6697                         ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
6698                 .record();
6699 
6700         final long ident = Binder.clearCallingIdentity();
6701         try {
6702             mDeviceBroker.setSpeakerphoneOn(cb, uid, on, isPrivileged, eventSource);
6703         } finally {
6704             Binder.restoreCallingIdentity(ident);
6705         }
6706     }
6707 
6708     /** @see AudioManager#isSpeakerphoneOn() */
isSpeakerphoneOn()6709     public boolean isSpeakerphoneOn() {
6710         return mDeviceBroker.isSpeakerphoneOn();
6711     }
6712 
6713 
6714     /** BT SCO audio state seen by apps using the deprecated API setBluetoothScoOn().
6715      * @see isBluetoothScoOn() */
6716     private boolean mBtScoOnByApp;
6717 
6718     /** @see AudioManager#setBluetoothScoOn(boolean) */
setBluetoothScoOn(boolean on)6719     public void setBluetoothScoOn(boolean on) {
6720         if (!checkAudioSettingsPermission("setBluetoothScoOn()")) {
6721             return;
6722         }
6723 
6724         // Only enable calls from system components
6725         if (UserHandle.getCallingAppId() >= FIRST_APPLICATION_UID) {
6726             mBtScoOnByApp = on;
6727             return;
6728         }
6729 
6730         // for logging only
6731         final int uid = Binder.getCallingUid();
6732         final int pid = Binder.getCallingPid();
6733         final String eventSource = new StringBuilder("setBluetoothScoOn(").append(on)
6734                 .append(") from u/pid:").append(uid).append("/").append(pid).toString();
6735 
6736         //bt sco
6737         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
6738                 + MediaMetrics.SEPARATOR + "setBluetoothScoOn")
6739                 .setUid(uid)
6740                 .setPid(pid)
6741                 .set(MediaMetrics.Property.STATE, on
6742                         ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
6743                 .record();
6744 
6745         mDeviceBroker.setBluetoothScoOn(on, eventSource);
6746     }
6747 
6748     /** @see AudioManager#setA2dpSuspended(boolean) */
6749     @android.annotation.EnforcePermission(BLUETOOTH_STACK)
setA2dpSuspended(boolean enable)6750     public void setA2dpSuspended(boolean enable) {
6751         super.setA2dpSuspended_enforcePermission();
6752         final String eventSource = new StringBuilder("setA2dpSuspended(").append(enable)
6753                 .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
6754                 .append(Binder.getCallingPid()).toString();
6755         mDeviceBroker.setA2dpSuspended(enable, false /*internal*/, eventSource);
6756     }
6757 
6758     /** @see AudioManager#setA2dpSuspended(boolean) */
6759     @android.annotation.EnforcePermission(BLUETOOTH_STACK)
setLeAudioSuspended(boolean enable)6760     public void setLeAudioSuspended(boolean enable) {
6761         super.setLeAudioSuspended_enforcePermission();
6762         final String eventSource = new StringBuilder("setLeAudioSuspended(").append(enable)
6763                 .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
6764                 .append(Binder.getCallingPid()).toString();
6765         mDeviceBroker.setLeAudioSuspended(enable, false /*internal*/, eventSource);
6766     }
6767 
6768     /** @see AudioManager#isBluetoothScoOn()
6769      * Note that it doesn't report internal state, but state seen by apps (which may have
6770      * called setBluetoothScoOn() */
isBluetoothScoOn()6771     public boolean isBluetoothScoOn() {
6772         return mBtScoOnByApp || mDeviceBroker.isBluetoothScoOn();
6773     }
6774 
6775     // TODO investigate internal users due to deprecation of SDK API
6776     /** @see AudioManager#setBluetoothA2dpOn(boolean) */
setBluetoothA2dpOn(boolean on)6777     public void setBluetoothA2dpOn(boolean on) {
6778         if (!checkAudioSettingsPermission("setBluetoothA2dpOn()")) {
6779             return;
6780         }
6781 
6782         // for logging only
6783         final int uid = Binder.getCallingUid();
6784         final int pid = Binder.getCallingPid();
6785         final String eventSource = new StringBuilder("setBluetoothA2dpOn(").append(on)
6786                 .append(") from u/pid:").append(uid).append("/")
6787                 .append(pid).toString();
6788 
6789         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
6790                 + MediaMetrics.SEPARATOR + "setBluetoothA2dpOn")
6791                 .setUid(uid)
6792                 .setPid(pid)
6793                 .set(MediaMetrics.Property.STATE, on
6794                         ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
6795                 .record();
6796 
6797         mDeviceBroker.setBluetoothA2dpOn_Async(on, eventSource);
6798     }
6799 
6800     /** @see AudioManager#isBluetoothA2dpOn() */
isBluetoothA2dpOn()6801     public boolean isBluetoothA2dpOn() {
6802         return mDeviceBroker.isBluetoothA2dpOn();
6803     }
6804 
6805     /** @see AudioManager#startBluetoothSco() */
startBluetoothSco(IBinder cb, int targetSdkVersion)6806     public void startBluetoothSco(IBinder cb, int targetSdkVersion) {
6807         if (!checkAudioSettingsPermission("startBluetoothSco()")) {
6808             return;
6809         }
6810 
6811         final int uid = Binder.getCallingUid();
6812         final int pid = Binder.getCallingPid();
6813         final int scoAudioMode =
6814                 (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ?
6815                         BtHelper.SCO_MODE_VIRTUAL_CALL : BtHelper.SCO_MODE_UNDEFINED;
6816         final String eventSource = new StringBuilder("startBluetoothSco()")
6817                 .append(") from u/pid:").append(uid).append("/")
6818                 .append(pid).toString();
6819 
6820         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
6821                 .setUid(uid)
6822                 .setPid(pid)
6823                 .set(MediaMetrics.Property.EVENT, "startBluetoothSco")
6824                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
6825                         BtHelper.scoAudioModeToString(scoAudioMode))
6826                 .record();
6827         startBluetoothScoInt(cb, uid, scoAudioMode, eventSource);
6828 
6829     }
6830 
6831     /** @see AudioManager#startBluetoothScoVirtualCall() */
startBluetoothScoVirtualCall(IBinder cb)6832     public void startBluetoothScoVirtualCall(IBinder cb) {
6833         if (!checkAudioSettingsPermission("startBluetoothScoVirtualCall()")) {
6834             return;
6835         }
6836 
6837         final int uid = Binder.getCallingUid();
6838         final int pid = Binder.getCallingPid();
6839         final String eventSource = new StringBuilder("startBluetoothScoVirtualCall()")
6840                 .append(") from u/pid:").append(uid).append("/")
6841                 .append(pid).toString();
6842 
6843         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
6844                 .setUid(uid)
6845                 .setPid(pid)
6846                 .set(MediaMetrics.Property.EVENT, "startBluetoothScoVirtualCall")
6847                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
6848                         BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_VIRTUAL_CALL))
6849                 .record();
6850         startBluetoothScoInt(cb, uid, BtHelper.SCO_MODE_VIRTUAL_CALL, eventSource);
6851     }
6852 
startBluetoothScoInt(IBinder cb, int uid, int scoAudioMode, @NonNull String eventSource)6853     void startBluetoothScoInt(IBinder cb, int uid, int scoAudioMode, @NonNull String eventSource) {
6854         MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
6855                 .set(MediaMetrics.Property.EVENT, "startBluetoothScoInt")
6856                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
6857                         BtHelper.scoAudioModeToString(scoAudioMode));
6858 
6859         if (!checkAudioSettingsPermission("startBluetoothSco()") ||
6860                 !mSystemReady) {
6861             mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission or systemReady").record();
6862             return;
6863         }
6864         final boolean isPrivileged = mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE)
6865                 == PackageManager.PERMISSION_GRANTED;
6866         final long ident = Binder.clearCallingIdentity();
6867         try {
6868             mDeviceBroker.startBluetoothScoForClient(
6869                     cb, uid, scoAudioMode, isPrivileged, eventSource);
6870         } finally {
6871             Binder.restoreCallingIdentity(ident);
6872         }
6873         mmi.record();
6874     }
6875 
6876     /** @see AudioManager#stopBluetoothSco() */
stopBluetoothSco(IBinder cb)6877     public void stopBluetoothSco(IBinder cb){
6878         if (!checkAudioSettingsPermission("stopBluetoothSco()") ||
6879                 !mSystemReady) {
6880             return;
6881         }
6882         final int uid = Binder.getCallingUid();
6883         final int pid = Binder.getCallingPid();
6884         final String eventSource =  new StringBuilder("stopBluetoothSco()")
6885                 .append(") from u/pid:").append(uid).append("/")
6886                 .append(pid).toString();
6887         final boolean isPrivileged = mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE)
6888                 == PackageManager.PERMISSION_GRANTED;
6889         final long ident = Binder.clearCallingIdentity();
6890         try {
6891             mDeviceBroker.stopBluetoothScoForClient(cb, uid, isPrivileged, eventSource);
6892         } finally {
6893             Binder.restoreCallingIdentity(ident);
6894         }
6895         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
6896                 .setUid(uid)
6897                 .setPid(pid)
6898                 .set(MediaMetrics.Property.EVENT, "stopBluetoothSco")
6899                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
6900                         BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_UNDEFINED))
6901                 .record();
6902     }
6903 
6904 
getContentResolver()6905     /*package*/ ContentResolver getContentResolver() {
6906         return mContentResolver;
6907     }
6908 
6909     @VisibleForTesting(visibility = PACKAGE)
getSettings()6910     public SettingsAdapter getSettings() {
6911         return mSettings;
6912     }
6913 
6914     ///////////////////////////////////////////////////////////////////////////
6915     // Internal methods
6916     ///////////////////////////////////////////////////////////////////////////
6917 
6918     /**
6919      * Checks if the adjustment should change ringer mode instead of just
6920      * adjusting volume. If so, this will set the proper ringer mode and volume
6921      * indices on the stream states.
6922      */
checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted, String caller, int flags)6923     private int checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted,
6924             String caller, int flags) {
6925         int result = FLAG_ADJUST_VOLUME;
6926         if (isPlatformTelevision() || mIsSingleVolume) {
6927             return result;
6928         }
6929 
6930         int ringerMode = getRingerModeInternal();
6931 
6932         switch (ringerMode) {
6933         case RINGER_MODE_NORMAL:
6934             if (direction == AudioManager.ADJUST_LOWER) {
6935                 if (mHasVibrator) {
6936                     // "step" is the delta in internal index units corresponding to a
6937                     // change of 1 in UI index units.
6938                     // Because of rounding when rescaling from one stream index range to its alias
6939                     // index range, we cannot simply test oldIndex == step:
6940                     //   (step <= oldIndex < 2 * step) is equivalent to: (old UI index == 1)
6941                     if (step <= oldIndex && oldIndex < 2 * step) {
6942                         ringerMode = RINGER_MODE_VIBRATE;
6943                         mLoweredFromNormalToVibrateTime = SystemClock.uptimeMillis();
6944                     }
6945                 } else {
6946                     if (oldIndex == step && mVolumePolicy.volumeDownToEnterSilent) {
6947                         ringerMode = RINGER_MODE_SILENT;
6948                     }
6949                 }
6950             }
6951             break;
6952         case RINGER_MODE_VIBRATE:
6953             if (!mHasVibrator) {
6954                 Log.e(TAG, "checkForRingerModeChange() current ringer mode is vibrate" +
6955                         "but no vibrator is present");
6956                 break;
6957             }
6958             if (direction == AudioManager.ADJUST_LOWER) {
6959                 if (mPrevVolDirection != AudioManager.ADJUST_LOWER) {
6960                     if (mVolumePolicy.volumeDownToEnterSilent) {
6961                         final long diff = SystemClock.uptimeMillis()
6962                                 - mLoweredFromNormalToVibrateTime;
6963                         if (diff > mVolumePolicy.vibrateToSilentDebounce
6964                                 && mRingerModeDelegate.canVolumeDownEnterSilent()) {
6965                             ringerMode = RINGER_MODE_SILENT;
6966                         }
6967                     } else {
6968                         result |= AudioManager.FLAG_SHOW_VIBRATE_HINT;
6969                     }
6970                 }
6971             } else if (direction == AudioManager.ADJUST_RAISE
6972                     || direction == AudioManager.ADJUST_TOGGLE_MUTE
6973                     || direction == AudioManager.ADJUST_UNMUTE) {
6974                 ringerMode = RINGER_MODE_NORMAL;
6975             }
6976             result &= ~FLAG_ADJUST_VOLUME;
6977             break;
6978         case RINGER_MODE_SILENT:
6979             if (direction == AudioManager.ADJUST_RAISE
6980                     || direction == AudioManager.ADJUST_TOGGLE_MUTE
6981                     || direction == AudioManager.ADJUST_UNMUTE) {
6982                 if (!mVolumePolicy.volumeUpToExitSilent) {
6983                     result |= AudioManager.FLAG_SHOW_SILENT_HINT;
6984                 } else {
6985                   if (mHasVibrator && direction == AudioManager.ADJUST_RAISE) {
6986                       ringerMode = RINGER_MODE_VIBRATE;
6987                   } else {
6988                       // If we don't have a vibrator or they were toggling mute
6989                       // go straight back to normal.
6990                       ringerMode = RINGER_MODE_NORMAL;
6991                   }
6992                 }
6993             }
6994             result &= ~FLAG_ADJUST_VOLUME;
6995             break;
6996         default:
6997             Log.e(TAG, "checkForRingerModeChange() wrong ringer mode: "+ringerMode);
6998             break;
6999         }
7000 
7001         if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode)
7002                 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)
7003                 && (flags & AudioManager.FLAG_FROM_KEY) == 0) {
7004             throw new SecurityException("Not allowed to change Do Not Disturb state");
7005         }
7006 
7007         setRingerMode(ringerMode, TAG + ".checkForRingerModeChange", false /*external*/);
7008 
7009         mPrevVolDirection = direction;
7010 
7011         return result;
7012     }
7013 
7014     @Override
isStreamAffectedByRingerMode(int streamType)7015     public boolean isStreamAffectedByRingerMode(int streamType) {
7016         return (mRingerModeAffectedStreams & (1 << streamType)) != 0;
7017     }
7018 
isStreamAffectedByCurrentZen(int streamType)7019     public boolean isStreamAffectedByCurrentZen(int streamType) {
7020         return (mZenModeAffectedStreams & (1 << streamType)) != 0;
7021     }
7022 
isStreamMutedByRingerOrZenMode(int streamType)7023     private boolean isStreamMutedByRingerOrZenMode(int streamType) {
7024         return (sRingerAndZenModeMutedStreams & (1 << streamType)) != 0;
7025     }
7026 
7027     /**
7028      * Volume streams can be muted based on the current DND state:
7029      * DND total silence: ringer, notification, system, media and alarms streams muted by DND
7030      * DND alarms only:  ringer, notification, system streams muted by DND
7031      * DND priority only: alarms, media, system, ringer and notification streams can be muted by
7032      * DND.  The current applied zenPolicy determines which streams will be muted by DND.
7033      * @return true if changed, else false
7034      */
updateZenModeAffectedStreams()7035     private boolean updateZenModeAffectedStreams() {
7036         if (!mSystemReady) {
7037             return false;
7038         }
7039 
7040         // If DND is off, no streams are muted by DND
7041         int zenModeAffectedStreams = 0;
7042         final int zenMode = mNm.getZenMode();
7043 
7044         if (zenMode == Settings.Global.ZEN_MODE_NO_INTERRUPTIONS) {
7045             zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM;
7046             zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION;
7047             zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING;
7048             zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM;
7049             zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC;
7050         } else if (zenMode == Settings.Global.ZEN_MODE_ALARMS) {
7051             zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM;
7052             zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION;
7053             zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING;
7054         } else if (zenMode == Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
7055             NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy();
7056             if ((zenPolicy.priorityCategories
7057                     & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0) {
7058                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM;
7059             }
7060 
7061             if ((zenPolicy.priorityCategories
7062                     & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0) {
7063                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC;
7064             }
7065 
7066             // even if zen isn't muting the system stream, the ringer mode can still mute
7067             // the system stream
7068             if ((zenPolicy.priorityCategories
7069                     & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0) {
7070                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM;
7071             }
7072 
7073             if (ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(zenPolicy)) {
7074                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION;
7075                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING;
7076             }
7077         }
7078 
7079         if (mZenModeAffectedStreams != zenModeAffectedStreams) {
7080             mZenModeAffectedStreams = zenModeAffectedStreams;
7081             return true;
7082         }
7083 
7084         return false;
7085     }
7086 
7087     @GuardedBy("mSettingsLock")
updateRingerAndZenModeAffectedStreams()7088     private boolean updateRingerAndZenModeAffectedStreams() {
7089         boolean updatedZenModeAffectedStreams = updateZenModeAffectedStreams();
7090         int ringerModeAffectedStreams = mSettings.getSystemIntForUser(mContentResolver,
7091                 Settings.System.MODE_RINGER_STREAMS_AFFECTED,
7092                 ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
7093                  (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)),
7094                  UserHandle.USER_CURRENT);
7095         if (mIsSingleVolume) {
7096             ringerModeAffectedStreams = 0;
7097         } else if (mRingerModeDelegate != null) {
7098             ringerModeAffectedStreams = mRingerModeDelegate
7099                     .getRingerModeAffectedStreams(ringerModeAffectedStreams);
7100         }
7101         if (mCameraSoundForced) {
7102             ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
7103         } else {
7104             ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
7105         }
7106         if (mStreamVolumeAlias[AudioSystem.STREAM_DTMF] == AudioSystem.STREAM_RING) {
7107             ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF);
7108         } else {
7109             ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF);
7110         }
7111 
7112         if (ringerModeAffectsAlarm()) {
7113             if (mRingerModeAffectsAlarm) {
7114                 boolean muteAlarmWithRinger =
7115                         mSettings.getGlobalInt(mContentResolver,
7116                         Settings.Global.MUTE_ALARM_STREAM_WITH_RINGER_MODE,
7117                         /* def= */ 0) != 0;
7118                 if (muteAlarmWithRinger) {
7119                     ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_ALARM);
7120                 } else {
7121                     ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_ALARM);
7122                 }
7123             }
7124         }
7125         if (ringerModeAffectedStreams != mRingerModeAffectedStreams) {
7126             mSettings.putSystemIntForUser(mContentResolver,
7127                     Settings.System.MODE_RINGER_STREAMS_AFFECTED,
7128                     ringerModeAffectedStreams,
7129                     UserHandle.USER_CURRENT);
7130             mRingerModeAffectedStreams = ringerModeAffectedStreams;
7131             return true;
7132         }
7133         return updatedZenModeAffectedStreams;
7134     }
7135 
7136     @Override
isStreamAffectedByMute(int streamType)7137     public boolean isStreamAffectedByMute(int streamType) {
7138         return (mMuteAffectedStreams & (1 << streamType)) != 0;
7139     }
7140 
7141     @Override
isStreamMutableByUi(int streamType)7142     public boolean isStreamMutableByUi(int streamType) {
7143         return (mUserMutableStreams & (1 << streamType)) != 0;
7144     }
7145 
ensureValidDirection(int direction)7146     private void ensureValidDirection(int direction) {
7147         switch (direction) {
7148             case AudioManager.ADJUST_LOWER:
7149             case AudioManager.ADJUST_RAISE:
7150             case AudioManager.ADJUST_SAME:
7151             case AudioManager.ADJUST_MUTE:
7152             case AudioManager.ADJUST_UNMUTE:
7153             case AudioManager.ADJUST_TOGGLE_MUTE:
7154                 break;
7155             default:
7156                 throw new IllegalArgumentException("Bad direction " + direction);
7157         }
7158     }
7159 
ensureValidStreamType(int streamType)7160     private void ensureValidStreamType(int streamType) {
7161         if (streamType < 0 || streamType >= mStreamStates.length) {
7162             throw new IllegalArgumentException("Bad stream type " + streamType);
7163         }
7164     }
7165 
isMuteAdjust(int adjust)7166     private boolean isMuteAdjust(int adjust) {
7167         return adjust == AudioManager.ADJUST_MUTE || adjust == AudioManager.ADJUST_UNMUTE
7168                 || adjust == AudioManager.ADJUST_TOGGLE_MUTE;
7169     }
7170 
7171     /** only public for mocking/spying, do not call outside of AudioService */
7172     @VisibleForTesting
isInCommunication()7173     public boolean isInCommunication() {
7174         boolean IsInCall = false;
7175 
7176         TelecomManager telecomManager =
7177                 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
7178 
7179         final long ident = Binder.clearCallingIdentity();
7180         try {
7181             IsInCall = telecomManager.isInCall();
7182         } finally {
7183             Binder.restoreCallingIdentity(ident);
7184         }
7185 
7186         int mode = mMode.get();
7187         return (IsInCall
7188                 || mode == AudioManager.MODE_IN_COMMUNICATION
7189                 || mode == AudioManager.MODE_IN_CALL);
7190     }
7191 
7192     /**
7193      * For code clarity for getActiveStreamType(int)
7194      * @param delay_ms max time since last stream activity to consider
7195      * @return true if stream is active in streams handled by AudioFlinger now or
7196      *     in the last "delay_ms" ms.
7197      */
wasStreamActiveRecently(int stream, int delay_ms)7198     private boolean wasStreamActiveRecently(int stream, int delay_ms) {
7199         return mAudioSystem.isStreamActive(stream, delay_ms)
7200                 || mAudioSystem.isStreamActiveRemotely(stream, delay_ms);
7201     }
7202 
getActiveStreamType(int suggestedStreamType)7203     private int getActiveStreamType(int suggestedStreamType) {
7204         if (mIsSingleVolume
7205                 && suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
7206             return AudioSystem.STREAM_MUSIC;
7207         }
7208 
7209         switch (mPlatformType) {
7210         case AudioSystem.PLATFORM_VOICE:
7211             if (isInCommunication()
7212                     || mAudioSystem.isStreamActive(AudioManager.STREAM_VOICE_CALL, 0)) {
7213                 if (mDeviceBroker.isBluetoothScoActive()) {
7214                     // Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO...");
7215                     return AudioSystem.STREAM_BLUETOOTH_SCO;
7216                 } else {
7217                     // Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL...");
7218                     return AudioSystem.STREAM_VOICE_CALL;
7219                 }
7220             } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
7221                 if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
7222                     if (DEBUG_VOL)
7223                         Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active");
7224                     return AudioSystem.STREAM_RING;
7225                 } else if (wasStreamActiveRecently(
7226                         AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
7227                         if (DEBUG_VOL) {
7228                             Log.v(
7229                                     TAG,
7230                                     "getActiveStreamType: Forcing STREAM_NOTIFICATION stream"
7231                                             + " active");
7232                         }
7233                         return AudioSystem.STREAM_NOTIFICATION;
7234                 } else {
7235                     if (DEBUG_VOL) {
7236                         Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK("
7237                                 + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default");
7238                     }
7239                     return DEFAULT_VOL_STREAM_NO_PLAYBACK;
7240                 }
7241             } else if (
7242                     wasStreamActiveRecently(AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
7243                 if (DEBUG_VOL)
7244                     Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION stream active");
7245                 return AudioSystem.STREAM_NOTIFICATION;
7246             } else if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
7247                 if (DEBUG_VOL)
7248                     Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active");
7249                 return AudioSystem.STREAM_RING;
7250             }
7251         default:
7252             if (isInCommunication()) {
7253                 if (mDeviceBroker.isBluetoothScoActive()) {
7254                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO");
7255                     return AudioSystem.STREAM_BLUETOOTH_SCO;
7256                 } else {
7257                     if (DEBUG_VOL)  Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL");
7258                     return AudioSystem.STREAM_VOICE_CALL;
7259                 }
7260             } else if (mAudioSystem.isStreamActive(
7261                     AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
7262                 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION");
7263                 return AudioSystem.STREAM_NOTIFICATION;
7264             } else if (mAudioSystem.isStreamActive(
7265                     AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
7266                 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING");
7267                 return AudioSystem.STREAM_RING;
7268             } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
7269                 if (mAudioSystem.isStreamActive(
7270                         AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
7271                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION");
7272                     return AudioSystem.STREAM_NOTIFICATION;
7273                 }
7274                 if (mAudioSystem.isStreamActive(
7275                         AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
7276                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING");
7277                     return AudioSystem.STREAM_RING;
7278                 }
7279                 if (DEBUG_VOL) {
7280                     Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK("
7281                             + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default");
7282                 }
7283                 return DEFAULT_VOL_STREAM_NO_PLAYBACK;
7284             }
7285             break;
7286         }
7287         if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Returning suggested type "
7288                 + suggestedStreamType);
7289         return suggestedStreamType;
7290     }
7291 
broadcastRingerMode(String action, int ringerMode)7292     private void broadcastRingerMode(String action, int ringerMode) {
7293         if (!mSystemServer.isPrivileged()) {
7294             return;
7295         }
7296         // Send sticky broadcast
7297         Intent broadcast = new Intent(action);
7298         broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, ringerMode);
7299         broadcast.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
7300                 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
7301         sendStickyBroadcastToAll(broadcast);
7302     }
7303 
broadcastVibrateSetting(int vibrateType)7304     private void broadcastVibrateSetting(int vibrateType) {
7305         if (!mSystemServer.isPrivileged()) {
7306             return;
7307         }
7308         // Send broadcast
7309         if (mActivityManagerInternal.isSystemReady()) {
7310             Intent broadcast = new Intent(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
7311             broadcast.putExtra(AudioManager.EXTRA_VIBRATE_TYPE, vibrateType);
7312             broadcast.putExtra(AudioManager.EXTRA_VIBRATE_SETTING, getVibrateSetting(vibrateType));
7313             sendBroadcastToAll(broadcast, null /* options */);
7314         }
7315     }
7316 
7317     // Message helper methods
7318     /**
7319      * Queue a message on the given handler's message queue, after acquiring the service wake lock.
7320      * Note that the wake lock needs to be released after the message has been handled.
7321      */
queueMsgUnderWakeLock(Handler handler, int msg, int arg1, int arg2, Object obj, int delay)7322     private void queueMsgUnderWakeLock(Handler handler, int msg,
7323             int arg1, int arg2, Object obj, int delay) {
7324         final long ident = Binder.clearCallingIdentity();
7325         try {
7326             // Always acquire the wake lock as AudioService because it is released by the
7327             // message handler.
7328             mAudioEventWakeLock.acquire();
7329         } finally {
7330             Binder.restoreCallingIdentity(ident);
7331         }
7332         sendMsg(handler, msg, SENDMSG_QUEUE, arg1, arg2, obj, delay);
7333     }
7334 
sendMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, int delay)7335     private static void sendMsg(Handler handler, int msg,
7336             int existingMsgPolicy, int arg1, int arg2, Object obj, int delay) {
7337         if (existingMsgPolicy == SENDMSG_REPLACE) {
7338             handler.removeMessages(msg);
7339         } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) {
7340             return;
7341         }
7342 
7343         final long time = SystemClock.uptimeMillis() + delay;
7344         handler.sendMessageAtTime(handler.obtainMessage(msg, arg1, arg2, obj), time);
7345     }
7346 
sendBundleMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, Bundle bundle, int delay)7347     private static void sendBundleMsg(Handler handler, int msg,
7348             int existingMsgPolicy, int arg1, int arg2, Object obj, Bundle bundle, int delay) {
7349         if (existingMsgPolicy == SENDMSG_REPLACE) {
7350             handler.removeMessages(msg);
7351         } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) {
7352             return;
7353         }
7354 
7355         final long time = SystemClock.uptimeMillis() + delay;
7356         Message message = handler.obtainMessage(msg, arg1, arg2, obj);
7357         message.setData(bundle);
7358         handler.sendMessageAtTime(message, time);
7359     }
7360 
checkAudioSettingsPermission(String method)7361     boolean checkAudioSettingsPermission(String method) {
7362         if (callingOrSelfHasAudioSettingsPermission()) {
7363             return true;
7364         }
7365         String msg = "Audio Settings Permission Denial: " + method + " from pid="
7366                 + Binder.getCallingPid()
7367                 + ", uid=" + Binder.getCallingUid();
7368         Log.w(TAG, msg);
7369         return false;
7370     }
7371 
callingOrSelfHasAudioSettingsPermission()7372     private boolean callingOrSelfHasAudioSettingsPermission() {
7373         return mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_SETTINGS)
7374                 == PackageManager.PERMISSION_GRANTED;
7375     }
7376 
callingHasAudioSettingsPermission()7377     private boolean callingHasAudioSettingsPermission() {
7378         return mContext.checkCallingPermission(MODIFY_AUDIO_SETTINGS)
7379                 == PackageManager.PERMISSION_GRANTED;
7380     }
7381 
hasAudioSettingsPermission(int uid, int pid)7382     private boolean hasAudioSettingsPermission(int uid, int pid) {
7383         return mContext.checkPermission(MODIFY_AUDIO_SETTINGS, pid, uid)
7384                 == PackageManager.PERMISSION_GRANTED;
7385     }
7386 
7387     /**
7388      * Minimum attenuation that can be set for alarms over speaker by an application that
7389      * doesn't have the MODIFY_AUDIO_SETTINGS permission.
7390      */
7391     protected static final float MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB = -36.0f;
7392 
7393     /**
7394      * Configures the VolumeStreamState instances for minimum stream index that can be accessed
7395      * without MODIFY_AUDIO_SETTINGS permission.
7396      * Can only be done successfully once audio policy has finished reading its configuration files
7397      * for the volume curves. If not, getStreamVolumeDB will return NaN, and the min value will
7398      * remain at the stream min index value.
7399      */
initMinStreamVolumeWithoutModifyAudioSettings()7400     protected void initMinStreamVolumeWithoutModifyAudioSettings() {
7401         int idx;
7402         int deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER_SAFE;
7403         if (Float.isNaN(AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM,
7404                 MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM], deviceForAlarm))) {
7405             deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER;
7406         }
7407         for (idx = MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM];
7408                 idx >= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]; idx--) {
7409             if (AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM, idx, deviceForAlarm)
7410                     < MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB) {
7411                 break;
7412             }
7413         }
7414         final int safeIndex = idx <= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]
7415                 ? MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]
7416                 : Math.min(idx + 1, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]);
7417         // update the VolumeStreamState for STREAM_ALARM and its aliases
7418         for (int stream : mStreamVolumeAlias) {
7419             if (mStreamVolumeAlias[stream] == AudioSystem.STREAM_ALARM) {
7420                 mStreamStates[stream].updateNoPermMinIndex(safeIndex);
7421             }
7422         }
7423     }
7424 
7425     /**
7426      * Returns device associated with the stream volume.
7427      *
7428      * Only public for mocking/spying, do not call outside of AudioService.
7429      * Device volume aliasing means DEVICE_OUT_SPEAKER may be returned for
7430      * DEVICE_OUT_SPEAKER_SAFE.
7431      */
7432     @VisibleForTesting
getDeviceForStream(int stream)7433     public int getDeviceForStream(int stream) {
7434         return selectOneAudioDevice(getDeviceSetForStream(stream));
7435     }
7436 
7437     /*
7438      * Must match native apm_extract_one_audio_device() used in getDeviceForVolume()
7439      * or the wrong device volume may be adjusted.
7440      */
selectOneAudioDevice(Set<Integer> deviceSet)7441     private int selectOneAudioDevice(Set<Integer> deviceSet) {
7442         if (deviceSet.isEmpty()) {
7443             return AudioSystem.DEVICE_NONE;
7444         } else if (deviceSet.size() == 1) {
7445             return deviceSet.iterator().next();
7446         } else {
7447             // Multiple device selection is either:
7448             //  - dock + one other device: give priority to dock in this case.
7449             //  - speaker + one other device: give priority to speaker in this case.
7450             //  - one A2DP device + another device: happens with duplicated output. In this case
7451             // retain the device on the A2DP output as the other must not correspond to an active
7452             // selection if not the speaker.
7453             //  - HDMI-CEC system audio mode only output: give priority to available item in order.
7454 
7455             if (deviceSet.contains(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET)) {
7456                 return AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET;
7457             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPEAKER)) {
7458                 return AudioSystem.DEVICE_OUT_SPEAKER;
7459             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPEAKER_SAFE)) {
7460                 // Note: DEVICE_OUT_SPEAKER_SAFE not present in getDeviceSetForStreamDirect
7461                 return AudioSystem.DEVICE_OUT_SPEAKER_SAFE;
7462             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_HDMI_ARC)) {
7463                 return AudioSystem.DEVICE_OUT_HDMI_ARC;
7464             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_HDMI_EARC)) {
7465                 return AudioSystem.DEVICE_OUT_HDMI_EARC;
7466             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_AUX_LINE)) {
7467                 return AudioSystem.DEVICE_OUT_AUX_LINE;
7468             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPDIF)) {
7469                 return AudioSystem.DEVICE_OUT_SPDIF;
7470             } else {
7471                 // At this point, deviceSet should contain exactly one A2DP device;
7472                 // regardless, return the first A2DP device in numeric order.
7473                 // If there is no A2DP device, this falls through to log an error.
7474                 for (int deviceType : deviceSet) {
7475                     if (AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(deviceType)) {
7476                         return deviceType;
7477                     }
7478                 }
7479             }
7480         }
7481         Log.w(TAG, "selectOneAudioDevice returning DEVICE_NONE from invalid device combination "
7482                 + AudioSystem.deviceSetToString(deviceSet));
7483         return AudioSystem.DEVICE_NONE;
7484     }
7485 
7486     /**
7487      * @see AudioManager#getDevicesForStream(int)
7488      * @deprecated on {@link android.os.Build.VERSION_CODES#T} as new devices
7489      *              will have multi-bit device types since S.
7490      *              Use {@link #getDevicesForAttributes()} instead.
7491      */
7492     @Override
7493     @Deprecated
getDeviceMaskForStream(int streamType)7494     public int getDeviceMaskForStream(int streamType) {
7495         ensureValidStreamType(streamType);
7496         // no permission required
7497         final long token = Binder.clearCallingIdentity();
7498         try {
7499             return AudioSystem.getDeviceMaskFromSet(
7500                     getDeviceSetForStreamDirect(streamType));
7501         } finally {
7502             Binder.restoreCallingIdentity(token);
7503         }
7504     }
7505 
7506     /**
7507      * Returns the devices associated with a stream type.
7508      *
7509      * SPEAKER_SAFE will alias to SPEAKER.
7510      */
7511     @NonNull
getDeviceSetForStreamDirect(int stream)7512     private Set<Integer> getDeviceSetForStreamDirect(int stream) {
7513         final AudioAttributes attr =
7514                 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream);
7515         Set<Integer> deviceSet =
7516                 AudioSystem.generateAudioDeviceTypesSet(
7517                         getDevicesForAttributesInt(attr, true /* forVolume */));
7518         return deviceSet;
7519     }
7520 
7521     /**
7522      * Returns a reference to the list of devices for the stream, do not modify.
7523      *
7524      * The device returned may be aliased to the actual device whose volume curve
7525      * will be used.  For example DEVICE_OUT_SPEAKER_SAFE aliases to DEVICE_OUT_SPEAKER.
7526      */
7527     @NonNull
getDeviceSetForStream(int stream)7528     public Set<Integer> getDeviceSetForStream(int stream) {
7529         ensureValidStreamType(stream);
7530         synchronized (VolumeStreamState.class) {
7531             return mStreamStates[stream].observeDevicesForStream_syncVSS(true);
7532         }
7533     }
7534 
onObserveDevicesForAllStreams(int skipStream)7535     private void onObserveDevicesForAllStreams(int skipStream) {
7536         synchronized (mSettingsLock) {
7537             synchronized (VolumeStreamState.class) {
7538                 for (int stream = 0; stream < mStreamStates.length; stream++) {
7539                     if (stream != skipStream) {
7540                         Set<Integer> deviceSet =
7541                                 mStreamStates[stream].observeDevicesForStream_syncVSS(
7542                                         false /*checkOthers*/);
7543                         for (Integer device : deviceSet) {
7544                             // Update volume states for devices routed for the stream
7545                             updateVolumeStates(device, stream,
7546                                     "AudioService#onObserveDevicesForAllStreams");
7547                         }
7548                     }
7549                 }
7550             }
7551         }
7552     }
7553 
7554     /** only public for mocking/spying, do not call outside of AudioService */
7555     @VisibleForTesting
postObserveDevicesForAllStreams()7556     public void postObserveDevicesForAllStreams() {
7557         postObserveDevicesForAllStreams(-1);
7558     }
7559 
7560     /** only public for mocking/spying, do not call outside of AudioService */
7561     @VisibleForTesting
postObserveDevicesForAllStreams(int skipStream)7562     public void postObserveDevicesForAllStreams(int skipStream) {
7563         sendMsg(mAudioHandler,
7564                 MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS,
7565                 SENDMSG_QUEUE, skipStream /*arg1*/, 0 /*arg2*/, null /*obj*/,
7566                 0 /*delay*/);
7567     }
7568 
7569     /**
7570      * @see AudioDeviceVolumeManager#setDeviceAbsoluteMultiVolumeBehavior
7571      *
7572      * @param register Whether the listener is to be registered or unregistered. If false, the
7573      *                 device adopts variable volume behavior.
7574      */
7575     @RequiresPermission(anyOf = { MODIFY_AUDIO_ROUTING, BLUETOOTH_PRIVILEGED })
registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register, IAudioDeviceVolumeDispatcher cb, String packageName, AudioDeviceAttributes device, List<VolumeInfo> volumes, boolean handlesVolumeAdjustment, @AudioManager.AbsoluteDeviceVolumeBehavior int deviceVolumeBehavior)7576     public void registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register,
7577             IAudioDeviceVolumeDispatcher cb, String packageName,
7578             AudioDeviceAttributes device, List<VolumeInfo> volumes,
7579             boolean handlesVolumeAdjustment,
7580             @AudioManager.AbsoluteDeviceVolumeBehavior int deviceVolumeBehavior) {
7581         // verify permissions
7582         if (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING)
7583                 != PackageManager.PERMISSION_GRANTED
7584                 && mContext.checkCallingOrSelfPermission(BLUETOOTH_PRIVILEGED)
7585                 != PackageManager.PERMISSION_GRANTED) {
7586             throw new SecurityException(
7587                     "Missing MODIFY_AUDIO_ROUTING or BLUETOOTH_PRIVILEGED permissions");
7588         }
7589         // verify arguments
7590         Objects.requireNonNull(device);
7591         Objects.requireNonNull(volumes);
7592 
7593         int deviceOut = device.getInternalType();
7594         if (register) {
7595             AbsoluteVolumeDeviceInfo info = new AbsoluteVolumeDeviceInfo(
7596                     device, volumes, cb, handlesVolumeAdjustment, deviceVolumeBehavior);
7597             AbsoluteVolumeDeviceInfo oldInfo = mAbsoluteVolumeDeviceInfoMap.get(deviceOut);
7598             boolean volumeBehaviorChanged = (oldInfo == null)
7599                     || (oldInfo.mDeviceVolumeBehavior != deviceVolumeBehavior);
7600             if (volumeBehaviorChanged) {
7601                 removeAudioSystemDeviceOutFromFullVolumeDevices(deviceOut);
7602                 removeAudioSystemDeviceOutFromFixedVolumeDevices(deviceOut);
7603                 addAudioSystemDeviceOutToAbsVolumeDevices(deviceOut, info);
7604 
7605                 dispatchDeviceVolumeBehavior(device, deviceVolumeBehavior);
7606             }
7607             // Update stream volumes to the given device, if specified in a VolumeInfo.
7608             // Mute state is not updated because it is stream-wide - the only way to mute a
7609             // stream's output to a particular device is to set the volume index to zero.
7610             for (VolumeInfo volumeInfo : volumes) {
7611                 if (volumeInfo.getVolumeIndex() != VolumeInfo.INDEX_NOT_SET
7612                         && volumeInfo.getMinVolumeIndex() != VolumeInfo.INDEX_NOT_SET
7613                         && volumeInfo.getMaxVolumeIndex() != VolumeInfo.INDEX_NOT_SET) {
7614                     if (volumeInfo.hasStreamType()) {
7615                         setStreamVolumeInt(volumeInfo.getStreamType(),
7616                                 rescaleIndex(volumeInfo, volumeInfo.getStreamType()),
7617                                 deviceOut, false /*force*/, packageName,
7618                                 true /*hasModifyAudioSettings*/);
7619                     } else {
7620                         for (int streamType : volumeInfo.getVolumeGroup().getLegacyStreamTypes()) {
7621                             setStreamVolumeInt(streamType, rescaleIndex(volumeInfo, streamType),
7622                                     deviceOut, false /*force*/, packageName,
7623                                     true /*hasModifyAudioSettings*/);
7624                         }
7625                     }
7626                 }
7627             }
7628         } else {
7629             boolean wasAbsVol = removeAudioSystemDeviceOutFromAbsVolumeDevices(deviceOut) != null;
7630             if (wasAbsVol) {
7631                 dispatchDeviceVolumeBehavior(device, AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE);
7632             }
7633         }
7634     }
7635 
7636     /**
7637      * @see AudioManager#setDeviceVolumeBehavior(AudioDeviceAttributes, int)
7638      * @param device the audio device to be affected
7639      * @param deviceVolumeBehavior one of the device behaviors
7640      */
7641     @android.annotation.EnforcePermission(anyOf = {
7642             MODIFY_AUDIO_ROUTING, MODIFY_AUDIO_SETTINGS_PRIVILEGED })
setDeviceVolumeBehavior(@onNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName)7643     public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
7644             @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName) {
7645         // verify permissions
7646         super.setDeviceVolumeBehavior_enforcePermission();
7647         // verify arguments
7648         Objects.requireNonNull(device);
7649         AudioManager.enforceValidVolumeBehavior(deviceVolumeBehavior);
7650 
7651         device = retrieveBluetoothAddress(device);
7652 
7653         sVolumeLogger.enqueue(new EventLogger.StringEvent("setDeviceVolumeBehavior: dev:"
7654                 + AudioSystem.getOutputDeviceName(device.getInternalType()) + " addr:"
7655                 + Utils.anonymizeBluetoothAddress(device.getAddress()) + " behavior:"
7656                 + AudioDeviceVolumeManager.volumeBehaviorName(deviceVolumeBehavior)
7657                 + " pack:" + pkgName).printLog(TAG));
7658         if (pkgName == null) {
7659             pkgName = "";
7660         }
7661         if (device.getType() == TYPE_BLUETOOTH_A2DP) {
7662             avrcpSupportsAbsoluteVolume(device.getAddress(),
7663                     deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
7664             return;
7665         }
7666 
7667         setDeviceVolumeBehaviorInternal(device, deviceVolumeBehavior, pkgName);
7668         persistDeviceVolumeBehavior(device.getInternalType(), deviceVolumeBehavior);
7669     }
7670 
setDeviceVolumeBehaviorInternal(@onNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller)7671     private void setDeviceVolumeBehaviorInternal(@NonNull AudioDeviceAttributes device,
7672             @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller) {
7673         int audioSystemDeviceOut = device.getInternalType();
7674         boolean volumeBehaviorChanged = false;
7675         // update device masks based on volume behavior
7676         switch (deviceVolumeBehavior) {
7677             case AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE:
7678                 volumeBehaviorChanged |=
7679                         removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut)
7680                         | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut)
7681                         | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut)
7682                                 != null);
7683                 break;
7684             case AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED:
7685                 volumeBehaviorChanged |=
7686                         removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut)
7687                         | addAudioSystemDeviceOutToFixedVolumeDevices(audioSystemDeviceOut)
7688                         | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut)
7689                                 != null);
7690                 break;
7691             case AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL:
7692                 volumeBehaviorChanged |=
7693                         addAudioSystemDeviceOutToFullVolumeDevices(audioSystemDeviceOut)
7694                         | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut)
7695                         | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut)
7696                                 != null);
7697                 break;
7698             case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE:
7699             case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY:
7700             case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE:
7701                 throw new IllegalArgumentException("Absolute volume unsupported for now");
7702         }
7703 
7704         if (volumeBehaviorChanged) {
7705             sendMsg(mAudioHandler, MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR, SENDMSG_QUEUE,
7706                     deviceVolumeBehavior, 0, device, /*delay*/ 0);
7707         }
7708 
7709         // log event and caller
7710         sDeviceLogger.enqueue(new EventLogger.StringEvent(
7711                 "Volume behavior " + deviceVolumeBehavior + " for dev=0x"
7712                       + Integer.toHexString(audioSystemDeviceOut) + " from:" + caller));
7713         // make sure we have a volume entry for this device, and that volume is updated according
7714         // to volume behavior
7715         postUpdateVolumeStatesForAudioDevice(audioSystemDeviceOut,
7716                 "setDeviceVolumeBehavior:" + caller);
7717     }
7718 
7719     /**
7720      * @see AudioManager#getDeviceVolumeBehavior(AudioDeviceAttributes)
7721      * @param device the audio output device type
7722      * @return the volume behavior for the device
7723      */
7724     @android.annotation.EnforcePermission(anyOf = {
7725             MODIFY_AUDIO_ROUTING, QUERY_AUDIO_STATE,  MODIFY_AUDIO_SETTINGS_PRIVILEGED
7726     })
7727     public @AudioManager.DeviceVolumeBehavior
getDeviceVolumeBehavior(@onNull AudioDeviceAttributes device)7728     int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
7729         // verify permissions
7730         super.getDeviceVolumeBehavior_enforcePermission();
7731         // verify parameters
7732         Objects.requireNonNull(device);
7733 
7734         device = retrieveBluetoothAddress(device);
7735 
7736         return getDeviceVolumeBehaviorInt(device);
7737     }
7738 
7739     private @AudioManager.DeviceVolumeBehavior
getDeviceVolumeBehaviorInt(@onNull AudioDeviceAttributes device)7740             int getDeviceVolumeBehaviorInt(@NonNull AudioDeviceAttributes device) {
7741         // Get the internal type set by the AudioDeviceAttributes constructor which is always more
7742         // exact (avoids double conversions) than a conversion from SDK type via
7743         // AudioDeviceInfo.convertDeviceTypeToInternalDevice()
7744         final int audioSystemDeviceOut = device.getInternalType();
7745 
7746         // setDeviceVolumeBehavior has not been explicitly called for the device type. Deduce the
7747         // current volume behavior.
7748         if (mFullVolumeDevices.contains(audioSystemDeviceOut)) {
7749             return AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL;
7750         }
7751         if (mFixedVolumeDevices.contains(audioSystemDeviceOut)) {
7752             return AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED;
7753         }
7754         if (mAbsVolumeMultiModeCaseDevices.contains(audioSystemDeviceOut)) {
7755             return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE;
7756         }
7757         if (mAbsoluteVolumeDeviceInfoMap.containsKey(audioSystemDeviceOut)) {
7758             return mAbsoluteVolumeDeviceInfoMap.get(audioSystemDeviceOut).mDeviceVolumeBehavior;
7759         }
7760 
7761         if (isA2dpAbsoluteVolumeDevice(audioSystemDeviceOut)
7762                 || AudioSystem.isLeAudioDeviceType(audioSystemDeviceOut)) {
7763             return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE;
7764         }
7765         return AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE;
7766     }
7767 
7768     /**
7769      * @see AudioManager#isVolumeFixed()
7770      * Note there are no permission checks on this operation, as this is part of API 21
7771      * @return true if the current device's volume behavior for media is
7772      *         DEVICE_VOLUME_BEHAVIOR_FIXED
7773      */
isVolumeFixed()7774     public boolean isVolumeFixed() {
7775         if (mUseFixedVolume) {
7776             return true;
7777         }
7778         final AudioAttributes attributes = new AudioAttributes.Builder()
7779                 .setUsage(AudioAttributes.USAGE_MEDIA)
7780                 .build();
7781         // calling getDevice*Int to bypass permission check
7782         final List<AudioDeviceAttributes> devices =
7783                 getDevicesForAttributesInt(attributes, true /* forVolume */);
7784         for (AudioDeviceAttributes device : devices) {
7785             if (getDeviceVolumeBehaviorInt(device) == AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED) {
7786                 return true;
7787             }
7788         }
7789         return false;
7790     }
7791 
7792     /*package*/ static final int CONNECTION_STATE_DISCONNECTED = 0;
7793     /*package*/ static final int CONNECTION_STATE_CONNECTED = 1;
7794     /**
7795      * The states that can be used with AudioService.setWiredDeviceConnectionState()
7796      * Attention: those values differ from those in BluetoothProfile, follow annotations to
7797      * distinguish between @ConnectionState and @BtProfileConnectionState
7798      */
7799     @IntDef({
7800             CONNECTION_STATE_DISCONNECTED,
7801             CONNECTION_STATE_CONNECTED,
7802     })
7803     @Retention(RetentionPolicy.SOURCE)
7804     public @interface ConnectionState {}
7805 
7806     /**
7807      * Default SAD for a TV using ARC, used when the Amplifier didn't report any SADs.
7808      * Represents 2-channel LPCM including all defined sample rates and bit depths.
7809      * For the format definition, see Table 34 in the CEA standard CEA-861-D.
7810      */
7811     private static final byte[] DEFAULT_ARC_AUDIO_DESCRIPTOR = new byte[]{0x09, 0x7f, 0x07};
7812 
7813     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
7814     /**
7815      * see AudioManager.setWiredDeviceConnectionState()
7816      */
setWiredDeviceConnectionState(@onNull AudioDeviceAttributes attributes, @ConnectionState int state, String caller)7817     public void setWiredDeviceConnectionState(@NonNull AudioDeviceAttributes attributes,
7818             @ConnectionState int state, String caller) {
7819         super.setWiredDeviceConnectionState_enforcePermission();
7820         Objects.requireNonNull(attributes);
7821 
7822         attributes = retrieveBluetoothAddress(attributes);
7823 
7824         // When using ARC, a TV should use default 2 channel LPCM if the Amplifier didn't
7825         // report any SADs. See section 13.15.3 of the HDMI-CEC spec version 1.4b.
7826         if (attributes.getType() == AudioDeviceInfo.TYPE_HDMI_ARC
7827                 && attributes.getRole() == AudioDeviceAttributes.ROLE_OUTPUT
7828                 && attributes.getAudioDescriptors().isEmpty()) {
7829             attributes = new AudioDeviceAttributes(
7830                     attributes.getRole(),
7831                     attributes.getType(),
7832                     attributes.getAddress(),
7833                     attributes.getName(),
7834                     attributes.getAudioProfiles(),
7835                     new ArrayList<AudioDescriptor>(Collections.singletonList(
7836                             new AudioDescriptor(
7837                                     AudioDescriptor.STANDARD_EDID,
7838                                     AudioProfile.AUDIO_ENCAPSULATION_TYPE_NONE,
7839                                     DEFAULT_ARC_AUDIO_DESCRIPTOR
7840                             )
7841                     ))
7842             );
7843         }
7844 
7845         if (state != CONNECTION_STATE_CONNECTED
7846                 && state != CONNECTION_STATE_DISCONNECTED) {
7847             throw new IllegalArgumentException("Invalid state " + state);
7848         }
7849         new MediaMetrics.Item(mMetricsId + "setWiredDeviceConnectionState")
7850                 .set(MediaMetrics.Property.ADDRESS, attributes.getAddress())
7851                 .set(MediaMetrics.Property.CLIENT_NAME, caller)
7852                 .set(MediaMetrics.Property.DEVICE,
7853                         AudioSystem.getDeviceName(attributes.getInternalType()))
7854                 .set(MediaMetrics.Property.NAME, attributes.getName())
7855                 .set(MediaMetrics.Property.STATE,
7856                         state == CONNECTION_STATE_CONNECTED ? "connected" : "disconnected")
7857                 .record();
7858         mDeviceBroker.setWiredDeviceConnectionState(attributes, state, caller);
7859         // The Dynamic Soundbar mode feature introduces dynamic presence for an HDMI Audio System
7860         // Client. For example, the device can start with the Audio System Client unavailable.
7861         // When the feature is activated the client becomes available, therefore Audio Service
7862         // requests a new HDMI Audio System Client instance when the ARC status is changed.
7863         if (attributes.getInternalType() == AudioSystem.DEVICE_IN_HDMI_ARC) {
7864             updateHdmiAudioSystemClient();
7865         }
7866     }
7867 
7868     /**
7869      * Replace the current HDMI Audio System Client.
7870      * See {@link #setWiredDeviceConnectionState(AudioDeviceAttributes, int, String)}.
7871      */
updateHdmiAudioSystemClient()7872     private void updateHdmiAudioSystemClient() {
7873         Slog.d(TAG, "Hdmi Audio System Client is updated");
7874         synchronized (mHdmiClientLock) {
7875             mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient();
7876         }
7877     }
7878 
7879     /** @see AudioManager#setTestDeviceConnectionState(AudioDeviceAttributes, boolean) */
setTestDeviceConnectionState(@onNull AudioDeviceAttributes device, boolean connected)7880     public void setTestDeviceConnectionState(@NonNull AudioDeviceAttributes device,
7881             boolean connected) {
7882         Objects.requireNonNull(device);
7883         enforceModifyAudioRoutingPermission();
7884 
7885         device = retrieveBluetoothAddress(device);
7886 
7887         mDeviceBroker.setTestDeviceConnectionState(device,
7888                 connected ? CONNECTION_STATE_CONNECTED : CONNECTION_STATE_DISCONNECTED);
7889         // simulate a routing update from native
7890         sendMsg(mAudioHandler,
7891                 MSG_ROUTING_UPDATED,
7892                 SENDMSG_REPLACE, 0, 0, null,
7893                 /*delay*/ 0);
7894     }
7895 
7896     /**
7897      * @hide
7898      * The states that can be used with AudioService.setBluetoothHearingAidDeviceConnectionState()
7899      * and AudioService.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent()
7900      */
7901     @IntDef({
7902             BluetoothProfile.STATE_DISCONNECTED,
7903             BluetoothProfile.STATE_CONNECTED,
7904     })
7905     @Retention(RetentionPolicy.SOURCE)
7906     public @interface BtProfileConnectionState {}
7907 
7908     /**
7909      * @hide
7910      * The profiles that can be used with AudioService.handleBluetoothActiveDeviceChanged()
7911      */
7912     @IntDef({
7913             BluetoothProfile.HEARING_AID,
7914             BluetoothProfile.A2DP,
7915             BluetoothProfile.A2DP_SINK,
7916             BluetoothProfile.LE_AUDIO,
7917             BluetoothProfile.LE_AUDIO_BROADCAST,
7918     })
7919     @Retention(RetentionPolicy.SOURCE)
7920     public @interface BtProfile {}
7921 
7922 
7923     @android.annotation.EnforcePermission(BLUETOOTH_STACK)
7924     /**
7925      * See AudioManager.handleBluetoothActiveDeviceChanged(...)
7926      */
handleBluetoothActiveDeviceChanged(BluetoothDevice newDevice, BluetoothDevice previousDevice, @NonNull BluetoothProfileConnectionInfo info)7927     public void handleBluetoothActiveDeviceChanged(BluetoothDevice newDevice,
7928             BluetoothDevice previousDevice, @NonNull BluetoothProfileConnectionInfo info) {
7929         handleBluetoothActiveDeviceChanged_enforcePermission();
7930         if (info == null) {
7931             throw new IllegalArgumentException("Illegal null BluetoothProfileConnectionInfo for"
7932                     + " device " + previousDevice + " -> " + newDevice);
7933         }
7934         final int profile = info.getProfile();
7935         if (profile != BluetoothProfile.A2DP && profile != BluetoothProfile.A2DP_SINK
7936                 && profile != BluetoothProfile.LE_AUDIO
7937                 && profile != BluetoothProfile.LE_AUDIO_BROADCAST
7938                 && profile != BluetoothProfile.HEARING_AID
7939                 && !(mDeviceBroker.isScoManagedByAudio() && profile == BluetoothProfile.HEADSET)) {
7940             throw new IllegalArgumentException("Illegal BluetoothProfile profile for device "
7941                     + previousDevice + " -> " + newDevice + ". Got: " + profile);
7942         }
7943 
7944         sDeviceLogger.enqueue(new EventLogger.StringEvent("BluetoothActiveDeviceChanged for "
7945                 + BluetoothProfile.getProfileName(profile) + ", device update " + previousDevice
7946                 + " -> " + newDevice).printLog(TAG));
7947         AudioDeviceBroker.BtDeviceChangedData data =
7948                 new AudioDeviceBroker.BtDeviceChangedData(newDevice, previousDevice, info,
7949                         "AudioService");
7950         sendMsg(mAudioHandler, MSG_BT_DEV_CHANGED, SENDMSG_QUEUE, 0, 0,
7951                 /*obj*/ data, /*delay*/ 0);
7952     }
7953 
7954     /** only public for mocking/spying, do not call outside of AudioService */
7955     @VisibleForTesting
setMusicMute(boolean mute)7956     public void setMusicMute(boolean mute) {
7957         mStreamStates[AudioSystem.STREAM_MUSIC].muteInternally(mute);
7958     }
7959 
7960     private static final Set<Integer> DEVICE_MEDIA_UNMUTED_ON_PLUG_SET;
7961     static {
7962         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET = new HashSet<>();
7963         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADSET);
7964         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE);
7965         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_LINE);
7966         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_HEARING_AID);
7967         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_A2DP_SET);
7968         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_BLE_SET);
7969         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_USB_SET);
7970     }
7971 
7972     /** only public for mocking/spying, do not call outside of AudioService */
7973     @VisibleForTesting
postAccessoryPlugMediaUnmute(int newDevice)7974     public void postAccessoryPlugMediaUnmute(int newDevice) {
7975         sendMsg(mAudioHandler, MSG_ACCESSORY_PLUG_MEDIA_UNMUTE, SENDMSG_QUEUE,
7976                 newDevice, 0, null, 0);
7977     }
7978 
onAccessoryPlugMediaUnmute(int newDevice)7979     private void onAccessoryPlugMediaUnmute(int newDevice) {
7980         if (DEBUG_VOL) {
7981             Log.i(TAG, String.format("onAccessoryPlugMediaUnmute newDevice=%d [%s]",
7982                     newDevice, AudioSystem.getOutputDeviceName(newDevice)));
7983         }
7984 
7985         if (mNm.getZenMode() != Settings.Global.ZEN_MODE_NO_INTERRUPTIONS
7986                 && !isStreamMutedByRingerOrZenMode(AudioSystem.STREAM_MUSIC)
7987                 && DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.contains(newDevice)
7988                 && mStreamStates[AudioSystem.STREAM_MUSIC].mIsMuted
7989                 && mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(newDevice) != 0
7990                 && getDeviceSetForStreamDirect(AudioSystem.STREAM_MUSIC).contains(newDevice)) {
7991             if (DEBUG_VOL) {
7992                 Log.i(TAG, String.format("onAccessoryPlugMediaUnmute unmuting device=%d [%s]",
7993                         newDevice, AudioSystem.getOutputDeviceName(newDevice)));
7994             }
7995             // Locking mSettingsLock to avoid inversion when calling vss.mute -> vss.doMute ->
7996             // vss.updateVolumeGroupIndex
7997             synchronized (mSettingsLock) {
7998                 mStreamStates[AudioSystem.STREAM_MUSIC].mute(false, "onAccessoryPlugMediaUnmute");
7999             }
8000         }
8001     }
8002 
8003     /**
8004      * See AudioManager.hasHapticChannels(Context, Uri).
8005      */
hasHapticChannels(Uri uri)8006     public boolean hasHapticChannels(Uri uri) {
8007         return AudioManager.hasHapticChannelsImpl(mContext, uri);
8008     }
8009 
8010     ///////////////////////////////////////////////////////////////////////////
8011     // Inner classes
8012     ///////////////////////////////////////////////////////////////////////////
8013     /**
8014      * Key is the AudioManager VolumeGroupId
8015      * Value is the VolumeGroupState
8016      */
8017     private static final SparseArray<VolumeGroupState> sVolumeGroupStates = new SparseArray<>();
8018 
initVolumeGroupStates()8019     private void initVolumeGroupStates() {
8020         for (final AudioVolumeGroup avg : getAudioVolumeGroups()) {
8021             try {
8022                 // if no valid attributes, this volume group is not controllable, throw exception
8023                 ensureValidAttributes(avg);
8024                 sVolumeGroupStates.append(avg.getId(), new VolumeGroupState(avg));
8025             } catch (IllegalArgumentException e) {
8026                 // Volume Groups without attributes are not controllable through set/get volume
8027                 // using attributes. Do not append them.
8028                 if (DEBUG_VOL) {
8029                     Log.d(TAG, "volume group " + avg.name() + " for internal policy needs");
8030                 }
8031                 continue;
8032             }
8033         }
8034 
8035         // need mSettingsLock for vgs.applyAllVolumes -> vss.setIndex which grabs this lock after
8036         // VSS.class. Locking order needs to be preserved
8037         synchronized (mSettingsLock) {
8038             for (int i = 0; i < sVolumeGroupStates.size(); i++) {
8039                 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
8040                 vgs.applyAllVolumes(/* userSwitch= */ false);
8041             }
8042         }
8043     }
8044 
ensureValidAttributes(AudioVolumeGroup avg)8045     private void ensureValidAttributes(AudioVolumeGroup avg) {
8046         boolean hasAtLeastOneValidAudioAttributes = avg.getAudioAttributes().stream()
8047                 .anyMatch(aa -> !aa.equals(AudioProductStrategy.getDefaultAttributes()));
8048         if (!hasAtLeastOneValidAudioAttributes) {
8049             throw new IllegalArgumentException("Volume Group " + avg.name()
8050                     + " has no valid audio attributes");
8051         }
8052     }
8053 
readVolumeGroupsSettings(boolean userSwitch)8054     private void readVolumeGroupsSettings(boolean userSwitch) {
8055         synchronized (mSettingsLock) {
8056             synchronized (VolumeStreamState.class) {
8057                 if (DEBUG_VOL) {
8058                     Log.d(TAG, "readVolumeGroupsSettings userSwitch=" + userSwitch);
8059                 }
8060                 for (int i = 0; i < sVolumeGroupStates.size(); i++) {
8061                     VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
8062                     // as for STREAM_MUSIC, preserve volume from one user to the next.
8063                     if (!(userSwitch && vgs.isMusic())) {
8064                         vgs.clearIndexCache();
8065                         vgs.readSettings();
8066                     }
8067                     vgs.applyAllVolumes(userSwitch);
8068                 }
8069             }
8070         }
8071     }
8072 
8073     // Called upon crash of AudioServer
restoreVolumeGroups()8074     private void restoreVolumeGroups() {
8075         if (DEBUG_VOL) {
8076             Log.v(TAG, "restoreVolumeGroups");
8077         }
8078 
8079         // need mSettingsLock for vgs.applyAllVolumes -> vss.setIndex which grabs this lock after
8080         // VSS.class. Locking order needs to be preserved
8081         synchronized (mSettingsLock) {
8082             for (int i = 0; i < sVolumeGroupStates.size(); i++) {
8083                 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
8084                 vgs.applyAllVolumes(false/*userSwitch*/);
8085             }
8086         }
8087     }
8088 
dumpVolumeGroups(PrintWriter pw)8089     private void dumpVolumeGroups(PrintWriter pw) {
8090         pw.println("\nVolume Groups (device: index)");
8091         for (int i = 0; i < sVolumeGroupStates.size(); i++) {
8092             final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
8093             vgs.dump(pw);
8094             pw.println("");
8095         }
8096     }
8097 
isCallStream(int stream)8098     private static boolean isCallStream(int stream) {
8099         return stream == AudioSystem.STREAM_VOICE_CALL
8100                 || stream == AudioSystem.STREAM_BLUETOOTH_SCO;
8101     }
8102 
getVolumeGroupForStreamType(int stream)8103     private static int getVolumeGroupForStreamType(int stream) {
8104         AudioAttributes attributes =
8105                 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream);
8106         if (attributes.equals(new AudioAttributes.Builder().build())) {
8107             return AudioVolumeGroup.DEFAULT_VOLUME_GROUP;
8108         }
8109         return AudioProductStrategy.getVolumeGroupIdForAudioAttributes(
8110                 attributes, /* fallbackOnDefault= */ false);
8111     }
8112 
8113     // NOTE: Locking order for synchronized objects related to volume management:
8114     //  1     mSettingsLock
8115     //  2       VolumeStreamState.class
8116     private class VolumeGroupState {
8117         private final AudioVolumeGroup mAudioVolumeGroup;
8118         private final SparseIntArray mIndexMap = new SparseIntArray(8);
8119         private int mIndexMin;
8120         private int mIndexMax;
8121         private boolean mHasValidStreamType = false;
8122         private int mPublicStreamType = AudioSystem.STREAM_MUSIC;
8123         private AudioAttributes mAudioAttributes = AudioProductStrategy.getDefaultAttributes();
8124         private boolean mIsMuted = false;
8125         private String mSettingName;
8126 
8127         // No API in AudioSystem to get a device from strategy or from attributes.
8128         // Need a valid public stream type to use current API getDeviceForStream
getDeviceForVolume()8129         private int getDeviceForVolume() {
8130             return getDeviceForStream(mPublicStreamType);
8131         }
8132 
VolumeGroupState(AudioVolumeGroup avg)8133         private VolumeGroupState(AudioVolumeGroup avg) {
8134             mAudioVolumeGroup = avg;
8135             if (DEBUG_VOL) {
8136                 Log.v(TAG, "VolumeGroupState for " + avg.toString());
8137             }
8138             // mAudioAttributes is the default at this point
8139             for (AudioAttributes aa : avg.getAudioAttributes()) {
8140                 if (!aa.equals(mAudioAttributes)) {
8141                     mAudioAttributes = aa;
8142                     break;
8143                 }
8144             }
8145             int[] streamTypes = mAudioVolumeGroup.getLegacyStreamTypes();
8146             String streamSettingName = "";
8147             if (streamTypes.length != 0) {
8148                 // Uses already initialized MIN / MAX if a stream type is attached to group
8149                 for (int streamType : streamTypes) {
8150                     if (streamType != AudioSystem.STREAM_DEFAULT
8151                             && streamType < AudioSystem.getNumStreamTypes()) {
8152                         mPublicStreamType = streamType;
8153                         mHasValidStreamType = true;
8154                         streamSettingName = System.VOLUME_SETTINGS_INT[mPublicStreamType];
8155                         break;
8156                     }
8157                 }
8158                 mIndexMin = MIN_STREAM_VOLUME[mPublicStreamType];
8159                 mIndexMax = MAX_STREAM_VOLUME[mPublicStreamType];
8160             } else if (!avg.getAudioAttributes().isEmpty()) {
8161                 mIndexMin = AudioSystem.getMinVolumeIndexForAttributes(mAudioAttributes);
8162                 mIndexMax = AudioSystem.getMaxVolumeIndexForAttributes(mAudioAttributes);
8163             } else {
8164                 throw new IllegalArgumentException("volume group: " + mAudioVolumeGroup.name()
8165                         + " has neither valid attributes nor valid stream types assigned");
8166             }
8167             mSettingName = !streamSettingName.isEmpty() ? streamSettingName : ("volume_" + name());
8168             // Load volume indexes from data base
8169             readSettings();
8170         }
8171 
getLegacyStreamTypes()8172         public @NonNull int[] getLegacyStreamTypes() {
8173             return mAudioVolumeGroup.getLegacyStreamTypes();
8174         }
8175 
name()8176         public String name() {
8177             return mAudioVolumeGroup.name();
8178         }
8179 
getId()8180         public int getId() {
8181             return mAudioVolumeGroup.getId();
8182         }
8183 
8184         /**
8185          * Volume group with non null minimum index are considered as non mutable, thus
8186          * bijectivity is broken with potential associated stream type.
8187          * VOICE_CALL stream has minVolumeIndex > 0  but can be muted directly by an
8188          * app that has MODIFY_PHONE_STATE permission.
8189          */
isVssMuteBijective(int stream)8190         private boolean isVssMuteBijective(int stream) {
8191             return isStreamAffectedByMute(stream)
8192                     && (getMinIndex() == (mStreamStates[stream].mIndexMin + 5) / 10)
8193                     && (getMinIndex() == 0 || isCallStream(stream));
8194         }
8195 
isMutable()8196         private boolean isMutable() {
8197             return mIndexMin == 0 || (mHasValidStreamType && isVssMuteBijective(mPublicStreamType));
8198         }
8199         /**
8200          * Mute/unmute the volume group
8201          * @param muted the new mute state
8202          */
8203         @GuardedBy("AudioService.VolumeStreamState.class")
mute(boolean muted)8204         public boolean mute(boolean muted) {
8205             if (!isMutable()) {
8206                 // Non mutable volume group
8207                 if (DEBUG_VOL) {
8208                     Log.d(TAG, "invalid mute on unmutable volume group " + name());
8209                 }
8210                 return false;
8211             }
8212             boolean changed = (mIsMuted != muted);
8213             // As for VSS, mute shall apply minIndex to all devices found in IndexMap and default.
8214             if (changed) {
8215                 mIsMuted = muted;
8216                 applyAllVolumes(false /*userSwitch*/);
8217             }
8218             return changed;
8219         }
8220 
isMuted()8221         public boolean isMuted() {
8222             return mIsMuted;
8223         }
8224 
adjustVolume(int direction, int flags)8225         public void adjustVolume(int direction, int flags) {
8226             synchronized (mSettingsLock) {
8227                 synchronized (AudioService.VolumeStreamState.class) {
8228                     int device = getDeviceForVolume();
8229                     int previousIndex = getIndex(device);
8230                     if (isMuteAdjust(direction) && !isMutable()) {
8231                         // Non mutable volume group
8232                         if (DEBUG_VOL) {
8233                             Log.d(TAG, "invalid mute on unmutable volume group " + name());
8234                         }
8235                         return;
8236                     }
8237                     switch (direction) {
8238                         case AudioManager.ADJUST_TOGGLE_MUTE: {
8239                             // Note: If muted by volume 0, unmute will restore volume 0.
8240                             mute(!mIsMuted);
8241                             break;
8242                         }
8243                         case AudioManager.ADJUST_UNMUTE:
8244                             // Note: If muted by volume 0, unmute will restore volume 0.
8245                             mute(false);
8246                             break;
8247                         case AudioManager.ADJUST_MUTE:
8248                             // May be already muted by setvolume 0, prevent from setting same value
8249                             if (previousIndex != 0) {
8250                                 // bypass persist
8251                                 mute(true);
8252                             }
8253                             mIsMuted = true;
8254                             break;
8255                         case AudioManager.ADJUST_RAISE:
8256                             // As for stream, RAISE during mute will increment the index
8257                             setVolumeIndex(Math.min(previousIndex + 1, mIndexMax),  device, flags);
8258                             break;
8259                         case AudioManager.ADJUST_LOWER:
8260                             // For stream, ADJUST_LOWER on a muted VSS is a no-op
8261                             // If we decide to unmute on ADJUST_LOWER, cannot fallback on
8262                             // adjustStreamVolume for group associated to legacy stream type
8263                             if (isMuted() && previousIndex != 0) {
8264                                 mute(false);
8265                             } else {
8266                                 int newIndex = Math.max(previousIndex - 1, mIndexMin);
8267                                 setVolumeIndex(newIndex, device, flags);
8268                             }
8269                             break;
8270                     }
8271                 }
8272             }
8273         }
8274 
getVolumeIndex()8275         public int getVolumeIndex() {
8276             synchronized (AudioService.VolumeStreamState.class) {
8277                 return getIndex(getDeviceForVolume());
8278             }
8279         }
8280 
setVolumeIndex(int index, int flags)8281         public void setVolumeIndex(int index, int flags) {
8282             synchronized (mSettingsLock) {
8283                 synchronized (AudioService.VolumeStreamState.class) {
8284                     if (mUseFixedVolume) {
8285                         return;
8286                     }
8287                     setVolumeIndex(index, getDeviceForVolume(), flags);
8288                 }
8289             }
8290         }
8291 
8292         @GuardedBy("AudioService.VolumeStreamState.class")
setVolumeIndex(int index, int device, int flags)8293         private void setVolumeIndex(int index, int device, int flags) {
8294             // Update cache & persist (muted by volume 0 shall be persisted)
8295             updateVolumeIndex(index, device);
8296             // setting non-zero volume for a muted stream unmutes the stream and vice versa,
8297             boolean changed = mute(index == 0);
8298             if (!changed) {
8299                 // Set the volume index only if mute operation is a no-op
8300                 index = getValidIndex(index);
8301                 setVolumeIndexInt(index, device, flags);
8302             }
8303         }
8304 
8305         @GuardedBy("AudioService.VolumeStreamState.class")
updateVolumeIndex(int index, int device)8306         public void updateVolumeIndex(int index, int device) {
8307             // Filter persistency if already exist and the index has not changed
8308             if (mIndexMap.indexOfKey(device) < 0 || mIndexMap.get(device) != index) {
8309                 // Update local cache
8310                 mIndexMap.put(device, getValidIndex(index));
8311 
8312                 // update data base - post a persist volume group msg
8313                 sendMsg(mAudioHandler,
8314                         MSG_PERSIST_VOLUME_GROUP,
8315                         SENDMSG_QUEUE,
8316                         device,
8317                         0,
8318                         this,
8319                         PERSIST_DELAY);
8320             }
8321         }
8322 
8323         @GuardedBy("AudioService.VolumeStreamState.class")
setVolumeIndexInt(int index, int device, int flags)8324         private void setVolumeIndexInt(int index, int device, int flags) {
8325             // Reflect mute state of corresponding stream by forcing index to 0 if muted
8326             // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted.
8327             // This allows RX path muting by the audio HAL only when explicitly muted but not when
8328             // index is just set to 0 to repect BT requirements
8329             if (mHasValidStreamType && isVssMuteBijective(mPublicStreamType)
8330                     && mStreamStates[mPublicStreamType].isFullyMuted()) {
8331                 index = 0;
8332             } else if (mPublicStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0) {
8333                 index = 1;
8334             }
8335             // Set the volume index
8336             mAudioSystem.setVolumeIndexForAttributes(mAudioAttributes, index, device);
8337         }
8338 
8339         @GuardedBy("AudioService.VolumeStreamState.class")
getIndex(int device)8340         private int getIndex(int device) {
8341             int index = mIndexMap.get(device, -1);
8342             // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
8343             return (index != -1) ? index : mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT);
8344         }
8345 
8346         @GuardedBy("AudioService.VolumeStreamState.class")
hasIndexForDevice(int device)8347         private boolean hasIndexForDevice(int device) {
8348             return (mIndexMap.get(device, -1) != -1);
8349         }
8350 
getMaxIndex()8351         public int getMaxIndex() {
8352             return mIndexMax;
8353         }
8354 
getMinIndex()8355         public int getMinIndex() {
8356             return mIndexMin;
8357         }
8358 
isValidStream(int stream)8359         private boolean isValidStream(int stream) {
8360             return (stream != AudioSystem.STREAM_DEFAULT) && (stream < mStreamStates.length);
8361         }
8362 
isMusic()8363         public boolean isMusic() {
8364             return mHasValidStreamType && mPublicStreamType == AudioSystem.STREAM_MUSIC;
8365         }
8366 
applyAllVolumes(boolean userSwitch)8367         public void applyAllVolumes(boolean userSwitch) {
8368             String caller = "from vgs";
8369             synchronized (AudioService.VolumeStreamState.class) {
8370                 // apply device specific volumes first
8371                 for (int i = 0; i < mIndexMap.size(); i++) {
8372                     int device = mIndexMap.keyAt(i);
8373                     int index = mIndexMap.valueAt(i);
8374                     boolean synced = false;
8375                     if (device != AudioSystem.DEVICE_OUT_DEFAULT) {
8376                         for (int stream : getLegacyStreamTypes()) {
8377                             if (isValidStream(stream)) {
8378                                 boolean streamMuted = mStreamStates[stream].mIsMuted;
8379                                 int deviceForStream = getDeviceForStream(stream);
8380                                 int indexForStream =
8381                                         (mStreamStates[stream].getIndex(deviceForStream) + 5) / 10;
8382                                 if (device == deviceForStream) {
8383                                     if (indexForStream == index && (isMuted() == streamMuted)
8384                                             && isVssMuteBijective(stream)) {
8385                                         synced = true;
8386                                         continue;
8387                                     }
8388                                     if (vgsVssSyncMuteOrder()) {
8389                                         if ((isMuted() != streamMuted) && isVssMuteBijective(
8390                                                 stream)) {
8391                                             mStreamStates[stream].mute(isMuted(),
8392                                                     "VGS.applyAllVolumes#1");
8393                                         }
8394                                     }
8395                                     if (indexForStream != index) {
8396                                         mStreamStates[stream].setIndex(index * 10, device, caller,
8397                                                 true /*hasModifyAudioSettings*/);
8398                                     }
8399                                     if (!vgsVssSyncMuteOrder()) {
8400                                         if ((isMuted() != streamMuted) && isVssMuteBijective(
8401                                                 stream)) {
8402                                             mStreamStates[stream].mute(isMuted(),
8403                                                     "VGS.applyAllVolumes#1");
8404                                         }
8405                                     }
8406                                 }
8407                             }
8408                         }
8409                         if (!synced) {
8410                             if (DEBUG_VOL) {
8411                                 Log.d(TAG, "applyAllVolumes: apply index " + index + ", group "
8412                                         + mAudioVolumeGroup.name() + " and device "
8413                                         + AudioSystem.getOutputDeviceName(device));
8414                             }
8415                             setVolumeIndexInt(isMuted() ? 0 : index, device, 0 /*flags*/);
8416                         }
8417                     }
8418                 }
8419                 // apply default volume last: by convention , default device volume will be used
8420                 // by audio policy manager if no explicit volume is present for a given device type
8421                 int index = getIndex(AudioSystem.DEVICE_OUT_DEFAULT);
8422                 boolean synced = false;
8423                 int deviceForVolume = getDeviceForVolume();
8424                 boolean forceDeviceSync = userSwitch && (mIndexMap.indexOfKey(deviceForVolume) < 0);
8425                 for (int stream : getLegacyStreamTypes()) {
8426                     if (isValidStream(stream)) {
8427                         boolean streamMuted = mStreamStates[stream].mIsMuted;
8428                         int defaultStreamIndex = (mStreamStates[stream].getIndex(
8429                                         AudioSystem.DEVICE_OUT_DEFAULT) + 5) / 10;
8430                         if (forceDeviceSync) {
8431                             mStreamStates[stream].setIndex(index * 10, deviceForVolume, caller,
8432                                     true /*hasModifyAudioSettings*/);
8433                         }
8434                         if (defaultStreamIndex == index && (isMuted() == streamMuted)
8435                                 && isVssMuteBijective(stream)) {
8436                             synced = true;
8437                             continue;
8438                         }
8439                         if (defaultStreamIndex != index) {
8440                             mStreamStates[stream].setIndex(
8441                                     index * 10, AudioSystem.DEVICE_OUT_DEFAULT, caller,
8442                                     true /*hasModifyAudioSettings*/);
8443                         }
8444                         if ((isMuted() != streamMuted) && isVssMuteBijective(stream)) {
8445                             mStreamStates[stream].mute(isMuted(), "VGS.applyAllVolumes#2");
8446                         }
8447                     }
8448                 }
8449                 if (!synced) {
8450                     if (DEBUG_VOL) {
8451                         Log.d(TAG, "applyAllVolumes: apply default device index " + index
8452                                 + ", group " + mAudioVolumeGroup.name());
8453                     }
8454                     setVolumeIndexInt(
8455                             isMuted() ? 0 : index, AudioSystem.DEVICE_OUT_DEFAULT, 0 /*flags*/);
8456                 }
8457                 if (forceDeviceSync) {
8458                     if (DEBUG_VOL) {
8459                         Log.d(TAG, "applyAllVolumes: forceDeviceSync index " + index
8460                                 + ", device " + AudioSystem.getOutputDeviceName(deviceForVolume)
8461                                 + ", group " + mAudioVolumeGroup.name());
8462                     }
8463                     setVolumeIndexInt(isMuted() ? 0 : index, deviceForVolume, 0);
8464                 }
8465             }
8466         }
8467 
clearIndexCache()8468         public void clearIndexCache() {
8469             mIndexMap.clear();
8470         }
8471 
persistVolumeGroup(int device)8472         private void persistVolumeGroup(int device) {
8473             // No need to persist the index if the volume group is backed up
8474             // by a public stream type as this is redundant
8475             if (mUseFixedVolume || mHasValidStreamType) {
8476                 return;
8477             }
8478             if (DEBUG_VOL) {
8479                 Log.v(TAG, "persistVolumeGroup: storing index " + getIndex(device) + " for group "
8480                         + mAudioVolumeGroup.name()
8481                         + ", device " + AudioSystem.getOutputDeviceName(device)
8482                         + " and User=" + getCurrentUserId()
8483                         + " mSettingName: " + mSettingName);
8484             }
8485 
8486             boolean success = mSettings.putSystemIntForUser(mContentResolver,
8487                     getSettingNameForDevice(device),
8488                     getIndex(device),
8489                     isMusic() ? UserHandle.USER_SYSTEM : UserHandle.USER_CURRENT);
8490             if (!success) {
8491                 Log.e(TAG, "persistVolumeGroup failed for group " +  mAudioVolumeGroup.name());
8492             }
8493         }
8494 
readSettings()8495         public void readSettings() {
8496             synchronized (AudioService.VolumeStreamState.class) {
8497                 // force maximum volume on all streams if fixed volume property is set
8498                 if (mUseFixedVolume) {
8499                     mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
8500                     return;
8501                 }
8502                 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
8503                     // retrieve current volume for device
8504                     // if no volume stored for current volume group and device, use default volume
8505                     // if default device, continue otherwise
8506                     int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT)
8507                             ? AudioSystem.DEFAULT_STREAM_VOLUME[mPublicStreamType] : -1;
8508                     int index;
8509                     String name = getSettingNameForDevice(device);
8510                     index = mSettings.getSystemIntForUser(
8511                             mContentResolver, name, defaultIndex,
8512                             isMusic() ? UserHandle.USER_SYSTEM : UserHandle.USER_CURRENT);
8513                     if (index == -1) {
8514                         continue;
8515                     }
8516                     if (mPublicStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED
8517                             && mCameraSoundForced) {
8518                         index = mIndexMax;
8519                     }
8520                     if (DEBUG_VOL) {
8521                         Log.v(TAG, "readSettings: found stored index " + getValidIndex(index)
8522                                  + " for group " + mAudioVolumeGroup.name() + ", device: " + name
8523                                  + ", User=" + getCurrentUserId());
8524                     }
8525                     mIndexMap.put(device, getValidIndex(index));
8526                 }
8527             }
8528         }
8529 
8530         @GuardedBy("AudioService.VolumeStreamState.class")
getValidIndex(int index)8531         private int getValidIndex(int index) {
8532             if (index < mIndexMin) {
8533                 return mIndexMin;
8534             } else if (mUseFixedVolume || index > mIndexMax) {
8535                 return mIndexMax;
8536             }
8537             return index;
8538         }
8539 
getSettingNameForDevice(int device)8540         public @NonNull String getSettingNameForDevice(int device) {
8541             String suffix = AudioSystem.getOutputDeviceName(device);
8542             if (suffix.isEmpty()) {
8543                 return mSettingName;
8544             }
8545             return mSettingName + "_" + AudioSystem.getOutputDeviceName(device);
8546         }
8547 
setSettingName(String settingName)8548         void setSettingName(String settingName) {
8549             mSettingName = settingName;
8550         }
8551 
getSettingName()8552         String getSettingName() {
8553             return mSettingName;
8554         }
8555 
dump(PrintWriter pw)8556         private void dump(PrintWriter pw) {
8557             pw.println("- VOLUME GROUP " + mAudioVolumeGroup.name() + ":");
8558             pw.print("   Muted: ");
8559             pw.println(mIsMuted);
8560             pw.print("   Min: ");
8561             pw.println(mIndexMin);
8562             pw.print("   Max: ");
8563             pw.println(mIndexMax);
8564             pw.print("   Current: ");
8565             for (int i = 0; i < mIndexMap.size(); i++) {
8566                 if (i > 0) {
8567                     pw.print(", ");
8568                 }
8569                 int device = mIndexMap.keyAt(i);
8570                 pw.print(Integer.toHexString(device));
8571                 String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
8572                         : AudioSystem.getOutputDeviceName(device);
8573                 if (!deviceName.isEmpty()) {
8574                     pw.print(" (");
8575                     pw.print(deviceName);
8576                     pw.print(")");
8577                 }
8578                 pw.print(": ");
8579                 pw.print(mIndexMap.valueAt(i));
8580             }
8581             pw.println();
8582             pw.print("   Devices: ");
8583             int n = 0;
8584             int devices = getDeviceForVolume();
8585             for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
8586                 if ((devices & device) == device) {
8587                     if (n++ > 0) {
8588                         pw.print(", ");
8589                     }
8590                     pw.print(AudioSystem.getOutputDeviceName(device));
8591                 }
8592             }
8593             pw.println();
8594             pw.print("   Streams: ");
8595             Arrays.stream(getLegacyStreamTypes())
8596                     .forEach(stream -> pw.print(AudioSystem.streamToString(stream) + " "));
8597         }
8598     }
8599 
8600 
8601     // NOTE: Locking order for synchronized objects related to volume or ringer mode management:
8602     //  1 mScoclient OR mSafeMediaVolumeState
8603     //  2   mSetModeLock
8604     //  3     mSettingsLock
8605     //  4       VolumeStreamState.class
8606     /*package*/ class VolumeStreamState {
8607         private final int mStreamType;
8608         private VolumeGroupState mVolumeGroupState = null;
8609         private int mIndexMin;
8610         // min index when user doesn't have permission to change audio settings
8611         private int mIndexMinNoPerm;
8612         private int mIndexMax;
8613 
8614         private boolean mIsMuted = false;
8615         private boolean mIsMutedInternally = false;
8616         private String mVolumeIndexSettingName;
8617         @NonNull private Set<Integer> mObservedDeviceSet = new TreeSet<>();
8618 
8619         private final SparseIntArray mIndexMap = new SparseIntArray(8) {
8620             @Override
8621             public void put(int key, int value) {
8622                 super.put(key, value);
8623                 record("put", key, value);
8624             }
8625             @Override
8626             public void setValueAt(int index, int value) {
8627                 super.setValueAt(index, value);
8628                 record("setValueAt", keyAt(index), value);
8629             }
8630 
8631             // Record all changes in the VolumeStreamState
8632             private void record(String event, int key, int value) {
8633                 final String device = key == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
8634                         : AudioSystem.getOutputDeviceName(key);
8635                 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_VOLUME + MediaMetrics.SEPARATOR
8636                         + AudioSystem.streamToString(mStreamType)
8637                         + "." + device)
8638                         .set(MediaMetrics.Property.EVENT, event)
8639                         .set(MediaMetrics.Property.INDEX, value)
8640                         .set(MediaMetrics.Property.MIN_INDEX, mIndexMin)
8641                         .set(MediaMetrics.Property.MAX_INDEX, mIndexMax)
8642                         .record();
8643             }
8644         };
8645         private final Intent mVolumeChanged;
8646         private final Bundle mVolumeChangedOptions;
8647         private final Intent mStreamDevicesChanged;
8648         private final Bundle mStreamDevicesChangedOptions;
8649 
VolumeStreamState(String settingName, int streamType)8650         private VolumeStreamState(String settingName, int streamType) {
8651             mVolumeIndexSettingName = settingName;
8652 
8653             mStreamType = streamType;
8654             mIndexMin = MIN_STREAM_VOLUME[streamType] * 10;
8655             mIndexMinNoPerm = mIndexMin; // may be overwritten later in updateNoPermMinIndex()
8656             mIndexMax = MAX_STREAM_VOLUME[streamType] * 10;
8657             final int status = AudioSystem.initStreamVolume(
8658                     streamType, mIndexMin / 10, mIndexMax / 10);
8659             if (status != AudioSystem.AUDIO_STATUS_OK) {
8660                 sLifecycleLogger.enqueue(new EventLogger.StringEvent(
8661                          "VSS() stream:" + streamType + " initStreamVolume=" + status)
8662                         .printLog(ALOGE, TAG));
8663                 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0,
8664                         "VSS()" /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
8665             }
8666 
8667             readSettings();
8668             mVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION);
8669             mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
8670             final BroadcastOptions volumeChangedOptions = BroadcastOptions.makeBasic();
8671             // This allows us to discard older broadcasts still waiting to be delivered
8672             // which have the same namespace (VOLUME_CHANGED_ACTION) and key (mStreamType).
8673             volumeChangedOptions.setDeliveryGroupPolicy(DELIVERY_GROUP_POLICY_MOST_RECENT);
8674             volumeChangedOptions.setDeliveryGroupMatchingKey(
8675                     AudioManager.VOLUME_CHANGED_ACTION, String.valueOf(mStreamType));
8676             volumeChangedOptions.setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE);
8677             mVolumeChangedOptions = volumeChangedOptions.toBundle();
8678 
8679             mStreamDevicesChanged = new Intent(AudioManager.STREAM_DEVICES_CHANGED_ACTION);
8680             mStreamDevicesChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
8681             final BroadcastOptions streamDevicesChangedOptions = BroadcastOptions.makeBasic();
8682             streamDevicesChangedOptions.setDeliveryGroupPolicy(DELIVERY_GROUP_POLICY_MOST_RECENT);
8683             streamDevicesChangedOptions.setDeliveryGroupMatchingKey(
8684                     AudioManager.STREAM_DEVICES_CHANGED_ACTION, String.valueOf(mStreamType));
8685             streamDevicesChangedOptions.setDeferralPolicy(
8686                     BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE);
8687             mStreamDevicesChangedOptions = streamDevicesChangedOptions.toBundle();
8688         }
8689 
8690         /**
8691          * Associate a {@link volumeGroupState} on the {@link VolumeStreamState}.
8692          * <p> It helps to synchronize the index, mute attributes on the maching
8693          * {@link volumeGroupState}
8694          * @param volumeGroupState matching the {@link VolumeStreamState}
8695          */
setVolumeGroupState(VolumeGroupState volumeGroupState)8696         public void setVolumeGroupState(VolumeGroupState volumeGroupState) {
8697             mVolumeGroupState = volumeGroupState;
8698             if (mVolumeGroupState != null) {
8699                 mVolumeGroupState.setSettingName(mVolumeIndexSettingName);
8700             }
8701         }
8702         /**
8703          * Update the minimum index that can be used without MODIFY_AUDIO_SETTINGS permission
8704          * @param index minimum index expressed in "UI units", i.e. no 10x factor
8705          */
updateNoPermMinIndex(int index)8706         public void updateNoPermMinIndex(int index) {
8707             mIndexMinNoPerm = index * 10;
8708             if (mIndexMinNoPerm < mIndexMin) {
8709                 Log.e(TAG, "Invalid mIndexMinNoPerm for stream " + mStreamType);
8710                 mIndexMinNoPerm = mIndexMin;
8711             }
8712         }
8713 
8714         /**
8715          * Returns a list of devices associated with the stream type.
8716          *
8717          * This is a reference to the local list, do not modify.
8718          */
8719         @GuardedBy("VolumeStreamState.class")
8720         @NonNull
observeDevicesForStream_syncVSS( boolean checkOthers)8721         public Set<Integer> observeDevicesForStream_syncVSS(
8722                 boolean checkOthers) {
8723             if (!mSystemServer.isPrivileged()) {
8724                 return new TreeSet<Integer>();
8725             }
8726             final Set<Integer> deviceSet =
8727                     getDeviceSetForStreamDirect(mStreamType);
8728             if (deviceSet.equals(mObservedDeviceSet)) {
8729                 return mObservedDeviceSet;
8730             }
8731 
8732             // Use legacy bit masks for message signalling.
8733             // TODO(b/185386781): message needs update since it uses devices bit-mask.
8734             final int devices = AudioSystem.getDeviceMaskFromSet(deviceSet);
8735             final int prevDevices = AudioSystem.getDeviceMaskFromSet(mObservedDeviceSet);
8736 
8737             mObservedDeviceSet = deviceSet;
8738             if (checkOthers) {
8739                 // one stream's devices have changed, check the others
8740                 postObserveDevicesForAllStreams(mStreamType);
8741             }
8742             // log base stream changes to the event log
8743             if (mStreamVolumeAlias[mStreamType] == mStreamType) {
8744                 EventLogTags.writeStreamDevicesChanged(mStreamType, prevDevices, devices);
8745             }
8746             // send STREAM_DEVICES_CHANGED_ACTION on the message handler so it is scheduled after
8747             // the postObserveDevicesForStreams is handled
8748             final SomeArgs args = SomeArgs.obtain();
8749             args.arg1 = mStreamDevicesChanged;
8750             args.arg2 = mStreamDevicesChangedOptions;
8751             sendMsg(mAudioHandler,
8752                     MSG_STREAM_DEVICES_CHANGED,
8753                     SENDMSG_QUEUE, prevDevices /*arg1*/, devices /*arg2*/,
8754                     // ok to send reference to this object, it is final
8755                     args /*obj*/, 0 /*delay*/);
8756             return mObservedDeviceSet;
8757         }
8758 
getSettingNameForDevice(int device)8759         public @Nullable String getSettingNameForDevice(int device) {
8760             if (!hasValidSettingsName()) {
8761                 return null;
8762             }
8763             final String suffix = AudioSystem.getOutputDeviceName(device);
8764             if (suffix.isEmpty()) {
8765                 return mVolumeIndexSettingName;
8766             }
8767             return mVolumeIndexSettingName + "_" + suffix;
8768         }
8769 
hasValidSettingsName()8770         private boolean hasValidSettingsName() {
8771             return (mVolumeIndexSettingName != null && !mVolumeIndexSettingName.isEmpty());
8772         }
8773 
setSettingName(String settingName)8774         void setSettingName(String settingName) {
8775             mVolumeIndexSettingName = settingName;
8776             if (mVolumeGroupState != null) {
8777                 mVolumeGroupState.setSettingName(mVolumeIndexSettingName);
8778             }
8779         }
8780 
getSettingName()8781         String getSettingName() {
8782             return mVolumeIndexSettingName;
8783         }
8784 
readSettings()8785         public void readSettings() {
8786             synchronized (mSettingsLock) {
8787                 synchronized (VolumeStreamState.class) {
8788                     // force maximum volume on all streams if fixed volume property is set
8789                     if (mUseFixedVolume) {
8790                         mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
8791                         return;
8792                     }
8793                     // do not read system stream volume from settings: this stream is always aliased
8794                     // to another stream type and its volume is never persisted. Values in settings can
8795                     // only be stale values
8796                     if ((mStreamType == AudioSystem.STREAM_SYSTEM) ||
8797                             (mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED)) {
8798                         int index = 10 * AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType];
8799                         if (mCameraSoundForced) {
8800                             index = mIndexMax;
8801                         }
8802                         mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, index);
8803                         return;
8804                     }
8805                 }
8806             }
8807             synchronized (VolumeStreamState.class) {
8808                 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
8809 
8810                     // retrieve current volume for device
8811                     // if no volume stored for current stream and device, use default volume if default
8812                     // device, continue otherwise
8813                     int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) ?
8814                             AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType] : -1;
8815                     int index;
8816                     if (!hasValidSettingsName()) {
8817                         index = defaultIndex;
8818                     } else {
8819                         String name = getSettingNameForDevice(device);
8820                         index = mSettings.getSystemIntForUser(
8821                                 mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT);
8822                     }
8823                     if (index == -1) {
8824                         continue;
8825                     }
8826 
8827                     mIndexMap.put(device, getValidIndex(10 * index,
8828                             true /*hasModifyAudioSettings*/));
8829                 }
8830             }
8831         }
8832 
getAbsoluteVolumeIndex(int index)8833         private int getAbsoluteVolumeIndex(int index) {
8834             if (absVolumeIndexFix()) {
8835                 // The attenuation is applied in the APM. No need to manipulate the index here
8836                 return index;
8837             } else {
8838                 /* Special handling for Bluetooth Absolute Volume scenario
8839                  * If we send full audio gain, some accessories are too loud even at its lowest
8840                  * volume. We are not able to enumerate all such accessories, so here is the
8841                  * workaround from phone side.
8842                  * Pre-scale volume at lowest volume steps 1 2 and 3.
8843                  * For volume step 0, set audio gain to 0 as some accessories won't mute on their
8844                  * end.
8845                  */
8846                 if (index == 0) {
8847                     // 0% for volume 0
8848                     index = 0;
8849                 } else if (!disablePrescaleAbsoluteVolume() && index > 0 && index <= 3) {
8850                     // Pre-scale for volume steps 1 2 and 3
8851                     index = (int) (mIndexMax * mPrescaleAbsoluteVolume[index - 1]) / 10;
8852                 } else {
8853                     // otherwise, full gain
8854                     index = (mIndexMax + 5) / 10;
8855                 }
8856                 return index;
8857             }
8858         }
8859 
setStreamVolumeIndex(int index, int device)8860         private void setStreamVolumeIndex(int index, int device) {
8861             // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted.
8862             // This allows RX path muting by the audio HAL only when explicitly muted but not when
8863             // index is just set to 0 to repect BT requirements
8864             if (mStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0
8865                     && !isFullyMuted()) {
8866                 index = 1;
8867             }
8868 
8869             if (DEBUG_VOL) {
8870                 Log.d(TAG, "setStreamVolumeIndexAS(" + mStreamType + ", " + index + ", " + device
8871                         + ")");
8872             }
8873             mAudioSystem.setStreamVolumeIndexAS(mStreamType, index, device);
8874         }
8875 
8876         // must be called while synchronized VolumeStreamState.class
applyDeviceVolume_syncVSS(int device)8877         /*package*/ void applyDeviceVolume_syncVSS(int device) {
8878             int index;
8879             if (isFullyMuted()) {
8880                 index = 0;
8881             } else if (isAbsoluteVolumeDevice(device)
8882                     || isA2dpAbsoluteVolumeDevice(device)
8883                     || AudioSystem.isLeAudioDeviceType(device)) {
8884                 // do not change the volume logic for dynamic abs behavior devices like HDMI
8885                 if (absVolumeIndexFix() && isAbsoluteVolumeDevice(device)) {
8886                     index = getAbsoluteVolumeIndex((mIndexMax + 5) / 10);
8887                 } else {
8888                     index = getAbsoluteVolumeIndex((getIndex(device) + 5) / 10);
8889                 }
8890             } else if (isFullVolumeDevice(device)) {
8891                 index = (mIndexMax + 5)/10;
8892             } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
8893                 if (absVolumeIndexFix()) {
8894                     index = getAbsoluteVolumeIndex((getIndex(device) + 5) / 10);
8895                 } else {
8896                     index = (mIndexMax + 5) / 10;
8897                 }
8898             } else {
8899                 index = (getIndex(device) + 5)/10;
8900             }
8901 
8902             setStreamVolumeIndex(index, device);
8903         }
8904 
applyAllVolumes()8905         public void applyAllVolumes() {
8906             synchronized (VolumeStreamState.class) {
8907                 // apply device specific volumes first
8908                 int index;
8909                 boolean isAbsoluteVolume = false;
8910                 for (int i = 0; i < mIndexMap.size(); i++) {
8911                     final int device = mIndexMap.keyAt(i);
8912                     if (device != AudioSystem.DEVICE_OUT_DEFAULT) {
8913                         if (isFullyMuted()) {
8914                             index = 0;
8915                         } else if (isAbsoluteVolumeDevice(device)
8916                                 || isA2dpAbsoluteVolumeDevice(device)
8917                                 || AudioSystem.isLeAudioDeviceType(device)) {
8918                             isAbsoluteVolume = true;
8919                             // do not change the volume logic for dynamic abs behavior devices
8920                             // like HDMI
8921                             if (absVolumeIndexFix() && isAbsoluteVolumeDevice(device)) {
8922                                 index = getAbsoluteVolumeIndex((mIndexMax + 5) / 10);
8923                             } else {
8924                                 index = getAbsoluteVolumeIndex((getIndex(device) + 5) / 10);
8925                             }
8926                         } else if (isFullVolumeDevice(device)) {
8927                             index = (mIndexMax + 5)/10;
8928                         } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
8929                             if (absVolumeIndexFix()) {
8930                                 isAbsoluteVolume = true;
8931                                 index = getAbsoluteVolumeIndex((getIndex(device) + 5) / 10);
8932                             } else {
8933                                 index = (mIndexMax + 5) / 10;
8934                             }
8935                         } else {
8936                             index = (mIndexMap.valueAt(i) + 5)/10;
8937                         }
8938 
8939                         sendMsg(mAudioHandler, SoundDoseHelper.MSG_CSD_UPDATE_ATTENUATION,
8940                                 SENDMSG_REPLACE, device,  isAbsoluteVolume ? 1 : 0, this,
8941                                 /*delay=*/0);
8942 
8943                         setStreamVolumeIndex(index, device);
8944                     }
8945                 }
8946                 // apply default volume last: by convention , default device volume will be used
8947                 // by audio policy manager if no explicit volume is present for a given device type
8948                 if (isFullyMuted()) {
8949                     index = 0;
8950                 } else {
8951                     index = (getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)/10;
8952                 }
8953                 setStreamVolumeIndex(index, AudioSystem.DEVICE_OUT_DEFAULT);
8954             }
8955         }
8956 
adjustIndex(int deltaIndex, int device, String caller, boolean hasModifyAudioSettings)8957         public boolean adjustIndex(int deltaIndex, int device, String caller,
8958                 boolean hasModifyAudioSettings) {
8959             return setIndex(getIndex(device) + deltaIndex, device, caller,
8960                     hasModifyAudioSettings);
8961         }
8962 
setIndex(int index, int device, String caller, boolean hasModifyAudioSettings)8963         public boolean setIndex(int index, int device, String caller,
8964                 boolean hasModifyAudioSettings) {
8965             boolean changed;
8966             int oldIndex;
8967             final boolean isCurrentDevice;
8968             final StringBuilder aliasStreamIndexes = new StringBuilder();
8969             synchronized (mSettingsLock) {
8970                 synchronized (VolumeStreamState.class) {
8971                     oldIndex = getIndex(device);
8972                     index = getValidIndex(index, hasModifyAudioSettings);
8973                     // for STREAM_SYSTEM_ENFORCED, do not sync aliased streams on the enforced index
8974                     int aliasIndex = index;
8975                     if ((mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED) && mCameraSoundForced) {
8976                         index = mIndexMax;
8977                     }
8978                     mIndexMap.put(device, index);
8979 
8980                     changed = oldIndex != index;
8981                     // Apply change to all streams using this one as alias if:
8982                     // - the index actually changed OR
8983                     // - there is no volume index stored for this device on alias stream.
8984                     // If changing volume of current device, also change volume of current
8985                     // device on aliased stream
8986                     isCurrentDevice = (device == getDeviceForStream(mStreamType));
8987                     final int numStreamTypes = AudioSystem.getNumStreamTypes();
8988                     for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
8989                         final VolumeStreamState aliasStreamState = mStreamStates[streamType];
8990                         if (streamType != mStreamType &&
8991                                 mStreamVolumeAlias[streamType] == mStreamType &&
8992                                 (changed || !aliasStreamState.hasIndexForDevice(device))) {
8993                             final int scaledIndex =
8994                                     rescaleIndex(aliasIndex, mStreamType, streamType);
8995                             boolean changedAlias = aliasStreamState.setIndex(scaledIndex, device,
8996                                     caller, hasModifyAudioSettings);
8997                             if (isCurrentDevice) {
8998                                 changedAlias |= aliasStreamState.setIndex(scaledIndex,
8999                                         getDeviceForStream(streamType), caller,
9000                                         hasModifyAudioSettings);
9001                             }
9002                             if (changedAlias) {
9003                                 aliasStreamIndexes.append(AudioSystem.streamToString(streamType))
9004                                         .append(":").append((scaledIndex + 5) / 10).append(" ");
9005                             }
9006                         }
9007                     }
9008                     // Mirror changes in SPEAKER ringtone volume on SCO when
9009                     if (changed && mStreamType == AudioSystem.STREAM_RING
9010                             && device == AudioSystem.DEVICE_OUT_SPEAKER) {
9011                         for (int i = 0; i < mIndexMap.size(); i++) {
9012                             int otherDevice = mIndexMap.keyAt(i);
9013                             if (AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(otherDevice)) {
9014                                 mIndexMap.put(otherDevice, index);
9015                             }
9016                         }
9017                     }
9018                 }
9019             }
9020             if (changed) {
9021                 // If associated to volume group, update group cache
9022                 updateVolumeGroupIndex(device, /* forceMuteState= */ false);
9023 
9024                 oldIndex = (oldIndex + 5) / 10;
9025                 index = (index + 5) / 10;
9026                 // log base stream changes to the event log
9027                 if (mStreamVolumeAlias[mStreamType] == mStreamType) {
9028                     if (caller == null) {
9029                         Log.w(TAG, "No caller for volume_changed event", new Throwable());
9030                     }
9031                     EventLogTags.writeVolumeChanged(mStreamType, oldIndex, index, mIndexMax / 10,
9032                             caller);
9033                 }
9034                 // fire changed intents for all streams, but only when the device it changed on
9035                 //  is the current device
9036                 if ((index != oldIndex) && isCurrentDevice) {
9037                     // for single volume devices, only send the volume change broadcast
9038                     // on the alias stream
9039                     if (!mIsSingleVolume || (mStreamVolumeAlias[mStreamType] == mStreamType)) {
9040                         mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index);
9041                         mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE,
9042                                 oldIndex);
9043                         mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS,
9044                                 mStreamVolumeAlias[mStreamType]);
9045                         if (mStreamType == mStreamVolumeAlias[mStreamType]) {
9046                             String aliasStreamIndexesString = "";
9047                             if (!aliasStreamIndexes.isEmpty()) {
9048                                 aliasStreamIndexesString =
9049                                         " aliased streams: " + aliasStreamIndexes;
9050                             }
9051                             AudioService.sVolumeLogger.enqueue(new VolChangedBroadcastEvent(
9052                                     mStreamType, aliasStreamIndexesString, index, oldIndex));
9053                         }
9054                         sendBroadcastToAll(mVolumeChanged, mVolumeChangedOptions);
9055                     }
9056                 }
9057             }
9058             return changed;
9059         }
9060 
getIndex(int device)9061         public int getIndex(int device) {
9062             synchronized (VolumeStreamState.class) {
9063                 int index = mIndexMap.get(device, -1);
9064                 if (index == -1) {
9065                     // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
9066                     index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT);
9067                 }
9068                 return index;
9069             }
9070         }
9071 
getVolumeInfo(int device)9072         public @NonNull VolumeInfo getVolumeInfo(int device) {
9073             synchronized (VolumeStreamState.class) {
9074                 int index = mIndexMap.get(device, -1);
9075                 if (index == -1) {
9076                     // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
9077                     index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT);
9078                 }
9079                 final VolumeInfo vi = new VolumeInfo.Builder(mStreamType)
9080                         .setMinVolumeIndex(mIndexMin)
9081                         .setMaxVolumeIndex(mIndexMax)
9082                         .setVolumeIndex(index)
9083                         .setMuted(isFullyMuted())
9084                         .build();
9085                 return vi;
9086             }
9087         }
9088 
hasIndexForDevice(int device)9089         public boolean hasIndexForDevice(int device) {
9090             synchronized (VolumeStreamState.class) {
9091                 return (mIndexMap.get(device, -1) != -1);
9092             }
9093         }
9094 
getMaxIndex()9095         public int getMaxIndex() {
9096             return mIndexMax;
9097         }
9098 
9099         /**
9100          * @return the lowest index regardless of permissions
9101          */
getMinIndex()9102         public int getMinIndex() {
9103             return mIndexMin;
9104         }
9105 
9106         /**
9107          * @param isPrivileged true if the caller is privileged and not subject to minimum
9108          *                     volume index thresholds
9109          * @return the lowest index that this caller can set or adjust to
9110          */
getMinIndex(boolean isPrivileged)9111         public int getMinIndex(boolean isPrivileged) {
9112             return isPrivileged ? mIndexMin : mIndexMinNoPerm;
9113         }
9114 
9115         /**
9116          * Copies all device/index pairs from the given VolumeStreamState after initializing
9117          * them with the volume for DEVICE_OUT_DEFAULT. No-op if the source VolumeStreamState
9118          * has the same stream type as this instance.
9119          * @param srcStream
9120          * @param caller
9121          */
9122         // must be sync'd on mSettingsLock before VolumeStreamState.class
9123         @GuardedBy("VolumeStreamState.class")
setAllIndexes(VolumeStreamState srcStream, String caller)9124         public void setAllIndexes(VolumeStreamState srcStream, String caller) {
9125             if (mStreamType == srcStream.mStreamType) {
9126                 return;
9127             }
9128             int srcStreamType = srcStream.getStreamType();
9129             // apply default device volume from source stream to all devices first in case
9130             // some devices are present in this stream state but not in source stream state
9131             int index = srcStream.getIndex(AudioSystem.DEVICE_OUT_DEFAULT);
9132             index = rescaleIndex(index, srcStreamType, mStreamType);
9133             for (int i = 0; i < mIndexMap.size(); i++) {
9134                 mIndexMap.put(mIndexMap.keyAt(i), index);
9135             }
9136             // Now apply actual volume for devices in source stream state
9137             SparseIntArray srcMap = srcStream.mIndexMap;
9138             for (int i = 0; i < srcMap.size(); i++) {
9139                 int device = srcMap.keyAt(i);
9140                 index = srcMap.valueAt(i);
9141                 index = rescaleIndex(index, srcStreamType, mStreamType);
9142 
9143                 setIndex(index, device, caller, true /*hasModifyAudioSettings*/);
9144             }
9145         }
9146 
9147         // must be sync'd on mSettingsLock before VolumeStreamState.class
9148         @GuardedBy("VolumeStreamState.class")
setAllIndexesToMax()9149         public void setAllIndexesToMax() {
9150             for (int i = 0; i < mIndexMap.size(); i++) {
9151                 mIndexMap.put(mIndexMap.keyAt(i), mIndexMax);
9152             }
9153         }
9154 
9155         // If associated to volume group, update group cache
updateVolumeGroupIndex(int device, boolean forceMuteState)9156         private void updateVolumeGroupIndex(int device, boolean forceMuteState) {
9157             // need mSettingsLock when called from setIndex for vgs.mute -> vgs.applyAllVolumes ->
9158             // vss.setIndex which grabs this lock after VSS.class. Locking order needs to be
9159             // preserved
9160             synchronized (mSettingsLock) {
9161                 synchronized (VolumeStreamState.class) {
9162                     if (mVolumeGroupState != null) {
9163                         int groupIndex = (getIndex(device) + 5) / 10;
9164                         if (DEBUG_VOL) {
9165                             Log.d(TAG, "updateVolumeGroupIndex for stream " + mStreamType
9166                                     + ", muted=" + mIsMuted + ", device=" + device + ", index="
9167                                     + getIndex(device) + ", group " + mVolumeGroupState.name()
9168                                     + " Muted=" + mVolumeGroupState.isMuted() + ", Index="
9169                                     + groupIndex + ", forceMuteState=" + forceMuteState);
9170                         }
9171                         mVolumeGroupState.updateVolumeIndex(groupIndex, device);
9172                         // Only propage mute of stream when applicable
9173                         if (isMutable()) {
9174                             // For call stream, align mute only when muted, not when index is set to
9175                             // 0
9176                             mVolumeGroupState.mute(
9177                                     forceMuteState ? mIsMuted :
9178                                             (groupIndex == 0 && !isCallStream(mStreamType))
9179                                                     || mIsMuted);
9180                         }
9181                     }
9182                 }
9183             }
9184         }
9185 
9186         /**
9187          * Mute/unmute the stream
9188          * @param state the new mute state
9189          * @return true if the mute state was changed
9190          */
mute(boolean state, String source)9191         public boolean mute(boolean state, String source) {
9192             boolean changed = false;
9193             synchronized (VolumeStreamState.class) {
9194                 changed = mute(state, true, source);
9195             }
9196             if (changed) {
9197                 broadcastMuteSetting(mStreamType, state);
9198             }
9199             return changed;
9200         }
9201 
9202         /**
9203          * Mute/unmute the stream by AudioService
9204          * @param state the new mute state
9205          * @return true if the mute state was changed
9206          */
muteInternally(boolean state)9207         public boolean muteInternally(boolean state) {
9208             boolean changed = false;
9209             synchronized (VolumeStreamState.class) {
9210                 if (state != mIsMutedInternally) {
9211                     changed = true;
9212                     mIsMutedInternally = state;
9213                     // mute immediately to avoid delay and preemption when using a message.
9214                     applyAllVolumes();
9215                 }
9216             }
9217             if (changed) {
9218                 sVolumeLogger.enqueue(new VolumeEvent(
9219                         VolumeEvent.VOL_MUTE_STREAM_INT, mStreamType, state));
9220             }
9221             return changed;
9222         }
9223 
9224         @GuardedBy("VolumeStreamState.class")
isFullyMuted()9225         public boolean isFullyMuted() {
9226             return mIsMuted || mIsMutedInternally;
9227         }
9228 
9229 
isMutable()9230         private boolean isMutable() {
9231             return isStreamAffectedByMute(mStreamType)
9232                     && (mIndexMin == 0 || isCallStream(mStreamType));
9233         }
9234 
9235         /**
9236          * Mute/unmute the stream
9237          * @param state the new mute state
9238          * @param apply true to propagate to HW, or false just to update the cache. May be needed
9239          * to mute a stream and its aliases as applyAllVolume will force settings to aliases.
9240          * It prevents unnecessary calls to {@see AudioSystem#setStreamVolume}
9241          * @return true if the mute state was changed
9242          */
mute(boolean state, boolean apply, String src)9243         public boolean mute(boolean state, boolean apply, String src) {
9244             synchronized (VolumeStreamState.class) {
9245                 boolean changed = state != mIsMuted;
9246                 if (changed) {
9247                     sMuteLogger.enqueue(
9248                             new AudioServiceEvents.StreamMuteEvent(mStreamType, state, src));
9249                     // check to see if unmuting should not have happened due to ringer muted streams
9250                     if (!state && isStreamMutedByRingerOrZenMode(mStreamType)) {
9251                         Log.e(TAG, "Unmuting stream " + mStreamType
9252                                 + " despite ringer-zen muted stream 0x"
9253                                 + Integer.toHexString(AudioService.sRingerAndZenModeMutedStreams),
9254                                 new Exception()); // this will put a stack trace in the logs
9255                         sMuteLogger.enqueue(new AudioServiceEvents.StreamUnmuteErrorEvent(
9256                                 mStreamType, AudioService.sRingerAndZenModeMutedStreams));
9257                     }
9258                     mIsMuted = state;
9259                     if (apply) {
9260                         doMute();
9261                     }
9262                 }
9263                 return changed;
9264             }
9265         }
9266 
doMute()9267         public void doMute() {
9268             synchronized (VolumeStreamState.class) {
9269                 // If associated to volume group, update group cache
9270                 updateVolumeGroupIndex(getDeviceForStream(mStreamType), /* forceMuteState= */ true);
9271 
9272                 // Set the new mute volume. This propagates the values to
9273                 // the audio system, otherwise the volume won't be changed
9274                 // at the lower level.
9275                 sendMsg(mAudioHandler,
9276                         MSG_SET_ALL_VOLUMES,
9277                         SENDMSG_QUEUE,
9278                         0,
9279                         0,
9280                         this, 0);
9281             }
9282         }
9283 
getStreamType()9284         public int getStreamType() {
9285             return mStreamType;
9286         }
9287 
checkFixedVolumeDevices()9288         public void checkFixedVolumeDevices() {
9289             synchronized (VolumeStreamState.class) {
9290                 // ignore settings for fixed volume devices: volume should always be at max or 0
9291                 if (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_MUSIC) {
9292                     for (int i = 0; i < mIndexMap.size(); i++) {
9293                         int device = mIndexMap.keyAt(i);
9294                         int index = mIndexMap.valueAt(i);
9295                         if (isFullVolumeDevice(device)
9296                                 || (isFixedVolumeDevice(device) && index != 0)) {
9297                             mIndexMap.put(device, mIndexMax);
9298                         }
9299                         applyDeviceVolume_syncVSS(device);
9300                     }
9301                 }
9302             }
9303         }
9304 
getValidIndex(int index, boolean hasModifyAudioSettings)9305         private int getValidIndex(int index, boolean hasModifyAudioSettings) {
9306             final int indexMin = hasModifyAudioSettings ? mIndexMin : mIndexMinNoPerm;
9307             if (index < indexMin) {
9308                 return indexMin;
9309             } else if (mUseFixedVolume || index > mIndexMax) {
9310                 return mIndexMax;
9311             }
9312 
9313             return index;
9314         }
9315 
dump(PrintWriter pw)9316         private void dump(PrintWriter pw) {
9317             pw.print("   Muted: ");
9318             pw.println(mIsMuted);
9319             pw.print("   Muted Internally: ");
9320             pw.println(mIsMutedInternally);
9321             pw.print("   Min: ");
9322             pw.print((mIndexMin + 5) / 10);
9323             if (mIndexMin != mIndexMinNoPerm) {
9324                 pw.print(" w/o perm:");
9325                 pw.println((mIndexMinNoPerm + 5) / 10);
9326             } else {
9327                 pw.println();
9328             }
9329             pw.print("   Max: ");
9330             pw.println((mIndexMax + 5) / 10);
9331             pw.print("   streamVolume:"); pw.println(getStreamVolume(mStreamType));
9332             pw.print("   Current: ");
9333             for (int i = 0; i < mIndexMap.size(); i++) {
9334                 if (i > 0) {
9335                     pw.print(", ");
9336                 }
9337                 final int device = mIndexMap.keyAt(i);
9338                 pw.print(Integer.toHexString(device));
9339                 final String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
9340                         : AudioSystem.getOutputDeviceName(device);
9341                 if (!deviceName.isEmpty()) {
9342                     pw.print(" (");
9343                     pw.print(deviceName);
9344                     pw.print(")");
9345                 }
9346                 pw.print(": ");
9347                 final int index = (mIndexMap.valueAt(i) + 5) / 10;
9348                 pw.print(index);
9349             }
9350             pw.println();
9351             pw.print("   Devices: ");
9352             pw.print(AudioSystem.deviceSetToString(getDeviceSetForStream(mStreamType)));
9353             pw.println();
9354             pw.print("   Volume Group: ");
9355             pw.println(mVolumeGroupState != null ? mVolumeGroupState.name() : "n/a");
9356         }
9357     }
9358 
9359     /** Thread that handles native AudioSystem control. */
9360     private class AudioSystemThread extends Thread {
AudioSystemThread()9361         AudioSystemThread() {
9362             super("AudioService");
9363         }
9364 
9365         @Override
run()9366         public void run() {
9367             // Set this thread up so the handler will work on it
9368             Looper.prepare();
9369 
9370             synchronized(AudioService.this) {
9371                 mAudioHandler = new AudioHandler();
9372 
9373                 // Notify that the handler has been created
9374                 AudioService.this.notify();
9375             }
9376 
9377             // Listen for volume change requests that are set by VolumePanel
9378             Looper.loop();
9379         }
9380     }
9381 
9382     private static final class DeviceVolumeUpdate {
9383         final int mStreamType;
9384         final int mDevice;
9385         final @NonNull String mCaller;
9386         private static final int NO_NEW_INDEX = -2049;
9387         private final int mVssVolIndex;
9388 
9389         // Constructor with volume index, meant to cause this volume to be set and applied for the
9390         // given stream type on the given device
DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller)9391         DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller) {
9392             mStreamType = streamType;
9393             mVssVolIndex = vssVolIndex;
9394             mDevice = device;
9395             mCaller = caller;
9396         }
9397 
9398         // Constructor with no volume index, meant to cause re-apply of volume for the given
9399         // stream type on the given device
DeviceVolumeUpdate(int streamType, int device, @NonNull String caller)9400         DeviceVolumeUpdate(int streamType, int device, @NonNull String caller) {
9401             mStreamType = streamType;
9402             mVssVolIndex = NO_NEW_INDEX;
9403             mDevice = device;
9404             mCaller = caller;
9405         }
9406 
hasVolumeIndex()9407         boolean hasVolumeIndex() {
9408             return mVssVolIndex != NO_NEW_INDEX;
9409         }
9410 
getVolumeIndex()9411         int getVolumeIndex() throws IllegalStateException {
9412             Preconditions.checkState(mVssVolIndex != NO_NEW_INDEX);
9413             return mVssVolIndex;
9414         }
9415     }
9416 
9417     /** only public for mocking/spying, do not call outside of AudioService */
9418     @VisibleForTesting
postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device, String caller)9419     public void postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device,
9420                                                 String caller) {
9421         sendMsg(mAudioHandler,
9422                 MSG_SET_DEVICE_STREAM_VOLUME,
9423                 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/,
9424                 new DeviceVolumeUpdate(streamType, vssVolIndex, device, caller),
9425                 0 /*delay*/);
9426     }
9427 
postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller)9428     /*package*/ void postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller) {
9429         sendMsg(mAudioHandler,
9430                 MSG_SET_DEVICE_STREAM_VOLUME,
9431                 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/,
9432                 new DeviceVolumeUpdate(streamType, device, caller),
9433                 0 /*delay*/);
9434     }
9435 
onSetVolumeIndexOnDevice(@onNull DeviceVolumeUpdate update)9436     private void onSetVolumeIndexOnDevice(@NonNull DeviceVolumeUpdate update) {
9437         final VolumeStreamState streamState = mStreamStates[update.mStreamType];
9438         if (update.hasVolumeIndex()) {
9439             int index = update.getVolumeIndex();
9440             if (mSoundDoseHelper.checkSafeMediaVolume(update.mStreamType, index, update.mDevice)) {
9441                 index = mSoundDoseHelper.safeMediaVolumeIndex(update.mDevice);
9442             }
9443             streamState.setIndex(index, update.mDevice, update.mCaller,
9444                     // trusted as index is always validated before message is posted
9445                     true /*hasModifyAudioSettings*/);
9446             sVolumeLogger.enqueue(new EventLogger.StringEvent(update.mCaller + " dev:0x"
9447                     + Integer.toHexString(update.mDevice) + " volIdx:" + index));
9448         } else {
9449             sVolumeLogger.enqueue(new EventLogger.StringEvent(update.mCaller
9450                     + " update vol on dev:0x" + Integer.toHexString(update.mDevice)));
9451         }
9452         setDeviceVolume(streamState, update.mDevice);
9453     }
9454 
setDeviceVolume(VolumeStreamState streamState, int device)9455     /*package*/ void setDeviceVolume(VolumeStreamState streamState, int device) {
9456 
9457         synchronized (VolumeStreamState.class) {
9458             sendMsg(mAudioHandler, SoundDoseHelper.MSG_CSD_UPDATE_ATTENUATION, SENDMSG_REPLACE,
9459                     device, (isAbsoluteVolumeDevice(device) || isA2dpAbsoluteVolumeDevice(device)
9460                             || AudioSystem.isLeAudioDeviceType(device) ? 1 : 0),
9461                     streamState, /*delay=*/0);
9462             // Apply volume
9463             streamState.applyDeviceVolume_syncVSS(device);
9464 
9465             // Apply change to all streams using this one as alias
9466             int numStreamTypes = AudioSystem.getNumStreamTypes();
9467             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
9468                 if (streamType != streamState.mStreamType &&
9469                         mStreamVolumeAlias[streamType] == streamState.mStreamType) {
9470                     // Make sure volume is also maxed out on A2DP device for aliased stream
9471                     // that may have a different device selected
9472                     int streamDevice = getDeviceForStream(streamType);
9473                     if ((device != streamDevice)
9474                             && (isAbsoluteVolumeDevice(device)
9475                                 || isA2dpAbsoluteVolumeDevice(device)
9476                                 || AudioSystem.isLeAudioDeviceType(device))) {
9477                         mStreamStates[streamType].applyDeviceVolume_syncVSS(device);
9478                     }
9479                     mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice);
9480                 }
9481             }
9482         }
9483         // Post a persist volume msg
9484         sendMsg(mAudioHandler,
9485                 MSG_PERSIST_VOLUME,
9486                 SENDMSG_QUEUE,
9487                 device,
9488                 0,
9489                 streamState,
9490                 PERSIST_DELAY);
9491 
9492     }
9493 
9494     /** Handles internal volume messages in separate volume thread. */
9495     /*package*/ class AudioHandler extends Handler {
9496 
AudioHandler()9497         AudioHandler() {
9498             super();
9499         }
9500 
AudioHandler(Looper looper)9501         AudioHandler(Looper looper) {
9502             super(looper);
9503         }
9504 
setAllVolumes(VolumeStreamState streamState)9505         private void setAllVolumes(VolumeStreamState streamState) {
9506 
9507             // Apply volume
9508             streamState.applyAllVolumes();
9509 
9510             // Apply change to all streams using this one as alias
9511             int numStreamTypes = AudioSystem.getNumStreamTypes();
9512             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
9513                 if (streamType != streamState.mStreamType &&
9514                         mStreamVolumeAlias[streamType] == streamState.mStreamType) {
9515                     mStreamStates[streamType].applyAllVolumes();
9516                 }
9517             }
9518         }
9519 
persistVolume(VolumeStreamState streamState, int device)9520         private void persistVolume(VolumeStreamState streamState, int device) {
9521             if (mUseFixedVolume) {
9522                 return;
9523             }
9524             if (mIsSingleVolume && (streamState.mStreamType != AudioSystem.STREAM_MUSIC)) {
9525                 return;
9526             }
9527 
9528             // Persisting STREAM_SYSTEM_ENFORCED index is not needed as its alias (STREAM_RING)
9529             // is persisted. This can also be problematic when the enforcement is active as it will
9530             // override current SYSTEM_RING persisted value given they share the same settings name
9531             // (due to aliasing).
9532             if (streamState.mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED) {
9533                 return;
9534             }
9535             if (streamState.hasValidSettingsName()) {
9536                 mSettings.putSystemIntForUser(mContentResolver,
9537                         streamState.getSettingNameForDevice(device),
9538                         (streamState.getIndex(device) + 5) / 10,
9539                         UserHandle.USER_CURRENT);
9540             }
9541         }
9542 
persistRingerMode(int ringerMode)9543         private void persistRingerMode(int ringerMode) {
9544             if (mUseFixedVolume) {
9545                 return;
9546             }
9547             mSettings.putGlobalInt(mContentResolver, Settings.Global.MODE_RINGER, ringerMode);
9548         }
9549 
onNotifyVolumeEvent(@onNull IAudioPolicyCallback apc, @AudioManager.VolumeAdjustment int direction)9550         private void onNotifyVolumeEvent(@NonNull IAudioPolicyCallback apc,
9551                 @AudioManager.VolumeAdjustment int direction) {
9552             try {
9553                 apc.notifyVolumeAdjust(direction);
9554             } catch(Exception e) {
9555                 // nothing we can do about this. Do not log error, too much potential for spam
9556             }
9557         }
9558 
9559         @Override
handleMessage(Message msg)9560         public void handleMessage(Message msg) {
9561             switch (msg.what) {
9562 
9563                 case MSG_SET_DEVICE_VOLUME:
9564                     setDeviceVolume((VolumeStreamState) msg.obj, msg.arg1);
9565                     break;
9566 
9567                 case MSG_SET_ALL_VOLUMES:
9568                     setAllVolumes((VolumeStreamState) msg.obj);
9569                     break;
9570 
9571                 case MSG_PERSIST_VOLUME:
9572                     persistVolume((VolumeStreamState) msg.obj, msg.arg1);
9573                     break;
9574 
9575                 case MSG_PERSIST_VOLUME_GROUP:
9576                     final VolumeGroupState vgs = (VolumeGroupState) msg.obj;
9577                     vgs.persistVolumeGroup(msg.arg1);
9578                     break;
9579 
9580                 case MSG_PERSIST_RINGER_MODE:
9581                     // note that the value persisted is the current ringer mode, not the
9582                     // value of ringer mode as of the time the request was made to persist
9583                     persistRingerMode(getRingerModeInternal());
9584                     break;
9585 
9586                 case MSG_AUDIO_SERVER_DIED:
9587                     onAudioServerDied();
9588                     break;
9589 
9590                 case MSG_DISPATCH_AUDIO_SERVER_STATE:
9591                     onDispatchAudioServerStateChange(msg.arg1 == 1);
9592                     break;
9593 
9594                 case MSG_UNLOAD_SOUND_EFFECTS:
9595                     mSfxHelper.unloadSoundEffects();
9596                     break;
9597 
9598                 case MSG_LOAD_SOUND_EFFECTS:
9599                 {
9600                     LoadSoundEffectReply reply = (LoadSoundEffectReply) msg.obj;
9601                     if (mSystemReady) {
9602                         mSfxHelper.loadSoundEffects(reply);
9603                     } else {
9604                         Log.w(TAG, "[schedule]loadSoundEffects() called before boot complete");
9605                         if (reply != null) {
9606                             reply.run(false);
9607                         }
9608                     }
9609                 }
9610                     break;
9611 
9612                 case MSG_PLAY_SOUND_EFFECT:
9613                     mSfxHelper.playSoundEffect(msg.arg1, msg.arg2);
9614                     break;
9615 
9616                 case MSG_SET_FORCE_USE:
9617                 {
9618                     final String eventSource = (String) msg.obj;
9619                     final int useCase = msg.arg1;
9620                     final int config = msg.arg2;
9621                     if (useCase == AudioSystem.FOR_MEDIA) {
9622                         Log.wtf(TAG, "Invalid force use FOR_MEDIA in AudioService from "
9623                                 + eventSource);
9624                         break;
9625                     }
9626                     new MediaMetrics.Item(MediaMetrics.Name.AUDIO_FORCE_USE
9627                             + MediaMetrics.SEPARATOR + AudioSystem.forceUseUsageToString(useCase))
9628                             .set(MediaMetrics.Property.EVENT, "setForceUse")
9629                             .set(MediaMetrics.Property.FORCE_USE_DUE_TO, eventSource)
9630                             .set(MediaMetrics.Property.FORCE_USE_MODE,
9631                                     AudioSystem.forceUseConfigToString(config))
9632                             .record();
9633                     sForceUseLogger.enqueue(
9634                             new AudioServiceEvents.ForceUseEvent(useCase, config, eventSource));
9635                     mAudioSystem.setForceUse(useCase, config);
9636                 }
9637                     break;
9638 
9639                 case MSG_DISABLE_AUDIO_FOR_UID:
9640                     mPlaybackMonitor.disableAudioForUid( msg.arg1 == 1 /* disable */,
9641                             msg.arg2 /* uid */);
9642                     mAudioEventWakeLock.release();
9643                     break;
9644 
9645                 case MSG_INIT_STREAMS_VOLUMES:
9646                     onInitStreamsAndVolumes();
9647                     mAudioEventWakeLock.release();
9648                     break;
9649 
9650                 case MSG_INIT_ADI_DEVICE_STATES:
9651                     onInitAdiDeviceStates();
9652                     mAudioEventWakeLock.release();
9653                     break;
9654 
9655                 case MSG_INIT_SPATIALIZER:
9656                     onInitSpatializer();
9657                     // the device inventory can only be synchronized after the
9658                     // spatializer has been initialized
9659                     mDeviceBroker.postSynchronizeAdiDevicesInInventory(null);
9660                     mAudioEventWakeLock.release();
9661                     break;
9662 
9663                 case MSG_INIT_HEADTRACKING_SENSORS:
9664                     mSpatializerHelper.onInitSensors();
9665                     break;
9666 
9667                 case MSG_RESET_SPATIALIZER:
9668                     mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect);
9669                     break;
9670 
9671                 case MSG_SYSTEM_READY:
9672                     onSystemReady();
9673                     break;
9674 
9675                 case MSG_INDICATE_SYSTEM_READY:
9676                     onIndicateSystemReady();
9677                     break;
9678 
9679                 case MSG_ACCESSORY_PLUG_MEDIA_UNMUTE:
9680                     onAccessoryPlugMediaUnmute(msg.arg1);
9681                     break;
9682 
9683                 case MSG_UNMUTE_STREAM_ON_SINGLE_VOL_DEVICE:
9684                     onUnmuteStreamOnSingleVolDevice(msg.arg1, msg.arg2);
9685                     break;
9686 
9687                 case MSG_DYN_POLICY_MIX_STATE_UPDATE:
9688                     onDynPolicyMixStateUpdate((String) msg.obj, msg.arg1);
9689                     break;
9690 
9691                 case MSG_NOTIFY_VOL_EVENT:
9692                     onNotifyVolumeEvent((IAudioPolicyCallback) msg.obj, msg.arg1);
9693                     break;
9694 
9695                 case MSG_ENABLE_SURROUND_FORMATS:
9696                     onEnableSurroundFormats((ArrayList<Integer>) msg.obj);
9697                     break;
9698 
9699                 case MSG_UPDATE_RINGER_MODE:
9700                     onUpdateRingerModeServiceInt();
9701                     break;
9702 
9703                 case MSG_SET_DEVICE_STREAM_VOLUME:
9704                     onSetVolumeIndexOnDevice((DeviceVolumeUpdate) msg.obj);
9705                     break;
9706 
9707                 case MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS:
9708                     onObserveDevicesForAllStreams(/*skipStream*/ msg.arg1);
9709                     break;
9710 
9711                 case MSG_HDMI_VOLUME_CHECK:
9712                     onCheckVolumeCecOnHdmiConnection(msg.arg1, (String) msg.obj);
9713                     break;
9714 
9715                 case MSG_PLAYBACK_CONFIG_CHANGE:
9716                     onPlaybackConfigChange((List<AudioPlaybackConfiguration>) msg.obj);
9717                     break;
9718                 case MSG_RECORDING_CONFIG_CHANGE:
9719                     onRecordingConfigChange((List<AudioRecordingConfiguration>) msg.obj);
9720                     break;
9721 
9722                 case MSG_BROADCAST_MICROPHONE_MUTE:
9723                     mSystemServer.sendMicrophoneMuteChangedIntent();
9724                     break;
9725 
9726                 case MSG_BROADCAST_MASTER_MUTE:
9727                     mSystemServer.broadcastMasterMuteStatus(msg.arg1 == 1);
9728                     break;
9729 
9730                 case MSG_CHECK_MODE_FOR_UID:
9731                     synchronized (mDeviceBroker.mSetModeLock) {
9732                         if (msg.obj == null) {
9733                             break;
9734                         }
9735                         // Update active playback/recording for apps requesting IN_COMMUNICATION
9736                         // mode after a grace period following the mode change
9737                         SetModeDeathHandler h = (SetModeDeathHandler) msg.obj;
9738                         if (mSetModeDeathHandlers.indexOf(h) < 0) {
9739                             break;
9740                         }
9741                         boolean wasActive = h.isActive();
9742                         h.setPlaybackActive(isPlaybackActiveForUid(h.getUid()));
9743                         h.setRecordingActive(isRecordingActiveForUid(h.getUid()));
9744                         if (wasActive != h.isActive()) {
9745                             onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(),
9746                                     mContext.getPackageName(), false /*force*/);
9747                         }
9748                     }
9749                     break;
9750 
9751                 case MSG_STREAM_DEVICES_CHANGED:
9752                     final SomeArgs args = (SomeArgs) msg.obj;
9753                     final Intent intent = (Intent) args.arg1;
9754                     final Bundle options = (Bundle) args.arg2;
9755                     args.recycle();
9756                     sendBroadcastToAll(intent
9757                             .putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_DEVICES, msg.arg1)
9758                             .putExtra(AudioManager.EXTRA_VOLUME_STREAM_DEVICES, msg.arg2),
9759                             options);
9760                     break;
9761 
9762                 case MSG_UPDATE_VOLUME_STATES_FOR_DEVICE:
9763                     onUpdateVolumeStatesForAudioDevice(msg.arg1, (String) msg.obj);
9764                     break;
9765 
9766                 case MSG_REINIT_VOLUMES:
9767                     onReinitVolumes((String) msg.obj);
9768                     break;
9769 
9770                 case MSG_UPDATE_A11Y_SERVICE_UIDS:
9771                     onUpdateAccessibilityServiceUids();
9772                     break;
9773 
9774                 case MSG_UPDATE_AUDIO_MODE:
9775                     synchronized (mDeviceBroker.mSetModeLock) {
9776                         onUpdateAudioMode(msg.arg1, msg.arg2, (String) msg.obj, false /*force*/);
9777                     }
9778                     break;
9779 
9780                 case MSG_BT_DEV_CHANGED:
9781                     mDeviceBroker.queueOnBluetoothActiveDeviceChanged(
9782                             (AudioDeviceBroker.BtDeviceChangedData) msg.obj);
9783                     break;
9784 
9785                 case MSG_DISPATCH_AUDIO_MODE:
9786                     dispatchMode(msg.arg1);
9787                     break;
9788 
9789                 case MSG_ROUTING_UPDATED:
9790                     onRoutingUpdatedFromAudioThread();
9791                     break;
9792 
9793                 case MSG_ADD_ASSISTANT_SERVICE_UID:
9794                     onAddAssistantServiceUids(new int[]{msg.arg1});
9795                     break;
9796 
9797                 case MSG_REMOVE_ASSISTANT_SERVICE_UID:
9798                     onRemoveAssistantServiceUids(new int[]{msg.arg1});
9799                     break;
9800                 case MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID:
9801                     updateActiveAssistantServiceUids();
9802                     break;
9803 
9804                 case MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR:
9805                     dispatchDeviceVolumeBehavior((AudioDeviceAttributes) msg.obj, msg.arg1);
9806                     break;
9807 
9808                 case MSG_ROTATION_UPDATE:
9809                     // rotation parameter format: "rotation=x" where x is one of 0, 90, 180, 270
9810                     mAudioSystem.setParameters((String) msg.obj);
9811                     break;
9812 
9813                 case MSG_FOLD_UPDATE:
9814                     // fold parameter format: "device_folded=x" where x is one of on, off
9815                     mAudioSystem.setParameters((String) msg.obj);
9816                     break;
9817 
9818                 case MSG_NO_LOG_FOR_PLAYER_I:
9819                     mPlaybackMonitor.ignorePlayerIId(msg.arg1);
9820                     break;
9821 
9822                 case MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES:
9823                     onDispatchPreferredMixerAttributesChanged(msg.getData(), msg.arg1);
9824                     break;
9825 
9826                 case MSG_CONFIGURATION_CHANGED:
9827                     onConfigurationChanged();
9828                     break;
9829 
9830                 case MusicFxHelper.MSG_EFFECT_CLIENT_GONE:
9831                     mMusicFxHelper.handleMessage(msg);
9832                     break;
9833 
9834                 case SoundDoseHelper.MSG_CONFIGURE_SAFE_MEDIA:
9835                 case SoundDoseHelper.MSG_CONFIGURE_SAFE_MEDIA_FORCED:
9836                 case SoundDoseHelper.MSG_PERSIST_SAFE_VOLUME_STATE:
9837                 case SoundDoseHelper.MSG_PERSIST_MUSIC_ACTIVE_MS:
9838                 case SoundDoseHelper.MSG_PERSIST_CSD_VALUES:
9839                 case SoundDoseHelper.MSG_CSD_UPDATE_ATTENUATION:
9840                 case SoundDoseHelper.MSG_LOWER_VOLUME_TO_RS1:
9841                     mSoundDoseHelper.handleMessage(msg);
9842                     break;
9843 
9844                 default:
9845                     Log.e(TAG, "Unsupported msgId " + msg.what);
9846             }
9847         }
9848     }
9849 
9850     private class SettingsObserver extends ContentObserver {
9851 
SettingsObserver()9852         SettingsObserver() {
9853             super(new Handler());
9854             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
9855                     Settings.Global.ZEN_MODE), false, this);
9856             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
9857                     Settings.Global.ZEN_MODE_CONFIG_ETAG), false, this);
9858             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
9859                     Settings.Global.MUTE_ALARM_STREAM_WITH_RINGER_MODE), false, this);
9860             mContentResolver.registerContentObserver(Settings.System.getUriFor(
9861                 Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this);
9862             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
9863                 Settings.Global.DOCK_AUDIO_MEDIA_ENABLED), false, this);
9864             mContentResolver.registerContentObserver(Settings.System.getUriFor(
9865                     Settings.System.MASTER_MONO), false, this, UserHandle.USER_ALL);
9866             mContentResolver.registerContentObserver(Settings.System.getUriFor(
9867                     Settings.System.MASTER_BALANCE), false, this, UserHandle.USER_ALL);
9868 
9869             mEncodedSurroundMode = mSettings.getGlobalInt(
9870                     mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT,
9871                     Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
9872             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
9873                     Settings.Global.ENCODED_SURROUND_OUTPUT), false, this);
9874             mEnabledSurroundFormats = mSettings.getGlobalString(
9875                     mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
9876             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
9877                     Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS), false, this);
9878 
9879             mContentResolver.registerContentObserver(Settings.Secure.getUriFor(
9880                     Settings.Secure.VOICE_INTERACTION_SERVICE), false, this);
9881         }
9882 
9883         @Override
onChange(boolean selfChange)9884         public void onChange(boolean selfChange) {
9885             super.onChange(selfChange);
9886             // FIXME This synchronized is not necessary if mSettingsLock only protects mRingerMode.
9887             //       However there appear to be some missing locks around sRingerAndZenModeMutedStreams
9888             //       and mRingerModeAffectedStreams, so will leave this synchronized for now.
9889             //       sRingerAndZenModeMutedStreams and mMuteAffectedStreams are safe (only accessed once).
9890             synchronized (mSettingsLock) {
9891                 if (updateRingerAndZenModeAffectedStreams()) {
9892                     /*
9893                      * Ensure all stream types that should be affected by ringer mode
9894                      * are in the proper state.
9895                      */
9896                     setRingerModeInt(getRingerModeInternal(), false);
9897                 }
9898                 readDockAudioSettings(mContentResolver);
9899                 updateMasterMono(mContentResolver);
9900                 updateMasterBalance(mContentResolver);
9901                 updateEncodedSurroundOutput();
9902                 sendEnabledSurroundFormats(mContentResolver, mSurroundModeChanged);
9903                 updateAssistantUIdLocked(/* forceUpdate= */ false);
9904             }
9905         }
9906 
updateEncodedSurroundOutput()9907         private void updateEncodedSurroundOutput() {
9908             int newSurroundMode = mSettings.getGlobalInt(
9909                 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT,
9910                 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
9911             // Did it change?
9912             if (mEncodedSurroundMode != newSurroundMode) {
9913                 // Send to AudioPolicyManager
9914                 sendEncodedSurroundMode(newSurroundMode, "SettingsObserver");
9915                 mDeviceBroker.toggleHdmiIfConnected_Async();
9916                 mEncodedSurroundMode = newSurroundMode;
9917                 mSurroundModeChanged = true;
9918             } else {
9919                 mSurroundModeChanged = false;
9920             }
9921         }
9922     }
9923 
avrcpSupportsAbsoluteVolume(String address, boolean support)9924     private void avrcpSupportsAbsoluteVolume(String address, boolean support) {
9925         // address is not used for now, but may be used when multiple a2dp devices are supported
9926         sVolumeLogger.enqueue(new EventLogger.StringEvent("avrcpSupportsAbsoluteVolume addr="
9927                 + Utils.anonymizeBluetoothAddress(address) + " support=" + support).printLog(TAG));
9928         mDeviceBroker.setAvrcpAbsoluteVolumeSupported(support);
9929         setAvrcpAbsoluteVolumeSupported(support);
9930     }
9931 
setAvrcpAbsoluteVolumeSupported(boolean support)9932     /*package*/ void setAvrcpAbsoluteVolumeSupported(boolean support) {
9933         mAvrcpAbsVolSupported = support;
9934         if (absVolumeIndexFix()) {
9935             int a2dpDev = AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP;
9936             synchronized (mCachedAbsVolDrivingStreamsLock) {
9937                 mCachedAbsVolDrivingStreams.compute(a2dpDev, (dev, stream) -> {
9938                     if (stream != null && !mAvrcpAbsVolSupported) {
9939                         mAudioSystem.setDeviceAbsoluteVolumeEnabled(a2dpDev, /*address=*/
9940                                 "", /*enabled*/false, AudioSystem.DEVICE_NONE);
9941                         return null;
9942                     }
9943                     // For A2DP and AVRCP we need to set the driving stream based on the
9944                     // BT contextual stream. Hence, we need to make sure in adjustStreamVolume
9945                     // and setStreamVolume that the driving abs volume stream is consistent.
9946                     int streamToDriveAbs = getBluetoothContextualVolumeStream();
9947                     if (stream == null || stream != streamToDriveAbs) {
9948                         mAudioSystem.setDeviceAbsoluteVolumeEnabled(a2dpDev, /*address=*/
9949                                 "", /*enabled*/true, streamToDriveAbs);
9950                     }
9951                     return streamToDriveAbs;
9952                 });
9953             }
9954         }
9955         sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE,
9956                     AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0,
9957                     mStreamStates[AudioSystem.STREAM_MUSIC], 0);
9958     }
9959 
9960     /**
9961      * @return true if there is currently a registered dynamic mixing policy that affects media
9962      * and is not a render + loopback policy
9963      */
9964     // only public for mocking/spying
9965     @VisibleForTesting
hasMediaDynamicPolicy()9966     public boolean hasMediaDynamicPolicy() {
9967         synchronized (mAudioPolicies) {
9968             if (mAudioPolicies.isEmpty()) {
9969                 return false;
9970             }
9971             final Collection<AudioPolicyProxy> appColl = mAudioPolicies.values();
9972             for (AudioPolicyProxy app : appColl) {
9973                 if (app.hasMixAffectingUsage(AudioAttributes.USAGE_MEDIA,
9974                         AudioMix.ROUTE_FLAG_LOOP_BACK_RENDER)) {
9975                     return true;
9976                 }
9977             }
9978             return false;
9979         }
9980     }
9981 
9982     /** only public for mocking/spying, do not call outside of AudioService */
9983     @VisibleForTesting
checkMusicActive(int deviceType, String caller)9984     public void checkMusicActive(int deviceType, String caller) {
9985         if (mSoundDoseHelper.safeDevicesContains(deviceType)) {
9986             mSoundDoseHelper.scheduleMusicActiveCheck();
9987         }
9988     }
9989 
9990     /**
9991      * Receiver for misc intent broadcasts the Phone app cares about.
9992      */
9993     private class AudioServiceBroadcastReceiver extends BroadcastReceiver {
9994         @Override
onReceive(Context context, Intent intent)9995         public void onReceive(Context context, Intent intent) {
9996             final String action = intent.getAction();
9997             int outDevice;
9998             int inDevice;
9999             int state;
10000 
10001             if (action.equals(Intent.ACTION_DOCK_EVENT)) {
10002                 int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
10003                         Intent.EXTRA_DOCK_STATE_UNDOCKED);
10004                 int config;
10005                 switch (dockState) {
10006                     case Intent.EXTRA_DOCK_STATE_DESK:
10007                         config = AudioSystem.FORCE_BT_DESK_DOCK;
10008                         break;
10009                     case Intent.EXTRA_DOCK_STATE_CAR:
10010                         config = AudioSystem.FORCE_BT_CAR_DOCK;
10011                         break;
10012                     case Intent.EXTRA_DOCK_STATE_LE_DESK:
10013                         config = AudioSystem.FORCE_ANALOG_DOCK;
10014                         break;
10015                     case Intent.EXTRA_DOCK_STATE_HE_DESK:
10016                         config = AudioSystem.FORCE_DIGITAL_DOCK;
10017                         break;
10018                     case Intent.EXTRA_DOCK_STATE_UNDOCKED:
10019                     default:
10020                         config = AudioSystem.FORCE_NONE;
10021                 }
10022                 // Low end docks have a menu to enable or disable audio
10023                 // (see mDockAudioMediaEnabled)
10024                 if (!((dockState == Intent.EXTRA_DOCK_STATE_LE_DESK)
10025                         || ((dockState == Intent.EXTRA_DOCK_STATE_UNDOCKED)
10026                                 && (mDockState == Intent.EXTRA_DOCK_STATE_LE_DESK)))) {
10027                     mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, config,
10028                             "ACTION_DOCK_EVENT intent");
10029                 }
10030                 mDockState = dockState;
10031             } else if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED)
10032                     || action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
10033                 mDeviceBroker.postReceiveBtEvent(intent);
10034             } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
10035                 if (mMonitorRotation) {
10036                     RotationHelper.enable();
10037                 }
10038                 AudioSystem.setParameters("screen_state=on");
10039             } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
10040                 if (mMonitorRotation) {
10041                     //reduce wakeups (save current) by only listening when display is on
10042                     RotationHelper.disable();
10043                 }
10044                 AudioSystem.setParameters("screen_state=off");
10045             } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
10046                 sendMsg(mAudioHandler,
10047                         MSG_CONFIGURATION_CHANGED,
10048                         SENDMSG_REPLACE,
10049                         0,
10050                         0,
10051                         null, 0);
10052             } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
10053                 // the current audio focus owner is likely no longer valid
10054                 final boolean audioDiscarded = mMediaFocusControl.maybeDiscardAudioFocusOwner();
10055                 if (audioDiscarded && mUserSwitchedReceived) {
10056                     // attempt to stop music playback for background user except on first user
10057                     // switch (i.e. first boot)
10058                     mDeviceBroker.postBroadcastBecomingNoisy();
10059                 }
10060                 mUserSwitchedReceived = true;
10061 
10062                 if (mSupportsMicPrivacyToggle) {
10063                     mMicMuteFromPrivacyToggle = mSensorPrivacyManagerInternal
10064                             .isSensorPrivacyEnabled(getCurrentUserId(),
10065                                     SensorPrivacyManager.Sensors.MICROPHONE);
10066                     setMicrophoneMuteNoCallerCheck(getCurrentUserId());
10067                 }
10068 
10069                 // load volume settings for new user
10070                 readAudioSettings(true /*userSwitch*/);
10071                 // preserve STREAM_MUSIC volume from one user to the next.
10072                 sendMsg(mAudioHandler,
10073                         MSG_SET_ALL_VOLUMES,
10074                         SENDMSG_QUEUE,
10075                         0,
10076                         0,
10077                         mStreamStates[AudioSystem.STREAM_MUSIC], 0);
10078             } else if (action.equals(Intent.ACTION_USER_BACKGROUND)) {
10079                 // Disable audio recording for the background user/profile
10080                 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
10081                 if (userId >= 0) {
10082                     // TODO Kill recording streams instead of killing processes holding permission
10083                     UserInfo userInfo = UserManagerService.getInstance().getUserInfo(userId);
10084                     killBackgroundUserProcessesWithRecordAudioPermission(userInfo);
10085                 }
10086                 try {
10087                     UserManagerService.getInstance().setUserRestriction(
10088                             UserManager.DISALLOW_RECORD_AUDIO, true, userId);
10089                 } catch (IllegalArgumentException e) {
10090                     Slog.w(TAG, "Failed to apply DISALLOW_RECORD_AUDIO restriction: " + e);
10091                 }
10092             } else if (action.equals(Intent.ACTION_USER_FOREGROUND)) {
10093                 // Enable audio recording for foreground user/profile
10094                 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
10095                 try {
10096                     UserManagerService.getInstance().setUserRestriction(
10097                             UserManager.DISALLOW_RECORD_AUDIO, false, userId);
10098                 } catch (IllegalArgumentException e) {
10099                     Slog.w(TAG, "Failed to apply DISALLOW_RECORD_AUDIO restriction: " + e);
10100                 }
10101             } else if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION) ||
10102                     action.equals(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION)) {
10103                 mMusicFxHelper.handleAudioEffectBroadcast(context, intent);
10104             } else if (action.equals(Intent.ACTION_PACKAGES_SUSPENDED)) {
10105                 final int[] suspendedUids = intent.getIntArrayExtra(Intent.EXTRA_CHANGED_UID_LIST);
10106                 final String[] suspendedPackages =
10107                         intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
10108                 if (suspendedPackages == null || suspendedUids == null
10109                         || suspendedPackages.length != suspendedUids.length) {
10110                     return;
10111                 }
10112                 for (int i = 0; i < suspendedUids.length; i++) {
10113                     if (!TextUtils.isEmpty(suspendedPackages[i])) {
10114                         mMediaFocusControl.noFocusForSuspendedApp(
10115                                 suspendedPackages[i], suspendedUids[i]);
10116                     }
10117                 }
10118             } else if (action.equals(ACTION_CHECK_MUSIC_ACTIVE)) {
10119                 mSoundDoseHelper.onCheckMusicActive(ACTION_CHECK_MUSIC_ACTIVE,
10120                         mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0));
10121             }
10122         }
10123     } // end class AudioServiceBroadcastReceiver
10124 
10125     private class AudioServiceUserRestrictionsListener implements UserRestrictionsListener {
10126 
10127         @Override
onUserRestrictionsChanged(int userId, Bundle newRestrictions, Bundle prevRestrictions)10128         public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
10129                 Bundle prevRestrictions) {
10130             // Update mic mute state.
10131             {
10132                 final boolean wasRestricted =
10133                         prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE);
10134                 final boolean isRestricted =
10135                         newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE);
10136                 if (wasRestricted != isRestricted) {
10137                     mMicMuteFromRestrictions = isRestricted;
10138                     setMicrophoneMuteNoCallerCheck(userId);
10139                 }
10140             }
10141 
10142             // Update speaker mute state.
10143             {
10144                 final boolean wasRestricted =
10145                         prevRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME)
10146                                 || prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE);
10147                 final boolean isRestricted =
10148                         newRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME)
10149                                 || newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE);
10150                 if (wasRestricted != isRestricted) {
10151                     setMasterMuteInternalNoCallerCheck(
10152                             isRestricted, /* flags =*/ 0, userId, "onUserRestrictionsChanged");
10153                 }
10154             }
10155         }
10156     } // end class AudioServiceUserRestrictionsListener
10157 
killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser)10158     private void killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser) {
10159         PackageManager pm = mContext.getPackageManager();
10160         // Find the home activity of the user. It should not be killed to avoid expensive restart,
10161         // when the user switches back. For managed profiles, we should kill all recording apps
10162         ComponentName homeActivityName = null;
10163         if (!oldUser.isManagedProfile()) {
10164             homeActivityName = LocalServices.getService(
10165                     ActivityTaskManagerInternal.class).getHomeActivityForUser(oldUser.id);
10166         }
10167         final String[] permissions = { Manifest.permission.RECORD_AUDIO };
10168         List<PackageInfo> packages;
10169         try {
10170             packages = AppGlobals.getPackageManager()
10171                     .getPackagesHoldingPermissions(permissions, 0, oldUser.id).getList();
10172         } catch (RemoteException e) {
10173             throw new AndroidRuntimeException(e);
10174         }
10175         for (int j = packages.size() - 1; j >= 0; j--) {
10176             PackageInfo pkg = packages.get(j);
10177             // Skip system processes
10178             if (UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID) {
10179                 continue;
10180             }
10181             // Skip packages that have permission to interact across users
10182             if (pm.checkPermission(Manifest.permission.INTERACT_ACROSS_USERS, pkg.packageName)
10183                     == PackageManager.PERMISSION_GRANTED) {
10184                 continue;
10185             }
10186             if (homeActivityName != null
10187                     && pkg.packageName.equals(homeActivityName.getPackageName())
10188                     && pkg.applicationInfo.isSystemApp()) {
10189                 continue;
10190             }
10191             try {
10192                 final int uid = pkg.applicationInfo.uid;
10193                 ActivityManager.getService().killUid(UserHandle.getAppId(uid),
10194                         UserHandle.getUserId(uid),
10195                         "killBackgroundUserProcessesWithAudioRecordPermission");
10196             } catch (RemoteException e) {
10197                 Log.w(TAG, "Error calling killUid", e);
10198             }
10199         }
10200     }
10201 
10202 
10203     //==========================================================================================
10204     // Audio Focus
10205     //==========================================================================================
10206     /**
10207      * Returns whether a focus request is eligible to force ducking.
10208      * Will return true if:
10209      * - the AudioAttributes have a usage of USAGE_ASSISTANCE_ACCESSIBILITY,
10210      * - the focus request is AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK,
10211      * - the associated Bundle has KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING set to true,
10212      * - the uid of the requester is a known accessibility service or root.
10213      * @param aa AudioAttributes of the focus request
10214      * @param uid uid of the focus requester
10215      * @return true if ducking is to be forced
10216      */
forceFocusDuckingForAccessibility(@ullable AudioAttributes aa, int request, int uid)10217     private boolean forceFocusDuckingForAccessibility(@Nullable AudioAttributes aa,
10218             int request, int uid) {
10219         if (aa == null || aa.getUsage() != AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY
10220                 || request != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) {
10221             return false;
10222         }
10223         final Bundle extraInfo = aa.getBundle();
10224         if (extraInfo == null ||
10225                 !extraInfo.getBoolean(AudioFocusRequest.KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING)) {
10226             return false;
10227         }
10228         if (uid == 0) {
10229             return true;
10230         }
10231         synchronized (mAccessibilityServiceUidsLock) {
10232             if (mAccessibilityServiceUids != null) {
10233                 int callingUid = Binder.getCallingUid();
10234                 for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
10235                     if (mAccessibilityServiceUids[i] == callingUid) {
10236                         return true;
10237                     }
10238                 }
10239             }
10240         }
10241         return false;
10242     }
10243 
isSupportedSystemUsage(@udioAttributes.AttributeUsage int usage)10244     private boolean isSupportedSystemUsage(@AudioAttributes.AttributeUsage int usage) {
10245         synchronized (mSupportedSystemUsagesLock) {
10246             for (int i = 0; i < mSupportedSystemUsages.length; i++) {
10247                 if (mSupportedSystemUsages[i] == usage) {
10248                     return true;
10249                 }
10250             }
10251             return false;
10252         }
10253     }
10254 
validateAudioAttributesUsage(@onNull AudioAttributes audioAttributes)10255     private void validateAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) {
10256         @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage();
10257         if (AudioAttributes.isSystemUsage(usage)) {
10258             if ((usage == AudioAttributes.USAGE_CALL_ASSISTANT
10259                     && (audioAttributes.getAllFlags() & AudioAttributes.FLAG_CALL_REDIRECTION) != 0
10260                     && callerHasPermission(CALL_AUDIO_INTERCEPTION))
10261                     || callerHasPermission(MODIFY_AUDIO_ROUTING)) {
10262                 if (!isSupportedSystemUsage(usage)) {
10263                     throw new IllegalArgumentException(
10264                             "Unsupported usage " + AudioAttributes.usageToString(usage));
10265                 }
10266             } else {
10267                 throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission");
10268             }
10269         }
10270     }
10271 
isValidAudioAttributesUsage(@onNull AudioAttributes audioAttributes)10272     private boolean isValidAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) {
10273         @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage();
10274         if (AudioAttributes.isSystemUsage(usage)) {
10275             return isSupportedSystemUsage(usage)
10276                     && ((usage == AudioAttributes.USAGE_CALL_ASSISTANT
10277                         && (audioAttributes.getAllFlags()
10278                             & AudioAttributes.FLAG_CALL_REDIRECTION) != 0
10279                         && callerHasPermission(CALL_AUDIO_INTERCEPTION))
10280                         || callerHasPermission(MODIFY_AUDIO_ROUTING));
10281         }
10282         return true;
10283     }
10284 
requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb, IAudioFocusDispatcher fd, String clientId, String callingPackageName, String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk)10285     public int requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb,
10286             IAudioFocusDispatcher fd, String clientId, String callingPackageName,
10287             String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk) {
10288         if ((flags & AudioManager.AUDIOFOCUS_FLAG_TEST) != 0) {
10289             throw new IllegalArgumentException("Invalid test flag");
10290         }
10291         final int uid = Binder.getCallingUid();
10292         MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus")
10293                 .setUid(uid)
10294                 //.putInt("durationHint", durationHint)
10295                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName)
10296                 .set(MediaMetrics.Property.CLIENT_NAME, clientId)
10297                 .set(MediaMetrics.Property.EVENT, "requestAudioFocus")
10298                 .set(MediaMetrics.Property.FLAGS, flags);
10299 
10300         // permission checks
10301         if (aa != null && !isValidAudioAttributesUsage(aa)) {
10302             final String reason = "Request using unsupported usage";
10303             Log.w(TAG, reason);
10304             mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
10305                     .record();
10306             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
10307         }
10308         if ((flags & AudioManager.AUDIOFOCUS_FLAG_LOCK) == AudioManager.AUDIOFOCUS_FLAG_LOCK) {
10309             if (AudioSystem.IN_VOICE_COMM_FOCUS_ID.equals(clientId)) {
10310                 if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
10311                             MODIFY_PHONE_STATE)) {
10312                     final String reason = "Invalid permission to (un)lock audio focus";
10313                     Log.e(TAG, reason, new Exception());
10314                     mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
10315                             .record();
10316                     return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
10317                 }
10318             } else {
10319                 // only a registered audio policy can be used to lock focus
10320                 synchronized (mAudioPolicies) {
10321                     if (!mAudioPolicies.containsKey(pcb.asBinder())) {
10322                         final String reason =
10323                                 "Invalid unregistered AudioPolicy to (un)lock audio focus";
10324                         Log.e(TAG, reason);
10325                         mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
10326                                 .record();
10327                         return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
10328                     }
10329                 }
10330             }
10331         }
10332 
10333         if (callingPackageName == null || clientId == null || aa == null) {
10334             final String reason = "Invalid null parameter to request audio focus";
10335             Log.e(TAG, reason);
10336             mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
10337                     .record();
10338             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
10339         }
10340 
10341         // does caller have system privileges to bypass HardeningEnforcer
10342         boolean permissionOverridesCheck = false;
10343         if ((mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
10344                 == PackageManager.PERMISSION_GRANTED)
10345                 || (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING)
10346                 == PackageManager.PERMISSION_GRANTED)) {
10347             permissionOverridesCheck = true;
10348         } else if (uid < UserHandle.AID_APP_START) {
10349             permissionOverridesCheck = true;
10350         }
10351 
10352         final long token = Binder.clearCallingIdentity();
10353         try {
10354             if (!permissionOverridesCheck && mHardeningEnforcer.blockFocusMethod(uid,
10355                     HardeningEnforcer.METHOD_AUDIO_MANAGER_REQUEST_AUDIO_FOCUS,
10356                     clientId, durationHint, callingPackageName, attributionTag, sdk)) {
10357                 final String reason = "Audio focus request blocked by hardening";
10358                 Log.w(TAG, reason);
10359                 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason).record();
10360                 return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
10361             }
10362         } finally {
10363             Binder.restoreCallingIdentity(token);
10364         }
10365 
10366         mmi.record();
10367         return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd,
10368                 clientId, callingPackageName, flags, sdk,
10369                 forceFocusDuckingForAccessibility(aa, durationHint, uid), -1 /*testUid, ignored*/,
10370                 permissionOverridesCheck);
10371     }
10372 
10373     /** 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)10374     public int requestAudioFocusForTest(AudioAttributes aa, int durationHint, IBinder cb,
10375             IAudioFocusDispatcher fd, String clientId, String callingPackageName,
10376             int flags, int fakeUid, int sdk) {
10377         if (!enforceQueryAudioStateForTest("focus request")) {
10378             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
10379         }
10380         if (callingPackageName == null || clientId == null || aa == null) {
10381             final String reason = "Invalid null parameter to request audio focus";
10382             Log.e(TAG, reason);
10383             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
10384         }
10385         return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd,
10386                 clientId, callingPackageName, flags,
10387                 sdk, false /*forceDuck*/, fakeUid, true /*permissionOverridesCheck*/);
10388     }
10389 
abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)10390     public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa,
10391             String callingPackageName) {
10392         MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus")
10393                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName)
10394                 .set(MediaMetrics.Property.CLIENT_NAME, clientId)
10395                 .set(MediaMetrics.Property.EVENT, "abandonAudioFocus");
10396 
10397         if (aa != null && !isValidAudioAttributesUsage(aa)) {
10398             Log.w(TAG, "Request using unsupported usage.");
10399             mmi.set(MediaMetrics.Property.EARLY_RETURN, "unsupported usage").record();
10400 
10401             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
10402         }
10403         mmi.record();
10404         return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName);
10405     }
10406 
10407     /** see {@link AudioManager#abandonAudioFocusForTest(AudioFocusRequest, String)} */
abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)10408     public int abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId,
10409             AudioAttributes aa, String callingPackageName) {
10410         if (!enforceQueryAudioStateForTest("focus abandon")) {
10411             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
10412         }
10413         return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName);
10414     }
10415 
10416     /** see {@link AudioManager#getFocusDuckedUidsForTest()} */
10417     @Override
10418     @EnforcePermission("android.permission.QUERY_AUDIO_STATE")
getFocusDuckedUidsForTest()10419     public @NonNull List<Integer> getFocusDuckedUidsForTest() {
10420         super.getFocusDuckedUidsForTest_enforcePermission();
10421         return mPlaybackMonitor.getFocusDuckedUids();
10422     }
10423 
unregisterAudioFocusClient(String clientId)10424     public void unregisterAudioFocusClient(String clientId) {
10425         new MediaMetrics.Item(mMetricsId + "focus")
10426                 .set(MediaMetrics.Property.CLIENT_NAME, clientId)
10427                 .set(MediaMetrics.Property.EVENT, "unregisterAudioFocusClient")
10428                 .record();
10429         mMediaFocusControl.unregisterAudioFocusClient(clientId);
10430     }
10431 
getCurrentAudioFocus()10432     public int getCurrentAudioFocus() {
10433         return mMediaFocusControl.getCurrentAudioFocus();
10434     }
10435 
getFocusRampTimeMs(int focusGain, AudioAttributes attr)10436     public int getFocusRampTimeMs(int focusGain, AudioAttributes attr) {
10437         return mMediaFocusControl.getFocusRampTimeMs(focusGain, attr);
10438     }
10439 
10440     /**
10441      * Test method to return the duration of the fade out applied on the players of a focus loser
10442      * @see AudioManager#getFocusFadeOutDurationForTest()
10443      * @return the fade out duration, in ms
10444      */
10445     @EnforcePermission("android.permission.QUERY_AUDIO_STATE")
getFocusFadeOutDurationForTest()10446     public long getFocusFadeOutDurationForTest() {
10447         super.getFocusFadeOutDurationForTest_enforcePermission();
10448         return mMediaFocusControl.getFocusFadeOutDurationForTest();
10449     }
10450 
10451     /**
10452      * Test method to return the length of time after a fade out before the focus loser is unmuted
10453      * (and is faded back in).
10454      * @see AudioManager#getFocusUnmuteDelayAfterFadeOutForTest()
10455      * @return the time gap after a fade out completion on focus loss, and fade in start, in ms
10456      */
10457     @Override
10458     @EnforcePermission("android.permission.QUERY_AUDIO_STATE")
getFocusUnmuteDelayAfterFadeOutForTest()10459     public long getFocusUnmuteDelayAfterFadeOutForTest() {
10460         super.getFocusUnmuteDelayAfterFadeOutForTest_enforcePermission();
10461         return mMediaFocusControl.getFocusUnmuteDelayAfterFadeOutForTest();
10462     }
10463 
10464     /**
10465      * Test method to start preventing applications from requesting audio focus during a test,
10466      * which could interfere with the testing of the functionality/behavior under test.
10467      * Calling this method needs to be paired with a call to {@link #exitAudioFocusFreezeForTest}
10468      * when the testing is done. If this is not the case (e.g. in case of a test crash),
10469      * a death observer mechanism will ensure the system is not left in a bad state, but this should
10470      * not be relied on when implementing tests.
10471      * @see AudioManager#enterAudioFocusFreezeForTest(List)
10472      * @param cb IBinder to track the death of the client of this method
10473      * @param exemptedUids a list of UIDs that are exempt from the freeze. This would for instance
10474      *                     be those of the test runner and other players used in the test
10475      * @return true if the focus freeze mode is successfully entered, false if there was an issue,
10476      *     such as another freeze currently used.
10477      */
10478     @Override
10479     @EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
enterAudioFocusFreezeForTest(IBinder cb, int[] exemptedUids)10480     public boolean enterAudioFocusFreezeForTest(IBinder cb, int[] exemptedUids) {
10481         super.enterAudioFocusFreezeForTest_enforcePermission();
10482         Objects.requireNonNull(exemptedUids);
10483         Objects.requireNonNull(cb);
10484         return mMediaFocusControl.enterAudioFocusFreezeForTest(cb, exemptedUids);
10485     }
10486 
10487     /**
10488      * Test method to end preventing applications from requesting audio focus during a test.
10489      * @see AudioManager#exitAudioFocusFreezeForTest()
10490      * @param cb IBinder identifying the client of this method
10491      * @return true if the focus freeze mode is successfully exited, false if there was an issue,
10492      *     such as the freeze already having ended, or not started.
10493      */
10494     @Override
10495     @EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
exitAudioFocusFreezeForTest(IBinder cb)10496     public boolean exitAudioFocusFreezeForTest(IBinder cb) {
10497         super.exitAudioFocusFreezeForTest_enforcePermission();
10498         Objects.requireNonNull(cb);
10499         return mMediaFocusControl.exitAudioFocusFreezeForTest(cb);
10500     }
10501 
10502     /** only public for mocking/spying, do not call outside of AudioService */
10503     @VisibleForTesting
hasAudioFocusUsers()10504     public boolean hasAudioFocusUsers() {
10505         return mMediaFocusControl.hasAudioFocusUsers();
10506     }
10507 
10508     /** see {@link AudioManager#getFadeOutDurationOnFocusLossMillis(AudioAttributes)} */
10509     @Override
getFadeOutDurationOnFocusLossMillis(AudioAttributes aa)10510     public long getFadeOutDurationOnFocusLossMillis(AudioAttributes aa) {
10511         if (!enforceQueryAudioStateForTest("fade out duration")) {
10512             return 0;
10513         }
10514         return mMediaFocusControl.getFadeOutDurationOnFocusLossMillis(aa);
10515     }
10516 
enforceQueryAudioStateForTest(String mssg)10517     private boolean enforceQueryAudioStateForTest(String mssg) {
10518         if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
10519                 Manifest.permission.QUERY_AUDIO_STATE)) {
10520             final String reason = "Doesn't have QUERY_AUDIO_STATE permission for "
10521                     + mssg + " test API";
10522             Log.e(TAG, reason, new Exception());
10523             return false;
10524         }
10525         return true;
10526     }
10527 
10528     //==========================================================================================
10529     private final @NonNull SpatializerHelper mSpatializerHelper;
10530     /**
10531      * Initialized from property ro.audio.spatializer_enabled
10532      * Should only be 1 when the device ships with a Spatializer effect
10533      */
10534     private final boolean mHasSpatializerEffect;
10535     /**
10536      * Default value for the spatial audio feature
10537      */
10538     private static final boolean SPATIAL_AUDIO_ENABLED_DEFAULT = true;
10539 
enforceModifyDefaultAudioEffectsPermission()10540     private void enforceModifyDefaultAudioEffectsPermission() {
10541         if (mContext.checkCallingOrSelfPermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10542                 != PackageManager.PERMISSION_GRANTED) {
10543             throw new SecurityException("Missing MODIFY_DEFAULT_AUDIO_EFFECTS permission");
10544         }
10545     }
10546 
10547     /**
10548      * Returns the immersive audio level that the platform is capable of
10549      * @see Spatializer#getImmersiveAudioLevel()
10550      */
getSpatializerImmersiveAudioLevel()10551     public int getSpatializerImmersiveAudioLevel() {
10552         return mSpatializerHelper.getCapableImmersiveAudioLevel();
10553     }
10554 
10555     /** @see Spatializer#isEnabled() */
isSpatializerEnabled()10556     public boolean isSpatializerEnabled() {
10557         return mSpatializerHelper.isEnabled();
10558     }
10559 
10560     /** @see Spatializer#isAvailable() */
isSpatializerAvailable()10561     public boolean isSpatializerAvailable() {
10562         return mSpatializerHelper.isAvailable();
10563     }
10564 
10565     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10566     /** @see Spatializer#isAvailableForDevice(AudioDeviceAttributes) */
isSpatializerAvailableForDevice(@onNull AudioDeviceAttributes device)10567     public boolean isSpatializerAvailableForDevice(@NonNull AudioDeviceAttributes device)  {
10568         super.isSpatializerAvailableForDevice_enforcePermission();
10569 
10570         return mSpatializerHelper.isAvailableForDevice(Objects.requireNonNull(device));
10571     }
10572 
10573     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10574     /** @see Spatializer#hasHeadTracker(AudioDeviceAttributes) */
hasHeadTracker(@onNull AudioDeviceAttributes device)10575     public boolean hasHeadTracker(@NonNull AudioDeviceAttributes device) {
10576         super.hasHeadTracker_enforcePermission();
10577 
10578         return mSpatializerHelper.hasHeadTracker(Objects.requireNonNull(device));
10579     }
10580 
10581     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10582     /** @see Spatializer#setHeadTrackerEnabled(boolean, AudioDeviceAttributes) */
setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device)10583     public void setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device) {
10584         super.setHeadTrackerEnabled_enforcePermission();
10585 
10586         mSpatializerHelper.setHeadTrackerEnabled(enabled, Objects.requireNonNull(device));
10587     }
10588 
10589     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10590     /** @see Spatializer#isHeadTrackerEnabled(AudioDeviceAttributes) */
isHeadTrackerEnabled(@onNull AudioDeviceAttributes device)10591     public boolean isHeadTrackerEnabled(@NonNull AudioDeviceAttributes device) {
10592         super.isHeadTrackerEnabled_enforcePermission();
10593 
10594         return mSpatializerHelper.isHeadTrackerEnabled(Objects.requireNonNull(device));
10595     }
10596 
10597     /** @see Spatializer#isHeadTrackerAvailable() */
isHeadTrackerAvailable()10598     public boolean isHeadTrackerAvailable() {
10599         return mSpatializerHelper.isHeadTrackerAvailable();
10600     }
10601 
10602     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10603     /** @see Spatializer#setSpatializerEnabled(boolean) */
setSpatializerEnabled(boolean enabled)10604     public void setSpatializerEnabled(boolean enabled) {
10605         super.setSpatializerEnabled_enforcePermission();
10606 
10607         mSpatializerHelper.setFeatureEnabled(enabled);
10608     }
10609 
10610     /** @see Spatializer#canBeSpatialized() */
canBeSpatialized( @onNull AudioAttributes attributes, @NonNull AudioFormat format)10611     public boolean canBeSpatialized(
10612             @NonNull AudioAttributes attributes, @NonNull AudioFormat format) {
10613         Objects.requireNonNull(attributes);
10614         Objects.requireNonNull(format);
10615         return mSpatializerHelper.canBeSpatialized(attributes, format);
10616     }
10617 
10618     /** @see Spatializer.SpatializerInfoDispatcherStub */
registerSpatializerCallback( @onNull ISpatializerCallback cb)10619     public void registerSpatializerCallback(
10620             @NonNull ISpatializerCallback cb) {
10621         Objects.requireNonNull(cb);
10622         mSpatializerHelper.registerStateCallback(cb);
10623     }
10624 
10625     /** @see Spatializer.SpatializerInfoDispatcherStub */
unregisterSpatializerCallback( @onNull ISpatializerCallback cb)10626     public void unregisterSpatializerCallback(
10627             @NonNull ISpatializerCallback cb) {
10628         Objects.requireNonNull(cb);
10629         mSpatializerHelper.unregisterStateCallback(cb);
10630     }
10631 
10632     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10633     /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */
registerSpatializerHeadTrackingCallback( @onNull ISpatializerHeadTrackingModeCallback cb)10634     public void registerSpatializerHeadTrackingCallback(
10635             @NonNull ISpatializerHeadTrackingModeCallback cb) {
10636         super.registerSpatializerHeadTrackingCallback_enforcePermission();
10637 
10638         Objects.requireNonNull(cb);
10639         mSpatializerHelper.registerHeadTrackingModeCallback(cb);
10640     }
10641 
10642     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10643     /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */
unregisterSpatializerHeadTrackingCallback( @onNull ISpatializerHeadTrackingModeCallback cb)10644     public void unregisterSpatializerHeadTrackingCallback(
10645             @NonNull ISpatializerHeadTrackingModeCallback cb) {
10646         super.unregisterSpatializerHeadTrackingCallback_enforcePermission();
10647 
10648         Objects.requireNonNull(cb);
10649         mSpatializerHelper.unregisterHeadTrackingModeCallback(cb);
10650     }
10651 
10652     /** @see Spatializer.SpatializerHeadTrackerAvailableDispatcherStub */
registerSpatializerHeadTrackerAvailableCallback( @onNull ISpatializerHeadTrackerAvailableCallback cb, boolean register)10653     public void registerSpatializerHeadTrackerAvailableCallback(
10654             @NonNull ISpatializerHeadTrackerAvailableCallback cb, boolean register) {
10655         Objects.requireNonNull(cb);
10656         mSpatializerHelper.registerHeadTrackerAvailableCallback(cb, register);
10657     }
10658 
10659     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10660     /** @see Spatializer#setOnHeadToSoundstagePoseUpdatedListener */
registerHeadToSoundstagePoseCallback( @onNull ISpatializerHeadToSoundStagePoseCallback cb)10661     public void registerHeadToSoundstagePoseCallback(
10662             @NonNull ISpatializerHeadToSoundStagePoseCallback cb) {
10663         super.registerHeadToSoundstagePoseCallback_enforcePermission();
10664 
10665         Objects.requireNonNull(cb);
10666         mSpatializerHelper.registerHeadToSoundstagePoseCallback(cb);
10667     }
10668 
10669     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10670     /** @see Spatializer#clearOnHeadToSoundstagePoseUpdatedListener */
unregisterHeadToSoundstagePoseCallback( @onNull ISpatializerHeadToSoundStagePoseCallback cb)10671     public void unregisterHeadToSoundstagePoseCallback(
10672             @NonNull ISpatializerHeadToSoundStagePoseCallback cb) {
10673         super.unregisterHeadToSoundstagePoseCallback_enforcePermission();
10674 
10675         Objects.requireNonNull(cb);
10676         mSpatializerHelper.unregisterHeadToSoundstagePoseCallback(cb);
10677     }
10678 
10679     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10680     /** @see Spatializer#getSpatializerCompatibleAudioDevices() */
getSpatializerCompatibleAudioDevices()10681     public @NonNull List<AudioDeviceAttributes> getSpatializerCompatibleAudioDevices() {
10682         super.getSpatializerCompatibleAudioDevices_enforcePermission();
10683 
10684         return mSpatializerHelper.getCompatibleAudioDevices();
10685     }
10686 
10687     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10688     /** @see Spatializer#addSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */
addSpatializerCompatibleAudioDevice(@onNull AudioDeviceAttributes ada)10689     public void addSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
10690         super.addSpatializerCompatibleAudioDevice_enforcePermission();
10691 
10692         Objects.requireNonNull(ada);
10693         mSpatializerHelper.addCompatibleAudioDevice(ada);
10694     }
10695 
10696     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10697     /** @see Spatializer#removeSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */
removeSpatializerCompatibleAudioDevice(@onNull AudioDeviceAttributes ada)10698     public void removeSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
10699         super.removeSpatializerCompatibleAudioDevice_enforcePermission();
10700 
10701         Objects.requireNonNull(ada);
10702         mSpatializerHelper.removeCompatibleAudioDevice(ada);
10703     }
10704 
10705     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10706     /** @see Spatializer#getSupportedHeadTrackingModes() */
getSupportedHeadTrackingModes()10707     public int[] getSupportedHeadTrackingModes() {
10708         super.getSupportedHeadTrackingModes_enforcePermission();
10709 
10710         return mSpatializerHelper.getSupportedHeadTrackingModes();
10711     }
10712 
10713     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10714     /** @see Spatializer#getHeadTrackingMode() */
getActualHeadTrackingMode()10715     public int getActualHeadTrackingMode() {
10716         super.getActualHeadTrackingMode_enforcePermission();
10717 
10718         return mSpatializerHelper.getActualHeadTrackingMode();
10719     }
10720 
10721     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10722     /** @see Spatializer#getDesiredHeadTrackingMode() */
getDesiredHeadTrackingMode()10723     public int getDesiredHeadTrackingMode() {
10724         super.getDesiredHeadTrackingMode_enforcePermission();
10725 
10726         return mSpatializerHelper.getDesiredHeadTrackingMode();
10727     }
10728 
10729     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10730     /** @see Spatializer#setGlobalTransform */
setSpatializerGlobalTransform(@onNull float[] transform)10731     public void setSpatializerGlobalTransform(@NonNull float[] transform) {
10732         super.setSpatializerGlobalTransform_enforcePermission();
10733 
10734         Objects.requireNonNull(transform);
10735         mSpatializerHelper.setGlobalTransform(transform);
10736     }
10737 
10738     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10739     /** @see Spatializer#recenterHeadTracker() */
recenterHeadTracker()10740     public void recenterHeadTracker() {
10741         super.recenterHeadTracker_enforcePermission();
10742 
10743         mSpatializerHelper.recenterHeadTracker();
10744     }
10745 
10746     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10747     /** @see Spatializer#setDesiredHeadTrackingMode */
setDesiredHeadTrackingMode(@patializer.HeadTrackingModeSet int mode)10748     public void setDesiredHeadTrackingMode(@Spatializer.HeadTrackingModeSet int mode) {
10749         super.setDesiredHeadTrackingMode_enforcePermission();
10750 
10751         switch(mode) {
10752             case Spatializer.HEAD_TRACKING_MODE_DISABLED:
10753             case Spatializer.HEAD_TRACKING_MODE_RELATIVE_WORLD:
10754             case Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE:
10755                 break;
10756             default:
10757                 return;
10758         }
10759         mSpatializerHelper.setDesiredHeadTrackingMode(mode);
10760     }
10761 
10762     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10763     /** @see Spatializer#setEffectParameter */
setSpatializerParameter(int key, @NonNull byte[] value)10764     public void setSpatializerParameter(int key, @NonNull byte[] value) {
10765         super.setSpatializerParameter_enforcePermission();
10766 
10767         Objects.requireNonNull(value);
10768         mSpatializerHelper.setEffectParameter(key, value);
10769     }
10770 
10771     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10772     /** @see Spatializer#getEffectParameter */
getSpatializerParameter(int key, @NonNull byte[] value)10773     public void getSpatializerParameter(int key, @NonNull byte[] value) {
10774         super.getSpatializerParameter_enforcePermission();
10775 
10776         Objects.requireNonNull(value);
10777         mSpatializerHelper.getEffectParameter(key, value);
10778     }
10779 
10780     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10781     /** @see Spatializer#getOutput */
getSpatializerOutput()10782     public int getSpatializerOutput() {
10783         super.getSpatializerOutput_enforcePermission();
10784 
10785         return mSpatializerHelper.getOutput();
10786     }
10787 
10788     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10789     /** @see Spatializer#setOnSpatializerOutputChangedListener */
registerSpatializerOutputCallback(ISpatializerOutputCallback cb)10790     public void registerSpatializerOutputCallback(ISpatializerOutputCallback cb) {
10791         super.registerSpatializerOutputCallback_enforcePermission();
10792 
10793         Objects.requireNonNull(cb);
10794         mSpatializerHelper.registerSpatializerOutputCallback(cb);
10795     }
10796 
10797     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
10798     /** @see Spatializer#clearOnSpatializerOutputChangedListener */
unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb)10799     public void unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb) {
10800         super.unregisterSpatializerOutputCallback_enforcePermission();
10801 
10802         Objects.requireNonNull(cb);
10803         mSpatializerHelper.unregisterSpatializerOutputCallback(cb);
10804     }
10805 
10806     /**
10807      * post a message to schedule init/release of head tracking sensors
10808      * whether to initialize or release sensors is based on the state of spatializer
10809      */
postInitSpatializerHeadTrackingSensors()10810     void postInitSpatializerHeadTrackingSensors() {
10811         sendMsg(mAudioHandler,
10812                 MSG_INIT_HEADTRACKING_SENSORS,
10813                 SENDMSG_REPLACE,
10814                 /*arg1*/ 0, /*arg2*/ 0, TAG, /*delay*/ 0);
10815     }
10816 
10817     /**
10818      * post a message to schedule a reset of the spatializer state
10819      */
postResetSpatializer()10820     void postResetSpatializer() {
10821         sendMsg(mAudioHandler,
10822                 MSG_RESET_SPATIALIZER,
10823                 SENDMSG_REPLACE,
10824                 /*arg1*/ 0, /*arg2*/ 0, TAG, /*delay*/ 0);
10825     }
10826 
onInitAdiDeviceStates()10827     void onInitAdiDeviceStates() {
10828         mDeviceBroker.onReadAudioDeviceSettings();
10829         mSoundDoseHelper.initCachedAudioDeviceCategories(
10830                 mDeviceBroker.getImmutableDeviceInventory());
10831     }
10832 
onInitSpatializer()10833     void onInitSpatializer() {
10834         mSpatializerHelper.init(/*effectExpected*/ mHasSpatializerEffect);
10835         mSpatializerHelper.setFeatureEnabled(mHasSpatializerEffect);
10836     }
10837 
isSADevice(AdiDeviceState deviceState)10838     /*package*/ boolean isSADevice(AdiDeviceState deviceState) {
10839         return mSpatializerHelper.isSADevice(deviceState);
10840     }
10841 
isBluetoothPrividged()10842     private boolean isBluetoothPrividged() {
10843         return PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
10844                 Manifest.permission.BLUETOOTH_CONNECT)
10845                 || Binder.getCallingUid() == Process.SYSTEM_UID;
10846     }
10847 
retrieveBluetoothAddresses(List<AudioDeviceAttributes> devices)10848     List<AudioDeviceAttributes> retrieveBluetoothAddresses(List<AudioDeviceAttributes> devices) {
10849         if (isBluetoothPrividged()) {
10850             return devices;
10851         }
10852 
10853         List<AudioDeviceAttributes> checkedDevices = new ArrayList<AudioDeviceAttributes>();
10854         for (AudioDeviceAttributes ada : devices) {
10855             if (ada == null) {
10856                 continue;
10857             }
10858             checkedDevices.add(retrieveBluetoothAddressUncheked(ada));
10859         }
10860         return checkedDevices;
10861     }
10862 
retrieveBluetoothAddress(@onNull AudioDeviceAttributes ada)10863     AudioDeviceAttributes retrieveBluetoothAddress(@NonNull AudioDeviceAttributes ada) {
10864         if (isBluetoothPrividged()) {
10865             return ada;
10866         }
10867         return retrieveBluetoothAddressUncheked(ada);
10868     }
10869 
retrieveBluetoothAddressUncheked(@onNull AudioDeviceAttributes ada)10870     AudioDeviceAttributes retrieveBluetoothAddressUncheked(@NonNull AudioDeviceAttributes ada) {
10871         Objects.requireNonNull(ada);
10872         if (AudioSystem.isBluetoothDevice(ada.getInternalType())) {
10873             String anonymizedAddress = Utils.anonymizeBluetoothAddress(ada.getAddress());
10874             for (AdiDeviceState ads : mDeviceBroker.getImmutableDeviceInventory()) {
10875                 if (!(AudioSystem.isBluetoothDevice(ads.getInternalDeviceType())
10876                         && (ada.getInternalType() == ads.getInternalDeviceType())
10877                         && anonymizedAddress.equals(Utils.anonymizeBluetoothAddress(
10878                                 ads.getDeviceAddress())))) {
10879                     continue;
10880                 }
10881                 ada.setAddress(ads.getDeviceAddress());
10882                 break;
10883             }
10884         }
10885         return ada;
10886     }
10887 
anonymizeAudioDeviceAttributesList( List<AudioDeviceAttributes> devices)10888     private List<AudioDeviceAttributes> anonymizeAudioDeviceAttributesList(
10889                 List<AudioDeviceAttributes> devices) {
10890         if (isBluetoothPrividged()) {
10891             return devices;
10892         }
10893         return anonymizeAudioDeviceAttributesListUnchecked(devices);
10894     }
10895 
anonymizeAudioDeviceAttributesListUnchecked( List<AudioDeviceAttributes> devices)10896     /* package */ List<AudioDeviceAttributes> anonymizeAudioDeviceAttributesListUnchecked(
10897             List<AudioDeviceAttributes> devices) {
10898         List<AudioDeviceAttributes> anonymizedDevices = new ArrayList<AudioDeviceAttributes>();
10899         for (AudioDeviceAttributes ada : devices) {
10900             anonymizedDevices.add(anonymizeAudioDeviceAttributesUnchecked(ada));
10901         }
10902         return anonymizedDevices;
10903     }
10904 
anonymizeAudioDeviceAttributesUnchecked( AudioDeviceAttributes ada)10905     private AudioDeviceAttributes anonymizeAudioDeviceAttributesUnchecked(
10906             AudioDeviceAttributes ada) {
10907         if (!AudioSystem.isBluetoothDevice(ada.getInternalType())) {
10908             return ada;
10909         }
10910         AudioDeviceAttributes res = new AudioDeviceAttributes(ada);
10911         res.setAddress(Utils.anonymizeBluetoothAddress(ada.getAddress()));
10912         return res;
10913     }
10914 
anonymizeAudioDeviceAttributes(AudioDeviceAttributes ada)10915     private AudioDeviceAttributes anonymizeAudioDeviceAttributes(AudioDeviceAttributes ada) {
10916         if (isBluetoothPrividged()) {
10917             return ada;
10918         }
10919 
10920         return anonymizeAudioDeviceAttributesUnchecked(ada);
10921     }
10922 
10923     // ========================================================================================
10924     // LoudnessCodecConfigurator
10925 
10926     @Override
registerLoudnessCodecUpdatesDispatcher(ILoudnessCodecUpdatesDispatcher dispatcher)10927     public void registerLoudnessCodecUpdatesDispatcher(ILoudnessCodecUpdatesDispatcher dispatcher) {
10928         mLoudnessCodecHelper.registerLoudnessCodecUpdatesDispatcher(dispatcher);
10929     }
10930 
10931     @Override
unregisterLoudnessCodecUpdatesDispatcher( ILoudnessCodecUpdatesDispatcher dispatcher)10932     public void unregisterLoudnessCodecUpdatesDispatcher(
10933             ILoudnessCodecUpdatesDispatcher dispatcher) {
10934         mLoudnessCodecHelper.unregisterLoudnessCodecUpdatesDispatcher(dispatcher);
10935     }
10936 
10937     /** @see LoudnessCodecController#create(int) */
10938     @Override
startLoudnessCodecUpdates(int sessionId)10939     public void startLoudnessCodecUpdates(int sessionId) {
10940         mLoudnessCodecHelper.startLoudnessCodecUpdates(sessionId);
10941     }
10942 
10943     /** @see LoudnessCodecController#release() */
10944     @Override
stopLoudnessCodecUpdates(int sessionId)10945     public void stopLoudnessCodecUpdates(int sessionId) {
10946         mLoudnessCodecHelper.stopLoudnessCodecUpdates(sessionId);
10947     }
10948 
10949     /** @see LoudnessCodecController#addMediaCodec(MediaCodec) */
10950     @Override
addLoudnessCodecInfo(int sessionId, int mediaCodecHash, LoudnessCodecInfo codecInfo)10951     public void addLoudnessCodecInfo(int sessionId, int mediaCodecHash,
10952             LoudnessCodecInfo codecInfo) {
10953         mLoudnessCodecHelper.addLoudnessCodecInfo(sessionId, mediaCodecHash, codecInfo);
10954     }
10955 
10956     /** @see LoudnessCodecController#removeMediaCodec(MediaCodec) */
10957     @Override
removeLoudnessCodecInfo(int sessionId, LoudnessCodecInfo codecInfo)10958     public void removeLoudnessCodecInfo(int sessionId, LoudnessCodecInfo codecInfo) {
10959         mLoudnessCodecHelper.removeLoudnessCodecInfo(sessionId, codecInfo);
10960     }
10961 
10962     /** @see LoudnessCodecController#getLoudnessCodecParams(MediaCodec) */
10963     @Override
getLoudnessParams(LoudnessCodecInfo codecInfo)10964     public PersistableBundle getLoudnessParams(LoudnessCodecInfo codecInfo) {
10965         return mLoudnessCodecHelper.getLoudnessParams(codecInfo);
10966     }
10967 
10968     //==========================================================================================
10969 
10970     // camera sound is forced if any of the resources corresponding to one active SIM
10971     // demands it.
readCameraSoundForced()10972     private boolean readCameraSoundForced() {
10973         if (SystemProperties.getBoolean("audio.camerasound.force", false)
10974                 || mContext.getResources().getBoolean(
10975                         com.android.internal.R.bool.config_camera_sound_forced)) {
10976             return true;
10977         }
10978 
10979         SubscriptionManager subscriptionManager = mContext.getSystemService(
10980                 SubscriptionManager.class);
10981         if (subscriptionManager == null) {
10982             Log.e(TAG, "readCameraSoundForced cannot create SubscriptionManager!");
10983             return false;
10984         }
10985         int[] subscriptionIds = subscriptionManager.getActiveSubscriptionIdList(false);
10986         for (int subId : subscriptionIds) {
10987             if (SubscriptionManager.getResourcesForSubId(mContext, subId).getBoolean(
10988                     com.android.internal.R.bool.config_camera_sound_forced)) {
10989                 return true;
10990             }
10991         }
10992         return false;
10993     }
10994 
10995     //==========================================================================================
10996     private final Object mMuteAwaitConnectionLock = new Object();
10997 
10998     /**
10999      * The device that is expected to be connected soon, and causes players to be muted until
11000      * its connection, or it times out.
11001      * Null when no active muting command, or it has timed out.
11002      */
11003     @GuardedBy("mMuteAwaitConnectionLock")
11004     private AudioDeviceAttributes mMutingExpectedDevice;
11005     @GuardedBy("mMuteAwaitConnectionLock")
11006     private @Nullable int[] mMutedUsagesAwaitingConnection;
11007 
11008     /** @see AudioManager#muteAwaitConnection */
11009     @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection
muteAwaitConnection(@onNull int[] usages, @NonNull AudioDeviceAttributes device, long timeOutMs)11010     public void muteAwaitConnection(@NonNull int[] usages,
11011             @NonNull AudioDeviceAttributes device, long timeOutMs) {
11012         Objects.requireNonNull(usages);
11013         Objects.requireNonNull(device);
11014         enforceModifyAudioRoutingPermission();
11015 
11016         final AudioDeviceAttributes ada = retrieveBluetoothAddress(device);
11017 
11018         if (timeOutMs <= 0 || usages.length == 0) {
11019             throw new IllegalArgumentException("Invalid timeOutMs/usagesToMute");
11020         }
11021         Log.i(TAG, "muteAwaitConnection dev:" + device + " timeOutMs:" + timeOutMs
11022                 + " usages:" + Arrays.toString(usages));
11023 
11024         if (mDeviceBroker.isDeviceConnected(ada)) {
11025             // not throwing an exception as there could be a race between a connection (server-side,
11026             // notification of connection in flight) and a mute operation (client-side)
11027             Log.i(TAG, "muteAwaitConnection ignored, device (" + device + ") already connected");
11028             return;
11029         }
11030         synchronized (mMuteAwaitConnectionLock) {
11031             if (mMutingExpectedDevice != null) {
11032                 Log.e(TAG, "muteAwaitConnection ignored, another in progress for device:"
11033                         + mMutingExpectedDevice);
11034                 throw new IllegalStateException("muteAwaitConnection already in progress");
11035             }
11036             mMutingExpectedDevice = ada;
11037             mMutedUsagesAwaitingConnection = usages;
11038             mPlaybackMonitor.muteAwaitConnection(usages, ada, timeOutMs);
11039         }
11040         dispatchMuteAwaitConnection((cb, isPrivileged) -> {
11041             try {
11042                 AudioDeviceAttributes dev = ada;
11043                 if (!isPrivileged) {
11044                     dev = anonymizeAudioDeviceAttributesUnchecked(ada);
11045                 }
11046                 cb.dispatchOnMutedUntilConnection(dev, usages);
11047             } catch (RemoteException e) { }
11048         });
11049     }
11050 
11051     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
11052     /** @see AudioManager#getMutingExpectedDevice */
getMutingExpectedDevice()11053     public @Nullable AudioDeviceAttributes getMutingExpectedDevice() {
11054         super.getMutingExpectedDevice_enforcePermission();
11055 
11056         synchronized (mMuteAwaitConnectionLock) {
11057             return anonymizeAudioDeviceAttributes(mMutingExpectedDevice);
11058         }
11059     }
11060 
11061     /** @see AudioManager#cancelMuteAwaitConnection */
11062     @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection
cancelMuteAwaitConnection(@onNull AudioDeviceAttributes device)11063     public void cancelMuteAwaitConnection(@NonNull AudioDeviceAttributes device) {
11064         Objects.requireNonNull(device);
11065         enforceModifyAudioRoutingPermission();
11066 
11067         final AudioDeviceAttributes ada = retrieveBluetoothAddress(device);
11068 
11069         Log.i(TAG, "cancelMuteAwaitConnection for device:" + device);
11070         final int[] mutedUsages;
11071         synchronized (mMuteAwaitConnectionLock) {
11072             if (mMutingExpectedDevice == null) {
11073                 // not throwing an exception as there could be a race between a timeout
11074                 // (server-side) and a cancel operation (client-side)
11075                 Log.i(TAG, "cancelMuteAwaitConnection ignored, no expected device");
11076                 return;
11077             }
11078             if (!ada.equalTypeAddress(mMutingExpectedDevice)) {
11079                 Log.e(TAG, "cancelMuteAwaitConnection ignored, got " + device
11080                         + "] but expected device is" + mMutingExpectedDevice);
11081                 throw new IllegalStateException("cancelMuteAwaitConnection for wrong device");
11082             }
11083             mutedUsages = mMutedUsagesAwaitingConnection;
11084             mMutingExpectedDevice = null;
11085             mMutedUsagesAwaitingConnection = null;
11086             mPlaybackMonitor.cancelMuteAwaitConnection("cancelMuteAwaitConnection dev:" + device);
11087         }
11088         dispatchMuteAwaitConnection((cb, isPrivileged) -> {
11089             try {
11090                 AudioDeviceAttributes dev = ada;
11091                 if (!isPrivileged) {
11092                     dev = anonymizeAudioDeviceAttributesUnchecked(ada);
11093                 }
11094                 cb.dispatchOnUnmutedEvent(
11095                         AudioManager.MuteAwaitConnectionCallback.EVENT_CANCEL, dev, mutedUsages);
11096             } catch (RemoteException e) { } });
11097     }
11098 
11099     final RemoteCallbackList<IMuteAwaitConnectionCallback> mMuteAwaitConnectionDispatchers =
11100             new RemoteCallbackList<IMuteAwaitConnectionCallback>();
11101 
11102     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
11103     /** @see AudioManager#registerMuteAwaitConnectionCallback */
registerMuteAwaitConnectionDispatcher(@onNull IMuteAwaitConnectionCallback cb, boolean register)11104     public void registerMuteAwaitConnectionDispatcher(@NonNull IMuteAwaitConnectionCallback cb,
11105             boolean register) {
11106         super.registerMuteAwaitConnectionDispatcher_enforcePermission();
11107 
11108         if (register) {
11109             mMuteAwaitConnectionDispatchers.register(cb, isBluetoothPrividged());
11110         } else {
11111             mMuteAwaitConnectionDispatchers.unregister(cb);
11112         }
11113     }
11114 
11115     @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection
checkMuteAwaitConnection()11116     void checkMuteAwaitConnection() {
11117         final AudioDeviceAttributes device;
11118         final int[] mutedUsages;
11119         synchronized (mMuteAwaitConnectionLock) {
11120             if (mMutingExpectedDevice == null) {
11121                 return;
11122             }
11123             device = mMutingExpectedDevice;
11124             mutedUsages = mMutedUsagesAwaitingConnection;
11125             if (!mDeviceBroker.isDeviceConnected(device)) {
11126                 return;
11127             }
11128             mMutingExpectedDevice = null;
11129             mMutedUsagesAwaitingConnection = null;
11130             mPlaybackMonitor.cancelMuteAwaitConnection(
11131                     "checkMuteAwaitConnection device " + device + " connected, unmuting");
11132         }
11133         dispatchMuteAwaitConnection((cb, isPrivileged) -> {
11134             try {
11135                 AudioDeviceAttributes ada = device;
11136                 if (!isPrivileged) {
11137                     ada = anonymizeAudioDeviceAttributesUnchecked(device);
11138                 }
11139                 cb.dispatchOnUnmutedEvent(AudioManager.MuteAwaitConnectionCallback.EVENT_CONNECTION,
11140                         ada, mutedUsages);
11141             } catch (RemoteException e) { } });
11142     }
11143 
11144     /**
11145      * Called by PlaybackActivityMonitor when the timeout hit for the mute on device connection
11146      */
11147     @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection
onMuteAwaitConnectionTimeout(@onNull AudioDeviceAttributes timedOutDevice)11148     void onMuteAwaitConnectionTimeout(@NonNull AudioDeviceAttributes timedOutDevice) {
11149         final int[] mutedUsages;
11150         synchronized (mMuteAwaitConnectionLock) {
11151             if (!timedOutDevice.equals(mMutingExpectedDevice)) {
11152                 return;
11153             }
11154             Log.i(TAG, "muteAwaitConnection timeout, clearing expected device "
11155                     + mMutingExpectedDevice);
11156             mutedUsages = mMutedUsagesAwaitingConnection;
11157             mMutingExpectedDevice = null;
11158             mMutedUsagesAwaitingConnection = null;
11159         }
11160         dispatchMuteAwaitConnection((cb, isPrivileged) -> {
11161             try {
11162                 cb.dispatchOnUnmutedEvent(
11163                         AudioManager.MuteAwaitConnectionCallback.EVENT_TIMEOUT,
11164                         timedOutDevice, mutedUsages);
11165             } catch (RemoteException e) { } });
11166     }
11167 
dispatchMuteAwaitConnection( java.util.function.BiConsumer<IMuteAwaitConnectionCallback, Boolean> callback)11168     private void dispatchMuteAwaitConnection(
11169             java.util.function.BiConsumer<IMuteAwaitConnectionCallback, Boolean> callback) {
11170         final int nbDispatchers = mMuteAwaitConnectionDispatchers.beginBroadcast();
11171         // lazy initialization as errors unlikely
11172         ArrayList<IMuteAwaitConnectionCallback> errorList = null;
11173         for (int i = 0; i < nbDispatchers; i++) {
11174             try {
11175                 callback.accept(mMuteAwaitConnectionDispatchers.getBroadcastItem(i),
11176                         (Boolean) mMuteAwaitConnectionDispatchers.getBroadcastCookie(i));
11177             } catch (Exception e) {
11178                 if (errorList == null) {
11179                     errorList = new ArrayList<>(1);
11180                 }
11181                 errorList.add(mMuteAwaitConnectionDispatchers.getBroadcastItem(i));
11182             }
11183         }
11184         if (errorList != null) {
11185             for (IMuteAwaitConnectionCallback errorItem : errorList) {
11186                 mMuteAwaitConnectionDispatchers.unregister(errorItem);
11187             }
11188         }
11189         mMuteAwaitConnectionDispatchers.finishBroadcast();
11190     }
11191 
11192     final RemoteCallbackList<IDeviceVolumeBehaviorDispatcher> mDeviceVolumeBehaviorDispatchers =
11193             new RemoteCallbackList<IDeviceVolumeBehaviorDispatcher>();
11194 
11195     /**
11196      *  @see AudioDeviceVolumeManager#addOnDeviceVolumeBehaviorChangedListener and
11197      *  AudioDeviceVolumeManager#removeOnDeviceVolumeBehaviorChangedListener
11198      */
registerDeviceVolumeBehaviorDispatcher(boolean register, @NonNull IDeviceVolumeBehaviorDispatcher dispatcher)11199     public void registerDeviceVolumeBehaviorDispatcher(boolean register,
11200             @NonNull IDeviceVolumeBehaviorDispatcher dispatcher) {
11201         enforceQueryStateOrModifyRoutingPermission();
11202         Objects.requireNonNull(dispatcher);
11203         if (register) {
11204             mDeviceVolumeBehaviorDispatchers.register(dispatcher);
11205         } else {
11206             mDeviceVolumeBehaviorDispatchers.unregister(dispatcher);
11207         }
11208     }
11209 
dispatchDeviceVolumeBehavior(AudioDeviceAttributes device, int volumeBehavior)11210     private void dispatchDeviceVolumeBehavior(AudioDeviceAttributes device, int volumeBehavior) {
11211         final int dispatchers = mDeviceVolumeBehaviorDispatchers.beginBroadcast();
11212         for (int i = 0; i < dispatchers; i++) {
11213             try {
11214                 mDeviceVolumeBehaviorDispatchers.getBroadcastItem(i)
11215                         .dispatchDeviceVolumeBehaviorChanged(device, volumeBehavior);
11216             } catch (RemoteException e) {
11217             }
11218         }
11219         mDeviceVolumeBehaviorDispatchers.finishBroadcast();
11220     }
11221 
11222     //==========================================================================================
11223     // Device orientation
11224     //==========================================================================================
11225     /**
11226      * Handles device configuration changes that may map to a change in rotation.
11227      * Monitoring rotation is optional, and is defined by the definition and value
11228      * of the "ro.audio.monitorRotation" system property.
11229      */
onConfigurationChanged()11230     private void onConfigurationChanged() {
11231         try {
11232             // reading new configuration "safely" (i.e. under try catch) in case anything
11233             // goes wrong.
11234             Configuration config = mContext.getResources().getConfiguration();
11235             mSoundDoseHelper.configureSafeMedia(/*forced*/false, TAG);
11236 
11237             boolean cameraSoundForced = readCameraSoundForced();
11238             synchronized (mSettingsLock) {
11239                 final boolean cameraSoundForcedChanged = (cameraSoundForced != mCameraSoundForced);
11240                 mCameraSoundForced = cameraSoundForced;
11241                 if (cameraSoundForcedChanged) {
11242                     if (!mIsSingleVolume) {
11243                         synchronized (VolumeStreamState.class) {
11244                             VolumeStreamState s = mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED];
11245                             if (cameraSoundForced) {
11246                                 s.setAllIndexesToMax();
11247                                 mRingerModeAffectedStreams &=
11248                                         ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
11249                             } else {
11250                                 s.setAllIndexes(mStreamStates[AudioSystem.STREAM_SYSTEM], TAG);
11251                                 mRingerModeAffectedStreams |=
11252                                         (1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
11253                             }
11254                         }
11255                         // take new state into account for streams muted by ringer mode
11256                         setRingerModeInt(getRingerModeInternal(), false);
11257                     }
11258                     mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM,
11259                             cameraSoundForced ?
11260                                     AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE,
11261                             "onConfigurationChanged");
11262                     sendMsg(mAudioHandler,
11263                             MSG_SET_ALL_VOLUMES,
11264                             SENDMSG_QUEUE,
11265                             0,
11266                             0,
11267                             mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED], 0);
11268 
11269                 }
11270             }
11271             mVolumeController.setLayoutDirection(config.getLayoutDirection());
11272         } catch (Exception e) {
11273             Log.e(TAG, "Error handling configuration change: ", e);
11274         }
11275     }
11276 
11277     @android.annotation.EnforcePermission(Manifest.permission.REMOTE_AUDIO_PLAYBACK)
11278     @Override
setRingtonePlayer(IRingtonePlayer player)11279     public void setRingtonePlayer(IRingtonePlayer player) {
11280         setRingtonePlayer_enforcePermission();
11281         mRingtonePlayer = player;
11282     }
11283 
11284     @Override
getRingtonePlayer()11285     public IRingtonePlayer getRingtonePlayer() {
11286         return mRingtonePlayer;
11287     }
11288 
11289     @Override
startWatchingRoutes(IAudioRoutesObserver observer)11290     public AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) {
11291         return mDeviceBroker.startWatchingRoutes(observer);
11292     }
11293 
11294     @Override
disableSafeMediaVolume(String callingPackage)11295     public void disableSafeMediaVolume(String callingPackage) {
11296         enforceVolumeController("disable the safe media volume");
11297         mSoundDoseHelper.disableSafeMediaVolume(callingPackage);
11298     }
11299 
11300     @Override
lowerVolumeToRs1(String callingPackage)11301     public void lowerVolumeToRs1(String callingPackage) {
11302         enforceVolumeController("lowerVolumeToRs1");
11303         postLowerVolumeToRs1();
11304     }
11305 
postLowerVolumeToRs1()11306     /*package*/ void postLowerVolumeToRs1() {
11307         sendMsg(mAudioHandler, SoundDoseHelper.MSG_LOWER_VOLUME_TO_RS1, SENDMSG_QUEUE,
11308                 // no params, no delay
11309                 0, 0, null, 0);
11310     }
11311 
11312     @Override
11313     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
getOutputRs2UpperBound()11314     public float getOutputRs2UpperBound() {
11315         super.getOutputRs2UpperBound_enforcePermission();
11316         return mSoundDoseHelper.getOutputRs2UpperBound();
11317     }
11318 
11319     @Override
11320     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setOutputRs2UpperBound(float rs2Value)11321     public void setOutputRs2UpperBound(float rs2Value) {
11322         super.setOutputRs2UpperBound_enforcePermission();
11323         mSoundDoseHelper.setOutputRs2UpperBound(rs2Value);
11324     }
11325 
11326     @Override
11327     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
getCsd()11328     public float getCsd() {
11329         super.getCsd_enforcePermission();
11330         return mSoundDoseHelper.getCsd();
11331     }
11332 
11333     @Override
11334     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setCsd(float csd)11335     public void setCsd(float csd) {
11336         super.setCsd_enforcePermission();
11337         if (csd < 0.0f) {
11338             mSoundDoseHelper.resetCsdTimeouts();
11339         } else {
11340             mSoundDoseHelper.setCsd(csd);
11341         }
11342     }
11343 
11344     @Override
11345     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
forceUseFrameworkMel(boolean useFrameworkMel)11346     public void forceUseFrameworkMel(boolean useFrameworkMel) {
11347         super.forceUseFrameworkMel_enforcePermission();
11348         mSoundDoseHelper.forceUseFrameworkMel(useFrameworkMel);
11349     }
11350 
11351     @Override
11352     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
forceComputeCsdOnAllDevices(boolean computeCsdOnAllDevices)11353     public void forceComputeCsdOnAllDevices(boolean computeCsdOnAllDevices) {
11354         super.forceComputeCsdOnAllDevices_enforcePermission();
11355         mSoundDoseHelper.forceComputeCsdOnAllDevices(computeCsdOnAllDevices);
11356     }
11357 
11358     @Override
11359     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
isCsdEnabled()11360     public boolean isCsdEnabled() {
11361         super.isCsdEnabled_enforcePermission();
11362         return mSoundDoseHelper.isCsdEnabled();
11363     }
11364 
11365     @Override
11366     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
isCsdAsAFeatureAvailable()11367     public boolean isCsdAsAFeatureAvailable() {
11368         super.isCsdAsAFeatureAvailable_enforcePermission();
11369         return mSoundDoseHelper.isCsdAsAFeatureAvailable();
11370     }
11371 
11372     @Override
11373     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
isCsdAsAFeatureEnabled()11374     public boolean isCsdAsAFeatureEnabled() {
11375         super.isCsdAsAFeatureEnabled_enforcePermission();
11376         return mSoundDoseHelper.isCsdAsAFeatureEnabled();
11377     }
11378 
11379     @Override
11380     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setCsdAsAFeatureEnabled(boolean csdToggleValue)11381     public void setCsdAsAFeatureEnabled(boolean csdToggleValue) {
11382         super.setCsdAsAFeatureEnabled_enforcePermission();
11383         mSoundDoseHelper.setCsdAsAFeatureEnabled(csdToggleValue);
11384     }
11385 
11386     @Override
11387     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setBluetoothAudioDeviceCategory_legacy(@onNull String address, boolean isBle, @AudioDeviceCategory int btAudioDeviceCategory)11388     public void setBluetoothAudioDeviceCategory_legacy(@NonNull String address, boolean isBle,
11389             @AudioDeviceCategory int btAudioDeviceCategory) {
11390         super.setBluetoothAudioDeviceCategory_legacy_enforcePermission();
11391         if (automaticBtDeviceType()) {
11392             // do nothing
11393             return;
11394         }
11395 
11396         final String addr = Objects.requireNonNull(address);
11397 
11398         AdiDeviceState deviceState = mDeviceBroker.findBtDeviceStateForAddress(addr,
11399                 (isBle ? AudioSystem.DEVICE_OUT_BLE_HEADSET
11400                         : AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP));
11401 
11402         int internalType = !isBle ? DEVICE_OUT_BLUETOOTH_A2DP
11403                 : ((btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES)
11404                         ? DEVICE_OUT_BLE_HEADSET : DEVICE_OUT_BLE_SPEAKER);
11405         int deviceType = !isBle ? TYPE_BLUETOOTH_A2DP
11406                 : ((btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES) ? TYPE_BLE_HEADSET
11407                         : TYPE_BLE_SPEAKER);
11408 
11409         if (deviceState == null) {
11410             deviceState = new AdiDeviceState(deviceType, internalType, addr);
11411         }
11412 
11413         deviceState.setAudioDeviceCategory(btAudioDeviceCategory);
11414 
11415         mDeviceBroker.addOrUpdateBtAudioDeviceCategoryInInventory(
11416                 deviceState, true /*syncInventory*/);
11417         mDeviceBroker.postPersistAudioDeviceSettings();
11418 
11419         mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes(),
11420                 false /* initState */);
11421         mSoundDoseHelper.setAudioDeviceCategory(addr, internalType,
11422                 btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES);
11423     }
11424 
11425     @Override
11426     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
11427     @AudioDeviceCategory
getBluetoothAudioDeviceCategory_legacy(@onNull String address, boolean isBle)11428     public int getBluetoothAudioDeviceCategory_legacy(@NonNull String address, boolean isBle) {
11429         super.getBluetoothAudioDeviceCategory_legacy_enforcePermission();
11430         if (automaticBtDeviceType()) {
11431             return AUDIO_DEVICE_CATEGORY_UNKNOWN;
11432         }
11433 
11434         final AdiDeviceState deviceState = mDeviceBroker.findBtDeviceStateForAddress(
11435                 Objects.requireNonNull(address), (isBle ? AudioSystem.DEVICE_OUT_BLE_HEADSET
11436                         : AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP));
11437         if (deviceState == null) {
11438             return AUDIO_DEVICE_CATEGORY_UNKNOWN;
11439         }
11440 
11441         return deviceState.getAudioDeviceCategory();
11442     }
11443 
11444     @Override
11445     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setBluetoothAudioDeviceCategory(@onNull String address, @AudioDeviceCategory int btAudioDeviceCategory)11446     public boolean setBluetoothAudioDeviceCategory(@NonNull String address,
11447             @AudioDeviceCategory int btAudioDeviceCategory) {
11448         super.setBluetoothAudioDeviceCategory_enforcePermission();
11449         if (!automaticBtDeviceType()) {
11450             return false;
11451         }
11452 
11453         final String addr = Objects.requireNonNull(address);
11454         if (isBluetoothAudioDeviceCategoryFixed(addr)) {
11455             Log.w(TAG, "Cannot set fixed audio device type for address "
11456                     + Utils.anonymizeBluetoothAddress(address));
11457             return false;
11458         }
11459 
11460         mDeviceBroker.addAudioDeviceWithCategoryInInventoryIfNeeded(address, btAudioDeviceCategory);
11461 
11462         return true;
11463     }
11464 
11465     @Override
11466     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
11467     @AudioDeviceCategory
getBluetoothAudioDeviceCategory(@onNull String address)11468     public int getBluetoothAudioDeviceCategory(@NonNull String address) {
11469         super.getBluetoothAudioDeviceCategory_enforcePermission();
11470         if (!automaticBtDeviceType()) {
11471             return AUDIO_DEVICE_CATEGORY_UNKNOWN;
11472         }
11473 
11474         return mDeviceBroker.getAndUpdateBtAdiDeviceStateCategoryForAddress(address);
11475     }
11476 
11477     @Override
11478     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
isBluetoothAudioDeviceCategoryFixed(@onNull String address)11479     public boolean isBluetoothAudioDeviceCategoryFixed(@NonNull String address) {
11480         super.isBluetoothAudioDeviceCategoryFixed_enforcePermission();
11481         if (!automaticBtDeviceType()) {
11482             return false;
11483         }
11484 
11485         return mDeviceBroker.isBluetoothAudioDeviceCategoryFixed(address);
11486     }
11487 
11488     /** Update the sound dose and spatializer state based on the new AdiDeviceState. */
11489     @VisibleForTesting(visibility = PACKAGE)
onUpdatedAdiDeviceState(AdiDeviceState deviceState, boolean initSA)11490     public void onUpdatedAdiDeviceState(AdiDeviceState deviceState, boolean initSA) {
11491         if (deviceState == null) {
11492             return;
11493         }
11494         mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes(), initSA);
11495         mSoundDoseHelper.setAudioDeviceCategory(deviceState.getDeviceAddress(),
11496                 deviceState.getInternalDeviceType(),
11497                 deviceState.getAudioDeviceCategory() == AUDIO_DEVICE_CATEGORY_HEADPHONES);
11498     }
11499 
11500     //==========================================================================================
11501     // Hdmi CEC:
11502     // - System audio mode:
11503     //     If Hdmi Cec's system audio mode is on, audio service should send the volume change
11504     //     to HdmiControlService so that the audio receiver can handle it.
11505     // - CEC sink:
11506     //     OUT_HDMI becomes a "full volume device", i.e. output is always at maximum level
11507     //     and volume changes won't be taken into account on this device. Volume adjustments
11508     //     are transformed into key events for the HDMI playback client.
11509     //==========================================================================================
11510 
11511     @GuardedBy("mHdmiClientLock")
updateHdmiCecSinkLocked(boolean hdmiCecSink)11512     private void updateHdmiCecSinkLocked(boolean hdmiCecSink) {
11513         if (!hasDeviceVolumeBehavior(AudioSystem.DEVICE_OUT_HDMI)) {
11514             if (hdmiCecSink) {
11515                 if (DEBUG_VOL) {
11516                     Log.d(TAG, "CEC sink: setting HDMI as full vol device");
11517                 }
11518                 setDeviceVolumeBehaviorInternal(
11519                         new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""),
11520                         AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL,
11521                         "AudioService.updateHdmiCecSinkLocked()");
11522             } else {
11523                 if (DEBUG_VOL) {
11524                     Log.d(TAG, "TV, no CEC: setting HDMI as regular vol device");
11525                 }
11526                 // Android TV devices without CEC service apply software volume on
11527                 // HDMI output
11528                 setDeviceVolumeBehaviorInternal(
11529                         new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""),
11530                         AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE,
11531                         "AudioService.updateHdmiCecSinkLocked()");
11532             }
11533             postUpdateVolumeStatesForAudioDevice(AudioSystem.DEVICE_OUT_HDMI,
11534                     "HdmiPlaybackClient.DisplayStatusCallback");
11535         }
11536     }
11537 
11538     private class MyHdmiControlStatusChangeListenerCallback
11539             implements HdmiControlManager.HdmiControlStatusChangeListener {
onStatusChange(@dmiControlManager.HdmiCecControl int isCecEnabled, boolean isCecAvailable)11540         public void onStatusChange(@HdmiControlManager.HdmiCecControl int isCecEnabled,
11541                 boolean isCecAvailable) {
11542             synchronized (mHdmiClientLock) {
11543                 if (mHdmiManager == null) return;
11544                 boolean cecEnabled = isCecEnabled == HdmiControlManager.HDMI_CEC_CONTROL_ENABLED;
11545                 updateHdmiCecSinkLocked(cecEnabled ? isCecAvailable : false);
11546             }
11547         }
11548     };
11549 
11550     private class MyHdmiCecVolumeControlFeatureListener
11551             implements HdmiControlManager.HdmiCecVolumeControlFeatureListener {
onHdmiCecVolumeControlFeature( @dmiControlManager.VolumeControl int hdmiCecVolumeControl)11552         public void onHdmiCecVolumeControlFeature(
11553                 @HdmiControlManager.VolumeControl int hdmiCecVolumeControl) {
11554             synchronized (mHdmiClientLock) {
11555                 if (mHdmiManager == null) return;
11556                 mHdmiCecVolumeControlEnabled =
11557                         hdmiCecVolumeControl == HdmiControlManager.VOLUME_CONTROL_ENABLED;
11558             }
11559         }
11560     };
11561 
11562     private final Object mHdmiClientLock = new Object();
11563 
11564     // If HDMI-CEC system audio is supported
11565     // Note that for CEC volume commands mHdmiCecVolumeControlEnabled will play a role on volume
11566     // commands
11567     private boolean mHdmiSystemAudioSupported = false;
11568     // Set only when device is tv.
11569     @GuardedBy("mHdmiClientLock")
11570     private HdmiTvClient mHdmiTvClient;
11571     // true if the device has system feature PackageManager.FEATURE_LEANBACK.
11572     // cached HdmiControlManager interface
11573     @GuardedBy("mHdmiClientLock")
11574     private HdmiControlManager mHdmiManager;
11575     // Set only when device is a set-top box.
11576     @GuardedBy("mHdmiClientLock")
11577     private HdmiPlaybackClient mHdmiPlaybackClient;
11578     // Set only when device is an audio system.
11579     @GuardedBy("mHdmiClientLock")
11580     private HdmiAudioSystemClient mHdmiAudioSystemClient;
11581     // True when volume control over HDMI CEC is used when CEC is enabled (meaningless otherwise)
11582     @GuardedBy("mHdmiClientLock")
11583     private boolean mHdmiCecVolumeControlEnabled;
11584 
11585     private MyHdmiControlStatusChangeListenerCallback mHdmiControlStatusChangeListenerCallback =
11586             new MyHdmiControlStatusChangeListenerCallback();
11587 
11588     private MyHdmiCecVolumeControlFeatureListener mMyHdmiCecVolumeControlFeatureListener =
11589             new MyHdmiCecVolumeControlFeatureListener();
11590 
11591     @Override
setHdmiSystemAudioSupported(boolean on)11592     public int setHdmiSystemAudioSupported(boolean on) {
11593         int device = AudioSystem.DEVICE_NONE;
11594         synchronized (mHdmiClientLock) {
11595             if (mHdmiManager != null) {
11596                 if (mHdmiTvClient == null && mHdmiAudioSystemClient == null) {
11597                     Log.w(TAG, "Only Hdmi-Cec enabled TV or audio system device supports"
11598                             + "system audio mode.");
11599                     return device;
11600                 }
11601                 if (mHdmiSystemAudioSupported != on) {
11602                     mHdmiSystemAudioSupported = on;
11603                     final int config = on ? AudioSystem.FORCE_HDMI_SYSTEM_AUDIO_ENFORCED :
11604                         AudioSystem.FORCE_NONE;
11605                     mDeviceBroker.setForceUse_Async(AudioSystem.FOR_HDMI_SYSTEM_AUDIO, config,
11606                             "setHdmiSystemAudioSupported");
11607                 }
11608                 // TODO(b/185386781): Update AudioManager API to use device list.
11609                 // So far, this value appears to be advisory for debug log.
11610                 device = getDeviceMaskForStream(AudioSystem.STREAM_MUSIC);
11611             }
11612         }
11613         return device;
11614     }
11615 
11616     @Override
isHdmiSystemAudioSupported()11617     public boolean isHdmiSystemAudioSupported() {
11618         return mHdmiSystemAudioSupported;
11619     }
11620 
11621     //==========================================================================================
11622     // Accessibility
11623 
initA11yMonitoring()11624     private void initA11yMonitoring() {
11625         final AccessibilityManager accessibilityManager =
11626                 (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
11627         updateDefaultStreamOverrideDelay(accessibilityManager.isTouchExplorationEnabled());
11628         updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive());
11629         accessibilityManager.addTouchExplorationStateChangeListener(this, null);
11630         accessibilityManager.addAccessibilityServicesStateChangeListener(this);
11631     }
11632 
11633     //---------------------------------------------------------------------------------
11634     // A11y: taking touch exploration into account for selecting the default
11635     //   stream override timeout when adjusting volume
11636     //---------------------------------------------------------------------------------
11637 
11638     // - STREAM_NOTIFICATION on tablets during this period after a notification stopped
11639     // - STREAM_RING on phones during this period after a notification stopped
11640     // - STREAM_MUSIC otherwise
11641 
11642     private static final int DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS = 0;
11643     private static final int TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS = 1000;
11644 
11645     private static int sStreamOverrideDelayMs;
11646 
11647     @Override
onTouchExplorationStateChanged(boolean enabled)11648     public void onTouchExplorationStateChanged(boolean enabled) {
11649         updateDefaultStreamOverrideDelay(enabled);
11650     }
11651 
updateDefaultStreamOverrideDelay(boolean touchExploreEnabled)11652     private void updateDefaultStreamOverrideDelay(boolean touchExploreEnabled) {
11653         if (touchExploreEnabled) {
11654             sStreamOverrideDelayMs = TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS;
11655         } else {
11656             sStreamOverrideDelayMs = DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS;
11657         }
11658         if (DEBUG_VOL) Log.d(TAG, "Touch exploration enabled=" + touchExploreEnabled
11659                 + " stream override delay is now " + sStreamOverrideDelayMs + " ms");
11660     }
11661 
11662     //---------------------------------------------------------------------------------
11663     // A11y: taking a11y state into account for the handling of a11y prompts volume
11664     //---------------------------------------------------------------------------------
11665 
11666     private static boolean sIndependentA11yVolume = false;
11667 
11668     // implementation of AccessibilityServicesStateChangeListener
11669     @Override
onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager)11670     public void onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager) {
11671         updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive());
11672     }
11673 
updateA11yVolumeAlias(boolean a11VolEnabled)11674     private void updateA11yVolumeAlias(boolean a11VolEnabled) {
11675         if (DEBUG_VOL) Log.d(TAG, "Accessibility volume enabled = " + a11VolEnabled);
11676         if (mIsSingleVolume) {
11677             if (DEBUG_VOL) Log.d(TAG, "Accessibility volume is not set on single volume device");
11678             return;
11679         }
11680         if (sIndependentA11yVolume != a11VolEnabled) {
11681             sIndependentA11yVolume = a11VolEnabled;
11682             // update the volume mapping scheme
11683             updateStreamVolumeAlias(true /*updateVolumes*/, TAG);
11684             // update the volume controller behavior
11685             mVolumeController.setA11yMode(sIndependentA11yVolume ?
11686                     VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME :
11687                         VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME);
11688             mVolumeController.postVolumeChanged(AudioManager.STREAM_ACCESSIBILITY, 0);
11689         }
11690     }
11691 
11692     //==========================================================================================
11693     // Camera shutter sound policy.
11694     // config_camera_sound_forced configuration option in config.xml defines if the camera shutter
11695     // sound is forced (sound even if the device is in silent mode) or not. This option is false by
11696     // default and can be overridden by country specific overlay in values-mccXXX/config.xml.
11697     //==========================================================================================
11698 
11699     // cached value of com.android.internal.R.bool.config_camera_sound_forced
11700     @GuardedBy("mSettingsLock")
11701     private boolean mCameraSoundForced;
11702 
11703     // called by android.hardware.Camera to populate CameraInfo.canDisableShutterSound
isCameraSoundForced()11704     public boolean isCameraSoundForced() {
11705         synchronized (mSettingsLock) {
11706             return mCameraSoundForced;
11707         }
11708     }
11709 
11710     //==========================================================================================
11711     // AudioService logging and dumpsys
11712     //==========================================================================================
11713     static final int LOG_NB_EVENTS_LIFECYCLE = 20;
11714     static final int LOG_NB_EVENTS_PHONE_STATE = 20;
11715     static final int LOG_NB_EVENTS_DEVICE_CONNECTION = 50;
11716     static final int LOG_NB_EVENTS_FORCE_USE = 20;
11717     static final int LOG_NB_EVENTS_VOLUME = 100;
11718     static final int LOG_NB_EVENTS_DYN_POLICY = 10;
11719     static final int LOG_NB_EVENTS_SPATIAL = 30;
11720     static final int LOG_NB_EVENTS_SOUND_DOSE = 30;
11721 
11722     static final int LOG_NB_EVENTS_LOUDNESS_CODEC = 30;
11723 
11724     static final EventLogger
11725             sLifecycleLogger = new EventLogger(LOG_NB_EVENTS_LIFECYCLE,
11726             "audio services lifecycle");
11727 
11728     static final EventLogger sMuteLogger = new EventLogger(30,
11729             "mute commands");
11730 
11731     final private EventLogger
11732             mModeLogger = new EventLogger(LOG_NB_EVENTS_PHONE_STATE,
11733             "phone state (logged after successful call to AudioSystem.setPhoneState(int, int))");
11734 
11735     // logs for wired + A2DP device connections:
11736     // - wired: logged before onSetWiredDeviceConnectionState() is executed
11737     // - A2DP: logged at reception of method call
11738     /*package*/ static final EventLogger
11739             sDeviceLogger = new EventLogger(
11740             LOG_NB_EVENTS_DEVICE_CONNECTION, "wired/A2DP/hearing aid device connection");
11741 
11742     static final EventLogger
11743             sForceUseLogger = new EventLogger(
11744             LOG_NB_EVENTS_FORCE_USE,
11745             "force use (logged before setForceUse() is executed)");
11746 
11747     static final EventLogger
11748             sVolumeLogger = new EventLogger(LOG_NB_EVENTS_VOLUME,
11749             "volume changes (logged when command received by AudioService)");
11750 
11751     static final EventLogger
11752             sSpatialLogger = new EventLogger(LOG_NB_EVENTS_SPATIAL,
11753             "spatial audio");
11754 
11755     final private EventLogger
11756             mDynPolicyLogger = new EventLogger(LOG_NB_EVENTS_DYN_POLICY,
11757             "dynamic policy events (logged when command received by AudioService)");
11758 
11759     private static final String[] RINGER_MODE_NAMES = new String[] {
11760             "SILENT",
11761             "VIBRATE",
11762             "NORMAL"
11763     };
11764 
dumpRingerMode(PrintWriter pw)11765     private void dumpRingerMode(PrintWriter pw) {
11766         pw.println("\nRinger mode: ");
11767         pw.println("- mode (internal) = " + RINGER_MODE_NAMES[mRingerMode]);
11768         pw.println("- mode (external) = " + RINGER_MODE_NAMES[mRingerModeExternal]);
11769         pw.println("- zen mode:" + Settings.Global.zenModeToString(mNm.getZenMode()));
11770         dumpRingerModeStreams(pw, "affected", mRingerModeAffectedStreams);
11771         dumpRingerModeStreams(pw, "muted", sRingerAndZenModeMutedStreams);
11772         pw.print("- delegate = "); pw.println(mRingerModeDelegate);
11773     }
11774 
dumpRingerModeStreams(PrintWriter pw, String type, int streams)11775     private void dumpRingerModeStreams(PrintWriter pw, String type, int streams) {
11776         pw.print("- ringer mode "); pw.print(type); pw.print(" streams = 0x");
11777         pw.print(Integer.toHexString(streams));
11778         if (streams != 0) {
11779             pw.print(" (");
11780             boolean first = true;
11781             for (int i = 0; i < AudioSystem.STREAM_NAMES.length; i++) {
11782                 final int stream = (1 << i);
11783                 if ((streams & stream) != 0) {
11784                     if (!first) pw.print(',');
11785                     pw.print(AudioSystem.STREAM_NAMES[i]);
11786                     streams &= ~stream;
11787                     first = false;
11788                 }
11789             }
11790             if (streams != 0) {
11791                 if (!first) pw.print(',');
11792                 pw.print(streams);
11793             }
11794             pw.print(')');
11795         }
11796         pw.println();
11797     }
11798 
getAbsoluteVolumeDevicesWithBehavior(int behavior)11799     private Set<Integer> getAbsoluteVolumeDevicesWithBehavior(int behavior) {
11800         return mAbsoluteVolumeDeviceInfoMap.entrySet().stream()
11801                 .filter(entry -> entry.getValue().mDeviceVolumeBehavior == behavior)
11802                 .map(Map.Entry::getKey)
11803                 .collect(Collectors.toSet());
11804     }
11805 
dumpDeviceTypes(@onNull Set<Integer> deviceTypes)11806     private String dumpDeviceTypes(@NonNull Set<Integer> deviceTypes) {
11807         Iterator<Integer> it = deviceTypes.iterator();
11808         if (!it.hasNext()) {
11809             return "";
11810         }
11811         final StringBuilder sb = new StringBuilder();
11812         sb.append("0x" + Integer.toHexString(it.next()));
11813         while (it.hasNext()) {
11814             sb.append("," + "0x" + Integer.toHexString(it.next()));
11815         }
11816         return sb.toString();
11817     }
11818 
11819     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)11820     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11821         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
11822 
11823         sLifecycleLogger.dump(pw);
11824         if (mAudioHandler != null) {
11825             pw.println("\nMessage handler (watch for unhandled messages):");
11826             mAudioHandler.dump(new PrintWriterPrinter(pw), "  ");
11827         } else {
11828             pw.println("\nMessage handler is null");
11829         }
11830         dumpFlags(pw);
11831         mHardeningEnforcer.dump(pw);
11832         mMediaFocusControl.dump(pw);
11833         dumpStreamStates(pw);
11834         dumpVolumeGroups(pw);
11835         dumpRingerMode(pw);
11836         dumpAudioMode(pw);
11837         pw.println("\nAudio routes:");
11838         pw.print("  mMainType=0x"); pw.println(Integer.toHexString(
11839                 mDeviceBroker.getCurAudioRoutes().mainType));
11840         pw.print("  mBluetoothName="); pw.println(mDeviceBroker.getCurAudioRoutes().bluetoothName);
11841 
11842         pw.println("\nOther state:");
11843         pw.print("  mUseVolumeGroupAliases="); pw.println(mUseVolumeGroupAliases);
11844         pw.print("  mVolumeController="); pw.println(mVolumeController);
11845         mSoundDoseHelper.dump(pw);
11846         pw.print("  sIndependentA11yVolume="); pw.println(sIndependentA11yVolume);
11847         pw.print("  mCameraSoundForced="); pw.println(isCameraSoundForced());
11848         pw.print("  mHasVibrator="); pw.println(mHasVibrator);
11849         pw.print("  mVolumePolicy="); pw.println(mVolumePolicy);
11850         pw.print("  mAvrcpAbsVolSupported="); pw.println(mAvrcpAbsVolSupported);
11851         pw.print("  mBtScoOnByApp="); pw.println(mBtScoOnByApp);
11852         pw.print("  mIsSingleVolume="); pw.println(mIsSingleVolume);
11853         pw.print("  mUseFixedVolume="); pw.println(mUseFixedVolume);
11854         pw.print("  mNotifAliasRing="); pw.println(mNotifAliasRing);
11855         pw.print("  mFixedVolumeDevices="); pw.println(dumpDeviceTypes(mFixedVolumeDevices));
11856         pw.print("  mFullVolumeDevices="); pw.println(dumpDeviceTypes(mFullVolumeDevices));
11857         pw.print("  absolute volume devices="); pw.println(dumpDeviceTypes(
11858                 getAbsoluteVolumeDevicesWithBehavior(
11859                         AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE)));
11860         pw.print("  adjust-only absolute volume devices="); pw.println(dumpDeviceTypes(
11861                 getAbsoluteVolumeDevicesWithBehavior(
11862                         AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY)));
11863         pw.print("  pre-scale for bluetooth absolute volume ");
11864         if (disablePrescaleAbsoluteVolume()) {
11865             pw.println("= disabled");
11866         } else {
11867             pw.println("=" + mPrescaleAbsoluteVolume[0]
11868                     + ", " + mPrescaleAbsoluteVolume[1]
11869                     + ", " + mPrescaleAbsoluteVolume[2]);
11870         }
11871         pw.print("  mExtVolumeController="); pw.println(mExtVolumeController);
11872         pw.print("  mHdmiAudioSystemClient="); pw.println(mHdmiAudioSystemClient);
11873         pw.print("  mHdmiPlaybackClient="); pw.println(mHdmiPlaybackClient);
11874         pw.print("  mHdmiTvClient="); pw.println(mHdmiTvClient);
11875         pw.print("  mHdmiSystemAudioSupported="); pw.println(mHdmiSystemAudioSupported);
11876         synchronized (mHdmiClientLock) {
11877             pw.print("  mHdmiCecVolumeControlEnabled="); pw.println(mHdmiCecVolumeControlEnabled);
11878         }
11879         pw.print("  mIsCallScreeningModeSupported="); pw.println(mIsCallScreeningModeSupported);
11880         pw.println("  mic mute FromSwitch=" + mMicMuteFromSwitch
11881                         + " FromRestrictions=" + mMicMuteFromRestrictions
11882                         + " FromApi=" + mMicMuteFromApi
11883                         + " from system=" + mMicMuteFromSystemCached);
11884         pw.print("  mMasterMute="); pw.println(mMasterMute.get());
11885         dumpAccessibilityServiceUids(pw);
11886         dumpAssistantServicesUids(pw);
11887 
11888         pw.print("  supportsBluetoothVariableLatency=");
11889         pw.println(AudioSystem.supportsBluetoothVariableLatency());
11890         pw.print("  isBluetoothVariableLatencyEnabled=");
11891         pw.println(AudioSystem.isBluetoothVariableLatencyEnabled());
11892 
11893         dumpAudioPolicies(pw);
11894         mDynPolicyLogger.dump(pw);
11895         mPlaybackMonitor.dump(pw);
11896         mRecordMonitor.dump(pw);
11897 
11898         pw.println("\nAudioDeviceBroker:");
11899         mDeviceBroker.dump(pw, "  ");
11900         pw.println("\nSoundEffects:");
11901         mSfxHelper.dump(pw, "  ");
11902 
11903         pw.println("\n");
11904         pw.println("\nEvent logs:");
11905         mModeLogger.dump(pw);
11906         pw.println("\n");
11907         sDeviceLogger.dump(pw);
11908         pw.println("\n");
11909         sForceUseLogger.dump(pw);
11910         pw.println("\n");
11911         sVolumeLogger.dump(pw);
11912         pw.println("\n");
11913         sMuteLogger.dump(pw);
11914         pw.println("\n");
11915         dumpSupportedSystemUsage(pw);
11916 
11917         pw.println("\n");
11918         pw.println("\nSpatial audio:");
11919         pw.println("mHasSpatializerEffect:" + mHasSpatializerEffect + " (effect present)");
11920         pw.println("isSpatializerEnabled:" + isSpatializerEnabled() + " (routing dependent)");
11921         mSpatializerHelper.dump(pw);
11922         sSpatialLogger.dump(pw);
11923 
11924         pw.println("\n");
11925         pw.println("\nLoudness alignment:");
11926         mLoudnessCodecHelper.dump(pw);
11927 
11928         mAudioSystem.dump(pw);
11929     }
11930 
dumpSupportedSystemUsage(PrintWriter pw)11931     private void dumpSupportedSystemUsage(PrintWriter pw) {
11932         pw.println("Supported System Usages:");
11933         synchronized (mSupportedSystemUsagesLock) {
11934             for (int i = 0; i < mSupportedSystemUsages.length; i++) {
11935                 pw.printf("\t%s\n", AudioAttributes.usageToString(mSupportedSystemUsages[i]));
11936             }
11937         }
11938     }
11939 
dumpAssistantServicesUids(PrintWriter pw)11940     private void dumpAssistantServicesUids(PrintWriter pw) {
11941         synchronized (mSettingsLock) {
11942             if (mAssistantUids.size() > 0) {
11943                 pw.println("  Assistant service UIDs:");
11944                 for (int uid : mAssistantUids) {
11945                     pw.println("  - " + uid);
11946                 }
11947             } else {
11948                 pw.println("  No Assistant service Uids.");
11949             }
11950         }
11951     }
11952 
dumpAccessibilityServiceUids(PrintWriter pw)11953     private void dumpAccessibilityServiceUids(PrintWriter pw) {
11954         synchronized (mSupportedSystemUsagesLock) {
11955             if (mAccessibilityServiceUids != null && mAccessibilityServiceUids.length > 0) {
11956                 pw.println("  Accessibility service Uids:");
11957                 for (int uid : mAccessibilityServiceUids) {
11958                     pw.println("  - " + uid);
11959                 }
11960             } else {
11961                 pw.println("  No accessibility service Uids.");
11962             }
11963         }
11964     }
11965 
11966     /**
11967      * Audio Analytics ids.
11968      */
11969     private static final String mMetricsId = MediaMetrics.Name.AUDIO_SERVICE
11970             + MediaMetrics.SEPARATOR;
11971 
initializeAudioServerPermissionProvider( Context context, AudioPolicyFacade audioPolicy, Executor audioserverExecutor)11972     private static AudioServerPermissionProvider initializeAudioServerPermissionProvider(
11973             Context context, AudioPolicyFacade audioPolicy, Executor audioserverExecutor) {
11974         Collection<PackageState> packageStates = null;
11975         try (PackageManagerLocal.UnfilteredSnapshot snapshot =
11976                     LocalManagerRegistry.getManager(PackageManagerLocal.class)
11977                         .withUnfilteredSnapshot()) {
11978             packageStates = snapshot.getPackageStates().values();
11979         }
11980         var umi = LocalServices.getService(UserManagerInternal.class);
11981         var pmsi = LocalServices.getService(PermissionManagerServiceInternal.class);
11982         var provider = new AudioServerPermissionProvider(packageStates,
11983                 (Integer uid, String perm) -> (pmsi.checkUidPermission(uid, perm,
11984                         Context.DEVICE_ID_DEFAULT) == PackageManager.PERMISSION_GRANTED),
11985                 () -> umi.getUserIds()
11986                 );
11987         audioPolicy.registerOnStartTask(() -> {
11988             provider.onServiceStart(audioPolicy.getPermissionController());
11989         });
11990 
11991         // Set up event listeners
11992         // Must be kept in sync with PermissionManager
11993         Runnable cacheSysPropHandler = new Runnable() {
11994             private AtomicReference<SystemProperties.Handle> mHandle = new AtomicReference();
11995             private AtomicLong mNonce = new AtomicLong();
11996             @Override
11997             public void run() {
11998                 if (mHandle.get() == null) {
11999                     // Cache the handle
12000                     mHandle.compareAndSet(null, SystemProperties.find(
12001                             PermissionManager.CACHE_KEY_PACKAGE_INFO));
12002                 }
12003                 long nonce;
12004                 SystemProperties.Handle ref;
12005                 if ((ref = mHandle.get()) != null && (nonce = ref.getLong(0)) != 0 &&
12006                         mNonce.getAndSet(nonce) != nonce) {
12007                     audioserverExecutor.execute(() -> provider.onPermissionStateChanged());
12008                 }
12009             }
12010         };
12011 
12012         SystemProperties.addChangeCallback(cacheSysPropHandler);
12013 
12014         IntentFilter packageUpdateFilter = new IntentFilter();
12015         packageUpdateFilter.addAction(ACTION_PACKAGE_ADDED);
12016         packageUpdateFilter.addAction(ACTION_PACKAGE_REMOVED);
12017         packageUpdateFilter.addDataScheme("package");
12018 
12019         context.registerReceiverForAllUsers(new BroadcastReceiver() {
12020             @Override
12021             public void onReceive(Context context, Intent intent) {
12022                 String action = intent.getAction();
12023                 String pkgName = intent.getData().getEncodedSchemeSpecificPart();
12024                 int uid = intent.getIntExtra(Intent.EXTRA_UID, Process.INVALID_UID);
12025                 if (intent.getBooleanExtra(EXTRA_REPLACING, false) ||
12026                         intent.getBooleanExtra(EXTRA_ARCHIVAL, false)) return;
12027                 if (action.equals(ACTION_PACKAGE_ADDED)) {
12028                     audioserverExecutor.execute(() ->
12029                             provider.onModifyPackageState(uid, pkgName, false /* isRemoved */));
12030                 } else if (action.equals(ACTION_PACKAGE_REMOVED)) {
12031                     audioserverExecutor.execute(() ->
12032                             provider.onModifyPackageState(uid, pkgName, true /* isRemoved */));
12033                 }
12034             }
12035         }, packageUpdateFilter, null, null); // main thread is fine, since dispatch on executor
12036         return provider;
12037     }
12038 
12039     // Inform AudioFlinger of our device's low RAM attribute
readAndSetLowRamDevice()12040     private static void readAndSetLowRamDevice()
12041     {
12042         boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic();
12043         long totalMemory = 1024 * 1024 * 1024; // 1GB is the default if ActivityManager fails.
12044 
12045         try {
12046             final ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();
12047             ActivityManager.getService().getMemoryInfo(info);
12048             totalMemory = info.totalMem;
12049         } catch (RemoteException e) {
12050             Log.w(TAG, "Cannot obtain MemoryInfo from ActivityManager, assume low memory device");
12051             isLowRamDevice = true;
12052         }
12053 
12054         final int status = AudioSystem.setLowRamDevice(isLowRamDevice, totalMemory);
12055         if (status != 0) {
12056             Log.w(TAG, "AudioFlinger informed of device's low RAM attribute; status " + status);
12057         }
12058     }
12059 
enforceVolumeController(String action)12060     private void enforceVolumeController(String action) {
12061         mContext.enforceCallingOrSelfPermission(Manifest.permission.STATUS_BAR_SERVICE,
12062                 "Only SystemUI can " + action);
12063     }
12064 
12065     @Override
setVolumeController(final IVolumeController controller)12066     public void setVolumeController(final IVolumeController controller) {
12067         enforceVolumeController("set the volume controller");
12068 
12069         // return early if things are not actually changing
12070         if (mVolumeController.isSameBinder(controller)) {
12071             return;
12072         }
12073 
12074         // dismiss the old volume controller
12075         mVolumeController.postDismiss();
12076         if (controller != null) {
12077             // we are about to register a new controller, listen for its death
12078             try {
12079                 controller.asBinder().linkToDeath(new DeathRecipient() {
12080                     @Override
12081                     public void binderDied() {
12082                         if (mVolumeController.isSameBinder(controller)) {
12083                             Log.w(TAG, "Current remote volume controller died, unregistering");
12084                             setVolumeController(null);
12085                         }
12086                     }
12087                 }, 0);
12088             } catch (RemoteException e) {
12089                 // noop
12090             }
12091         }
12092         mVolumeController.setController(controller);
12093         if (DEBUG_VOL) Log.d(TAG, "Volume controller: " + mVolumeController);
12094     }
12095 
12096     @Override
12097     @Nullable
getVolumeController()12098     public IVolumeController getVolumeController() {
12099         enforceVolumeController("get the volume controller");
12100         if (DEBUG_VOL) Log.d(TAG, "Volume controller: " + mVolumeController);
12101 
12102         return mVolumeController.getController();
12103     }
12104 
12105     @Override
notifyVolumeControllerVisible(final IVolumeController controller, boolean visible)12106     public void notifyVolumeControllerVisible(final IVolumeController controller, boolean visible) {
12107         enforceVolumeController("notify about volume controller visibility");
12108 
12109         // return early if the controller is not current
12110         if (!mVolumeController.isSameBinder(controller)) {
12111             return;
12112         }
12113 
12114         mVolumeController.setVisible(visible);
12115         if (DEBUG_VOL) Log.d(TAG, "Volume controller visible: " + visible);
12116     }
12117 
12118     @Override
setVolumePolicy(VolumePolicy policy)12119     public void setVolumePolicy(VolumePolicy policy) {
12120         enforceVolumeController("set volume policy");
12121         if (policy != null && !policy.equals(mVolumePolicy)) {
12122             mVolumePolicy = policy;
12123             if (DEBUG_VOL) Log.d(TAG, "Volume policy changed: " + mVolumePolicy);
12124         }
12125     }
12126 
12127     /** Interface used for enforcing the safe hearing standard. */
12128     public interface ISafeHearingVolumeController {
12129         /** Displays an instructional safeguard as required by the safe hearing standard. */
postDisplaySafeVolumeWarning(int flags)12130         void postDisplaySafeVolumeWarning(int flags);
12131 
12132         /** Displays a warning about transient exposure to high level playback */
postDisplayCsdWarning(@udioManager.CsdWarning int csdEvent, int displayDurationMs)12133         void postDisplayCsdWarning(@AudioManager.CsdWarning int csdEvent, int displayDurationMs);
12134     }
12135 
12136     /** Wrapper which encapsulates the {@link IVolumeController} functionality. */
12137     public class VolumeController implements ISafeHearingVolumeController {
12138         private static final String TAG = "VolumeController";
12139 
12140         private IVolumeController mController;
12141         private boolean mVisible;
12142         private long mNextLongPress;
12143         private int mLongPressTimeout;
12144 
setController(IVolumeController controller)12145         public void setController(IVolumeController controller) {
12146             mController = controller;
12147             mVisible = false;
12148         }
12149 
getController()12150         public IVolumeController getController() {
12151             return mController;
12152         }
12153 
loadSettings(ContentResolver cr)12154         public void loadSettings(ContentResolver cr) {
12155             mLongPressTimeout = mSettings.getSecureIntForUser(cr,
12156                     Settings.Secure.LONG_PRESS_TIMEOUT, 500, UserHandle.USER_CURRENT);
12157         }
12158 
suppressAdjustment(int resolvedStream, int flags, boolean isMute)12159         public boolean suppressAdjustment(int resolvedStream, int flags, boolean isMute) {
12160             if (isMute) {
12161                 return false;
12162             }
12163             boolean suppress = false;
12164             // Intended behavior:
12165             // 1/ if the stream is not the default UI stream, do not suppress (as it is not involved
12166             //    in bringing up the UI)
12167             // 2/ if the resolved and default stream is MUSIC, and media is playing, do not suppress
12168             // 3/ otherwise suppress the first adjustments that occur during the "long press
12169             //    timeout" interval. Note this is true regardless of whether this is a "real long
12170             //    press" (where the user keeps pressing on the volume button), or repeated single
12171             //    presses (here we don't know if we are in a real long press, or repeated fast
12172             //    button presses).
12173             //    Once the long press timeout occurs (mNextLongPress reset to 0), do not suppress.
12174             // Example: for a default and resolved stream of MUSIC, this allows modifying rapidly
12175             // the volume when media is playing (whether by long press or repeated individual
12176             // presses), or to bring up the volume UI when media is not playing, in order to make
12177             // another change (e.g. switch ringer modes) without changing media volume.
12178             if (resolvedStream == DEFAULT_VOL_STREAM_NO_PLAYBACK && mController != null) {
12179                 // never suppress media vol adjustement during media playback
12180                 if (resolvedStream == AudioSystem.STREAM_MUSIC
12181                         && mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, mLongPressTimeout))
12182                 {
12183                     // media is playing, adjust the volume right away
12184                     return false;
12185                 }
12186 
12187                 final long now = SystemClock.uptimeMillis();
12188                 if ((flags & AudioManager.FLAG_SHOW_UI) != 0 && !mVisible) {
12189                     // UI is not visible yet, adjustment is ignored
12190                     if (mNextLongPress < now) {
12191                         mNextLongPress = now + mLongPressTimeout;
12192                     }
12193                     suppress = true;
12194                 } else if (mNextLongPress > 0) {  // in a long-press
12195                     if (now > mNextLongPress) {
12196                         // long press triggered, no more suppression
12197                         mNextLongPress = 0;
12198                     } else {
12199                         // keep suppressing until the long press triggers
12200                         suppress = true;
12201                     }
12202                 }
12203             }
12204             return suppress;
12205         }
12206 
setVisible(boolean visible)12207         public void setVisible(boolean visible) {
12208             mVisible = visible;
12209         }
12210 
isSameBinder(IVolumeController controller)12211         public boolean isSameBinder(IVolumeController controller) {
12212             return Objects.equals(asBinder(), binder(controller));
12213         }
12214 
asBinder()12215         public IBinder asBinder() {
12216             return binder(mController);
12217         }
12218 
binder(IVolumeController controller)12219         private IBinder binder(IVolumeController controller) {
12220             return controller == null ? null : controller.asBinder();
12221         }
12222 
12223         @Override
toString()12224         public String toString() {
12225             return "VolumeController(" + asBinder() + ",mVisible=" + mVisible + ")";
12226         }
12227 
12228         @Override
postDisplaySafeVolumeWarning(int flags)12229         public void postDisplaySafeVolumeWarning(int flags) {
12230             if (mController == null)
12231                 return;
12232             flags = flags | AudioManager.FLAG_SHOW_UI;
12233             try {
12234                 mController.displaySafeVolumeWarning(flags);
12235             } catch (RemoteException e) {
12236                 Log.w(TAG, "Error calling displaySafeVolumeWarning", e);
12237             }
12238         }
12239 
12240         @Override
postDisplayCsdWarning( @udioManager.CsdWarning int csdWarning, int displayDurationMs)12241         public void postDisplayCsdWarning(
12242                 @AudioManager.CsdWarning int csdWarning, int displayDurationMs) {
12243             if (mController == null) {
12244                 Log.e(TAG, "Unable to display CSD warning, no controller");
12245                 return;
12246             }
12247             try {
12248                 mController.displayCsdWarning(csdWarning, displayDurationMs);
12249             } catch (RemoteException e) {
12250                 Log.w(TAG, "Error calling displayCsdWarning for warning " + csdWarning, e);
12251             }
12252         }
12253 
postVolumeChanged(int streamType, int flags)12254         public void postVolumeChanged(int streamType, int flags) {
12255             if (mController == null)
12256                 return;
12257             try {
12258                 mController.volumeChanged(streamType, flags);
12259             } catch (RemoteException e) {
12260                 Log.w(TAG, "Error calling volumeChanged", e);
12261             }
12262         }
12263 
postMasterMuteChanged(int flags)12264         public void postMasterMuteChanged(int flags) {
12265             if (mController == null)
12266                 return;
12267             try {
12268                 mController.masterMuteChanged(flags);
12269             } catch (RemoteException e) {
12270                 Log.w(TAG, "Error calling masterMuteChanged", e);
12271             }
12272         }
12273 
setLayoutDirection(int layoutDirection)12274         public void setLayoutDirection(int layoutDirection) {
12275             if (mController == null)
12276                 return;
12277             try {
12278                 mController.setLayoutDirection(layoutDirection);
12279             } catch (RemoteException e) {
12280                 Log.w(TAG, "Error calling setLayoutDirection", e);
12281             }
12282         }
12283 
postDismiss()12284         public void postDismiss() {
12285             if (mController == null)
12286                 return;
12287             try {
12288                 mController.dismiss();
12289             } catch (RemoteException e) {
12290                 Log.w(TAG, "Error calling dismiss", e);
12291             }
12292         }
12293 
setA11yMode(int a11yMode)12294         public void setA11yMode(int a11yMode) {
12295             if (mController == null)
12296                 return;
12297             try {
12298                 mController.setA11yMode(a11yMode);
12299             } catch (RemoteException e) {
12300                 Log.w(TAG, "Error calling setA11Mode", e);
12301             }
12302         }
12303     }
12304 
12305     /**
12306      * Interface for system components to get some extra functionality through
12307      * LocalServices.
12308      */
12309     final class AudioServiceInternal extends AudioManagerInternal {
12310         @Override
setRingerModeDelegate(RingerModeDelegate delegate)12311         public void setRingerModeDelegate(RingerModeDelegate delegate) {
12312             mRingerModeDelegate = delegate;
12313             if (mRingerModeDelegate != null) {
12314                 synchronized (mSettingsLock) {
12315                     updateRingerAndZenModeAffectedStreams();
12316                 }
12317                 setRingerModeInternal(getRingerModeInternal(), TAG + ".setRingerModeDelegate");
12318             }
12319         }
12320 
12321         @Override
getRingerModeInternal()12322         public int getRingerModeInternal() {
12323             return AudioService.this.getRingerModeInternal();
12324         }
12325 
12326         @Override
setRingerModeInternal(int ringerMode, String caller)12327         public void setRingerModeInternal(int ringerMode, String caller) {
12328             AudioService.this.setRingerModeInternal(ringerMode, caller);
12329         }
12330 
12331         @Override
silenceRingerModeInternal(String caller)12332         public void silenceRingerModeInternal(String caller) {
12333             AudioService.this.silenceRingerModeInternal(caller);
12334         }
12335 
12336         @Override
updateRingerModeAffectedStreamsInternal()12337         public void updateRingerModeAffectedStreamsInternal() {
12338             synchronized (mSettingsLock) {
12339                 if (updateRingerAndZenModeAffectedStreams()) {
12340                     setRingerModeInt(getRingerModeInternal(), false);
12341                 }
12342             }
12343         }
12344 
12345         @Override
addAssistantServiceUid(int uid)12346         public void addAssistantServiceUid(int uid) {
12347             sendMsg(mAudioHandler, MSG_ADD_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE,
12348                     uid, 0, null, 0);
12349         }
12350 
12351         @Override
removeAssistantServiceUid(int uid)12352         public void removeAssistantServiceUid(int uid) {
12353             sendMsg(mAudioHandler, MSG_REMOVE_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE,
12354                     uid, 0, null, 0);
12355         }
12356 
12357         @Override
setActiveAssistantServicesUids(IntArray activeUids)12358         public void setActiveAssistantServicesUids(IntArray activeUids) {
12359             synchronized (mSettingsLock) {
12360                 if (activeUids.size() == 0) {
12361                     mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS;
12362                 } else {
12363                     boolean changed = (mActiveAssistantServiceUids == null)
12364                             || (mActiveAssistantServiceUids.length != activeUids.size());
12365                     if (!changed) {
12366                         for (int i = 0; i < mActiveAssistantServiceUids.length; i++) {
12367                             if (activeUids.get(i) != mActiveAssistantServiceUids[i]) {
12368                                 changed = true;
12369                                 break;
12370                             }
12371                         }
12372                     }
12373                     if (changed) {
12374                         mActiveAssistantServiceUids = activeUids.toArray();
12375                     }
12376                 }
12377             }
12378             sendMsg(mAudioHandler, MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID, SENDMSG_REPLACE,
12379                     0, 0, null, 0);
12380         }
12381 
12382         @Override
setAccessibilityServiceUids(IntArray uids)12383         public void setAccessibilityServiceUids(IntArray uids) {
12384             // TODO(b/233287010): Fix voice interaction and a11y concurrency in audio policy service
12385             if (isPlatformAutomotive()) {
12386                 return;
12387             }
12388 
12389             synchronized (mAccessibilityServiceUidsLock) {
12390                 if (uids.size() == 0) {
12391                     mAccessibilityServiceUids = null;
12392                 } else {
12393                     boolean changed = (mAccessibilityServiceUids == null)
12394                             || (mAccessibilityServiceUids.length != uids.size());
12395                     if (!changed) {
12396                         for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
12397                             if (uids.get(i) != mAccessibilityServiceUids[i]) {
12398                                 changed = true;
12399                                 break;
12400                             }
12401                         }
12402                     }
12403                     if (changed) {
12404                         mAccessibilityServiceUids = uids.toArray();
12405                     }
12406                 }
12407                 sendMsg(mAudioHandler, MSG_UPDATE_A11Y_SERVICE_UIDS, SENDMSG_REPLACE,
12408                         0, 0, null, 0);
12409             }
12410         }
12411 
12412         /**
12413          * {@inheritDoc}
12414          */
12415         @Override
setInputMethodServiceUid(int uid)12416         public void setInputMethodServiceUid(int uid) {
12417             synchronized (mInputMethodServiceUidLock) {
12418                 if (mInputMethodServiceUid != uid) {
12419                     mAudioSystem.setCurrentImeUid(uid);
12420                     mInputMethodServiceUid = uid;
12421                 }
12422             }
12423         }
12424     }
12425 
onUpdateAccessibilityServiceUids()12426     private void onUpdateAccessibilityServiceUids() {
12427         int[] accessibilityServiceUids;
12428         synchronized (mAccessibilityServiceUidsLock) {
12429             accessibilityServiceUids = mAccessibilityServiceUids;
12430         }
12431         AudioSystem.setA11yServicesUids(accessibilityServiceUids);
12432     }
12433 
12434     //==========================================================================================
12435     // Audio policy management
12436     //==========================================================================================
registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection, AttributionSource attributionSource)12437     public String registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb,
12438             boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy,
12439             boolean isVolumeController, IMediaProjection projection,
12440             AttributionSource attributionSource) {
12441         Objects.requireNonNull(attributionSource);
12442         AudioSystem.setDynamicPolicyCallback(mDynPolicyCallback);
12443 
12444         if (!isPolicyRegisterAllowed(policyConfig,
12445                                      isFocusPolicy || isTestFocusPolicy || hasFocusListener,
12446                                      isVolumeController,
12447                                      projection)) {
12448             Slog.w(TAG, "Permission denied to register audio policy for pid "
12449                     + Binder.getCallingPid() + " / uid " + Binder.getCallingUid()
12450                     + ", need system permission or a MediaProjection that can project audio");
12451             return null;
12452         }
12453 
12454         String regId = null;
12455         synchronized (mAudioPolicies) {
12456             if (mAudioPolicies.containsKey(pcb.asBinder())) {
12457                 Slog.e(TAG, "Cannot re-register policy");
12458                 return null;
12459             }
12460             try {
12461                 AudioPolicyProxy app = new AudioPolicyProxy(policyConfig, pcb, hasFocusListener,
12462                         isFocusPolicy, isTestFocusPolicy, isVolumeController, projection,
12463                         attributionSource);
12464                 pcb.asBinder().linkToDeath(app, 0/*flags*/);
12465 
12466                 // logging after registration so we have the registration id
12467                 mDynPolicyLogger.enqueue((new EventLogger.StringEvent("registerAudioPolicy for "
12468                         + pcb.asBinder() + " u/pid:" + Binder.getCallingUid() + "/"
12469                         + Binder.getCallingPid() + " with config:" + app.toCompactLogString()))
12470                         .printLog(TAG));
12471 
12472                 regId = app.getRegistrationId();
12473                 mAudioPolicies.put(pcb.asBinder(), app);
12474             } catch (RemoteException e) {
12475                 // audio policy owner has already died!
12476                 Slog.w(TAG, "Audio policy registration failed, could not link to " + pcb +
12477                         " binder death", e);
12478                 return null;
12479             } catch (IllegalStateException e) {
12480                 Slog.w(TAG, "Audio policy registration failed for binder " + pcb, e);
12481                 return null;
12482             }
12483         }
12484         return regId;
12485     }
12486 
12487     /**
12488      * Called by an AudioPolicyProxy when the client dies.
12489      * Checks if an active playback for media use case is currently routed to one of the
12490      * remote submix devices owned by this dynamic policy and broadcasts a becoming noisy
12491      * intend in this case.
12492      * @param addresses list of remote submix device addresses to check.
12493      */
onPolicyClientDeath(List<String> addresses)12494     private void onPolicyClientDeath(List<String> addresses) {
12495         for (String address : addresses) {
12496             if (mPlaybackMonitor.hasActiveMediaPlaybackOnSubmixWithAddress(address)) {
12497                 mDeviceBroker.postBroadcastBecomingNoisy();
12498                 return;
12499             }
12500         }
12501     }
12502     /**
12503      * Apps with MODIFY_AUDIO_ROUTING can register any policy.
12504      * Apps with an audio capable MediaProjection are allowed to register a RENDER|LOOPBACK policy
12505      * as those policy do not modify the audio routing.
12506      */
isPolicyRegisterAllowed(AudioPolicyConfig policyConfig, boolean hasFocusAccess, boolean isVolumeController, IMediaProjection projection)12507     private boolean isPolicyRegisterAllowed(AudioPolicyConfig policyConfig,
12508                                             boolean hasFocusAccess,
12509                                             boolean isVolumeController,
12510                                             IMediaProjection projection) {
12511 
12512         boolean requireValidProjection = false;
12513         boolean requireCaptureAudioOrMediaOutputPerm = false;
12514         boolean requireModifyRouting = false;
12515         boolean requireCallAudioInterception = false;
12516         ArrayList<AudioMix> voiceCommunicationCaptureMixes = null;
12517 
12518 
12519         if (hasFocusAccess || isVolumeController) {
12520             requireModifyRouting |= true;
12521         } else if (policyConfig.getMixes().isEmpty()) {
12522             // An empty policy could be used to lock the focus or add mixes later
12523             requireModifyRouting |= true;
12524         }
12525         for (AudioMix mix : policyConfig.getMixes()) {
12526             // If mix is requesting privileged capture
12527             if (mix.getRule().allowPrivilegedMediaPlaybackCapture()) {
12528                 // then its format must be low quality enough
12529                 String privilegedMediaCaptureError =
12530                         mix.canBeUsedForPrivilegedMediaCapture(mix.getFormat());
12531                 if (privilegedMediaCaptureError != null) {
12532                     Log.e(TAG, privilegedMediaCaptureError);
12533                     return false;
12534                 }
12535                 // and it must have CAPTURE_MEDIA_OUTPUT or CAPTURE_AUDIO_OUTPUT permission
12536                 requireCaptureAudioOrMediaOutputPerm |= true;
12537 
12538             }
12539             // If mix is trying to explicitly capture USAGE_VOICE_COMMUNICATION
12540             if (mix.containsMatchAttributeRuleForUsage(
12541                     AudioAttributes.USAGE_VOICE_COMMUNICATION)
12542                     && (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER)) {
12543                 // It must have CAPTURE_USAGE_VOICE_COMMUNICATION_OUTPUT permission
12544                 // Note that for UID, USERID or EXCLDUE rules, the capture will be silenced
12545                 // in AudioPolicyMix
12546                 if (voiceCommunicationCaptureMixes == null) {
12547                     voiceCommunicationCaptureMixes = new ArrayList<AudioMix>();
12548                 }
12549                 voiceCommunicationCaptureMixes.add(mix);
12550             }
12551 
12552             // If mix is RENDER|LOOPBACK, then an audio MediaProjection is enough
12553             // otherwise MODIFY_AUDIO_ROUTING permission is required
12554             if (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER && projection != null) {
12555                 requireValidProjection |= true;
12556             } else if (mix.isForCallRedirection()) {
12557                 requireCallAudioInterception |= true;
12558             } else if (mix.containsMatchAttributeRuleForUsage(
12559                             AudioAttributes.USAGE_VOICE_COMMUNICATION)) {
12560                 requireModifyRouting |= true;
12561             }
12562         }
12563 
12564         if (requireCaptureAudioOrMediaOutputPerm
12565                 && !callerHasPermission(CAPTURE_MEDIA_OUTPUT)
12566                 && !callerHasPermission(CAPTURE_AUDIO_OUTPUT)) {
12567             Log.e(TAG, "Privileged audio capture requires CAPTURE_MEDIA_OUTPUT or "
12568                       + "CAPTURE_AUDIO_OUTPUT system permission");
12569             return false;
12570         }
12571 
12572         if (voiceCommunicationCaptureMixes != null && voiceCommunicationCaptureMixes.size() > 0) {
12573             if (!callerHasPermission(
12574                     Manifest.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT)) {
12575                 Log.e(TAG, "Audio capture for voice communication requires "
12576                         + "CAPTURE_VOICE_COMMUNICATION_OUTPUT system permission");
12577                 return false;
12578             }
12579 
12580             // If permission check succeeded, we set the flag in each of the mixing rules
12581             for (AudioMix mix : voiceCommunicationCaptureMixes) {
12582                 mix.getRule().setVoiceCommunicationCaptureAllowed(true);
12583             }
12584         }
12585 
12586         if (requireValidProjection && !canProjectAudio(projection)) {
12587             return false;
12588         }
12589 
12590         if (requireModifyRouting
12591                 && !callerHasPermission(MODIFY_AUDIO_ROUTING)) {
12592             Log.e(TAG, "Can not capture audio without MODIFY_AUDIO_ROUTING");
12593             return false;
12594         }
12595 
12596         if (requireCallAudioInterception && !callerHasPermission(CALL_AUDIO_INTERCEPTION)) {
12597             Log.e(TAG, "Can not capture audio without CALL_AUDIO_INTERCEPTION");
12598             return false;
12599         }
12600 
12601         return true;
12602     }
12603 
callerHasPermission(String permission)12604     private boolean callerHasPermission(String permission) {
12605         return mContext.checkCallingOrSelfPermission(permission)
12606                 == PackageManager.PERMISSION_GRANTED;
12607     }
12608 
12609     /** @return true if projection is a valid MediaProjection that can project audio. */
canProjectAudio(IMediaProjection projection)12610     private boolean canProjectAudio(IMediaProjection projection) {
12611         if (projection == null) {
12612             Log.e(TAG, "MediaProjection is null");
12613             return false;
12614         }
12615 
12616         IMediaProjectionManager projectionService = getProjectionService();
12617         if (projectionService == null) {
12618             Log.e(TAG, "Can't get service IMediaProjectionManager");
12619             return false;
12620         }
12621 
12622         final long token = Binder.clearCallingIdentity();
12623         try {
12624             if (!projectionService.isCurrentProjection(projection)) {
12625                 Log.w(TAG, "App passed invalid MediaProjection token");
12626                 return false;
12627             }
12628         } catch (RemoteException e) {
12629             Log.e(TAG, "Can't call .isCurrentProjection() on IMediaProjectionManager"
12630                     + projectionService.asBinder(), e);
12631             return false;
12632         } finally {
12633             Binder.restoreCallingIdentity(token);
12634         }
12635 
12636         try {
12637             if (!projection.canProjectAudio()) {
12638                 Log.w(TAG, "App passed MediaProjection that can not project audio");
12639                 return false;
12640             }
12641         } catch (RemoteException e) {
12642             Log.e(TAG, "Can't call .canProjectAudio() on valid IMediaProjection"
12643                     + projection.asBinder(), e);
12644             return false;
12645         }
12646 
12647         return true;
12648     }
12649 
getProjectionService()12650     private IMediaProjectionManager getProjectionService() {
12651         if (mProjectionService == null) {
12652             IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE);
12653             mProjectionService = IMediaProjectionManager.Stub.asInterface(b);
12654         }
12655         return mProjectionService;
12656     }
12657 
12658     /**
12659      * See {@link AudioManager#unregisterAudioPolicyAsync(AudioPolicy)}
12660      * Declared oneway
12661      * @param pcb nullable because on service interface
12662      */
unregisterAudioPolicyAsync(@ullable IAudioPolicyCallback pcb)12663     public void unregisterAudioPolicyAsync(@Nullable IAudioPolicyCallback pcb) {
12664         if (pcb == null) {
12665             return;
12666         }
12667         unregisterAudioPolicyInt(pcb, "unregisterAudioPolicyAsync");
12668     }
12669 
12670     /**
12671      * See {@link AudioManager#unregisterAudioPolicy(AudioPolicy)}
12672      * @param pcb nullable because on service interface
12673      */
unregisterAudioPolicy(@ullable IAudioPolicyCallback pcb)12674     public void unregisterAudioPolicy(@Nullable IAudioPolicyCallback pcb) {
12675         if (pcb == null) {
12676             return;
12677         }
12678         unregisterAudioPolicyInt(pcb, "unregisterAudioPolicy");
12679     }
12680 
12681 
unregisterAudioPolicyInt(@onNull IAudioPolicyCallback pcb, String operationName)12682     private void unregisterAudioPolicyInt(@NonNull IAudioPolicyCallback pcb, String operationName) {
12683         mDynPolicyLogger.enqueue((new EventLogger.StringEvent(operationName + " for "
12684                 + pcb.asBinder()).printLog(TAG)));
12685         synchronized (mAudioPolicies) {
12686             AudioPolicyProxy app = mAudioPolicies.remove(pcb.asBinder());
12687             if (app == null) {
12688                 Slog.w(TAG, "Trying to unregister unknown audio policy for pid "
12689                         + Binder.getCallingPid() + " / uid " + Binder.getCallingUid());
12690                 return;
12691             } else {
12692                 pcb.asBinder().unlinkToDeath(app, 0/*flags*/);
12693             }
12694             app.release();
12695         }
12696         // TODO implement clearing mix attribute matching info in native audio policy
12697     }
12698 
12699     /**
12700      * Checks whether caller has MODIFY_AUDIO_ROUTING permission, and the policy is registered.
12701      * @param errorMsg log warning if permission check failed.
12702      * @return null if the operation on the audio mixes should be cancelled.
12703      */
12704     @GuardedBy("mAudioPolicies")
checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg)12705     private AudioPolicyProxy checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg) {
12706         // permission check
12707         final boolean hasPermissionForPolicy =
12708                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
12709                         MODIFY_AUDIO_ROUTING));
12710         if (!hasPermissionForPolicy) {
12711             Slog.w(TAG, errorMsg + " for pid " +
12712                     + Binder.getCallingPid() + " / uid "
12713                     + Binder.getCallingUid() + ", need MODIFY_AUDIO_ROUTING");
12714             return null;
12715         }
12716         // policy registered?
12717         final AudioPolicyProxy app = mAudioPolicies.get(pcb.asBinder());
12718         if (app == null) {
12719             Slog.w(TAG, errorMsg + " for pid " +
12720                     + Binder.getCallingPid() + " / uid "
12721                     + Binder.getCallingUid() + ", unregistered policy");
12722             return null;
12723         }
12724         return app;
12725     }
12726 
12727     /**
12728      * Retrieves all audioMixes registered with the AudioPolicyManager
12729      * @return list of registered audio mixes
12730      */
getRegisteredPolicyMixes()12731     public List<AudioMix> getRegisteredPolicyMixes() {
12732         if (!android.media.audiopolicy.Flags.audioMixTestApi()) {
12733             return Collections.emptyList();
12734         }
12735 
12736         synchronized (mAudioPolicies) {
12737             return mAudioSystem.getRegisteredPolicyMixes();
12738         }
12739     }
12740 
addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)12741     public int addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) {
12742         if (DEBUG_AP) { Log.d(TAG, "addMixForPolicy for " + pcb.asBinder()
12743                 + " with config:" + policyConfig); }
12744         synchronized (mAudioPolicies) {
12745             final AudioPolicyProxy app =
12746                     checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy");
12747             if (app == null){
12748                 return AudioManager.ERROR;
12749             }
12750             return app.addMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS
12751                 ? AudioManager.SUCCESS : AudioManager.ERROR;
12752         }
12753     }
12754 
removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)12755     public int removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) {
12756         if (DEBUG_AP) { Log.d(TAG, "removeMixForPolicy for " + pcb.asBinder()
12757                 + " with config:" + policyConfig); }
12758         synchronized (mAudioPolicies) {
12759             final AudioPolicyProxy app =
12760                     checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy");
12761             if (app == null) {
12762                 return AudioManager.ERROR;
12763             }
12764             if (android.media.audiopolicy.Flags.audioMixOwnership()) {
12765                 for (AudioMix mix : policyConfig.getMixes()) {
12766                     if (!app.getMixes().contains(mix)) {
12767                         Slog.e(TAG,
12768                                 "removeMixForPolicy attempted to unregister AudioMix(es) not "
12769                                         + "belonging to the AudioPolicy");
12770                         return AudioManager.ERROR;
12771                     }
12772                 }
12773             }
12774             return app.removeMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS
12775                 ? AudioManager.SUCCESS : AudioManager.ERROR;
12776         }
12777     }
12778 
12779     /**
12780      * Update {@link AudioMixingRule}-s for already registered {@link AudioMix}-es.
12781      *
12782      * @param mixesToUpdate - array of already registered {@link AudioMix}-es to update.
12783      * @param updatedMixingRules - array of {@link AudioMixingRule}-s corresponding to
12784      *                           {@code mixesToUpdate} mixes. The array must be same size as
12785      *                           {@code mixesToUpdate} and i-th {@link AudioMixingRule} must
12786      *                           correspond to i-th {@link AudioMix} from mixesToUpdate array.
12787      * @param pcb - {@link IAudioPolicyCallback} corresponding to the registered
12788      *              {@link AudioPolicy} all {@link AudioMix}-es for {@code mixesToUpdate}
12789      *              are part of.
12790      * @return {@link AudioManager#SUCCESS} iff the mixing rules were updated successfully,
12791      *     {@link AudioManager#ERROR} otherwise.
12792      */
12793     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
updateMixingRulesForPolicy( @onNull AudioMix[] mixesToUpdate, @NonNull AudioMixingRule[] updatedMixingRules, @NonNull IAudioPolicyCallback pcb)12794     public int updateMixingRulesForPolicy(
12795             @NonNull AudioMix[] mixesToUpdate,
12796             @NonNull AudioMixingRule[] updatedMixingRules,
12797             @NonNull IAudioPolicyCallback pcb) {
12798         super.updateMixingRulesForPolicy_enforcePermission();
12799         Objects.requireNonNull(mixesToUpdate);
12800         Objects.requireNonNull(updatedMixingRules);
12801         Objects.requireNonNull(pcb);
12802         if (mixesToUpdate.length != updatedMixingRules.length) {
12803             Log.e(TAG, "Provided list of audio mixes to update and corresponding mixing rules "
12804                     + "have mismatching length (mixesToUpdate.length = " + mixesToUpdate.length
12805                     + ", updatedMixingRules.length = " + updatedMixingRules.length +  ").");
12806             return AudioManager.ERROR;
12807         }
12808         if (DEBUG_AP) {
12809             Log.d(TAG, "updateMixingRules for " + pcb.asBinder() + "with mix rules: ");
12810         }
12811         synchronized (mAudioPolicies) {
12812             final AudioPolicyProxy app =
12813                     checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy");
12814             if (app == null) {
12815                 return AudioManager.ERROR;
12816             }
12817             return app.updateMixingRules(mixesToUpdate, updatedMixingRules) == AudioSystem.SUCCESS
12818                     ? AudioManager.SUCCESS : AudioManager.ERROR;
12819         }
12820     }
12821 
12822     /** see AudioPolicy.setUidDeviceAffinity() */
setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)12823     public int setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid,
12824             @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) {
12825         if (DEBUG_AP) {
12826             Log.d(TAG, "setUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid);
12827         }
12828         synchronized (mAudioPolicies) {
12829             final AudioPolicyProxy app =
12830                     checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy");
12831             if (app == null) {
12832                 return AudioManager.ERROR;
12833             }
12834             if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) {
12835                 return AudioManager.ERROR;
12836             }
12837             return app.setUidDeviceAffinities(uid, deviceTypes, deviceAddresses);
12838         }
12839     }
12840 
12841     /** see AudioPolicy.setUserIdDeviceAffinity() */
setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)12842     public int setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId,
12843             @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) {
12844         if (DEBUG_AP) {
12845             Log.d(TAG, "setUserIdDeviceAffinity for " + pcb.asBinder() + " user:" + userId);
12846         }
12847 
12848         synchronized (mAudioPolicies) {
12849             final AudioPolicyProxy app =
12850                     checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy");
12851             if (app == null) {
12852                 return AudioManager.ERROR;
12853             }
12854             if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) {
12855                 return AudioManager.ERROR;
12856             }
12857             return app.setUserIdDeviceAffinities(userId, deviceTypes, deviceAddresses);
12858         }
12859     }
12860 
12861     /** see AudioPolicy.removeUidDeviceAffinity() */
removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid)12862     public int removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid) {
12863         if (DEBUG_AP) {
12864             Log.d(TAG, "removeUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid);
12865         }
12866         synchronized (mAudioPolicies) {
12867             final AudioPolicyProxy app =
12868                     checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy");
12869             if (app == null) {
12870                 return AudioManager.ERROR;
12871             }
12872             return app.removeUidDeviceAffinities(uid);
12873         }
12874     }
12875 
12876     /** see AudioPolicy.removeUserIdDeviceAffinity() */
removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId)12877     public int removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId) {
12878         if (DEBUG_AP) {
12879             Log.d(TAG, "removeUserIdDeviceAffinity for " + pcb.asBinder()
12880                     + " userId:" + userId);
12881         }
12882         synchronized (mAudioPolicies) {
12883             final AudioPolicyProxy app =
12884                     checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy");
12885             if (app == null) {
12886                 return AudioManager.ERROR;
12887             }
12888             return app.removeUserIdDeviceAffinities(userId);
12889         }
12890     }
12891 
setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb)12892     public int setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb) {
12893         if (DEBUG_AP) Log.d(TAG, "setFocusPropertiesForPolicy() duck behavior=" + duckingBehavior
12894                 + " policy " +  pcb.asBinder());
12895         synchronized (mAudioPolicies) {
12896             final AudioPolicyProxy app =
12897                     checkUpdateForPolicy(pcb, "Cannot change audio policy focus properties");
12898             if (app == null){
12899                 return AudioManager.ERROR;
12900             }
12901             if (!mAudioPolicies.containsKey(pcb.asBinder())) {
12902                 Slog.e(TAG, "Cannot change audio policy focus properties, unregistered policy");
12903                 return AudioManager.ERROR;
12904             }
12905             if (duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) {
12906                 // is there already one policy managing ducking?
12907                 for (AudioPolicyProxy policy : mAudioPolicies.values()) {
12908                     if (policy.mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) {
12909                         Slog.e(TAG, "Cannot change audio policy ducking behavior, already handled");
12910                         return AudioManager.ERROR;
12911                     }
12912                 }
12913             }
12914             app.mFocusDuckBehavior = duckingBehavior;
12915             mMediaFocusControl.setDuckingInExtPolicyAvailable(
12916                     duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY);
12917         }
12918         return AudioManager.SUCCESS;
12919     }
12920 
12921     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
12922     /** @see AudioPolicy#getFocusStack() */
getFocusStack()12923     public List<AudioFocusInfo> getFocusStack() {
12924         super.getFocusStack_enforcePermission();
12925 
12926         return mMediaFocusControl.getFocusStack();
12927     }
12928 
12929     /** @see AudioPolicy#sendFocusLoss */
sendFocusLoss(@onNull AudioFocusInfo focusLoser, @NonNull IAudioPolicyCallback apcb)12930     public boolean sendFocusLoss(@NonNull AudioFocusInfo focusLoser,
12931             @NonNull IAudioPolicyCallback apcb) {
12932         Objects.requireNonNull(focusLoser);
12933         Objects.requireNonNull(apcb);
12934         enforceModifyAudioRoutingPermission();
12935         if (!mAudioPolicies.containsKey(apcb.asBinder())) {
12936             throw new IllegalStateException("Only registered AudioPolicy can change focus");
12937         }
12938         if (!mAudioPolicies.get(apcb.asBinder()).mHasFocusListener) {
12939             throw new IllegalStateException("AudioPolicy must have focus listener to change focus");
12940         }
12941         return mMediaFocusControl.sendFocusLoss(focusLoser);
12942     }
12943 
12944     /**
12945      * see {@link AudioPolicy#setFadeManagerConfigurationForFocusLoss(FadeManagerConfiguration)}
12946      */
12947     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setFadeManagerConfigurationForFocusLoss( @onNull FadeManagerConfiguration fmcForFocusLoss)12948     public int setFadeManagerConfigurationForFocusLoss(
12949             @NonNull FadeManagerConfiguration fmcForFocusLoss) {
12950         super.setFadeManagerConfigurationForFocusLoss_enforcePermission();
12951         ensureFadeManagerConfigIsEnabled();
12952         Objects.requireNonNull(fmcForFocusLoss,
12953                 "Fade manager config for focus loss cannot be null");
12954         validateFadeManagerConfiguration(fmcForFocusLoss);
12955 
12956         return mPlaybackMonitor.setFadeManagerConfiguration(AudioManager.AUDIOFOCUS_LOSS,
12957                 fmcForFocusLoss);
12958     }
12959 
12960     /**
12961      * see {@link AudioPolicy#clearFadeManagerConfigurationForFocusLoss()}
12962      */
12963     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
clearFadeManagerConfigurationForFocusLoss()12964     public int clearFadeManagerConfigurationForFocusLoss() {
12965         super.clearFadeManagerConfigurationForFocusLoss_enforcePermission();
12966         ensureFadeManagerConfigIsEnabled();
12967 
12968         return mPlaybackMonitor.clearFadeManagerConfiguration(AudioManager.AUDIOFOCUS_LOSS);
12969     }
12970 
12971     /**
12972      * see {@link AudioPolicy#getFadeManagerConfigurationForFocusLoss()}
12973      */
12974     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
getFadeManagerConfigurationForFocusLoss()12975     public FadeManagerConfiguration getFadeManagerConfigurationForFocusLoss() {
12976         super.getFadeManagerConfigurationForFocusLoss_enforcePermission();
12977         ensureFadeManagerConfigIsEnabled();
12978 
12979         return mPlaybackMonitor.getFadeManagerConfiguration(AudioManager.AUDIOFOCUS_LOSS);
12980     }
12981 
12982     /**
12983      * @see AudioManager#getHalVersion
12984      */
getHalVersion()12985     public @Nullable AudioHalVersionInfo getHalVersion() {
12986         for (AudioHalVersionInfo version : AudioHalVersionInfo.VERSIONS) {
12987             try {
12988                 String versionStr = version.getMajorVersion() + "." + version.getMinorVersion();
12989                 final String aidlStr = "android.hardware.audio.core.IModule/default";
12990                 final String hidlStr = String.format("android.hardware.audio@%s::IDevicesFactory",
12991                         versionStr);
12992                 if (null != ServiceManager.checkService(aidlStr)) {
12993                     return version;
12994                 } else {
12995                     HwBinder.getService(hidlStr, "default");
12996                     return version;
12997                 }
12998             } catch (NoSuchElementException e) {
12999                 // Ignore, the specified HAL interface is not found.
13000             } catch (RemoteException re) {
13001                 Log.e(TAG, "Remote exception when getting hardware audio service:", re);
13002             }
13003         }
13004         return null;
13005     }
13006 
13007     /** see AudioManager.hasRegisteredDynamicPolicy */
hasRegisteredDynamicPolicy()13008     public boolean hasRegisteredDynamicPolicy() {
13009         synchronized (mAudioPolicies) {
13010             return !mAudioPolicies.isEmpty();
13011         }
13012     }
13013 
13014     /**
13015      * @see AudioManager#setPreferredMixerAttributes(
13016      *      AudioAttributes, AudioDeviceInfo, AudioMixerAttributes)
13017      */
setPreferredMixerAttributes(AudioAttributes attributes, int portId, AudioMixerAttributes mixerAttributes)13018     public int setPreferredMixerAttributes(AudioAttributes attributes,
13019             int portId, AudioMixerAttributes mixerAttributes) {
13020         Objects.requireNonNull(attributes);
13021         Objects.requireNonNull(mixerAttributes);
13022         if (!checkAudioSettingsPermission("setPreferredMixerAttributes()")) {
13023             return AudioSystem.PERMISSION_DENIED;
13024         }
13025         final int uid = Binder.getCallingUid();
13026         final int pid = Binder.getCallingPid();
13027         int status = AudioSystem.SUCCESS;
13028         final long token = Binder.clearCallingIdentity();
13029         try {
13030             final String logString = TextUtils.formatSimple(
13031                     "setPreferredMixerAttributes u/pid:%d/%d attr:%s mixerAttributes:%s portId:%d",
13032                     uid, pid, attributes.toString(), mixerAttributes.toString(), portId);
13033             sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
13034 
13035             status = mAudioSystem.setPreferredMixerAttributes(
13036                     attributes, portId, uid, mixerAttributes);
13037             if (status == AudioSystem.SUCCESS) {
13038                 dispatchPreferredMixerAttributesChanged(attributes, portId, mixerAttributes);
13039             } else {
13040                 Log.e(TAG, TextUtils.formatSimple("Error %d in %s)", status, logString));
13041             }
13042         } finally {
13043             Binder.restoreCallingIdentity(token);
13044         }
13045         return status;
13046     }
13047 
13048     /**
13049      * @see AudioManager#clearPreferredMixerAttributes(AudioAttributes, AudioDeviceInfo)
13050      */
clearPreferredMixerAttributes(AudioAttributes attributes, int portId)13051     public int clearPreferredMixerAttributes(AudioAttributes attributes, int portId) {
13052         Objects.requireNonNull(attributes);
13053         if (!checkAudioSettingsPermission("clearPreferredMixerAttributes()")) {
13054             return AudioSystem.PERMISSION_DENIED;
13055         }
13056         final int uid = Binder.getCallingUid();
13057         final int pid = Binder.getCallingPid();
13058         int status = AudioSystem.SUCCESS;
13059         final long token = Binder.clearCallingIdentity();
13060         try {
13061             final String logString = TextUtils.formatSimple(
13062                     "clearPreferredMixerAttributes u/pid:%d/%d attr:%s",
13063                     uid, pid, attributes.toString());
13064             sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
13065 
13066             status = mAudioSystem.clearPreferredMixerAttributes(attributes, portId, uid);
13067             if (status == AudioSystem.SUCCESS) {
13068                 dispatchPreferredMixerAttributesChanged(attributes, portId, null /*mixerAttr*/);
13069             } else {
13070                 Log.e(TAG, TextUtils.formatSimple("Error %d in %s)", status, logString));
13071             }
13072         } finally {
13073             Binder.restoreCallingIdentity(token);
13074         }
13075         return status;
13076     }
13077 
dispatchPreferredMixerAttributesChanged( AudioAttributes attr, int deviceId, AudioMixerAttributes mixerAttr)13078     void dispatchPreferredMixerAttributesChanged(
13079             AudioAttributes attr, int deviceId, AudioMixerAttributes mixerAttr) {
13080         Bundle bundle = new Bundle();
13081         bundle.putParcelable(KEY_AUDIO_ATTRIBUTES, attr);
13082         bundle.putParcelable(KEY_AUDIO_MIXER_ATTRIBUTES, mixerAttr);
13083         sendBundleMsg(mAudioHandler, MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES, SENDMSG_QUEUE,
13084                 deviceId, 0, null, bundle, 0);
13085     }
13086 
13087     final RemoteCallbackList<IPreferredMixerAttributesDispatcher> mPrefMixerAttrDispatcher =
13088             new RemoteCallbackList<IPreferredMixerAttributesDispatcher>();
13089     private static final String KEY_AUDIO_ATTRIBUTES = "audio_attributes";
13090     private static final String KEY_AUDIO_MIXER_ATTRIBUTES = "audio_mixer_attributes";
13091 
13092     /** @see AudioManager#addOnPreferredMixerAttributesChangedListener(
13093      *       Executor, AudioManager.OnPreferredMixerAttributesChangedListener)
13094      */
registerPreferredMixerAttributesDispatcher( @ullable IPreferredMixerAttributesDispatcher dispatcher)13095     public void registerPreferredMixerAttributesDispatcher(
13096             @Nullable IPreferredMixerAttributesDispatcher dispatcher) {
13097         if (dispatcher == null) {
13098             return;
13099         }
13100         mPrefMixerAttrDispatcher.register(dispatcher);
13101     }
13102 
13103     /** @see AudioManager#removeOnPreferredMixerAttributesChangedListener(
13104      *       AudioManager.OnPreferredMixerAttributesChangedListener)
13105      */
unregisterPreferredMixerAttributesDispatcher( @ullable IPreferredMixerAttributesDispatcher dispatcher)13106     public void unregisterPreferredMixerAttributesDispatcher(
13107             @Nullable IPreferredMixerAttributesDispatcher dispatcher) {
13108         if (dispatcher == null) {
13109             return;
13110         }
13111         mPrefMixerAttrDispatcher.unregister(dispatcher);
13112     }
13113 
onDispatchPreferredMixerAttributesChanged(Bundle data, int deviceId)13114     protected void onDispatchPreferredMixerAttributesChanged(Bundle data, int deviceId) {
13115         final int nbDispathers = mPrefMixerAttrDispatcher.beginBroadcast();
13116         final AudioAttributes attr = data.getParcelable(
13117                 KEY_AUDIO_ATTRIBUTES, AudioAttributes.class);
13118         final AudioMixerAttributes mixerAttr = data.getParcelable(
13119                 KEY_AUDIO_MIXER_ATTRIBUTES, AudioMixerAttributes.class);
13120         for (int i = 0; i < nbDispathers; i++) {
13121             try {
13122                 mPrefMixerAttrDispatcher.getBroadcastItem(i)
13123                         .dispatchPrefMixerAttributesChanged(attr, deviceId, mixerAttr);
13124             } catch (RemoteException e) {
13125                 Log.e(TAG, "Can't call dispatchPrefMixerAttributesChanged() "
13126                         + "IPreferredMixerAttributesDispatcher "
13127                         + mPrefMixerAttrDispatcher.getBroadcastItem(i).asBinder(), e);
13128             }
13129         }
13130         mPrefMixerAttrDispatcher.finishBroadcast();
13131     }
13132 
13133 
13134     /** @see AudioManager#supportsBluetoothVariableLatency() */
13135     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
supportsBluetoothVariableLatency()13136     public boolean supportsBluetoothVariableLatency() {
13137         super.supportsBluetoothVariableLatency_enforcePermission();
13138         try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
13139             return AudioSystem.supportsBluetoothVariableLatency();
13140         }
13141     }
13142 
13143     /** @see AudioManager#setBluetoothVariableLatencyEnabled(boolean) */
13144     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
setBluetoothVariableLatencyEnabled(boolean enabled)13145     public void setBluetoothVariableLatencyEnabled(boolean enabled) {
13146         super.setBluetoothVariableLatencyEnabled_enforcePermission();
13147         try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
13148             AudioSystem.setBluetoothVariableLatencyEnabled(enabled);
13149         }
13150     }
13151 
13152     /** @see AudioManager#isBluetoothVariableLatencyEnabled(boolean) */
13153     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
isBluetoothVariableLatencyEnabled()13154     public boolean isBluetoothVariableLatencyEnabled() {
13155         super.isBluetoothVariableLatencyEnabled_enforcePermission();
13156         try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
13157             return AudioSystem.isBluetoothVariableLatencyEnabled();
13158         }
13159     }
13160 
13161     private final Object mExtVolumeControllerLock = new Object();
13162     private IAudioPolicyCallback mExtVolumeController;
setExtVolumeController(IAudioPolicyCallback apc)13163     private void setExtVolumeController(IAudioPolicyCallback apc) {
13164         if (!mContext.getResources().getBoolean(
13165                 com.android.internal.R.bool.config_handleVolumeKeysInWindowManager)) {
13166             Log.e(TAG, "Cannot set external volume controller: device not set for volume keys" +
13167                     " handled in PhoneWindowManager");
13168             return;
13169         }
13170         synchronized (mExtVolumeControllerLock) {
13171             if (mExtVolumeController != null && !mExtVolumeController.asBinder().pingBinder()) {
13172                 Log.e(TAG, "Cannot set external volume controller: existing controller");
13173             }
13174             mExtVolumeController = apc;
13175         }
13176     }
13177 
dumpAudioPolicies(PrintWriter pw)13178     private void dumpAudioPolicies(PrintWriter pw) {
13179         pw.println("\nAudio policies:");
13180         synchronized (mAudioPolicies) {
13181             for (AudioPolicyProxy policy : mAudioPolicies.values()) {
13182                 pw.println(policy.toLogFriendlyString());
13183             }
13184         }
13185     }
13186 
ensureFadeManagerConfigIsEnabled()13187     private void ensureFadeManagerConfigIsEnabled() {
13188         Preconditions.checkState(enableFadeManagerConfiguration(),
13189                 "Fade manager configuration not supported");
13190     }
13191 
validateFadeManagerConfiguration(FadeManagerConfiguration fmc)13192     private void validateFadeManagerConfiguration(FadeManagerConfiguration fmc) {
13193         // validate permission of audio attributes
13194         List<AudioAttributes> attrs = fmc.getAudioAttributesWithVolumeShaperConfigs();
13195         for (int index = 0; index < attrs.size(); index++) {
13196             validateAudioAttributesUsage(attrs.get(index));
13197         }
13198     }
13199 
13200     //======================
13201     // Audio policy callbacks from AudioSystem for dynamic policies
13202     //======================
13203     private final AudioSystem.DynamicPolicyCallback mDynPolicyCallback =
13204             new AudioSystem.DynamicPolicyCallback() {
13205         public void onDynamicPolicyMixStateUpdate(String regId, int state) {
13206             if (!TextUtils.isEmpty(regId)) {
13207                 sendMsg(mAudioHandler, MSG_DYN_POLICY_MIX_STATE_UPDATE, SENDMSG_QUEUE,
13208                         state /*arg1*/, 0 /*arg2 ignored*/, regId /*obj*/, 0 /*delay*/);
13209             }
13210         }
13211     };
13212 
onDynPolicyMixStateUpdate(String regId, int state)13213     private void onDynPolicyMixStateUpdate(String regId, int state) {
13214         if (DEBUG_AP) Log.d(TAG, "onDynamicPolicyMixStateUpdate("+ regId + ", " + state +")");
13215         synchronized (mAudioPolicies) {
13216             for (AudioPolicyProxy policy : mAudioPolicies.values()) {
13217                 for (AudioMix mix : policy.getMixes()) {
13218                     if (mix.getRegistration().equals(regId)) {
13219                         try {
13220                             policy.mPolicyCallback.notifyMixStateUpdate(regId, state);
13221                         } catch (RemoteException e) {
13222                             Log.e(TAG, "Can't call notifyMixStateUpdate() on IAudioPolicyCallback "
13223                                     + policy.mPolicyCallback.asBinder(), e);
13224                         }
13225                         return;
13226                     }
13227                 }
13228             }
13229         }
13230     }
13231 
13232     //======================
13233     // Audio policy callbacks from AudioSystem for recording configuration updates
13234     //======================
13235     private final RecordingActivityMonitor mRecordMonitor;
13236 
registerRecordingCallback(IRecordingConfigDispatcher rcdb)13237     public void registerRecordingCallback(IRecordingConfigDispatcher rcdb) {
13238         final boolean isPrivileged =
13239                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
13240                         MODIFY_AUDIO_ROUTING));
13241         mRecordMonitor.registerRecordingCallback(rcdb, isPrivileged);
13242     }
13243 
unregisterRecordingCallback(IRecordingConfigDispatcher rcdb)13244     public void unregisterRecordingCallback(IRecordingConfigDispatcher rcdb) {
13245         mRecordMonitor.unregisterRecordingCallback(rcdb);
13246     }
13247 
getActiveRecordingConfigurations()13248     public List<AudioRecordingConfiguration> getActiveRecordingConfigurations() {
13249         final boolean isPrivileged = Binder.getCallingUid() == Process.SYSTEM_UID
13250                 || (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
13251                         MODIFY_AUDIO_ROUTING));
13252         return mRecordMonitor.getActiveRecordingConfigurations(isPrivileged);
13253     }
13254 
13255     //======================
13256     // Audio recording state notification from clients
13257     //======================
13258     /**
13259      * Track a recorder provided by the client
13260      */
trackRecorder(IBinder recorder)13261     public int trackRecorder(IBinder recorder) {
13262         return mRecordMonitor.trackRecorder(recorder);
13263     }
13264 
13265     /**
13266      * Receive an event from the client about a tracked recorder
13267      */
recorderEvent(int riid, int event)13268     public void recorderEvent(int riid, int event) {
13269         mRecordMonitor.recorderEvent(riid, event);
13270     }
13271 
13272     /**
13273      * Stop tracking the recorder
13274      */
releaseRecorder(int riid)13275     public void releaseRecorder(int riid) {
13276         mRecordMonitor.releaseRecorder(riid);
13277     }
13278 
13279     //======================
13280     // Audio playback notification
13281     //======================
13282     private final PlaybackActivityMonitor mPlaybackMonitor;
13283 
registerPlaybackCallback(IPlaybackConfigDispatcher pcdb)13284     public void registerPlaybackCallback(IPlaybackConfigDispatcher pcdb) {
13285         final boolean isPrivileged =
13286                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
13287                         MODIFY_AUDIO_ROUTING));
13288         mPlaybackMonitor.registerPlaybackCallback(pcdb, isPrivileged);
13289     }
13290 
unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb)13291     public void unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb) {
13292         mPlaybackMonitor.unregisterPlaybackCallback(pcdb);
13293     }
13294 
getActivePlaybackConfigurations()13295     public List<AudioPlaybackConfiguration> getActivePlaybackConfigurations() {
13296         final boolean isPrivileged =
13297                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
13298                         MODIFY_AUDIO_ROUTING));
13299         return mPlaybackMonitor.getActivePlaybackConfigurations(isPrivileged);
13300     }
13301 
trackPlayer(PlayerBase.PlayerIdCard pic)13302     public int trackPlayer(PlayerBase.PlayerIdCard pic) {
13303         if (pic != null && pic.mAttributes != null) {
13304             validateAudioAttributesUsage(pic.mAttributes);
13305         }
13306         return mPlaybackMonitor.trackPlayer(pic);
13307     }
13308 
playerAttributes(int piid, AudioAttributes attr)13309     public void playerAttributes(int piid, AudioAttributes attr) {
13310         if (attr != null) {
13311             validateAudioAttributesUsage(attr);
13312         }
13313         mPlaybackMonitor.playerAttributes(piid, attr, Binder.getCallingUid());
13314     }
13315 
13316     /**
13317      * Update player session ID
13318      * @param piid Player id to update
13319      * @param sessionId The new audio session ID
13320      */
playerSessionId(int piid, int sessionId)13321     public void playerSessionId(int piid, int sessionId) {
13322         if (sessionId <= AudioSystem.AUDIO_SESSION_ALLOCATE) {
13323             throw new IllegalArgumentException("invalid session Id " + sessionId);
13324         }
13325         mPlaybackMonitor.playerSessionId(piid, sessionId, Binder.getCallingUid());
13326     }
13327 
13328     /**
13329      * Update player event
13330      * @param piid Player id to update
13331      * @param event The new player event
13332      * @param eventValue The value associated with this event
13333      */
playerEvent(int piid, int event, int eventValue)13334     public void playerEvent(int piid, int event, int eventValue) {
13335         mPlaybackMonitor.playerEvent(piid, event, eventValue, Binder.getCallingUid());
13336     }
13337 
13338     /**
13339      * Update event for port id
13340      * @param portId Port id to update
13341      * @param event The new event for the given port
13342      * @param extras Bundle of extra values to describe the event
13343      */
portEvent(int portId, int event, @Nullable PersistableBundle extras)13344     public void portEvent(int portId, int event, @Nullable PersistableBundle extras) {
13345         mPlaybackMonitor.portEvent(portId, event, extras, Binder.getCallingUid());
13346     }
13347 
playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio)13348     public void playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio) {
13349         mPlaybackMonitor.playerHasOpPlayAudio(piid, hasOpPlayAudio, Binder.getCallingUid());
13350     }
13351 
releasePlayer(int piid)13352     public void releasePlayer(int piid) {
13353         mPlaybackMonitor.releasePlayer(piid, Binder.getCallingUid());
13354     }
13355 
13356     /**
13357      * Specifies whether the audio played by this app may or may not be captured by other apps or
13358      * the system.
13359      *
13360      * @param capturePolicy one of
13361      *     {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL},
13362      *     {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM},
13363      *     {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}.
13364      * @return AudioSystem.AUDIO_STATUS_OK if set allowed capture policy succeed.
13365      * @throws IllegalArgumentException if the argument is not a valid value.
13366      */
setAllowedCapturePolicy(int capturePolicy)13367     public int setAllowedCapturePolicy(int capturePolicy) {
13368         int callingUid = Binder.getCallingUid();
13369         int flags = AudioAttributes.capturePolicyToFlags(capturePolicy, 0x0);
13370         final long identity = Binder.clearCallingIdentity();
13371         try {
13372             synchronized (mPlaybackMonitor) {
13373                 int result = mAudioSystem.setAllowedCapturePolicy(callingUid, flags);
13374                 if (result == AudioSystem.AUDIO_STATUS_OK) {
13375                     mPlaybackMonitor.setAllowedCapturePolicy(callingUid, capturePolicy);
13376                 }
13377                 return result;
13378             }
13379         } finally {
13380             Binder.restoreCallingIdentity(identity);
13381         }
13382     }
13383 
13384     /**
13385      * Return the capture policy.
13386      * @return the cached capture policy for the calling uid.
13387      */
getAllowedCapturePolicy()13388     public int getAllowedCapturePolicy() {
13389         int callingUid = Binder.getCallingUid();
13390         final long identity = Binder.clearCallingIdentity();
13391         try {
13392             return mPlaybackMonitor.getAllowedCapturePolicy(callingUid);
13393         } finally {
13394             Binder.restoreCallingIdentity(identity);
13395         }
13396     }
13397 
13398     /* package */
isPlaybackActiveForUid(int uid)13399     boolean isPlaybackActiveForUid(int uid) {
13400         return mPlaybackMonitor.isPlaybackActiveForUid(uid);
13401     }
13402 
13403     /* package */
isRecordingActiveForUid(int uid)13404     boolean isRecordingActiveForUid(int uid) {
13405         return mRecordMonitor.isRecordingActiveForUid(uid);
13406     }
13407 
13408     //======================
13409     // Audio device management
13410     //======================
13411     private final AudioDeviceBroker mDeviceBroker;
13412 
13413     //======================
13414     // Audio policy proxy
13415     //======================
13416     private static final class AudioDeviceArray {
13417         final @NonNull int[] mDeviceTypes;
13418         final @NonNull String[] mDeviceAddresses;
AudioDeviceArray(@onNull int[] types, @NonNull String[] addresses)13419         AudioDeviceArray(@NonNull int[] types,  @NonNull String[] addresses) {
13420             mDeviceTypes = types;
13421             mDeviceAddresses = addresses;
13422         }
13423     }
13424 
13425     /**
13426      * This internal class inherits from AudioPolicyConfig, each instance contains all the
13427      * mixes of an AudioPolicy and their configurations.
13428      */
13429     public class AudioPolicyProxy extends AudioPolicyConfig implements IBinder.DeathRecipient {
13430         private static final String TAG = "AudioPolicyProxy";
13431         final IAudioPolicyCallback mPolicyCallback;
13432         final AttributionSource mAttributionSource;
13433         final boolean mHasFocusListener;
13434         final boolean mIsVolumeController;
13435         final HashMap<Integer, AudioDeviceArray> mUidDeviceAffinities =
13436                 new HashMap<Integer, AudioDeviceArray>();
13437 
13438         final HashMap<Integer, AudioDeviceArray> mUserIdDeviceAffinities =
13439                 new HashMap<>();
13440 
13441         final IMediaProjection mProjection;
13442         private final class UnregisterOnStopCallback extends IMediaProjectionCallback.Stub {
onStop()13443             public void onStop() {
13444                 unregisterAudioPolicyAsync(mPolicyCallback);
13445             }
13446 
13447             @Override
onCapturedContentResize(int width, int height)13448             public void onCapturedContentResize(int width, int height) {
13449                 // Ignore resize of the captured content.
13450             }
13451 
13452             @Override
onCapturedContentVisibilityChanged(boolean isVisible)13453             public void onCapturedContentVisibilityChanged(boolean isVisible) {
13454                 // Ignore visibility changes of the captured content.
13455             }
13456         };
13457         UnregisterOnStopCallback mProjectionCallback;
13458 
13459         /**
13460          * Audio focus ducking behavior for an audio policy.
13461          * This variable reflects the value that was successfully set in
13462          * {@link AudioService#setFocusPropertiesForPolicy(int, IAudioPolicyCallback)}. This
13463          * implies that a value of FOCUS_POLICY_DUCKING_IN_POLICY means the corresponding policy
13464          * is handling ducking for audio focus.
13465          */
13466         int mFocusDuckBehavior = AudioPolicy.FOCUS_POLICY_DUCKING_DEFAULT;
13467         boolean mIsFocusPolicy = false;
13468         boolean mIsTestFocusPolicy = false;
13469 
AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection, AttributionSource attributionSource)13470         AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token,
13471                 boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy,
13472                 boolean isVolumeController, IMediaProjection projection,
13473                 AttributionSource attributionSource) {
13474             super(config);
13475             setRegistration(new String(config.hashCode() + ":ap:" + mAudioPolicyCounter++));
13476             mPolicyCallback = token;
13477             mAttributionSource = attributionSource;
13478             mHasFocusListener = hasFocusListener;
13479             mIsVolumeController = isVolumeController;
13480             mProjection = projection;
13481             if (mHasFocusListener) {
13482                 mMediaFocusControl.addFocusFollower(mPolicyCallback);
13483                 // can only ever be true if there is a focus listener
13484                 if (isFocusPolicy) {
13485                     mIsFocusPolicy = true;
13486                     mIsTestFocusPolicy = isTestFocusPolicy;
13487                     mMediaFocusControl.setFocusPolicy(mPolicyCallback, mIsTestFocusPolicy);
13488                 }
13489             }
13490             if (mIsVolumeController) {
13491                 setExtVolumeController(mPolicyCallback);
13492             }
13493             if (mProjection != null) {
13494                 mProjectionCallback = new UnregisterOnStopCallback();
13495                 try {
13496                     mProjection.registerCallback(mProjectionCallback);
13497                 } catch (RemoteException e) {
13498                     release();
13499                     throw new IllegalStateException("MediaProjection callback registration failed, "
13500                             + "could not link to " + projection + " binder death", e);
13501                 }
13502             }
13503 
13504             int status = connectMixes();
13505             if (status != AudioSystem.SUCCESS) {
13506                 release();
13507                 throw new IllegalStateException("Could not connect mix, error: " + status);
13508             }
13509         }
13510 
binderDied()13511         public void binderDied() {
13512             mDynPolicyLogger.enqueue((new EventLogger.StringEvent("AudioPolicy "
13513                     + mPolicyCallback.asBinder() + " died").printLog(TAG)));
13514 
13515             List<String> addresses = new ArrayList<>();
13516             for (AudioMix mix : mMixes) {
13517                 addresses.add(mix.getRegistration());
13518             }
13519             onPolicyClientDeath(addresses);
13520 
13521             release();
13522         }
13523 
getRegistrationId()13524         String getRegistrationId() {
13525             return getRegistration();
13526         }
13527 
release()13528         void release() {
13529             if (mIsFocusPolicy) {
13530                 mMediaFocusControl.unsetFocusPolicy(mPolicyCallback, mIsTestFocusPolicy);
13531             }
13532             if (mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) {
13533                 mMediaFocusControl.setDuckingInExtPolicyAvailable(false);
13534             }
13535             if (mHasFocusListener) {
13536                 mMediaFocusControl.removeFocusFollower(mPolicyCallback);
13537             }
13538             if (mProjectionCallback != null) {
13539                 try {
13540                     mProjection.unregisterCallback(mProjectionCallback);
13541                 } catch (RemoteException e) {
13542                     Log.e(TAG, "Fail to unregister Audiopolicy callback from MediaProjection");
13543                 }
13544             }
13545             if (mIsVolumeController) {
13546                 synchronized (mExtVolumeControllerLock) {
13547                     mExtVolumeController = null;
13548                 }
13549             }
13550             final long identity = Binder.clearCallingIdentity();
13551             try {
13552                 if (android.media.audiopolicy.Flags.audioMixOwnership()) {
13553                     synchronized (mMixes) {
13554                         removeMixes(new ArrayList(mMixes));
13555                     }
13556                 } else {
13557                     mAudioSystem.registerPolicyMixes(mMixes, false);
13558                 }
13559             } finally {
13560                 Binder.restoreCallingIdentity(identity);
13561             }
13562             synchronized (mAudioPolicies) {
13563                 mAudioPolicies.remove(mPolicyCallback.asBinder());
13564             }
13565             try {
13566                 mPolicyCallback.notifyUnregistration();
13567             } catch (RemoteException e) { }
13568         }
13569 
hasMixAffectingUsage(int usage, int excludedFlags)13570         boolean hasMixAffectingUsage(int usage, int excludedFlags) {
13571             for (AudioMix mix : mMixes) {
13572                 if (mix.isAffectingUsage(usage)
13573                         && ((mix.getRouteFlags() & excludedFlags) != excludedFlags)) {
13574                     return true;
13575                 }
13576             }
13577             return false;
13578         }
13579 
13580         // Verify all the devices in the array are served by mixes defined in this policy
hasMixRoutedToDevices(@onNull int[] deviceTypes, @NonNull String[] deviceAddresses)13581         boolean hasMixRoutedToDevices(@NonNull int[] deviceTypes,
13582                 @NonNull String[] deviceAddresses) {
13583             for (int i = 0; i < deviceTypes.length; i++) {
13584                 boolean hasDevice = false;
13585                 for (AudioMix mix : mMixes) {
13586                     // this will check both that the mix has ROUTE_FLAG_RENDER and the device
13587                     // is reached by this mix
13588                     if (mix.isRoutedToDevice(deviceTypes[i], deviceAddresses[i])) {
13589                         hasDevice = true;
13590                         break;
13591                     }
13592                 }
13593                 if (!hasDevice) {
13594                     return false;
13595                 }
13596             }
13597             return true;
13598         }
13599 
addMixes(@onNull ArrayList<AudioMix> mixes)13600         int addMixes(@NonNull ArrayList<AudioMix> mixes) {
13601             synchronized (mMixes) {
13602                 if (android.media.audiopolicy.Flags.audioMixOwnership()) {
13603                     for (AudioMix mix : mixes) {
13604                         setMixRegistration(mix);
13605                         mix.setVirtualDeviceId(mAttributionSource.getDeviceId());
13606                     }
13607 
13608                     int result = mAudioSystem.registerPolicyMixes(mixes, true);
13609                     if (result == AudioSystem.SUCCESS) {
13610                         this.add(mixes);
13611                     }
13612                     return result;
13613                 }
13614                 this.add(mixes);
13615                 return mAudioSystem.registerPolicyMixes(mixes, true);
13616             }
13617         }
13618 
removeMixes(@onNull ArrayList<AudioMix> mixes)13619         int removeMixes(@NonNull ArrayList<AudioMix> mixes) {
13620             synchronized (mMixes) {
13621                 this.remove(mixes);
13622                 return mAudioSystem.registerPolicyMixes(mixes, false);
13623             }
13624         }
13625 
connectMixes()13626         @AudioSystem.AudioSystemError int connectMixes() {
13627             final long identity = Binder.clearCallingIdentity();
13628             try {
13629                 for (AudioMix mix : mMixes) {
13630                     mix.setVirtualDeviceId(mAttributionSource.getDeviceId());
13631                 }
13632                 return mAudioSystem.registerPolicyMixes(mMixes, true);
13633             } finally {
13634                 Binder.restoreCallingIdentity(identity);
13635             }
13636 
13637         }
13638 
updateMixingRules( @onNull AudioMix[] mixesToUpdate, @NonNull AudioMixingRule[] updatedMixingRules)13639         @AudioSystem.AudioSystemError int updateMixingRules(
13640                                         @NonNull AudioMix[] mixesToUpdate,
13641                                         @NonNull AudioMixingRule[] updatedMixingRules) {
13642             Objects.requireNonNull(mixesToUpdate);
13643             Objects.requireNonNull(updatedMixingRules);
13644 
13645             for (AudioMix mix : mixesToUpdate) {
13646                 mix.setVirtualDeviceId(mAttributionSource.getDeviceId());
13647             }
13648             if (mixesToUpdate.length != updatedMixingRules.length) {
13649                 Log.e(TAG, "Provided list of audio mixes to update and corresponding mixing rules "
13650                         + "have mismatching length (mixesToUpdate.length = " + mixesToUpdate.length
13651                         + ", updatedMixingRules.length = " + updatedMixingRules.length +  ").");
13652                 return AudioSystem.BAD_VALUE;
13653             }
13654 
13655             synchronized (mMixes) {
13656                 try (SafeCloseable unused = ClearCallingIdentityContext.create()) {
13657                     int ret = mAudioSystem.updateMixingRules(mixesToUpdate, updatedMixingRules);
13658                     if (ret == AudioSystem.SUCCESS) {
13659                         for (int i = 0; i < mixesToUpdate.length; i++) {
13660                             AudioMix audioMixToUpdate = mixesToUpdate[i];
13661                             AudioMixingRule audioMixingRule = updatedMixingRules[i];
13662                             mMixes.stream().filter(audioMixToUpdate::equals).findAny().ifPresent(
13663                                     mix -> mix.setAudioMixingRule(audioMixingRule));
13664                         }
13665                     }
13666                     return ret;
13667                 }
13668             }
13669         }
13670 
setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses)13671         int setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses) {
13672             final Integer Uid = new Integer(uid);
13673             if (mUidDeviceAffinities.remove(Uid) != null) {
13674                 if (removeUidDeviceAffinitiesFromSystem(uid) != AudioSystem.SUCCESS) {
13675                     Log.e(TAG, "AudioSystem. removeUidDeviceAffinities(" + uid + ") failed, "
13676                             + " cannot call AudioSystem.setUidDeviceAffinities");
13677                     return AudioManager.ERROR;
13678                 }
13679             }
13680             AudioDeviceArray deviceArray = new AudioDeviceArray(types, addresses);
13681             if (setUidDeviceAffinitiesOnSystem(uid, deviceArray) == AudioSystem.SUCCESS) {
13682                 mUidDeviceAffinities.put(Uid, deviceArray);
13683                 return AudioManager.SUCCESS;
13684             }
13685             Log.e(TAG, "AudioSystem. setUidDeviceAffinities(" + uid + ") failed");
13686             return AudioManager.ERROR;
13687         }
13688 
removeUidDeviceAffinities(int uid)13689         int removeUidDeviceAffinities(int uid) {
13690             if (mUidDeviceAffinities.remove(new Integer(uid)) != null) {
13691                 if (removeUidDeviceAffinitiesFromSystem(uid) == AudioSystem.SUCCESS) {
13692                     return AudioManager.SUCCESS;
13693                 }
13694             }
13695             Log.e(TAG, "AudioSystem. removeUidDeviceAffinities failed");
13696             return AudioManager.ERROR;
13697         }
13698 
removeUidDeviceAffinitiesFromSystem(int uid)13699         @AudioSystem.AudioSystemError private int removeUidDeviceAffinitiesFromSystem(int uid) {
13700             final long identity = Binder.clearCallingIdentity();
13701             try {
13702                 return mAudioSystem.removeUidDeviceAffinities(uid);
13703             } finally {
13704                 Binder.restoreCallingIdentity(identity);
13705             }
13706         }
13707 
setUidDeviceAffinitiesOnSystem(int uid, AudioDeviceArray deviceArray)13708         @AudioSystem.AudioSystemError private int setUidDeviceAffinitiesOnSystem(int uid,
13709                 AudioDeviceArray deviceArray) {
13710             final long identity = Binder.clearCallingIdentity();
13711             try {
13712                 return mAudioSystem.setUidDeviceAffinities(uid, deviceArray.mDeviceTypes,
13713                         deviceArray.mDeviceAddresses);
13714             } finally {
13715                 Binder.restoreCallingIdentity(identity);
13716             }
13717         }
13718 
setUserIdDeviceAffinities(int userId, @NonNull int[] types, @NonNull String[] addresses)13719         int setUserIdDeviceAffinities(int userId,
13720                 @NonNull int[] types, @NonNull String[] addresses) {
13721             final Integer UserId = new Integer(userId);
13722             if (mUserIdDeviceAffinities.remove(UserId) != null) {
13723                 if (removeUserIdDeviceAffinitiesFromSystem(userId) != AudioSystem.SUCCESS) {
13724                     Log.e(TAG, "AudioSystem. removeUserIdDeviceAffinities("
13725                             + UserId + ") failed, "
13726                             + " cannot call AudioSystem.setUserIdDeviceAffinities");
13727                     return AudioManager.ERROR;
13728                 }
13729             }
13730             AudioDeviceArray audioDeviceArray = new AudioDeviceArray(types, addresses);
13731             if (setUserIdDeviceAffinitiesOnSystem(userId, audioDeviceArray)
13732                     == AudioSystem.SUCCESS) {
13733                 mUserIdDeviceAffinities.put(UserId, audioDeviceArray);
13734                 return AudioManager.SUCCESS;
13735             }
13736             Log.e(TAG, "AudioSystem.setUserIdDeviceAffinities(" + userId + ") failed");
13737             return AudioManager.ERROR;
13738         }
13739 
removeUserIdDeviceAffinities(int userId)13740         int removeUserIdDeviceAffinities(int userId) {
13741             if (mUserIdDeviceAffinities.remove(new Integer(userId)) != null) {
13742                 if (removeUserIdDeviceAffinitiesFromSystem(userId) == AudioSystem.SUCCESS) {
13743                     return AudioManager.SUCCESS;
13744                 }
13745             }
13746             Log.e(TAG, "AudioSystem.removeUserIdDeviceAffinities failed");
13747             return AudioManager.ERROR;
13748         }
13749 
removeUserIdDeviceAffinitiesFromSystem( @serIdInt int userId)13750         @AudioSystem.AudioSystemError private int removeUserIdDeviceAffinitiesFromSystem(
13751                 @UserIdInt int userId) {
13752             final long identity = Binder.clearCallingIdentity();
13753             try {
13754                 return mAudioSystem.removeUserIdDeviceAffinities(userId);
13755             } finally {
13756                 Binder.restoreCallingIdentity(identity);
13757             }
13758         }
13759 
setUserIdDeviceAffinitiesOnSystem( @serIdInt int userId, AudioDeviceArray deviceArray)13760         @AudioSystem.AudioSystemError private int setUserIdDeviceAffinitiesOnSystem(
13761                 @UserIdInt int userId, AudioDeviceArray deviceArray) {
13762             final long identity = Binder.clearCallingIdentity();
13763             try {
13764                 return mAudioSystem.setUserIdDeviceAffinities(userId, deviceArray.mDeviceTypes,
13765                         deviceArray.mDeviceAddresses);
13766             } finally {
13767                 Binder.restoreCallingIdentity(identity);
13768             }
13769         }
13770 
setupDeviceAffinities()13771         @AudioSystem.AudioSystemError int setupDeviceAffinities() {
13772             for (Map.Entry<Integer, AudioDeviceArray> uidEntry : mUidDeviceAffinities.entrySet()) {
13773                 int uidStatus = removeUidDeviceAffinitiesFromSystem(uidEntry.getKey());
13774                 if (uidStatus != AudioSystem.SUCCESS) {
13775                     Log.e(TAG,
13776                             "setupDeviceAffinities failed to remove device affinity for uid "
13777                                     + uidEntry.getKey());
13778                     return uidStatus;
13779                 }
13780                 uidStatus = setUidDeviceAffinitiesOnSystem(uidEntry.getKey(), uidEntry.getValue());
13781                 if (uidStatus != AudioSystem.SUCCESS) {
13782                     Log.e(TAG,
13783                             "setupDeviceAffinities failed to set device affinity for uid "
13784                                     + uidEntry.getKey());
13785                     return uidStatus;
13786                 }
13787             }
13788 
13789             for (Map.Entry<Integer, AudioDeviceArray> userIdEntry :
13790                     mUserIdDeviceAffinities.entrySet()) {
13791                 int userIdStatus = removeUserIdDeviceAffinitiesFromSystem(userIdEntry.getKey());
13792                 if (userIdStatus != AudioSystem.SUCCESS) {
13793                     Log.e(TAG,
13794                             "setupDeviceAffinities failed to remove device affinity for userId "
13795                                     + userIdEntry.getKey());
13796                     return userIdStatus;
13797                 }
13798                 userIdStatus = setUserIdDeviceAffinitiesOnSystem(userIdEntry.getKey(),
13799                                 userIdEntry.getValue());
13800                 if (userIdStatus != AudioSystem.SUCCESS) {
13801                     Log.e(TAG,
13802                             "setupDeviceAffinities failed to set device affinity for userId "
13803                                     + userIdEntry.getKey());
13804                     return userIdStatus;
13805                 }
13806             }
13807             return AudioSystem.SUCCESS;
13808         }
13809 
13810         /** @return human readable debug informations summarizing the state of the object. */
toLogFriendlyString()13811         public String toLogFriendlyString() {
13812             String textDump = super.toLogFriendlyString();
13813             textDump += " Uid Device Affinities:\n";
13814             String spacer = "     ";
13815             textDump += logFriendlyAttributeDeviceArrayMap("Uid",
13816                     mUidDeviceAffinities, spacer);
13817             textDump += " UserId Device Affinities:\n";
13818             textDump += logFriendlyAttributeDeviceArrayMap("UserId",
13819                     mUserIdDeviceAffinities, spacer);
13820             textDump += " Proxy:\n";
13821             textDump += "   is focus policy= " + mIsFocusPolicy + "\n";
13822             if (mIsFocusPolicy) {
13823                 textDump += "     focus duck behaviour= " + mFocusDuckBehavior + "\n";
13824                 textDump += "     is test focus policy= " + mIsTestFocusPolicy + "\n";
13825                 textDump += "     has focus listener= " + mHasFocusListener  + "\n";
13826             }
13827             textDump += "   media projection= " + mProjection + "\n";
13828             return textDump;
13829         }
13830 
logFriendlyAttributeDeviceArrayMap(String attribute, Map<Integer, AudioDeviceArray> map, String spacer)13831         private String logFriendlyAttributeDeviceArrayMap(String attribute,
13832                 Map<Integer, AudioDeviceArray> map, String spacer) {
13833             final StringBuilder stringBuilder = new StringBuilder();
13834             for (Map.Entry<Integer, AudioDeviceArray> mapEntry : map.entrySet()) {
13835                 stringBuilder.append(spacer).append(attribute).append(": ")
13836                         .append(mapEntry.getKey()).append("\n");
13837                 AudioDeviceArray deviceArray = mapEntry.getValue();
13838                 String deviceSpacer = spacer + "   ";
13839                 for (int i = 0; i < deviceArray.mDeviceTypes.length; i++) {
13840                     stringBuilder.append(deviceSpacer).append("Type: 0x")
13841                             .append(Integer.toHexString(deviceArray.mDeviceTypes[i]))
13842                             .append(" Address: ").append(deviceArray.mDeviceAddresses[i])
13843                                     .append("\n");
13844                 }
13845             }
13846             return stringBuilder.toString();
13847         }
13848     };
13849 
13850     //======================
13851     // Audio policy: focus
13852     //======================
13853     /**  */
dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb)13854     public int dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb) {
13855         if (afi == null) {
13856             throw new IllegalArgumentException("Illegal null AudioFocusInfo");
13857         }
13858         if (pcb == null) {
13859             throw new IllegalArgumentException("Illegal null AudioPolicy callback");
13860         }
13861         synchronized (mAudioPolicies) {
13862             if (!mAudioPolicies.containsKey(pcb.asBinder())) {
13863                 throw new IllegalStateException("Unregistered AudioPolicy for focus dispatch");
13864             }
13865             return mMediaFocusControl.dispatchFocusChange(afi, focusChange);
13866         }
13867     }
13868 
setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult, IAudioPolicyCallback pcb)13869     public void setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult,
13870             IAudioPolicyCallback pcb) {
13871         if (afi == null) {
13872             throw new IllegalArgumentException("Illegal null AudioFocusInfo");
13873         }
13874         if (pcb == null) {
13875             throw new IllegalArgumentException("Illegal null AudioPolicy callback");
13876         }
13877         synchronized (mAudioPolicies) {
13878             if (!mAudioPolicies.containsKey(pcb.asBinder())) {
13879                 throw new IllegalStateException("Unregistered AudioPolicy for external focus");
13880             }
13881             mMediaFocusControl.setFocusRequestResultFromExtPolicy(afi, requestResult);
13882         }
13883     }
13884 
13885     /**
13886      * see {@link AudioManager#dispatchAudioFocusChangeWithFade(AudioFocusInfo, int, AudioPolicy,
13887      * List, FadeManagerConfiguration)}
13888      */
13889     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
dispatchFocusChangeWithFade(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb, List<AudioFocusInfo> otherActiveAfis, FadeManagerConfiguration transientFadeMgrConfig)13890     public int dispatchFocusChangeWithFade(AudioFocusInfo afi, int focusChange,
13891             IAudioPolicyCallback pcb, List<AudioFocusInfo> otherActiveAfis,
13892             FadeManagerConfiguration transientFadeMgrConfig) {
13893         super.dispatchFocusChangeWithFade_enforcePermission();
13894         ensureFadeManagerConfigIsEnabled();
13895         Objects.requireNonNull(afi, "AudioFocusInfo cannot be null");
13896         Objects.requireNonNull(pcb, "AudioPolicy callback cannot be null");
13897         Objects.requireNonNull(otherActiveAfis,
13898                 "Other active AudioFocusInfo list cannot be null");
13899         if (transientFadeMgrConfig != null) {
13900             validateFadeManagerConfiguration(transientFadeMgrConfig);
13901         }
13902 
13903         synchronized (mAudioPolicies) {
13904             Preconditions.checkState(mAudioPolicies.containsKey(pcb.asBinder()),
13905                     "Unregistered AudioPolicy for focus dispatch with fade");
13906 
13907             // set the transient fade manager config to be used for handling this focus change
13908             if (transientFadeMgrConfig != null) {
13909                 mPlaybackMonitor.setTransientFadeManagerConfiguration(focusChange,
13910                         transientFadeMgrConfig);
13911             }
13912             int status = mMediaFocusControl.dispatchFocusChangeWithFade(afi, focusChange,
13913                     otherActiveAfis);
13914 
13915             if (transientFadeMgrConfig != null) {
13916                 mPlaybackMonitor.clearTransientFadeManagerConfiguration(focusChange);
13917             }
13918             return status;
13919         }
13920     }
13921 
13922 
13923     /**
13924      * @see AudioManager#shouldNotificationSoundPlay(AudioAttributes)
13925      */
13926     @android.annotation.EnforcePermission(QUERY_AUDIO_STATE)
shouldNotificationSoundPlay(@onNull final AudioAttributes aa)13927     public boolean shouldNotificationSoundPlay(@NonNull final AudioAttributes aa) {
13928         super.shouldNotificationSoundPlay_enforcePermission();
13929         Objects.requireNonNull(aa);
13930 
13931         // don't play notifications if the stream volume associated with the
13932         // AudioAttributes of the notification record is 0 (non-zero volume implies
13933         // not silenced by SILENT or VIBRATE ringer mode)
13934         final int stream = AudioAttributes.toLegacyStreamType(aa);
13935         final boolean mutingFromVolume = getStreamVolume(stream) == 0;
13936         if (mutingFromVolume) {
13937             Slog.i(TAG, "shouldNotificationSoundPlay false: muted stream:" + stream
13938                     + " attr:" + aa);
13939             return false;
13940         }
13941 
13942         // don't play notifications if there is a user of GAIN_TRANSIENT_EXCLUSIVE audio focus
13943         // and the focus owner is recording
13944         final int uid = mMediaFocusControl.getExclusiveFocusOwnerUid();
13945         if (uid == -1) { // return value is -1 if focus isn't GAIN_TRANSIENT_EXCLUSIVE
13946             return true;
13947         }
13948         // is the owner of GAIN_TRANSIENT_EXCLUSIVE focus also recording?
13949         final boolean mutingFromFocusAndRecording = mRecordMonitor.isRecordingActiveForUid(uid);
13950         if (mutingFromFocusAndRecording) {
13951             Slog.i(TAG, "shouldNotificationSoundPlay false: exclusive focus owner recording "
13952                         + " uid:" + uid + " attr:" + aa);
13953             return false;
13954         }
13955         return true;
13956     }
13957 
13958     //======================
13959     // Audioserver state dispatch
13960     //======================
13961     private class AsdProxy implements IBinder.DeathRecipient {
13962         private final IAudioServerStateDispatcher mAsd;
13963 
AsdProxy(IAudioServerStateDispatcher asd)13964         AsdProxy(IAudioServerStateDispatcher asd) {
13965             mAsd = asd;
13966         }
13967 
binderDied()13968         public void binderDied() {
13969             synchronized (mAudioServerStateListeners) {
13970                 mAudioServerStateListeners.remove(mAsd.asBinder());
13971             }
13972         }
13973 
callback()13974         IAudioServerStateDispatcher callback() {
13975             return mAsd;
13976         }
13977     }
13978 
13979     private final HashMap<IBinder, AsdProxy> mAudioServerStateListeners =
13980             new HashMap<IBinder, AsdProxy>();
13981 
checkMonitorAudioServerStatePermission()13982     private void checkMonitorAudioServerStatePermission() {
13983         if (!(mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE)
13984                 == PackageManager.PERMISSION_GRANTED
13985                 || mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING)
13986                 == PackageManager.PERMISSION_GRANTED)) {
13987             throw new SecurityException("Not allowed to monitor audioserver state");
13988         }
13989     }
13990 
registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd)13991     public void registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd) {
13992         checkMonitorAudioServerStatePermission();
13993         synchronized (mAudioServerStateListeners) {
13994             if (mAudioServerStateListeners.containsKey(asd.asBinder())) {
13995                 Slog.w(TAG, "Cannot re-register audio server state dispatcher");
13996                 return;
13997             }
13998             AsdProxy asdp = new AsdProxy(asd);
13999             try {
14000                 asd.asBinder().linkToDeath(asdp, 0/*flags*/);
14001             } catch (RemoteException e) {
14002 
14003             }
14004             mAudioServerStateListeners.put(asd.asBinder(), asdp);
14005         }
14006     }
14007 
unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd)14008     public void unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd) {
14009         checkMonitorAudioServerStatePermission();
14010         synchronized (mAudioServerStateListeners) {
14011             AsdProxy asdp = mAudioServerStateListeners.remove(asd.asBinder());
14012             if (asdp == null) {
14013                 Slog.w(TAG, "Trying to unregister unknown audioserver state dispatcher for pid "
14014                         + Binder.getCallingPid() + " / uid " + Binder.getCallingUid());
14015                 return;
14016             } else {
14017                 asd.asBinder().unlinkToDeath(asdp, 0/*flags*/);
14018             }
14019         }
14020     }
14021 
isAudioServerRunning()14022     public boolean isAudioServerRunning() {
14023         checkMonitorAudioServerStatePermission();
14024         return (AudioSystem.checkAudioFlinger() == AudioSystem.AUDIO_STATUS_OK);
14025     }
14026 
14027     //======================
14028     // Audio HAL process dump
14029     //======================
14030 
14031     private static final String AUDIO_HAL_SERVICE_PREFIX = "android.hardware.audio";
14032 
getAudioAidlHalPids(HashSet<Integer> pids)14033     private void getAudioAidlHalPids(HashSet<Integer> pids) {
14034         try {
14035             ServiceDebugInfo[] infos = ServiceManager.getServiceDebugInfo();
14036             if (infos == null) return;
14037             for (ServiceDebugInfo info : infos) {
14038                 if (info.debugPid > 0 && info.name.startsWith(AUDIO_HAL_SERVICE_PREFIX)) {
14039                     pids.add(info.debugPid);
14040                 }
14041             }
14042         } catch (RuntimeException e) {
14043             // ignored, pid hashset does not change
14044         }
14045     }
14046 
getAudioHalHidlPids(HashSet<Integer> pids)14047     private void getAudioHalHidlPids(HashSet<Integer> pids) {
14048         try {
14049             IServiceManager serviceManager = IServiceManager.getService();
14050             ArrayList<IServiceManager.InstanceDebugInfo> dump =
14051                     serviceManager.debugDump();
14052             for (IServiceManager.InstanceDebugInfo info : dump) {
14053                 if (info.pid != IServiceManager.PidConstant.NO_PID
14054                         && info.interfaceName != null
14055                         && info.interfaceName.startsWith(AUDIO_HAL_SERVICE_PREFIX)) {
14056                     pids.add(info.pid);
14057                 }
14058             }
14059         } catch (RemoteException | RuntimeException e) {
14060             // ignored, pid hashset does not change
14061         }
14062     }
14063 
getAudioHalPids()14064     private Set<Integer> getAudioHalPids() {
14065         HashSet<Integer> pids = new HashSet<>();
14066         getAudioAidlHalPids(pids);
14067         getAudioHalHidlPids(pids);
14068         return pids;
14069     }
14070 
updateAudioHalPids()14071     private void updateAudioHalPids() {
14072         Set<Integer> pidsSet = getAudioHalPids();
14073         if (pidsSet.isEmpty()) {
14074             Slog.w(TAG, "Could not retrieve audio HAL service pids");
14075             return;
14076         }
14077         int[] pidsArray = pidsSet.stream().mapToInt(Integer::intValue).toArray();
14078         AudioSystem.setAudioHalPids(pidsArray);
14079     }
14080 
14081     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
14082     //======================
14083     // Multi Audio Focus
14084     //======================
setMultiAudioFocusEnabled(boolean enabled)14085     public void setMultiAudioFocusEnabled(boolean enabled) {
14086         super.setMultiAudioFocusEnabled_enforcePermission();
14087 
14088         if (mMediaFocusControl != null) {
14089             boolean mafEnabled = mMediaFocusControl.getMultiAudioFocusEnabled();
14090             if (mafEnabled != enabled) {
14091                 mMediaFocusControl.updateMultiAudioFocus(enabled);
14092                 if (!enabled) {
14093                     mDeviceBroker.postBroadcastBecomingNoisy();
14094                 }
14095             }
14096         }
14097     }
14098 
14099     /**
14100      * @hide
14101      * Sets an additional audio output device delay in milliseconds.
14102      *
14103      * The additional output delay is a request to the output device to
14104      * delay audio presentation (generally with respect to video presentation for better
14105      * synchronization).
14106      * It may not be supported by all output devices,
14107      * and typically increases the audio latency by the amount of additional
14108      * audio delay requested.
14109      *
14110      * If additional audio delay is supported by an audio output device,
14111      * it is expected to be supported for all output streams (and configurations)
14112      * opened on that device.
14113      *
14114      * @param deviceType
14115      * @param address
14116      * @param delayMillis delay in milliseconds desired.  This should be in range of {@code 0}
14117      *     to the value returned by {@link #getMaxAdditionalOutputDeviceDelay()}.
14118      * @return true if successful, false if the device does not support output device delay
14119      *     or the delay is not in range of {@link #getMaxAdditionalOutputDeviceDelay()}.
14120      */
14121     @Override
14122     //@RequiresPermission(MODIFY_AUDIO_ROUTING)
setAdditionalOutputDeviceDelay( @onNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis)14123     public boolean setAdditionalOutputDeviceDelay(
14124             @NonNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis) {
14125         Objects.requireNonNull(device, "device must not be null");
14126         enforceModifyAudioRoutingPermission();
14127 
14128         device = retrieveBluetoothAddress(device);
14129 
14130         final String getterKey = "additional_output_device_delay="
14131                 + device.getInternalType() + "," + device.getAddress(); // "getter" key as an id.
14132         final String setterKey = getterKey + "," + delayMillis;     // append the delay for setter
14133         return mRestorableParameters.setParameters(getterKey, setterKey)
14134                 == AudioSystem.AUDIO_STATUS_OK;
14135     }
14136 
14137     /**
14138      * @hide
14139      * Returns the current additional audio output device delay in milliseconds.
14140      *
14141      * @param deviceType
14142      * @param address
14143      * @return the additional output device delay. This is a non-negative number.
14144      *     {@code 0} is returned if unsupported.
14145      */
14146     @Override
14147     @IntRange(from = 0)
getAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)14148     public long getAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) {
14149         Objects.requireNonNull(device, "device must not be null");
14150 
14151         device = retrieveBluetoothAddress(device);
14152 
14153         final String key = "additional_output_device_delay";
14154         final String reply = AudioSystem.getParameters(
14155                 key + "=" + device.getInternalType() + "," + device.getAddress());
14156         long delayMillis;
14157         try {
14158             delayMillis = Long.parseLong(reply.substring(key.length() + 1));
14159         } catch (NullPointerException e) {
14160             delayMillis = 0;
14161         }
14162         return delayMillis;
14163     }
14164 
14165     /**
14166      * @hide
14167      * Returns the maximum additional audio output device delay in milliseconds.
14168      *
14169      * @param deviceType
14170      * @param address
14171      * @return the maximum output device delay in milliseconds that can be set.
14172      *     This is a non-negative number
14173      *     representing the additional audio delay supported for the device.
14174      *     {@code 0} is returned if unsupported.
14175      */
14176     @Override
14177     @IntRange(from = 0)
getMaxAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)14178     public long getMaxAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) {
14179         Objects.requireNonNull(device, "device must not be null");
14180 
14181         device = retrieveBluetoothAddress(device);
14182 
14183         final String key = "max_additional_output_device_delay";
14184         final String reply = AudioSystem.getParameters(
14185                 key + "=" + device.getInternalType() + "," + device.getAddress());
14186         long delayMillis;
14187         try {
14188             delayMillis = Long.parseLong(reply.substring(key.length() + 1));
14189         } catch (NullPointerException e) {
14190             delayMillis = 0;
14191         }
14192         return delayMillis;
14193     }
14194 
14195     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
14196     /** @see AudioManager#addAssistantServicesUids(int []) */
14197     @Override
addAssistantServicesUids(int [] assistantUids)14198     public void addAssistantServicesUids(int [] assistantUids) {
14199         super.addAssistantServicesUids_enforcePermission();
14200 
14201         Objects.requireNonNull(assistantUids);
14202 
14203         synchronized (mSettingsLock) {
14204             addAssistantServiceUidsLocked(assistantUids);
14205         }
14206     }
14207 
14208     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
14209     /** @see AudioManager#removeAssistantServicesUids(int []) */
14210     @Override
removeAssistantServicesUids(int [] assistantUids)14211     public void removeAssistantServicesUids(int [] assistantUids) {
14212         super.removeAssistantServicesUids_enforcePermission();
14213 
14214         Objects.requireNonNull(assistantUids);
14215         synchronized (mSettingsLock) {
14216             removeAssistantServiceUidsLocked(assistantUids);
14217         }
14218     }
14219 
14220     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
14221     /** @see AudioManager#getAssistantServicesUids() */
14222     @Override
getAssistantServicesUids()14223     public int[] getAssistantServicesUids() {
14224         super.getAssistantServicesUids_enforcePermission();
14225 
14226         int [] assistantUids;
14227         synchronized (mSettingsLock) {
14228             assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray();
14229         }
14230         return assistantUids;
14231     }
14232 
14233     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
14234     /** @see AudioManager#setActiveAssistantServiceUids(int []) */
14235     @Override
setActiveAssistantServiceUids(int [] activeAssistantUids)14236     public void setActiveAssistantServiceUids(int [] activeAssistantUids) {
14237         super.setActiveAssistantServiceUids_enforcePermission();
14238 
14239         Objects.requireNonNull(activeAssistantUids);
14240         synchronized (mSettingsLock) {
14241             mActiveAssistantServiceUids = activeAssistantUids;
14242         }
14243         updateActiveAssistantServiceUids();
14244     }
14245 
14246     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
14247     /** @see AudioManager#getActiveAssistantServiceUids() */
14248     @Override
getActiveAssistantServiceUids()14249     public int[] getActiveAssistantServiceUids() {
14250         super.getActiveAssistantServiceUids_enforcePermission();
14251 
14252         int [] activeAssistantUids;
14253         synchronized (mSettingsLock) {
14254             activeAssistantUids = mActiveAssistantServiceUids.clone();
14255         }
14256         return activeAssistantUids;
14257     }
14258 
getDeviceIdentityAddresses(AudioDeviceAttributes device)14259     List<String> getDeviceIdentityAddresses(AudioDeviceAttributes device) {
14260         return mDeviceBroker.getDeviceIdentityAddresses(device);
14261     }
14262 
14263     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
getMusicFxHelper()14264     MusicFxHelper getMusicFxHelper() {
14265         return mMusicFxHelper;
14266     }
14267 
14268     //======================
14269     // misc
14270     //======================
14271     private final HashMap<IBinder, AudioPolicyProxy> mAudioPolicies =
14272             new HashMap<IBinder, AudioPolicyProxy>();
14273     @GuardedBy("mAudioPolicies")
14274     private int mAudioPolicyCounter = 0;
14275 
14276     //======================
14277     // Helper functions for full and fixed volume device
14278     //======================
isFixedVolumeDevice(int deviceType)14279     private boolean isFixedVolumeDevice(int deviceType) {
14280         if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX
14281                 && mRecordMonitor.isLegacyRemoteSubmixActive()) {
14282             return false;
14283         }
14284         return mFixedVolumeDevices.contains(deviceType);
14285     }
14286 
isFullVolumeDevice(int deviceType)14287     private boolean isFullVolumeDevice(int deviceType) {
14288         if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX
14289                 && mRecordMonitor.isLegacyRemoteSubmixActive()) {
14290             return false;
14291         }
14292         return mFullVolumeDevices.contains(deviceType);
14293     }
14294 
14295     /**
14296      * Returns whether the input device uses absolute volume behavior, including its variants.
14297      * For included volume behaviors, see {@link AudioManager.AbsoluteDeviceVolumeBehavior}.
14298      *
14299      * This is distinct from Bluetooth A2DP absolute volume behavior
14300      * ({@link #isA2dpAbsoluteVolumeDevice}).
14301      */
isAbsoluteVolumeDevice(int deviceType)14302     private boolean isAbsoluteVolumeDevice(int deviceType) {
14303         return mAbsoluteVolumeDeviceInfoMap.containsKey(deviceType);
14304     }
14305 
14306     /**
14307      * Returns whether the input device is a Bluetooth A2dp device that uses absolute volume
14308      * behavior. This is distinct from the general implementation of absolute volume behavior
14309      * ({@link #isAbsoluteVolumeDevice}).
14310      */
isA2dpAbsoluteVolumeDevice(int deviceType)14311     private boolean isA2dpAbsoluteVolumeDevice(int deviceType) {
14312         return mAvrcpAbsVolSupported && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(deviceType);
14313     }
14314 
14315     //====================
14316     // Helper functions for {set,get}DeviceVolumeBehavior
14317     //====================
getSettingsNameForDeviceVolumeBehavior(int deviceType)14318     private static String getSettingsNameForDeviceVolumeBehavior(int deviceType) {
14319         return "AudioService_DeviceVolumeBehavior_" + AudioSystem.getOutputDeviceName(deviceType);
14320     }
14321 
persistDeviceVolumeBehavior(int deviceType, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior)14322     private void persistDeviceVolumeBehavior(int deviceType,
14323             @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior) {
14324         if (DEBUG_VOL) {
14325             Log.d(TAG, "Persisting Volume Behavior for DeviceType: " + deviceType);
14326         }
14327         final long callingIdentity = Binder.clearCallingIdentity();
14328         try {
14329             mSettings.putSystemIntForUser(mContentResolver,
14330                     getSettingsNameForDeviceVolumeBehavior(deviceType),
14331                     deviceVolumeBehavior,
14332                     UserHandle.USER_CURRENT);
14333         } finally {
14334             Binder.restoreCallingIdentity(callingIdentity);
14335         }
14336     }
14337 
14338     @AudioManager.DeviceVolumeBehaviorState
retrieveStoredDeviceVolumeBehavior(int deviceType)14339     private int retrieveStoredDeviceVolumeBehavior(int deviceType) {
14340         return mSettings.getSystemIntForUser(mContentResolver,
14341                 getSettingsNameForDeviceVolumeBehavior(deviceType),
14342                 AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET,
14343                 UserHandle.USER_CURRENT);
14344     }
14345 
restoreDeviceVolumeBehavior()14346     private void restoreDeviceVolumeBehavior() {
14347         for (int deviceType : AudioSystem.DEVICE_OUT_ALL_SET) {
14348             if (DEBUG_VOL) {
14349                 Log.d(TAG, "Retrieving Volume Behavior for DeviceType: " + deviceType);
14350             }
14351             int deviceVolumeBehavior = retrieveStoredDeviceVolumeBehavior(deviceType);
14352             if (deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET) {
14353                 if (DEBUG_VOL) {
14354                     Log.d(TAG, "Skipping Setting Volume Behavior for DeviceType: " + deviceType);
14355                 }
14356                 continue;
14357             }
14358 
14359             setDeviceVolumeBehaviorInternal(new AudioDeviceAttributes(deviceType, ""),
14360                     deviceVolumeBehavior, "AudioService.restoreDeviceVolumeBehavior()");
14361         }
14362     }
14363 
14364     /**
14365      * @param audioSystemDeviceOut one of AudioSystem.DEVICE_OUT_*
14366      * @return whether {@code audioSystemDeviceOut} has previously been set to a specific volume
14367      * behavior
14368      */
hasDeviceVolumeBehavior( int audioSystemDeviceOut)14369     private boolean hasDeviceVolumeBehavior(
14370             int audioSystemDeviceOut) {
14371         return retrieveStoredDeviceVolumeBehavior(audioSystemDeviceOut)
14372                 != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET;
14373     }
14374 
addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut)14375     private boolean addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut) {
14376         if (DEBUG_VOL) {
14377             Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
14378                     + " to mFixedVolumeDevices");
14379         }
14380         return mFixedVolumeDevices.add(audioSystemDeviceOut);
14381     }
14382 
removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut)14383     private boolean removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut) {
14384         if (DEBUG_VOL) {
14385             Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
14386                     + " from mFixedVolumeDevices");
14387         }
14388         return mFixedVolumeDevices.remove(audioSystemDeviceOut);
14389     }
14390 
addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut)14391     private boolean addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut) {
14392         if (DEBUG_VOL) {
14393             Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
14394                     + " to mFullVolumeDevices");
14395         }
14396         return mFullVolumeDevices.add(audioSystemDeviceOut);
14397     }
14398 
removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut)14399     private boolean removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut) {
14400         if (DEBUG_VOL) {
14401             Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
14402                     + " from mFullVolumeDevices");
14403         }
14404         return mFullVolumeDevices.remove(audioSystemDeviceOut);
14405     }
14406 
addAudioSystemDeviceOutToAbsVolumeDevices(int audioSystemDeviceOut, AbsoluteVolumeDeviceInfo info)14407     private void addAudioSystemDeviceOutToAbsVolumeDevices(int audioSystemDeviceOut,
14408             AbsoluteVolumeDeviceInfo info) {
14409         if (DEBUG_VOL) {
14410             Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
14411                     + " to mAbsoluteVolumeDeviceInfoMap with behavior "
14412                     + AudioDeviceVolumeManager.volumeBehaviorName(info.mDeviceVolumeBehavior)
14413             );
14414         }
14415         mAbsoluteVolumeDeviceInfoMap.put(audioSystemDeviceOut, info);
14416     }
14417 
removeAudioSystemDeviceOutFromAbsVolumeDevices( int audioSystemDeviceOut)14418     private AbsoluteVolumeDeviceInfo removeAudioSystemDeviceOutFromAbsVolumeDevices(
14419             int audioSystemDeviceOut) {
14420         if (DEBUG_VOL) {
14421             Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
14422                     + " from mAbsoluteVolumeDeviceInfoMap");
14423         }
14424         return mAbsoluteVolumeDeviceInfoMap.remove(audioSystemDeviceOut);
14425     }
14426 
14427     //====================
14428     // Helper functions for app ops
14429     //====================
14430     /**
14431      * Validates, and notes an app op for a given uid and package name.
14432      * Validation comes from exception catching: a security exception indicates the package
14433      * doesn't exist, an IAE indicates the uid and package don't match. The code only checks
14434      * if exception was thrown for robustness to code changes in op validation
14435      * @param op the app op to check
14436      * @param uid the uid of the caller
14437      * @param packageName the package to check
14438      * @return true if the origin of the call is valid (no uid / package mismatch) and the caller
14439      *      is allowed to perform the operation
14440      */
checkNoteAppOp(int op, int uid, String packageName, String attributionTag)14441     private boolean checkNoteAppOp(int op, int uid, String packageName, String attributionTag) {
14442         try {
14443             if (mAppOps.noteOp(op, uid, packageName, attributionTag, null)
14444                     != AppOpsManager.MODE_ALLOWED) {
14445                 return false;
14446             }
14447         } catch (Exception e) {
14448             Log.e(TAG, "Error noting op:" + op + " on uid:" + uid + " for package:"
14449                     + packageName, e);
14450             return false;
14451         }
14452         return true;
14453     }
14454 }
14455