• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.EXTRA_ARCHIVAL;
36 import static android.content.Intent.EXTRA_REPLACING;
37 import static android.media.AudioDeviceInfo.TYPE_BLUETOOTH_A2DP;
38 import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_HEADPHONES;
39 import static android.media.AudioManager.RINGER_MODE_NORMAL;
40 import static android.media.AudioManager.RINGER_MODE_SILENT;
41 import static android.media.AudioManager.RINGER_MODE_VIBRATE;
42 import static android.media.AudioManager.STREAM_SYSTEM;
43 import static android.media.audio.Flags.autoPublicVolumeApiHardening;
44 import static android.media.audio.Flags.cacheGetStreamMinMaxVolume;
45 import static android.media.audio.Flags.cacheGetStreamVolume;
46 import static android.media.audio.Flags.concurrentAudioRecordBypassPermission;
47 import static android.media.audio.Flags.featureSpatialAudioHeadtrackingLowLatency;
48 import static android.media.audio.Flags.focusFreezeTestApi;
49 import static android.media.audio.Flags.roForegroundAudioControl;
50 import static android.media.audio.Flags.scoManagedByAudio;
51 import static android.media.audiopolicy.Flags.enableFadeManagerConfiguration;
52 import static android.os.Process.FIRST_APPLICATION_UID;
53 import static android.os.Process.INVALID_UID;
54 import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE;
55 import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
56 import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE;
57 
58 import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
59 import static com.android.media.audio.Flags.alarmMinVolumeZero;
60 import static com.android.media.audio.Flags.asDeviceConnectionFailure;
61 import static com.android.media.audio.Flags.audioserverPermissions;
62 import static com.android.media.audio.Flags.disablePrescaleAbsoluteVolume;
63 import static com.android.media.audio.Flags.deferWearPermissionUpdates;
64 import static com.android.media.audio.Flags.equalScoLeaVcIndexRange;
65 import static com.android.media.audio.Flags.optimizeBtDeviceSwitch;
66 import static com.android.media.audio.Flags.replaceStreamBtSco;
67 import static com.android.media.audio.Flags.ringMyCar;
68 import static com.android.media.audio.Flags.ringerModeAffectsAlarm;
69 import static com.android.media.flags.Flags.enableAudioInputDeviceRoutingAndVolumeControl;
70 import static com.android.server.audio.SoundDoseHelper.ACTION_CHECK_MUSIC_ACTIVE;
71 import static com.android.server.utils.EventLogger.Event.ALOGE;
72 import static com.android.server.utils.EventLogger.Event.ALOGI;
73 import static com.android.server.utils.EventLogger.Event.ALOGW;
74 
75 import android.Manifest;
76 import android.annotation.EnforcePermission;
77 import android.annotation.IntDef;
78 import android.annotation.IntRange;
79 import android.annotation.NonNull;
80 import android.annotation.Nullable;
81 import android.annotation.RequiresPermission;
82 import android.annotation.SuppressLint;
83 import android.annotation.UserIdInt;
84 import android.app.ActivityManager;
85 import android.app.ActivityManagerInternal;
86 import android.app.AppGlobals;
87 import android.app.AppOpsManager;
88 import android.app.BroadcastOptions;
89 import android.app.IUidObserver;
90 import android.app.NotificationManager;
91 import android.app.PropertyInvalidatedCache;
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.IAudioManagerNative;
148 import android.media.IAudioModeDispatcher;
149 import android.media.IAudioRoutesObserver;
150 import android.media.IAudioServerStateDispatcher;
151 import android.media.IAudioService;
152 import android.media.ICapturePresetDevicesRoleDispatcher;
153 import android.media.ICommunicationDeviceDispatcher;
154 import android.media.IDeviceVolumeBehaviorDispatcher;
155 import android.media.IDevicesForAttributesCallback;
156 import android.media.ILoudnessCodecUpdatesDispatcher;
157 import android.media.IMuteAwaitConnectionCallback;
158 import android.media.IPlaybackConfigDispatcher;
159 import android.media.IPreferredMixerAttributesDispatcher;
160 import android.media.IRecordingConfigDispatcher;
161 import android.media.IRingtonePlayer;
162 import android.media.ISpatializerCallback;
163 import android.media.ISpatializerHeadToSoundStagePoseCallback;
164 import android.media.ISpatializerHeadTrackerAvailableCallback;
165 import android.media.ISpatializerHeadTrackingModeCallback;
166 import android.media.ISpatializerOutputCallback;
167 import android.media.IStrategyNonDefaultDevicesDispatcher;
168 import android.media.IStrategyPreferredDevicesDispatcher;
169 import android.media.IStreamAliasingDispatcher;
170 import android.media.IVolumeController;
171 import android.media.LoudnessCodecController;
172 import android.media.LoudnessCodecInfo;
173 import android.media.MediaCodec;
174 import android.media.MediaMetrics;
175 import android.media.MediaRecorder.AudioSource;
176 import android.media.PlayerBase;
177 import android.media.Spatializer;
178 import android.media.Utils;
179 import android.media.VolumeInfo;
180 import android.media.VolumePolicy;
181 import android.media.audiofx.AudioEffect;
182 import android.media.audiopolicy.AudioMix;
183 import android.media.audiopolicy.AudioMixingRule;
184 import android.media.audiopolicy.AudioPolicy;
185 import android.media.audiopolicy.AudioPolicyConfig;
186 import android.media.audiopolicy.AudioProductStrategy;
187 import android.media.audiopolicy.AudioVolumeGroup;
188 import android.media.audiopolicy.IAudioPolicyCallback;
189 import android.media.audiopolicy.IAudioVolumeChangeDispatcher;
190 import android.media.permission.ClearCallingIdentityContext;
191 import android.media.permission.SafeCloseable;
192 import android.media.projection.IMediaProjection;
193 import android.media.projection.IMediaProjectionCallback;
194 import android.media.projection.IMediaProjectionManager;
195 import android.media.session.MediaSessionManager;
196 import android.net.Uri;
197 import android.os.Binder;
198 import android.os.Build;
199 import android.os.Bundle;
200 import android.os.Handler;
201 import android.os.HandlerThread;
202 import android.os.HwBinder;
203 import android.os.IBinder;
204 import android.os.Looper;
205 import android.os.Message;
206 import android.os.PermissionEnforcer;
207 import android.os.PersistableBundle;
208 import android.os.PowerManager;
209 import android.os.Process;
210 import android.os.RemoteCallbackList;
211 import android.os.RemoteException;
212 import android.os.ResultReceiver;
213 import android.os.ServiceDebugInfo;
214 import android.os.ServiceManager;
215 import android.os.ShellCallback;
216 import android.os.SystemClock;
217 import android.os.SystemProperties;
218 import android.os.UserHandle;
219 import android.os.UserManager;
220 import android.os.VibrationAttributes;
221 import android.os.VibrationEffect;
222 import android.os.Vibrator;
223 import android.os.VibratorManager;
224 import android.permission.PermissionManager;
225 import android.provider.Settings;
226 import android.provider.Settings.System;
227 import android.service.notification.ZenModeConfig;
228 import android.telecom.TelecomManager;
229 import android.telephony.SubscriptionManager;
230 import android.text.TextUtils;
231 import android.util.AndroidRuntimeException;
232 import android.util.ArrayMap;
233 import android.util.ArraySet;
234 import android.util.IntArray;
235 import android.util.Log;
236 import android.util.PrintWriterPrinter;
237 import android.util.Slog;
238 import android.util.SparseArray;
239 import android.util.SparseIntArray;
240 import android.view.Display;
241 import android.view.KeyEvent;
242 import android.view.accessibility.AccessibilityManager;
243 import android.widget.Toast;
244 
245 import com.android.internal.annotations.GuardedBy;
246 import com.android.internal.annotations.VisibleForTesting;
247 import com.android.internal.os.SomeArgs;
248 import com.android.internal.util.DumpUtils;
249 import com.android.internal.util.Preconditions;
250 import com.android.modules.expresslog.Counter;
251 import com.android.server.EventLogTags;
252 import com.android.server.LocalManagerRegistry;
253 import com.android.server.LocalServices;
254 import com.android.server.SystemService;
255 import com.android.server.audio.AudioServiceEvents.DeviceVolumeEvent;
256 import com.android.server.audio.AudioServiceEvents.PhoneStateEvent;
257 import com.android.server.audio.AudioServiceEvents.VolChangedBroadcastEvent;
258 import com.android.server.audio.AudioServiceEvents.VolumeEvent;
259 import com.android.server.pm.PackageManagerLocal;
260 import com.android.server.pm.UserManagerInternal;
261 import com.android.server.pm.UserManagerInternal.UserRestrictionsListener;
262 import com.android.server.pm.UserManagerService;
263 import com.android.server.pm.permission.PermissionManagerServiceInternal;
264 import com.android.server.pm.pkg.PackageState;
265 import com.android.server.utils.EventLogger;
266 import com.android.server.wm.ActivityTaskManagerInternal;
267 
268 import java.io.FileDescriptor;
269 import java.io.PrintWriter;
270 import java.lang.annotation.Retention;
271 import java.lang.annotation.RetentionPolicy;
272 import java.text.SimpleDateFormat;
273 import java.util.ArrayList;
274 import java.util.Arrays;
275 import java.util.Collection;
276 import java.util.Collections;
277 import java.util.Date;
278 import java.util.HashMap;
279 import java.util.HashSet;
280 import java.util.Iterator;
281 import java.util.LinkedHashMap;
282 import java.util.List;
283 import java.util.Map;
284 import java.util.NoSuchElementException;
285 import java.util.Objects;
286 import java.util.Set;
287 import java.util.TreeSet;
288 import java.util.concurrent.CancellationException;
289 import java.util.concurrent.ExecutionException;
290 import java.util.concurrent.Executor;
291 import java.util.concurrent.Executors;
292 import java.util.concurrent.Future;
293 import java.util.concurrent.ScheduledExecutorService;
294 import java.util.concurrent.TimeUnit;
295 import java.util.concurrent.atomic.AtomicBoolean;
296 import java.util.concurrent.atomic.AtomicInteger;
297 import java.util.function.BooleanSupplier;
298 import java.util.stream.Collectors;
299 
300 /**
301  * The implementation of the audio service for volume, audio focus, device management...
302  * <p>
303  * This implementation focuses on delivering a responsive UI. Most methods are
304  * asynchronous to external calls. For example, the task of setting a volume
305  * will update our internal state, but in a separate thread will set the system
306  * volume and later persist to the database. Similarly, setting the ringer mode
307  * will update the state and broadcast a change and in a separate thread later
308  * persist the ringer mode.
309  *
310  * @hide
311  */
312 public class AudioService extends IAudioService.Stub
313         implements AccessibilityManager.TouchExplorationStateChangeListener,
314             AccessibilityManager.AccessibilityServicesStateChangeListener,
315             AudioSystemAdapter.OnRoutingUpdatedListener,
316             AudioSystemAdapter.OnVolRangeInitRequestListener {
317 
318     private static final String TAG = "AS.AudioService";
319 
320     private final AudioSystemAdapter mAudioSystem;
321     private final SystemServerAdapter mSystemServer;
322     private final SettingsAdapter mSettings;
323     private final AudioPolicyFacade mAudioPolicy;
324 
325     private final AudioServerPermissionProvider mPermissionProvider;
326 
327     private final MusicFxHelper mMusicFxHelper;
328 
329     /** Debug audio mode */
330     protected static final boolean DEBUG_MODE = false;
331 
332     /** Debug audio policy feature */
333     protected static final boolean DEBUG_AP = false;
334 
335     /** Debug volumes */
336     protected static final boolean DEBUG_VOL = false;
337 
338     /** debug calls to devices APIs */
339     protected static final boolean DEBUG_DEVICES = false;
340 
341     /** Debug communication route */
342     protected static final boolean DEBUG_COMM_RTE = false;
343 
344     /** Debug log sound fx (touchsounds...) in dumpsys */
345     protected static final boolean DEBUG_LOG_SOUND_FX = false;
346 
347     /** How long to delay before persisting a change in volume/ringer mode. */
348     private static final int PERSIST_DELAY = 500;
349 
350     /** How long to delay after a volume down event before unmuting a stream */
351     private static final int UNMUTE_STREAM_DELAY = 350;
352 
353     /**
354      * Delay before disconnecting a device that would cause BECOMING_NOISY intent to be sent,
355      * to give a chance to applications to pause.
356      */
357     @VisibleForTesting
358     public static final int BECOMING_NOISY_DELAY_MS = 1000;
359 
360     /**
361      * Only used in the result from {@link #checkForRingerModeChange(int, int, int)}
362      */
363     private static final int FLAG_ADJUST_VOLUME = 1;
364 
365     final Context mContext;
366     private final ContentResolver mContentResolver;
367     private final AppOpsManager mAppOps;
368 
369     /** do not use directly, use getMediaSessionManager() which handles lazy initialization */
370     @Nullable private volatile MediaSessionManager mMediaSessionManager;
371 
372     // the platform type affects volume and silent mode behavior
373     private final int mPlatformType;
374 
375     // indicates whether the system maps all streams to a single stream.
376     private final boolean mIsSingleVolume;
377 
378     /**
379      * indicates whether STREAM_NOTIFICATION is aliased to STREAM_RING
380      *     not final due to test method, see {@link #setNotifAliasRingForTest(boolean)}.
381      */
382     private boolean mNotifAliasRing = false;
383 
384     /**
385      * Test method to temporarily override whether STREAM_NOTIFICATION is aliased to STREAM_RING,
386      * volumes will be updated in case of a change.
387      * @param alias if true, STREAM_NOTIFICATION is aliased to STREAM_RING
388      */
389     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setNotifAliasRingForTest(boolean alias)390     public void setNotifAliasRingForTest(boolean alias) {
391         super.setNotifAliasRingForTest_enforcePermission();
392         boolean update = (mNotifAliasRing != alias);
393         mNotifAliasRing = alias;
394         if (update) {
395             updateStreamVolumeAlias(true, "AudioServiceTest");
396         }
397     }
398 
isPlatformVoice()399     /*package*/ boolean isPlatformVoice() {
400         return mPlatformType == AudioSystem.PLATFORM_VOICE;
401     }
402 
isPlatformTelevision()403     /*package*/ boolean isPlatformTelevision() {
404         return mPlatformType == AudioSystem.PLATFORM_TELEVISION;
405     }
406 
isPlatformAutomotive()407     /*package*/ boolean isPlatformAutomotive() {
408         return mPlatformType == AudioSystem.PLATFORM_AUTOMOTIVE;
409     }
410 
411     /** The controller for the volume UI. */
412     private final VolumeController mVolumeController = new VolumeController();
413 
414     /** Used only for testing to enable/disable the long press timeout volume actions. */
415     private final AtomicBoolean mVolumeControllerLongPressEnabled = new AtomicBoolean(true);
416 
417     // sendMsg() flags
418     /** If the msg is already queued, replace it with this one. */
419     private static final int SENDMSG_REPLACE = 0;
420     /** If the msg is already queued, ignore this one and leave the old. */
421     private static final int SENDMSG_NOOP = 1;
422     /** If the msg is already queued, queue this one and leave the old. */
423     private static final int SENDMSG_QUEUE = 2;
424 
425     // AudioHandler messages
426     /*package*/ static final int MSG_SET_DEVICE_VOLUME = 0;
427     private static final int MSG_PERSIST_VOLUME = 1;
428     private static final int MSG_PERSIST_VOLUME_GROUP = 2;
429     private static final int MSG_PERSIST_RINGER_MODE = 3;
430     private static final int MSG_AUDIO_SERVER_DIED = 4;
431     private static final int MSG_PLAY_SOUND_EFFECT = 5;
432     private static final int MSG_LOAD_SOUND_EFFECTS = 7;
433     private static final int MSG_SET_FORCE_USE = 8;
434     private static final int MSG_SET_ALL_VOLUMES = 10;
435     private static final int MSG_UNLOAD_SOUND_EFFECTS = 15;
436     private static final int MSG_SYSTEM_READY = 16;
437     private static final int MSG_UNMUTE_STREAM_ON_SINGLE_VOL_DEVICE = 18;
438     private static final int MSG_DYN_POLICY_MIX_STATE_UPDATE = 19;
439     private static final int MSG_INDICATE_SYSTEM_READY = 20;
440     private static final int MSG_ACCESSORY_PLUG_MEDIA_UNMUTE = 21;
441     private static final int MSG_NOTIFY_VOL_EVENT = 22;
442     private static final int MSG_DISPATCH_AUDIO_SERVER_STATE = 23;
443     private static final int MSG_ENABLE_SURROUND_FORMATS = 24;
444     private static final int MSG_UPDATE_RINGER_MODE = 25;
445     private static final int MSG_SET_DEVICE_STREAM_VOLUME = 26;
446     private static final int MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS = 27;
447     private static final int MSG_HDMI_VOLUME_CHECK = 28;
448     private static final int MSG_PLAYBACK_CONFIG_CHANGE = 29;
449     private static final int MSG_BROADCAST_MICROPHONE_MUTE = 30;
450     private static final int MSG_CHECK_MODE_FOR_UID = 31;
451     private static final int MSG_STREAM_DEVICES_CHANGED = 32;
452     private static final int MSG_UPDATE_VOLUME_STATES_FOR_DEVICE = 33;
453     private static final int MSG_REINIT_VOLUMES = 34;
454     private static final int MSG_UPDATE_A11Y_SERVICE_UIDS = 35;
455     private static final int MSG_UPDATE_AUDIO_MODE = 36;
456     private static final int MSG_RECORDING_CONFIG_CHANGE = 37;
457     private static final int MSG_BT_DEV_CHANGED = 38;
458     private static final int MSG_UPDATE_AUDIO_MODE_SIGNAL = 39;
459     private static final int MSG_DISPATCH_AUDIO_MODE = 40;
460     private static final int MSG_ROUTING_UPDATED = 41;
461     private static final int MSG_INIT_HEADTRACKING_SENSORS = 42;
462     private static final int MSG_ADD_ASSISTANT_SERVICE_UID = 44;
463     private static final int MSG_REMOVE_ASSISTANT_SERVICE_UID = 45;
464     private static final int MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID = 46;
465     private static final int MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR = 47;
466     private static final int MSG_ROTATION_UPDATE = 48;
467     private static final int MSG_FOLD_UPDATE = 49;
468     private static final int MSG_RESET_SPATIALIZER = 50;
469     private static final int MSG_NO_LOG_FOR_PLAYER_I = 51;
470     private static final int MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES = 52;
471     private static final int MSG_CONFIGURATION_CHANGED = 54;
472     private static final int MSG_BROADCAST_MASTER_MUTE = 55;
473     private static final int MSG_UPDATE_CONTEXTUAL_VOLUMES = 56;
474     private static final int MSG_BT_COMM_DEVICE_ACTIVE_UPDATE = 57;
475 
476     /**
477      * Messages handled by the {@link SoundDoseHelper}, do not exceed
478      * {@link MUSICFX_HELPER_MSG_START}.
479      */
480     /*package*/ static final int SAFE_MEDIA_VOLUME_MSG_START = 1000;
481 
482     /** Messages handled by the {@link MusicFxHelper}. */
483     /*package*/ static final int MUSICFX_HELPER_MSG_START = 1100;
484 
485     // start of messages handled under wakelock
486     //   these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
487     //   and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
488     private static final int MSG_DISABLE_AUDIO_FOR_UID = 100;
489     private static final int MSG_INIT_STREAMS_VOLUMES = 101;
490     private static final int MSG_INIT_SPATIALIZER = 102;
491     private static final int MSG_INIT_ADI_DEVICE_STATES = 103;
492 
493     private static final int MSG_INIT_INPUT_GAINS = 104;
494     private static final int MSG_APPLY_INPUT_GAIN_INDEX = 105;
495     private static final int MSG_PERSIST_INPUT_GAIN_INDEX = 106;
496 
497     // end of messages handled under wakelock
498 
499     // retry delay in case of failure to indicate system ready to AudioFlinger
500     private static final int INDICATE_SYSTEM_READY_RETRY_DELAY_MS = 1000;
501 
502     // List of empty UIDs used to reset the active assistant list
503     private static final int[] NO_ACTIVE_ASSISTANT_SERVICE_UIDS = new int[0];
504 
505     // check playback or record activity every 6 seconds for UIDs owning mode IN_COMMUNICATION
506     private static final int CHECK_MODE_FOR_UID_PERIOD_MS = 6000;
507 
508     // Roughly chosen to be long enough to suppress the autocork behavior of the permission
509     // cache (50ms), while not introducing visible permission leaks - since the app needs to
510     // restart, and trigger an action which requires permissions from audioserver before this
511     // delay. For RECORD_AUDIO, we are additionally protected by appops.
512     private static final int SCHEDULED_PERMISSION_UPDATE_DELAY_MS = 60;
513 
514     // Increased delay to not interefere with low core app launch latency
515     private static final int SCHEDULED_PERMISSION_UPDATE_LONG_DELAY_MS = 500;
516 
517     /** @see AudioSystemThread */
518     private AudioSystemThread mAudioSystemThread;
519     /** @see AudioHandler */
520     private AudioHandler mAudioHandler;
521     /**
522      *  @see VolumeStreamState
523      *  Mapping which contains for each stream type its associated {@link VolumeStreamState}
524      **/
525     private SparseArray<VolumeStreamState> mStreamStates;
526 
527     /**
528      * @see InputDeviceVolumeHelper
529      */
530     private InputDeviceVolumeHelper mInputDeviceVolumeHelper;
531 
getVolumeForDeviceIgnoreMute(int stream, int device)532     /*package*/ int getVolumeForDeviceIgnoreMute(int stream, int device) {
533         final VolumeStreamState streamState = mStreamStates.get(stream);
534         return streamState != null ? streamState.getIndex(device) : -1;
535     }
536 
537     /**
538      * Returns the {@link VolumeStreamState} corresponding to the passed stream type. This can be
539      * {@code null} since not all possible stream types have a valid {@link VolumeStreamState} (e.g.
540      * {@link AudioSystem#STREAM_BLUETOOTH_SCO}) is deprecated and will return a {@code null} stream
541      * state).
542      *
543      * @param stream the stream type for querying the stream state
544      *
545      * @return the {@link VolumeStreamState} corresponding to the passed stream type or {@code null}
546      */
547     @Nullable
getVssForStream(int stream)548     /*package*/ VolumeStreamState getVssForStream(int stream) {
549         return mStreamStates.get(stream);
550     }
551 
552     /**
553      * Returns the {@link VolumeStreamState} corresponding to the passed stream type. In case
554      * there is no associated stream state for the given stream type we return the default stream
555      * state for {@link AudioSystem#STREAM_MUSIC} (or throw an {@link IllegalArgumentException} in
556      * the ramp up phase of the replaceStreamBtSco flag to ensure that this case will never happen).
557      *
558      * @param stream the stream type for querying the stream state
559      *
560      * @return the {@link VolumeStreamState} corresponding to the passed stream type
561      */
562     @NonNull
getVssForStreamOrDefault(int stream)563     /*package*/ VolumeStreamState getVssForStreamOrDefault(int stream) {
564         VolumeStreamState streamState = mStreamStates.get(stream);
565         if (streamState == null) {
566             if (replaceStreamBtSco()) {
567                 throw new IllegalArgumentException("No VolumeStreamState for stream " + stream);
568             } else {
569                 Log.e(TAG, "No VolumeStreamState for stream " + stream
570                         + ". Returning default state for STREAM_MUSIC", new Exception());
571                 streamState = mStreamStates.get(AudioSystem.STREAM_MUSIC);
572             }
573         }
574         return streamState;
575     }
576 
getMaxVssVolumeForStream(int stream)577     /*package*/ int getMaxVssVolumeForStream(int stream) {
578         final VolumeStreamState streamState = mStreamStates.get(stream);
579         return streamState != null ? streamState.getMaxIndex() : -1;
580     }
581 
582     private SettingsObserver mSettingsObserver;
583 
584     private AtomicInteger mMode = new AtomicInteger(AudioSystem.MODE_NORMAL);
585 
586     // protects mRingerMode
587     private final Object mSettingsLock = new Object();
588 
589     // protects VolumeStreamState / VolumeGroupState operations
590     private final Object mVolumeStateLock = new Object();
591 
592    /** Maximum volume index values for audio streams */
593     protected static int[] MAX_STREAM_VOLUME = new int[] {
594         5,  // STREAM_VOICE_CALL
595         7,  // STREAM_SYSTEM
596         7,  // STREAM_RING            // configured by config_audio_ring_vol_steps
597         15, // STREAM_MUSIC
598         7,  // STREAM_ALARM
599         7,  // STREAM_NOTIFICATION    // configured by config_audio_notif_vol_steps
600         15, // STREAM_BLUETOOTH_SCO
601         7,  // STREAM_SYSTEM_ENFORCED
602         15, // STREAM_DTMF
603         15, // STREAM_TTS
604         15, // STREAM_ACCESSIBILITY
605         15  // STREAM_ASSISTANT
606     };
607 
608     /** Minimum volume index values for audio streams */
609     protected static int[] MIN_STREAM_VOLUME = new int[] {
610         1,  // STREAM_VOICE_CALL
611         0,  // STREAM_SYSTEM
612         0,  // STREAM_RING
613         0,  // STREAM_MUSIC
614         1,  // STREAM_ALARM
615         0,  // STREAM_NOTIFICATION
616         0,  // STREAM_BLUETOOTH_SCO
617         0,  // STREAM_SYSTEM_ENFORCED
618         0,  // STREAM_DTMF
619         0,  // STREAM_TTS
620         1,  // STREAM_ACCESSIBILITY
621         0   // STREAM_ASSISTANT
622     };
623 
624     /* sStreamVolumeAlias[] indicates for each stream if it uses the volume settings
625      * of another stream: This avoids multiplying the volume settings for hidden
626      * stream types that follow other stream behavior for volume settings
627      * NOTE: do not create loops in aliases!
628      * Some streams alias to different streams according to device category (phone or tablet) or
629      * use case (in call vs off call...). See updateStreamVolumeAlias() for more details.
630      *  sStreamVolumeAlias contains STREAM_VOLUME_ALIAS_VOICE aliases for a voice capable device
631      *  (phone), STREAM_VOLUME_ALIAS_TELEVISION for a television or set-top box and
632      *  STREAM_VOLUME_ALIAS_DEFAULT for other devices (e.g. tablets).*/
633     private final int[] STREAM_VOLUME_ALIAS_VOICE = new int[] {
634         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
635         AudioSystem.STREAM_RING,            // STREAM_SYSTEM
636         AudioSystem.STREAM_RING,            // STREAM_RING
637         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
638         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
639         AudioSystem.STREAM_RING,            // STREAM_NOTIFICATION
640         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
641         AudioSystem.STREAM_RING,            // STREAM_SYSTEM_ENFORCED
642         AudioSystem.STREAM_RING,            // STREAM_DTMF
643         AudioSystem.STREAM_MUSIC,           // STREAM_TTS
644         AudioSystem.STREAM_MUSIC,           // STREAM_ACCESSIBILITY
645         AudioSystem.STREAM_MUSIC            // STREAM_ASSISTANT
646     };
647     private final int[] STREAM_VOLUME_ALIAS_TELEVISION = new int[] {
648         AudioSystem.STREAM_MUSIC,       // STREAM_VOICE_CALL
649         AudioSystem.STREAM_MUSIC,       // STREAM_SYSTEM
650         AudioSystem.STREAM_MUSIC,       // STREAM_RING
651         AudioSystem.STREAM_MUSIC,       // STREAM_MUSIC
652         AudioSystem.STREAM_MUSIC,       // STREAM_ALARM
653         AudioSystem.STREAM_MUSIC,       // STREAM_NOTIFICATION
654         AudioSystem.STREAM_BLUETOOTH_SCO,       // STREAM_BLUETOOTH_SCO
655         AudioSystem.STREAM_MUSIC,       // STREAM_SYSTEM_ENFORCED
656         AudioSystem.STREAM_MUSIC,       // STREAM_DTMF
657         AudioSystem.STREAM_MUSIC,       // STREAM_TTS
658         AudioSystem.STREAM_MUSIC,       // STREAM_ACCESSIBILITY
659         AudioSystem.STREAM_MUSIC        // STREAM_ASSISTANT
660     };
661     /**
662      * Using Volume groups configuration allows to control volume per attributes
663      * and group definition may differ from stream aliases.
664      * So, do not alias any stream on one another when using volume groups.
665      * TODO(b/181140246): volume group definition hosting alias definition.
666      */
667     private final int[] STREAM_VOLUME_ALIAS_NONE = new int[] {
668         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
669         AudioSystem.STREAM_SYSTEM,          // STREAM_SYSTEM
670         AudioSystem.STREAM_RING,            // STREAM_RING
671         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
672         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
673         AudioSystem.STREAM_NOTIFICATION,    // STREAM_NOTIFICATION
674         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
675         AudioSystem.STREAM_SYSTEM_ENFORCED, // STREAM_SYSTEM_ENFORCED
676         AudioSystem.STREAM_DTMF,            // STREAM_DTMF
677         AudioSystem.STREAM_TTS,             // STREAM_TTS
678         AudioSystem.STREAM_ACCESSIBILITY,   // STREAM_ACCESSIBILITY
679         AudioSystem.STREAM_ASSISTANT        // STREAM_ASSISTANT
680     };
681     private final int[] STREAM_VOLUME_ALIAS_DEFAULT = new int[] {
682         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
683         AudioSystem.STREAM_RING,            // STREAM_SYSTEM
684         AudioSystem.STREAM_RING,            // STREAM_RING
685         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
686         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
687         AudioSystem.STREAM_RING,            // STREAM_NOTIFICATION
688         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
689         AudioSystem.STREAM_RING,            // STREAM_SYSTEM_ENFORCED
690         AudioSystem.STREAM_RING,            // STREAM_DTMF
691         AudioSystem.STREAM_MUSIC,           // STREAM_TTS
692         AudioSystem.STREAM_MUSIC,           // STREAM_ACCESSIBILITY
693         AudioSystem.STREAM_MUSIC            // STREAM_ASSISTANT
694     };
695     protected static SparseIntArray sStreamVolumeAlias;
696     private static final int UNSET_INDEX = -1;
697 
698     /**
699      * Map AudioSystem.STREAM_* constants to app ops.  This should be used
700      * after mapping through sStreamVolumeAlias.
701      */
702     private static final int[] STREAM_VOLUME_OPS = new int[] {
703         AppOpsManager.OP_AUDIO_VOICE_VOLUME,            // STREAM_VOICE_CALL
704         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_SYSTEM
705         AppOpsManager.OP_AUDIO_RING_VOLUME,             // STREAM_RING
706         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_MUSIC
707         AppOpsManager.OP_AUDIO_ALARM_VOLUME,            // STREAM_ALARM
708         AppOpsManager.OP_AUDIO_NOTIFICATION_VOLUME,     // STREAM_NOTIFICATION
709         AppOpsManager.OP_AUDIO_BLUETOOTH_VOLUME,        // STREAM_BLUETOOTH_SCO
710         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_SYSTEM_ENFORCED
711         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_DTMF
712         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_TTS
713         AppOpsManager.OP_AUDIO_ACCESSIBILITY_VOLUME,    // STREAM_ACCESSIBILITY
714         AppOpsManager.OP_AUDIO_MEDIA_VOLUME             // STREAM_ASSISTANT
715     };
716 
717     private final boolean mUseFixedVolume;
718     private final boolean mRingerModeAffectsAlarm;
719     private final boolean mUseVolumeGroupAliases;
720 
721     // If absolute volume is supported in AVRCP device
722     private volatile boolean mAvrcpAbsVolSupported = false;
723 
724     private final Object mCachedAbsVolDrivingStreamsLock = new Object();
725     // Contains for all the device types which support absolute volume the current streams that
726     // are driving the volume changes
727     @GuardedBy("mCachedAbsVolDrivingStreamsLock")
728     private final HashMap<Integer, Integer> mCachedAbsVolDrivingStreams = new HashMap<>(
729             Map.of(AudioSystem.DEVICE_OUT_BLE_HEADSET, AudioSystem.STREAM_MUSIC,
730                     AudioSystem.DEVICE_OUT_BLE_SPEAKER, AudioSystem.STREAM_MUSIC,
731                     AudioSystem.DEVICE_OUT_BLE_BROADCAST, AudioSystem.STREAM_MUSIC,
732                     AudioSystem.DEVICE_OUT_HEARING_AID, AudioSystem.STREAM_MUSIC
733             ));
734 
735     /**
736     * Default stream type used for volume control in the absence of playback
737     * e.g. user on homescreen, no app playing anything, presses hardware volume buttons, this
738     *    stream type is controlled.
739     */
740     protected static final int DEFAULT_VOL_STREAM_NO_PLAYBACK = AudioSystem.STREAM_MUSIC;
741 
742     private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() {
743         public void onError(int error) {
744             switch (error) {
745                 case AudioSystem.AUDIO_STATUS_SERVER_DIED:
746                     // check for null in case error callback is called during instance creation
747                     if (mRecordMonitor != null) {
748                         mRecordMonitor.onAudioServerDied();
749                     }
750                     // Notify the playback monitor that the audio server has died
751                     if (mPlaybackMonitor != null) {
752                         mPlaybackMonitor.onAudioServerDied();
753                     }
754                     sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED,
755                             SENDMSG_NOOP, 0, 0, null, 0);
756                     sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE,
757                             SENDMSG_QUEUE, 0, 0, null, 0);
758                     break;
759                 default:
760                     break;
761             }
762         }
763     };
764 
765     /**
766      * Current ringer mode from one of {@link AudioManager#RINGER_MODE_NORMAL},
767      * {@link AudioManager#RINGER_MODE_SILENT}, or
768      * {@link AudioManager#RINGER_MODE_VIBRATE}.
769      */
770     @GuardedBy("mSettingsLock")
771     private int mRingerMode;  // internal ringer mode, affects muting of underlying streams
772     @GuardedBy("mSettingsLock")
773     private int mRingerModeExternal = -1;  // reported ringer mode to outside clients (AudioManager)
774 
775     /** @see System#MODE_RINGER_STREAMS_AFFECTED */
776     @VisibleForTesting
777     protected int mRingerModeAffectedStreams = 0;
778 
779     private int mZenModeAffectedStreams = 0;
780 
781     // Streams currently muted by ringer mode and dnd
782     protected static volatile int sRingerAndZenModeMutedStreams;
783 
784     /** Streams that can be muted by system. Do not resolve to aliases when checking.
785      * @see System#MUTE_STREAMS_AFFECTED */
786     protected int mMuteAffectedStreams;
787 
788     /** Streams that can be muted by user. Do not resolve to aliases when checking.
789      * @see System#MUTE_STREAMS_AFFECTED */
790     private int mUserMutableStreams;
791 
792     /** The active bluetooth device type used for communication is sco. */
793     /*package*/ static final int BT_COMM_DEVICE_ACTIVE_SCO = 1;
794     /** The active bluetooth device type used for communication is ble headset. */
795     /*package*/ static final int BT_COMM_DEVICE_ACTIVE_BLE_HEADSET = 1 << 1;
796     /** The active bluetooth device type used for communication is ble speaker. */
797     /*package*/ static final int BT_COMM_DEVICE_ACTIVE_BLE_SPEAKER = 1 << 2;
798     @IntDef({
799             BT_COMM_DEVICE_ACTIVE_SCO, BT_COMM_DEVICE_ACTIVE_BLE_HEADSET,
800             BT_COMM_DEVICE_ACTIVE_BLE_SPEAKER
801     })
802     @Retention(RetentionPolicy.SOURCE)
803     public @interface BtCommDeviceActiveType {
804     }
805 
806     private final AtomicInteger mBtCommDeviceActive = new AtomicInteger(0);
807 
808     @NonNull
809     private SoundEffectsHelper mSfxHelper;
810 
811     /**
812      * NOTE: setVibrateSetting(), getVibrateSetting(), shouldVibrate() are deprecated.
813      * mVibrateSetting is just maintained during deprecation period but vibration policy is
814      * now only controlled by mHasVibrator and mRingerMode
815      */
816     private int mVibrateSetting;
817 
818     // Is there a vibrator
819     private final boolean mHasVibrator;
820     // Used to play vibrations
821     private Vibrator mVibrator;
822     private static final VibrationAttributes TOUCH_VIBRATION_ATTRIBUTES =
823             VibrationAttributes.createForUsage(VibrationAttributes.USAGE_TOUCH);
824 
825     // Handler for broadcast receiver
826     // TODO(b/335513647) combine handlers
827     private final HandlerThread mBroadcastHandlerThread;
828     // Broadcast receiver for device connections intent broadcasts
829     private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver();
830 
831     private final Executor mAudioServerLifecycleExecutor;
832     private long mSysPropListenerNativeHandle;
833     private CacheWatcher mCacheWatcher;
834     private final List<Future> mScheduledPermissionTasks = new ArrayList();
835 
836     private IMediaProjectionManager mProjectionService; // to validate projection token
837 
838     /** Interface for UserManagerService. */
839     private final UserManagerInternal mUserManagerInternal;
840     private final ActivityManagerInternal mActivityManagerInternal;
841     private final SensorPrivacyManagerInternal mSensorPrivacyManagerInternal;
842 
843     private final UserRestrictionsListener mUserRestrictionsListener =
844             new AudioServiceUserRestrictionsListener();
845 
846     private final IAudioManagerNative mNativeShim = new IAudioManagerNative.Stub() {
847         static final String METRIC_COUNTERS_PLAYBACK_PARTIAL =
848                 "media_audio.value_audio_playback_hardening_partial_restriction";
849         static final String METRIC_COUNTERS_PLAYBACK_STRICT =
850                 "media_audio.value_audio_playback_hardening_strict_would_restrict";
851         // oneway
852         @Override
853         public void playbackHardeningEvent(int uid, byte type, boolean bypassed) {
854             if (Binder.getCallingUid() != Process.AUDIOSERVER_UID) {
855                 return;
856             }
857             if (type == HardeningType.PARTIAL) {
858                 Counter.logIncrementWithUid(METRIC_COUNTERS_PLAYBACK_PARTIAL, uid);
859             } else if (type == HardeningType.FULL) {
860                 Counter.logIncrementWithUid(METRIC_COUNTERS_PLAYBACK_STRICT, uid);
861             } else {
862                 Slog.wtf(TAG, "Unexpected hardening type" + type);
863                 return;
864             }
865             String msg = "AudioHardening background playback "
866                     + (bypassed ? "would be " : "")
867                     + "muted for "
868                     + getPackageNameForUid(uid) + " (" + uid + "), "
869                     + "level: " + (type == HardeningType.PARTIAL ? "partial" : "full");
870 
871             AudioService.this.mHardeningLogger.enqueueAndSlog(msg,
872                     bypassed ? EventLogger.Event.ALOGI : EventLogger.Event.ALOGW, TAG);
873         }
874 
875         @Override
876         public void permissionUpdateBarrier() {
877             AudioService.this.permissionUpdateBarrier();
878         }
879 
880         /**
881          * Update mute state event for port
882          * @param portId Port id to update
883          * @param event the mute event containing info about the mute
884          */
885         @Override
886         public void portMuteEvent(int portId, int event) {
887             mPlaybackMonitor.portMuteEvent(portId, event, Binder.getCallingUid());
888         }
889     };
890 
891     // List of binder death handlers for setMode() client processes.
892     // The last process to have called setMode() is at the top of the list.
893     // package-private so it can be accessed in AudioDeviceBroker.getSetModeDeathHandlers
894     //TODO candidate to be moved to separate class that handles synchronization
895     @GuardedBy("mDeviceBroker.mSetModeLock")
896     /*package*/ final ArrayList<SetModeDeathHandler> mSetModeDeathHandlers =
897             new ArrayList<SetModeDeathHandler>();
898 
899     // true if boot sequence has been completed
900     private boolean mSystemReady;
901     // true if Intent.ACTION_USER_SWITCHED has ever been received
902     private boolean mUserSwitchedReceived;
903     // previous volume adjustment direction received by checkForRingerModeChange()
904     private int mPrevVolDirection = AudioManager.ADJUST_SAME;
905     // mVolumeControlStream is set by VolumePanel to temporarily force the stream type which volume
906     // is controlled by Vol keys.
907     private int mVolumeControlStream = -1;
908     // interpretation of whether the volume stream has been selected by the user by clicking on a
909     // volume slider to change which volume is controlled by the volume keys. Is false
910     // when mVolumeControlStream is -1.
911     private boolean mUserSelectedVolumeControlStream = false;
912     private final Object mForceControlStreamLock = new Object();
913     // VolumePanel is currently the only client of forceVolumeControlStream() and runs in system
914     // server process so in theory it is not necessary to monitor the client death.
915     // However it is good to be ready for future evolutions.
916     private ForceControlStreamClient mForceControlStreamClient = null;
917     // Used to play ringtones outside system_server
918     private volatile IRingtonePlayer mRingtonePlayer;
919 
920     // Devices for which the volume is fixed (volume is either max or muted)
921     Set<Integer> mFixedVolumeDevices = new HashSet<>(Arrays.asList(
922             AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET,
923             AudioSystem.DEVICE_OUT_AUX_LINE));
924     // Devices for which the volume is always max, no volume panel
925     Set<Integer> mFullVolumeDevices = new HashSet<>(Arrays.asList(
926             AudioSystem.DEVICE_OUT_HDMI_ARC,
927             AudioSystem.DEVICE_OUT_HDMI_EARC
928     ));
929 
930     private final Object mAbsoluteVolumeDeviceInfoMapLock = new Object();
931     // Devices where the framework sends a full scale audio signal, and controls the volume of
932     // the external audio system separately.
933     // For possible volume behaviors, see
934     // {@link AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior}.
935     @GuardedBy("mAbsoluteVolumeDeviceInfoMapLock")
936     Map<Integer, AbsoluteVolumeDeviceInfo> mAbsoluteVolumeDeviceInfoMap = new ArrayMap<>();
937 
938     /**
939      * Stores information about a device using absolute volume behavior.
940      */
941     private static final class AbsoluteVolumeDeviceInfo implements IBinder.DeathRecipient {
942         private final AudioService mParent;
943         private final AudioDeviceAttributes mDevice;
944         private final List<VolumeInfo> mVolumeInfos;
945         private final IAudioDeviceVolumeDispatcher mCallback;
946         private final boolean mHandlesVolumeAdjustment;
947         private @AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior int mDeviceVolumeBehavior;
948 
AbsoluteVolumeDeviceInfo( AudioService parent, AudioDeviceAttributes device, List<VolumeInfo> volumeInfos, IAudioDeviceVolumeDispatcher callback, boolean handlesVolumeAdjustment, @AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior int behavior)949         private AbsoluteVolumeDeviceInfo(
950                 AudioService parent,
951                 AudioDeviceAttributes device,
952                 List<VolumeInfo> volumeInfos,
953                 IAudioDeviceVolumeDispatcher callback,
954                 boolean handlesVolumeAdjustment,
955                 @AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior int behavior) {
956             this.mParent = parent;
957             this.mDevice = device;
958             this.mVolumeInfos = volumeInfos;
959             this.mCallback = callback;
960             this.mHandlesVolumeAdjustment = handlesVolumeAdjustment;
961             this.mDeviceVolumeBehavior = behavior;
962 
963             try {
964                 this.mCallback.asBinder().linkToDeath(this, 0);
965             } catch (RemoteException | NullPointerException e) {
966                 // NPE can be raised when mocking the callback object
967                 Slog.w(TAG, "Exception: " + e
968                         + "\nCannot listen to callback binder death for device " + mDevice);
969             }
970         }
971 
972         /**
973          * Given a stream type, returns a matching VolumeInfo.
974          */
975         @Nullable
getMatchingVolumeInfoForStream(int streamType)976         private VolumeInfo getMatchingVolumeInfoForStream(int streamType) {
977             for (VolumeInfo volumeInfo : mVolumeInfos) {
978                 boolean streamTypeMatches = volumeInfo.hasStreamType()
979                         && volumeInfo.getStreamType() == streamType;
980                 boolean volumeGroupMatches = volumeInfo.hasVolumeGroup()
981                         && Arrays.stream(volumeInfo.getVolumeGroup().getLegacyStreamTypes())
982                         .anyMatch(s -> s == streamType);
983                 if (streamTypeMatches || volumeGroupMatches) {
984                     return volumeInfo;
985                 }
986             }
987             return null;
988         }
989 
990         @Override
binderDied()991         public void binderDied() {
992             if (mParent.removeAudioSystemDeviceOutFromAbsVolumeDevices(mDevice.getInternalType())
993                     != null) {
994                 mParent.dispatchDeviceVolumeBehavior(mDevice,
995                         AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE);
996             }
997         }
998 
unlinkToDeath()999         public void unlinkToDeath() {
1000             try {
1001                 mCallback.asBinder().unlinkToDeath(this, 0);
1002             } catch (NullPointerException e) {
1003                 // NPE can be raised when mocking the callback object
1004                 Slog.w(TAG, "Exception: " + e
1005                         + "\nCannot unlink to death, null binder object for device " + mDevice);
1006             }
1007         }
1008     }
1009 
1010     // Devices for the which use the "absolute volume" concept (framework sends audio signal
1011     // full scale, and volume control separately) and can be used for multiple use cases reflected
1012     // by the audio mode (e.g. media playback in MODE_NORMAL, and phone calls in MODE_IN_CALL).
1013     Set<Integer> mAbsVolumeMultiModeCaseDevices = new HashSet<>(
1014             Arrays.asList(AudioSystem.DEVICE_OUT_HEARING_AID,
1015                           AudioSystem.DEVICE_OUT_BLE_HEADSET,
1016                           AudioSystem.DEVICE_OUT_BLE_SPEAKER));
1017 
1018     private final boolean mMonitorRotation;
1019 
1020     private boolean mDockAudioMediaEnabled = true;
1021 
1022     /**
1023      * RestorableParameters is a thread-safe class used to store a
1024      * first-in first-out history of parameters for replay / restoration.
1025      *
1026      * The idealized implementation of restoration would have a list of setting methods and
1027      * values to be called for restoration.  Explicitly managing such setters and
1028      * values would be tedious - a simpler method is to store the values and the
1029      * method implicitly by lambda capture (the values must be immutable or synchronization
1030      * needs to be taken).
1031      *
1032      * We provide queueRestoreWithRemovalIfTrue() to allow
1033      * the caller to provide a BooleanSupplier lambda, which conveniently packages
1034      * the setter and its parameters needed for restoration.  If during restoration,
1035      * the BooleanSupplier returns true, e.g. on error, it is removed from the mMap
1036      * so as not to be called on a subsequent restore.
1037      *
1038      * We provide a setParameters() method as an example helper method.
1039      */
1040     private static class RestorableParameters {
1041         /**
1042          * Sets a parameter and queues for restoration if successful.
1043          *
1044          * @param id a string handle associated with this parameter.
1045          * @param parameter the actual parameter string.
1046          * @return the result of AudioSystem.setParameters
1047          */
setParameters(@onNull String id, @NonNull String parameter)1048         public int setParameters(@NonNull String id, @NonNull String parameter) {
1049             Objects.requireNonNull(id, "id must not be null");
1050             Objects.requireNonNull(parameter, "parameter must not be null");
1051             synchronized (mMap) {
1052                 final int status = AudioSystem.setParameters(parameter);
1053                 if (status == AudioSystem.AUDIO_STATUS_OK) { // Java uses recursive mutexes.
1054                     queueRestoreWithRemovalIfTrue(id, () -> { // remove me if set fails.
1055                         return AudioSystem.setParameters(parameter) != AudioSystem.AUDIO_STATUS_OK;
1056                     });
1057                 }
1058                 // Implementation detail: We do not mMap.remove(id); on failure.
1059                 return status;
1060             }
1061         }
1062 
1063         /**
1064          * Queues a restore method which is executed on restoreAll().
1065          *
1066          * If the supplier null, the id is removed from the restore map.
1067          *
1068          * Note: When the BooleanSupplier restore method is executed
1069          * during restoreAll, if it returns true, it is removed from the
1070          * restore map.
1071          *
1072          * @param id a unique tag associated with the restore method.
1073          * @param supplier is a BooleanSupplier lambda.
1074          */
queueRestoreWithRemovalIfTrue( @onNull String id, @Nullable BooleanSupplier supplier)1075         public void queueRestoreWithRemovalIfTrue(
1076                 @NonNull String id, @Nullable BooleanSupplier supplier) {
1077             Objects.requireNonNull(id, "id must not be null");
1078             synchronized (mMap) {
1079                 if (supplier != null) {
1080                     mMap.put(id, supplier);
1081                 } else {
1082                     mMap.remove(id);
1083                 }
1084             }
1085         }
1086 
1087         /**
1088          * Restore all parameters
1089          *
1090          * During restoration after audioserver death, any BooleanSupplier that returns
1091          * true, for example on parameter restoration error, will be removed from mMap
1092          * so as not to be executed on a subsequent restoreAll().
1093          */
restoreAll()1094         public void restoreAll() {
1095             synchronized (mMap) {
1096                 // Note: removing from values() also removes from the backing map.
1097                 // TODO: Consider catching exceptions?
1098                 mMap.values().removeIf(v -> {
1099                     return v.getAsBoolean(); // this iterates the setters().
1100                 });
1101             }
1102         }
1103 
1104         /**
1105          * mMap is a LinkedHashMap<Key, Value> of parameters restored by restore().
1106          * The Key is a unique id tag for identification.
1107          * The Value is a lambda expression which returns true if the entry is to
1108          *     be removed.
1109          *
1110          * 1) For memory limitation purposes, mMap keeps the latest MAX_ENTRIES
1111          *    accessed in the map.
1112          * 2) Parameters are restored in order of queuing, first in first out,
1113          *    from earliest to latest.
1114          */
1115         @GuardedBy("mMap")
1116         private Map</* @NonNull */ String, /* @NonNull */ BooleanSupplier> mMap =
1117                 new LinkedHashMap<>() {
1118             // TODO: do we need this memory limitation?
1119             private static final int MAX_ENTRIES = 1000;  // limit our memory for now.
1120             @Override
1121             protected boolean removeEldestEntry(Map.Entry eldest) {
1122                 if (size() <= MAX_ENTRIES) return false;
1123                 Log.w(TAG, "Parameter map exceeds "
1124                         + MAX_ENTRIES + " removing " + eldest.getKey()); // don't silently remove.
1125                 return true;
1126             }
1127         };
1128     }
1129 
1130     // We currently have one instance for mRestorableParameters used for
1131     // setAdditionalOutputDeviceDelay().  Other methods requiring restoration could share this
1132     // or use their own instance.
1133     private RestorableParameters mRestorableParameters = new RestorableParameters();
1134 
1135     private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
1136 
1137     private PowerManager.WakeLock mAudioEventWakeLock;
1138 
1139     private final MediaFocusControl mMediaFocusControl;
1140 
1141     // Pre-scale for Bluetooth Absolute Volume
1142     private float[] mPrescaleAbsoluteVolume = new float[] {
1143         0.6f,    // Pre-scale for index 1
1144         0.8f,    // Pre-scale for index 2
1145         0.9f,   // Pre-scale for index 3
1146     };
1147 
1148     private NotificationManager mNm;
1149     private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate;
1150     private volatile VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT;
1151     private long mLoweredFromNormalToVibrateTime;
1152 
1153     // Array of Uids of valid assistant services to check if caller is one of them
1154     @GuardedBy("mSettingsLock")
1155     private final ArraySet<Integer> mAssistantUids = new ArraySet<>();
1156     @GuardedBy("mSettingsLock")
1157     private int mPrimaryAssistantUid = INVALID_UID;
1158 
1159     // Array of Uids of valid active assistant service to check if caller is one of them
1160     @GuardedBy("mSettingsLock")
1161     private int[] mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS;
1162 
1163     // Array of Uids of valid accessibility services to check if caller is one of them
1164     private final Object mAccessibilityServiceUidsLock = new Object();
1165     @GuardedBy("mAccessibilityServiceUidsLock")
1166     private int[] mAccessibilityServiceUids;
1167 
1168     // Input Method
1169     private final Object mInputMethodServiceUidLock = new Object();
1170     // Uid of the active input method service to check if caller is the one or not.
1171     @GuardedBy("mInputMethodServiceUidLock")
1172     private int mInputMethodServiceUid = android.os.Process.INVALID_UID;
1173 
1174     private int mEncodedSurroundMode;
1175     private String mEnabledSurroundFormats;
1176     private boolean mSurroundModeChanged;
1177 
1178     private boolean mSupportsMicPrivacyToggle;
1179 
1180     private boolean mMicMuteFromSwitch;
1181     private boolean mMicMuteFromApi;
1182     private boolean mMicMuteFromRestrictions;
1183     private boolean mMicMuteFromPrivacyToggle;
1184     // caches the value returned by AudioSystem.isMicrophoneMuted()
1185     private boolean mMicMuteFromSystemCached;
1186 
1187     private boolean mNavigationRepeatSoundEffectsEnabled;
1188     private boolean mHomeSoundEffectEnabled;
1189 
1190     private final SoundDoseHelper mSoundDoseHelper;
1191 
1192     private final LoudnessCodecHelper mLoudnessCodecHelper;
1193 
1194     private final HardeningEnforcer mHardeningEnforcer;
1195 
1196     private final AudioVolumeGroupHelperBase mAudioVolumeGroupHelper;
1197 
1198     private final Object mSupportedSystemUsagesLock = new Object();
1199     @GuardedBy("mSupportedSystemUsagesLock")
1200     private @AttributeSystemUsage int[] mSupportedSystemUsages =
1201             new int[]{AudioAttributes.USAGE_CALL_ASSISTANT};
1202 
1203     // Tracks the API/shell override of hardening enforcement used for debugging
1204     // When this is set to true, enforcement is on regardless of flag state and any specific
1205     // exemptions in place for compat purposes.
1206     private final AtomicBoolean mShouldEnableAllHardening = new AtomicBoolean(false);
1207 
1208     // Defines the format for the connection "address" for ALSA devices
makeAlsaAddressString(int card, int device)1209     public static String makeAlsaAddressString(int card, int device) {
1210         return "card=" + card + ";device=" + device;
1211     }
1212 
1213     private static class AudioVolumeGroupHelper extends AudioVolumeGroupHelperBase {
1214         @Override
getAudioVolumeGroups()1215         public List<AudioVolumeGroup> getAudioVolumeGroups() {
1216             return AudioVolumeGroup.getAudioVolumeGroups();
1217         }
1218     }
1219 
1220     public static final class Lifecycle extends SystemService {
1221         private AudioService mService;
1222 
Lifecycle(Context context)1223         public Lifecycle(Context context) {
1224             super(context);
1225             var audioserverLifecycleExecutor = Executors.newSingleThreadScheduledExecutor(
1226                     (Runnable r) -> new Thread(r, "audioserver_lifecycle"));
1227             var audioPolicyFacade = new DefaultAudioPolicyFacade(audioserverLifecycleExecutor);
1228             mService = new AudioService(context,
1229                               AudioSystemAdapter.getDefaultAdapter(),
1230                               SystemServerAdapter.getDefaultAdapter(context),
1231                               SettingsAdapter.getDefaultAdapter(),
1232                               new AudioVolumeGroupHelper(),
1233                               audioPolicyFacade,
1234                               null,
1235                               context.getSystemService(AppOpsManager.class),
1236                               PermissionEnforcer.fromContext(context),
1237                               audioserverPermissions() ?
1238                                 initializeAudioServerPermissionProvider(
1239                                     context, audioPolicyFacade, audioserverLifecycleExecutor) :
1240                                     null,
1241                               audioserverLifecycleExecutor
1242                               );
1243         }
1244 
1245         @Override
onStart()1246         public void onStart() {
1247             publishBinderService(Context.AUDIO_SERVICE, mService);
1248         }
1249 
1250         @Override
onBootPhase(int phase)1251         public void onBootPhase(int phase) {
1252             if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
1253                 mService.systemReady();
1254             }
1255         }
1256     }
1257 
1258     final private IUidObserver mUidObserver = new UidObserver() {
1259         @Override public void onUidGone(int uid, boolean disabled) {
1260             // Once the uid is no longer running, no need to keep trying to disable its audio.
1261             disableAudioForUid(false, uid);
1262         }
1263 
1264         @Override public void onUidCachedChanged(int uid, boolean cached) {
1265             disableAudioForUid(cached, uid);
1266         }
1267 
1268         private void disableAudioForUid(boolean disable, int uid) {
1269             queueMsgUnderWakeLock(mAudioHandler, MSG_DISABLE_AUDIO_FOR_UID,
1270                     disable ? 1 : 0 /* arg1 */,  uid /* arg2 */,
1271                     null /* obj */,  0 /* delay */);
1272         }
1273     };
1274 
1275     private AtomicBoolean mRttEnabled = new AtomicBoolean(false);
1276 
1277     private AtomicBoolean mMasterMute = new AtomicBoolean(false);
1278 
1279     private DisplayManager mDisplayManager;
1280 
1281     private DisplayListener mDisplayListener =
1282       new DisplayListener() {
1283         @Override
1284         public void onDisplayAdded(int displayId) {}
1285 
1286         @Override
1287         public void onDisplayRemoved(int displayId) {}
1288 
1289         @Override
1290         public void onDisplayChanged(int displayId) {
1291             if (displayId != Display.DEFAULT_DISPLAY) {
1292                 return;
1293             }
1294             int displayState = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY).getState();
1295             if (displayState == Display.STATE_ON) {
1296                 if (mMonitorRotation) {
1297                     RotationHelper.enable();
1298                 }
1299                 AudioSystem.setParameters("screen_state=on");
1300             } else {
1301                 if (mMonitorRotation) {
1302                     //reduce wakeups (save current) by only listening when display is on
1303                     RotationHelper.disable();
1304                 }
1305                 AudioSystem.setParameters("screen_state=off");
1306             }
1307         }
1308       };
1309 
1310     ///////////////////////////////////////////////////////////////////////////
1311     // Construction
1312     ///////////////////////////////////////////////////////////////////////////
1313 
1314 
1315     /**
1316      * @param context
1317      * @param audioSystem Adapter for {@link AudioSystem}
1318      * @param systemServer Adapter for privilieged functionality for system server components
1319      * @param settings Adapter for {@link Settings}
1320      * @param audioVolumeGroupHelper Adapter for {@link AudioVolumeGroup}
1321      * @param audioPolicy Interface of a facade to IAudioPolicyManager
1322      * @param looper Looper to use for the service's message handler. If this is null, an
1323      *               {@link AudioSystemThread} is created as the messaging thread instead.
1324      * @param appOps {@link AppOpsManager} system service
1325      * @param enforcer Used for permission enforcing
1326      * @param permissionProvider Used to push permissions to audioserver
1327      * @param audioserverLifecycleExecutor Used for tasks managing audioserver lifecycle
1328      */
1329     @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, Executor audioserverLifecycleExecutor)1330     public AudioService(Context context, AudioSystemAdapter audioSystem,
1331             SystemServerAdapter systemServer, SettingsAdapter settings,
1332             AudioVolumeGroupHelperBase audioVolumeGroupHelper, AudioPolicyFacade audioPolicy,
1333             @Nullable Looper looper, AppOpsManager appOps, @NonNull PermissionEnforcer enforcer,
1334             /* @NonNull */ AudioServerPermissionProvider permissionProvider,
1335             Executor audioserverLifecycleExecutor) {
1336         super(enforcer);
1337         sLifecycleLogger.enqueue(new EventLogger.StringEvent("AudioService()"));
1338         mContext = context;
1339         mContentResolver = context.getContentResolver();
1340         mAppOps = appOps;
1341 
1342         mPermissionProvider = permissionProvider;
1343         mAudioServerLifecycleExecutor = audioserverLifecycleExecutor;
1344 
1345         mAudioSystem = audioSystem;
1346         mSystemServer = systemServer;
1347         mAudioVolumeGroupHelper = audioVolumeGroupHelper;
1348         mSettings = settings;
1349         mAudioPolicy = audioPolicy;
1350         mAudioPolicy.registerOnStartTask(() -> {
1351             mAudioPolicy.setEnableHardening(mShouldEnableAllHardening.get());
1352         });
1353 
1354         mPlatformType = AudioSystem.getPlatformType(context);
1355 
1356         mBroadcastHandlerThread = new HandlerThread("AudioService Broadcast");
1357         mBroadcastHandlerThread.start();
1358 
1359         mDeviceBroker = new AudioDeviceBroker(mContext, this, mAudioSystem);
1360 
1361         mIsSingleVolume = AudioSystem.isSingleVolume(context);
1362 
1363         mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
1364         mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
1365         mSensorPrivacyManagerInternal =
1366                 LocalServices.getService(SensorPrivacyManagerInternal.class);
1367 
1368         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
1369         mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent");
1370 
1371         mSfxHelper = new SoundEffectsHelper(mContext, playerBase -> ignorePlayerLogs(playerBase));
1372 
1373         boolean binauralEnabledDefault = SystemProperties.getBoolean(
1374                 "ro.audio.spatializer_binaural_enabled_default", true);
1375         boolean transauralEnabledDefault = SystemProperties.getBoolean(
1376                 "ro.audio.spatializer_transaural_enabled_default", true);
1377         boolean headTrackingEnabledDefault = mContext.getResources().getBoolean(
1378                 com.android.internal.R.bool.config_spatial_audio_head_tracking_enabled_default);
1379 
1380         mSpatializerHelper = new SpatializerHelper(this, mAudioSystem, mDeviceBroker,
1381                 binauralEnabledDefault, transauralEnabledDefault, headTrackingEnabledDefault);
1382 
1383         mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
1384         mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator();
1385 
1386         mSupportsMicPrivacyToggle = context.getSystemService(SensorPrivacyManager.class)
1387                 .supportsSensorToggle(SensorPrivacyManager.Sensors.MICROPHONE);
1388 
1389         mUseVolumeGroupAliases = mContext.getResources().getBoolean(
1390                 com.android.internal.R.bool.config_handleVolumeAliasesUsingVolumeGroups);
1391 
1392         mAudioVolumeChangeHandler = new AudioVolumeChangeHandler(mAudioSystem);
1393         // Initialize volume
1394         // Priority 1 - Android Property
1395         // Priority 2 - Audio Policy Service
1396         // Priority 3 - Default Value
1397         if (AudioProductStrategy.getAudioProductStrategies().size() > 0) {
1398             int numStreamTypes = AudioSystem.getNumStreamTypes();
1399 
1400             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
1401                 AudioAttributes attr =
1402                         AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(
1403                                 streamType);
1404                 int maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr);
1405                 if (maxVolume != -1) {
1406                     MAX_STREAM_VOLUME[streamType] = maxVolume;
1407                 }
1408                 int minVolume = AudioSystem.getMinVolumeIndexForAttributes(attr);
1409                 if (minVolume != -1) {
1410                     MIN_STREAM_VOLUME[streamType] = minVolume;
1411                 }
1412             }
1413             if (mUseVolumeGroupAliases) {
1414                 // Set all default to uninitialized.
1415                 for (int stream = 0; stream < AudioSystem.DEFAULT_STREAM_VOLUME.length; stream++) {
1416                     AudioSystem.DEFAULT_STREAM_VOLUME[stream] = UNSET_INDEX;
1417                 }
1418             }
1419         }
1420 
1421         int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1);
1422         if (maxCallVolume != -1) {
1423             MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxCallVolume;
1424         }
1425 
1426         int defaultCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_default", -1);
1427         if (defaultCallVolume != -1 &&
1428                 defaultCallVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] &&
1429                 defaultCallVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]) {
1430             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = defaultCallVolume;
1431         } else {
1432             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] =
1433                     (MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] * 3) / 4;
1434         }
1435 
1436         int maxMusicVolume = SystemProperties.getInt("ro.config.media_vol_steps", -1);
1437         if (maxMusicVolume != -1) {
1438             MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxMusicVolume;
1439         }
1440 
1441         int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", -1);
1442         if (defaultMusicVolume != -1 &&
1443                 defaultMusicVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] &&
1444                 defaultMusicVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) {
1445             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = defaultMusicVolume;
1446         } else {
1447             if (isPlatformTelevision()) {
1448                 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] =
1449                         MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 4;
1450             } else {
1451                 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] =
1452                         MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 3;
1453             }
1454         }
1455 
1456         int maxAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_steps", -1);
1457         if (maxAlarmVolume != -1) {
1458             MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = maxAlarmVolume;
1459         }
1460 
1461         if (alarmMinVolumeZero()) {
1462             try {
1463                 int minAlarmVolume = mContext.getResources().getInteger(
1464                         com.android.internal.R.integer.config_audio_alarm_min_vol);
1465                 if (minAlarmVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]) {
1466                     MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = minAlarmVolume;
1467                 } else {
1468                     Log.e(TAG, "Error min alarm volume greater than max alarm volume");
1469                 }
1470             } catch (Resources.NotFoundException e) {
1471                 Log.e(TAG, "Error querying for alarm min volume ", e);
1472             }
1473         }
1474         int defaultAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_default", -1);
1475         if (defaultAlarmVolume != -1 &&
1476                 defaultAlarmVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]) {
1477             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = defaultAlarmVolume;
1478         } else {
1479             // Default is 6 out of 7 (default maximum), so scale accordingly.
1480             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] =
1481                         6 * MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] / 7;
1482         }
1483 
1484         int maxSystemVolume = SystemProperties.getInt("ro.config.system_vol_steps", -1);
1485         if (maxSystemVolume != -1) {
1486             MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = maxSystemVolume;
1487         }
1488 
1489         int defaultSystemVolume = SystemProperties.getInt("ro.config.system_vol_default", -1);
1490         if (defaultSystemVolume != -1 &&
1491                 defaultSystemVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]) {
1492             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = defaultSystemVolume;
1493         } else {
1494             // Default is to use maximum.
1495             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] =
1496                         MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM];
1497         }
1498 
1499         int minAssistantVolume = SystemProperties.getInt("ro.config.assistant_vol_min", -1);
1500         if (minAssistantVolume != -1) {
1501             MIN_STREAM_VOLUME[AudioSystem.STREAM_ASSISTANT] = minAssistantVolume;
1502         }
1503 
1504         // Read following properties to configure max volume (number of steps) and default volume
1505         //   for STREAM_NOTIFICATION and STREAM_RING:
1506         //      config_audio_notif_vol_default
1507         //      config_audio_notif_vol_steps
1508         //      config_audio_ring_vol_default
1509         //      config_audio_ring_vol_steps
1510         int[] streams = { AudioSystem.STREAM_NOTIFICATION, AudioSystem.STREAM_RING };
1511         int[] stepsResId = { com.android.internal.R.integer.config_audio_notif_vol_steps,
1512                 com.android.internal.R.integer.config_audio_ring_vol_steps };
1513         int[] defaultResId = { com.android.internal.R.integer.config_audio_notif_vol_default,
1514                 com.android.internal.R.integer.config_audio_ring_vol_default };
1515         for (int s = 0; s < streams.length; s++) {
1516             try {
1517                 final int maxVol = mContext.getResources().getInteger(stepsResId[s]);
1518                 if (maxVol <= 0) {
1519                     throw new IllegalArgumentException("Invalid negative max volume for stream "
1520                             + streams[s]);
1521                 }
1522                 Log.i(TAG, "Stream " + streams[s] + ": using max vol of " + maxVol);
1523                 MAX_STREAM_VOLUME[streams[s]] = maxVol;
1524             } catch (Resources.NotFoundException e) {
1525                 Log.e(TAG, "Error querying max vol for stream type " + streams[s], e);
1526             }
1527             try {
1528                 final int defaultVol = mContext.getResources().getInteger(defaultResId[s]);
1529                 if (defaultVol > MAX_STREAM_VOLUME[streams[s]]) {
1530                     throw new IllegalArgumentException("Invalid default volume (" + defaultVol
1531                             + ") for stream " + streams[s] + ", greater than max volume of "
1532                             + MAX_STREAM_VOLUME[streams[s]]);
1533                 }
1534                 if (defaultVol < MIN_STREAM_VOLUME[streams[s]]) {
1535                     throw new IllegalArgumentException("Invalid default volume (" + defaultVol
1536                             + ") for stream " + streams[s] + ", lower than min volume of "
1537                             + MIN_STREAM_VOLUME[streams[s]]);
1538                 }
1539                 Log.i(TAG, "Stream " + streams[s] + ": using default vol of " + defaultVol);
1540                 AudioSystem.DEFAULT_STREAM_VOLUME[streams[s]] = defaultVol;
1541             } catch (Resources.NotFoundException e) {
1542                 Log.e(TAG, "Error querying default vol for stream type " + streams[s], e);
1543             }
1544         }
1545 
1546         if (looper == null) {
1547             createAudioSystemThread();
1548         } else {
1549             mAudioHandler = new AudioHandler(looper);
1550         }
1551 
1552         mSoundDoseHelper = new SoundDoseHelper(this, mContext, mAudioHandler, mSettings,
1553                 mVolumeController);
1554 
1555         AudioSystem.setErrorCallback(mAudioSystemCallback);
1556 
1557         updateAudioHalPids();
1558 
1559         mUseFixedVolume = mContext.getResources().getBoolean(
1560                 com.android.internal.R.bool.config_useFixedVolume);
1561 
1562         mRingerModeAffectsAlarm = mContext.getResources().getBoolean(
1563                 com.android.internal.R.bool.config_audio_ringer_mode_affects_alarm_stream);
1564 
1565         mRecordMonitor = new RecordingActivityMonitor(mContext);
1566         mRecordMonitor.registerRecordingCallback(mVoiceRecordingActivityMonitor, true);
1567 
1568         // must be called before readPersistedSettings() which needs a valid sStreamVolumeAlias[]
1569         // array initialized by updateStreamVolumeAlias()
1570         updateStreamVolumeAlias(false /*updateVolumes*/, TAG);
1571         readPersistedSettings();
1572         readUserRestrictions();
1573 
1574         mLoudnessCodecHelper = new LoudnessCodecHelper(this);
1575 
1576         mPlaybackMonitor =
1577                 new PlaybackActivityMonitor(context, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM],
1578                         device -> onMuteAwaitConnectionTimeout(device),
1579                         stream -> isStreamMute(stream));
1580         mPlaybackMonitor.registerPlaybackCallback(mPlaybackActivityMonitor, true);
1581 
1582         mMediaFocusControl = new MediaFocusControl(mContext, mPlaybackMonitor);
1583 
1584         readAndSetLowRamDevice();
1585 
1586         mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported();
1587 
1588         if (mSystemServer.isPrivileged()) {
1589             LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal());
1590 
1591             mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
1592 
1593             mRecordMonitor.initMonitor();
1594         }
1595 
1596         mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false);
1597 
1598         mHasSpatializerEffect = SystemProperties.getBoolean("ro.audio.spatializer_enabled", false);
1599 
1600         // monitor routing updates coming from native
1601         mAudioSystem.setRoutingListener(this);
1602         // monitor requests for volume range initialization coming from native (typically when
1603         // errors are found by AudioPolicyManager
1604         mAudioSystem.setVolRangeInitReqListener(this);
1605 
1606         // done with service initialization, continue additional work in our Handler thread
1607         queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_STREAMS_VOLUMES,
1608                 0 /* arg1 */,  0 /* arg2 */, null /* obj */,  0 /* delay */);
1609         queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_ADI_DEVICE_STATES,
1610                 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */);
1611         queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_SPATIALIZER,
1612                 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */);
1613         if (enableAudioInputDeviceRoutingAndVolumeControl()) {
1614             queueMsgUnderWakeLock(
1615                     mAudioHandler,
1616                     MSG_INIT_INPUT_GAINS,
1617                     0 /* arg1 */,
1618                     0 /* arg2 */,
1619                     null /* obj */,
1620                     0 /* delay */);
1621         }
1622 
1623         mDisplayManager = context.getSystemService(DisplayManager.class);
1624 
1625         mMusicFxHelper = new MusicFxHelper(mContext, mAudioHandler);
1626 
1627         mHardeningEnforcer = new HardeningEnforcer(mContext, isPlatformAutomotive(),
1628                 mShouldEnableAllHardening,
1629                 mAppOps,
1630                 context.getPackageManager(),
1631                 mHardeningLogger);
1632     }
1633 
initVolumeStreamStates()1634     private void initVolumeStreamStates() {
1635         int numStreamTypes = AudioSystem.getNumStreamTypes();
1636         synchronized (mVolumeStateLock) {
1637             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
1638                 final VolumeStreamState streamState = getVssForStream(streamType);
1639                 if (streamState == null) {
1640                     continue;
1641                 }
1642                 int groupId = getVolumeGroupForStreamType(streamType);
1643                 if (groupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP
1644                         && sVolumeGroupStates.indexOfKey(groupId) >= 0) {
1645                     streamState.setVolumeGroupState(sVolumeGroupStates.get(groupId));
1646                 }
1647             }
1648         }
1649     }
1650 
1651     /**
1652      * Called by handling of MSG_INIT_STREAMS_VOLUMES
1653      */
onInitStreamsAndVolumes()1654     private void onInitStreamsAndVolumes() {
1655         synchronized (this) {
1656             mCameraSoundForced.set(readCameraSoundForced());
1657             sendMsg(mAudioHandler,
1658                     MSG_SET_FORCE_USE,
1659                     SENDMSG_QUEUE,
1660                     AudioSystem.FOR_SYSTEM,
1661                     mCameraSoundForced.get()
1662                             ? AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE,
1663                     new String("AudioService ctor"),
1664                     0);
1665         }
1666 
1667         createStreamStates();
1668 
1669         // must be called after createStreamStates() as it uses MUSIC volume as default if no
1670         // persistent data
1671         initVolumeGroupStates();
1672 
1673         mSoundDoseHelper.initSafeMediaVolumeIndex();
1674         // Link VGS on VSS
1675         initVolumeStreamStates();
1676 
1677         // Call setRingerModeInt() to apply correct mute
1678         // state on streams affected by ringer mode.
1679         sRingerAndZenModeMutedStreams = 0;
1680         sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent(
1681                 sRingerAndZenModeMutedStreams, "onInitStreamsAndVolumes"));
1682         setRingerModeInt(getRingerModeInternal(), false);
1683 
1684         if (!disablePrescaleAbsoluteVolume()) {
1685             final float[] preScale = new float[3];
1686             preScale[0] = mContext.getResources().getFraction(
1687                     com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index1,
1688                     1, 1);
1689             preScale[1] = mContext.getResources().getFraction(
1690                     com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index2,
1691                     1, 1);
1692             preScale[2] = mContext.getResources().getFraction(
1693                     com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index3,
1694                     1, 1);
1695             for (int i = 0; i < preScale.length; i++) {
1696                 if (0.0f <= preScale[i] && preScale[i] <= 1.0f) {
1697                     mPrescaleAbsoluteVolume[i] = preScale[i];
1698                 }
1699             }
1700         }
1701 
1702         initExternalEventReceivers();
1703 
1704         // check on volume initialization
1705         checkVolumeRangeInitialization("AudioService()");
1706 
1707         synchronized (mCachedAbsVolDrivingStreamsLock) {
1708             mCachedAbsVolDrivingStreams.forEach((dev, stream) -> {
1709                 boolean enabled = true;
1710                 if (dev == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
1711                     enabled = mAvrcpAbsVolSupported;
1712                 }
1713                 final int result = mAudioSystem.setDeviceAbsoluteVolumeEnabled(dev, /*address=*/"",
1714                         enabled, stream);
1715                 if (result != AudioSystem.AUDIO_STATUS_OK) {
1716                     sVolumeLogger.enqueueAndSlog(
1717                             new VolumeEvent(VolumeEvent.VOL_ABS_DEVICE_ENABLED_ERROR,
1718                                     result, dev, enabled, stream).eventToString(), ALOGE, TAG);
1719 
1720                 }
1721             });
1722         }
1723     }
1724 
1725     /** Called by handling of MSG_INIT_INPUT_GAINS */
onInitInputGains()1726     private void onInitInputGains() {
1727         mInputDeviceVolumeHelper =
1728                 new InputDeviceVolumeHelper(
1729                         mSettings,
1730                         mContentResolver,
1731                         System.INPUT_GAIN_INDEX_SETTINGS);
1732     }
1733 
1734     private SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionChangedListener =
1735             new SubscriptionManager.OnSubscriptionsChangedListener() {
1736                 @Override
1737                 public void onSubscriptionsChanged() {
1738                     Log.i(TAG, "onSubscriptionsChanged()");
1739                     sendMsg(mAudioHandler, MSG_CONFIGURATION_CHANGED, SENDMSG_REPLACE,
1740                             0, 0, null, 0);
1741                 }
1742             };
1743 
getMediaSessionManager()1744     private MediaSessionManager getMediaSessionManager() {
1745         if (mMediaSessionManager == null) {
1746             mMediaSessionManager = (MediaSessionManager) mContext
1747                     .getSystemService(Context.MEDIA_SESSION_SERVICE);
1748         }
1749         return mMediaSessionManager;
1750     }
1751 
1752     /**
1753      * Initialize intent receives and settings observers for this service.
1754      * Must be called after createStreamStates() as the handling of some events
1755      * may affect or need volumes, e.g. BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED
1756      * (for intent receiver), or Settings.Global.ZEN_MODE (for settings observer)
1757      */
initExternalEventReceivers()1758     private void initExternalEventReceivers() {
1759         mSettingsObserver = new SettingsObserver();
1760 
1761         // Register for device connection intent broadcasts.
1762         IntentFilter intentFilter =
1763                 new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
1764         if (!mDeviceBroker.isScoManagedByAudio()) {
1765             intentFilter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED);
1766         }
1767         intentFilter.addAction(Intent.ACTION_DOCK_EVENT);
1768         if (mDisplayManager == null) {
1769             intentFilter.addAction(Intent.ACTION_SCREEN_ON);
1770             intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
1771         }
1772         intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
1773         intentFilter.addAction(Intent.ACTION_USER_BACKGROUND);
1774         intentFilter.addAction(Intent.ACTION_USER_FOREGROUND);
1775         intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
1776         intentFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
1777 
1778         intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
1779         if (mMonitorRotation) {
1780             RotationHelper.init(mContext, mAudioHandler,
1781                     rotation -> onRotationUpdate(rotation),
1782                     foldState -> onFoldStateUpdate(foldState));
1783         }
1784 
1785         intentFilter.addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION);
1786         intentFilter.addAction(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION);
1787         intentFilter.addAction(ACTION_CHECK_MUSIC_ACTIVE);
1788         intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
1789 
1790         mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null,
1791                 mBroadcastHandlerThread.getThreadHandler(),
1792                 Context.RECEIVER_EXPORTED);
1793 
1794         SubscriptionManager subscriptionManager = mContext.getSystemService(
1795                 SubscriptionManager.class);
1796         if (subscriptionManager == null) {
1797             Log.e(TAG, "initExternalEventReceivers cannot create SubscriptionManager!");
1798         } else {
1799             subscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionChangedListener);
1800         }
1801 
1802         if (mDisplayManager != null) {
1803             mDisplayManager.registerDisplayListener(mDisplayListener, mAudioHandler);
1804         }
1805     }
1806 
systemReady()1807     public void systemReady() {
1808         sendMsg(mAudioHandler, MSG_SYSTEM_READY, SENDMSG_QUEUE,
1809                 0, 0, null, 0);
1810         if (false) {
1811             // This is turned off for now, because it is racy and thus causes apps to break.
1812             // Currently banning a uid means that if an app tries to start playing an audio
1813             // stream, that will be preventing, and unbanning it will not allow that stream
1814             // to resume.  However these changes in uid state are racy with what the app is doing,
1815             // so that after taking a process out of the cached state we can't guarantee that
1816             // we will unban the uid before the app actually tries to start playing audio.
1817             // (To do that, the activity manager would need to wait until it knows for sure
1818             // that the ban has been removed, before telling the app to do whatever it is
1819             // supposed to do that caused it to go out of the cached state.)
1820             try {
1821                 ActivityManager.getService().registerUidObserver(mUidObserver,
1822                         ActivityManager.UID_OBSERVER_CACHED | ActivityManager.UID_OBSERVER_GONE,
1823                         ActivityManager.PROCESS_STATE_UNKNOWN, null);
1824             } catch (RemoteException e) {
1825                 // ignored; both services live in system_server
1826             }
1827         }
1828     }
1829 
updateVibratorInfos()1830     private void updateVibratorInfos() {
1831         VibratorManager vibratorManager = mContext.getSystemService(VibratorManager.class);
1832         if (vibratorManager == null) {
1833             Slog.e(TAG, "Vibrator manager is not found");
1834             return;
1835         }
1836         int[] vibratorIds = vibratorManager.getVibratorIds();
1837         if (vibratorIds.length == 0) {
1838             Slog.d(TAG, "No vibrator found");
1839             return;
1840         }
1841         List<Vibrator> vibrators = new ArrayList<>(vibratorIds.length);
1842         for (int id : vibratorIds) {
1843             Vibrator vibrator = vibratorManager.getVibrator(id);
1844             if (vibrator != null) {
1845                 vibrators.add(vibrator);
1846             } else {
1847                 Slog.w(TAG, "Vibrator(" + id + ") is not found");
1848             }
1849         }
1850         if (vibrators.isEmpty()) {
1851             Slog.w(TAG, "Cannot find any available vibrator");
1852             return;
1853         }
1854         AudioSystem.setVibratorInfos(vibrators);
1855     }
1856 
onSystemReady()1857     public void onSystemReady() {
1858         mSystemReady = true;
1859         if (audioserverPermissions()) {
1860             setupPermissionListener();
1861         }
1862         scheduleLoadSoundEffects();
1863         mDeviceBroker.onSystemReady();
1864 
1865         if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_HDMI_CEC)) {
1866             synchronized (mHdmiClientLock) {
1867                 mHdmiManager = mContext.getSystemService(HdmiControlManager.class);
1868                 if (mHdmiManager != null) {
1869                     mHdmiManager.addHdmiControlStatusChangeListener(
1870                             mHdmiControlStatusChangeListenerCallback);
1871                     mHdmiManager.addHdmiCecVolumeControlFeatureListener(mContext.getMainExecutor(),
1872                             mMyHdmiCecVolumeControlFeatureListener);
1873                 }
1874                 mHdmiTvClient = mHdmiManager.getTvClient();
1875                 if (mHdmiTvClient != null) {
1876                     mFixedVolumeDevices.removeAll(
1877                             AudioSystem.DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET);
1878                 }
1879                 mHdmiPlaybackClient = mHdmiManager.getPlaybackClient();
1880                 mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient();
1881             }
1882         }
1883 
1884         if (mSupportsMicPrivacyToggle) {
1885             mSensorPrivacyManagerInternal.addSensorPrivacyListenerForAllUsers(
1886                     SensorPrivacyManager.Sensors.MICROPHONE, (userId, enabled) -> {
1887                         if (userId == getCurrentUserId()) {
1888                             mMicMuteFromPrivacyToggle = enabled;
1889                             setMicrophoneMuteNoCallerCheck(getCurrentUserId());
1890                         }
1891                     });
1892         }
1893 
1894         mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
1895 
1896         mSoundDoseHelper.configureSafeMedia(/*forced=*/true, TAG);
1897 
1898         initA11yMonitoring();
1899 
1900         mRoleObserver = new RoleObserver();
1901         mRoleObserver.register();
1902 
1903         onIndicateSystemReady();
1904 
1905         mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted();
1906         setMicMuteFromSwitchInput();
1907 
1908         initMinStreamVolumeWithoutModifyAudioSettings();
1909 
1910         updateVibratorInfos();
1911 
1912         synchronized (mSupportedSystemUsagesLock) {
1913             AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages);
1914         }
1915     }
1916 
1917     //-----------------------------------------------------------------
1918     // routing monitoring from AudioSystemAdapter
1919     @Override
onRoutingUpdatedFromNative()1920     public void onRoutingUpdatedFromNative() {
1921         sendMsg(mAudioHandler,
1922                 MSG_ROUTING_UPDATED,
1923                 SENDMSG_REPLACE, 0, 0, null,
1924                 /*delay*/ 0);
1925     }
1926 
1927     /**
1928      * called when handling MSG_ROUTING_UPDATED
1929      */
onRoutingUpdatedFromAudioThread()1930     void onRoutingUpdatedFromAudioThread() {
1931         if (mHasSpatializerEffect) {
1932             mSpatializerHelper.onRoutingUpdated();
1933         }
1934         checkMuteAwaitConnection();
1935         if (cacheGetStreamVolume()) {
1936             if (DEBUG_VOL) {
1937                 Log.d(TAG, "Clear volume cache after routing update");
1938             }
1939             AudioManager.clearVolumeCache(AudioManager.VOLUME_CACHING_API);
1940         }
1941     }
1942 
1943     //-----------------------------------------------------------------
1944     // rotation/fold updates coming from RotationHelper
onRotationUpdate(Integer rotation)1945     void onRotationUpdate(Integer rotation) {
1946         mSpatializerHelper.setDisplayOrientation((float) (rotation * Math.PI / 180.));
1947         // use REPLACE as only the last rotation matters
1948         final String rotationParameter = "rotation=" + rotation;
1949         sendMsg(mAudioHandler, MSG_ROTATION_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0,
1950                 /*obj*/ rotationParameter, /*delay*/ 0);
1951     }
1952 
onFoldStateUpdate(Boolean foldState)1953     void onFoldStateUpdate(Boolean foldState) {
1954         mSpatializerHelper.setFoldState(foldState);
1955         // use REPLACE as only the last fold state matters
1956         final String foldStateParameter = "device_folded=" + (foldState ? "on" : "off");
1957         sendMsg(mAudioHandler, MSG_FOLD_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0,
1958                 /*obj*/ foldStateParameter, /*delay*/ 0);
1959     }
1960 
1961     //-----------------------------------------------------------------
1962     // Communicate to PlayackActivityMonitor whether to log or not
1963     // the sound FX activity (useful for removing touch sounds in the activity logs)
ignorePlayerLogs(@onNull PlayerBase playerToIgnore)1964     void ignorePlayerLogs(@NonNull PlayerBase playerToIgnore) {
1965         if (DEBUG_LOG_SOUND_FX) {
1966             return;
1967         }
1968         sendMsg(mAudioHandler, MSG_NO_LOG_FOR_PLAYER_I, SENDMSG_REPLACE,
1969                 /*arg1, piid of the player*/ playerToIgnore.getPlayerIId(),
1970                 /*arg2 ignored*/ 0, /*obj ignored*/ null, /*delay*/ 0);
1971     }
1972 
1973     //-----------------------------------------------------------------
1974     // monitoring requests for volume range initialization
1975     @Override // AudioSystemAdapter.OnVolRangeInitRequestListener
onVolumeRangeInitRequestFromNative()1976     public void onVolumeRangeInitRequestFromNative() {
1977         sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_REPLACE, 0, 0,
1978                 "onVolumeRangeInitRequestFromNative" /*obj: caller, for dumpsys*/, /*delay*/ 0);
1979     }
1980 
1981     //-----------------------------------------------------------------
1982     RoleObserver mRoleObserver;
1983 
1984     class RoleObserver implements OnRoleHoldersChangedListener {
1985         private RoleManager mRm;
1986         private final Executor mExecutor;
1987 
RoleObserver()1988         RoleObserver() {
1989             mExecutor = mContext.getMainExecutor();
1990         }
1991 
register()1992         public void register() {
1993             mRm = (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE);
1994             if (mRm != null) {
1995                 mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.ALL);
1996                 synchronized (mSettingsLock) {
1997                     updateAssistantUIdLocked(/* forceUpdate= */ true);
1998                 }
1999             }
2000         }
2001 
2002         @Override
onRoleHoldersChanged(@onNull String roleName, @NonNull UserHandle user)2003         public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
2004             if (RoleManager.ROLE_ASSISTANT.equals(roleName)) {
2005                 synchronized (mSettingsLock) {
2006                     updateAssistantUIdLocked(/* forceUpdate= */ false);
2007                 }
2008             }
2009         }
2010 
getAssistantRoleHolder()2011         public String getAssistantRoleHolder() {
2012             String assitantPackage = "";
2013             if (mRm != null) {
2014                 List<String> assistants = mRm.getRoleHolders(RoleManager.ROLE_ASSISTANT);
2015                 assitantPackage = assistants.size() == 0 ? "" : assistants.get(0);
2016             }
2017             return assitantPackage;
2018         }
2019     }
2020 
onIndicateSystemReady()2021     void onIndicateSystemReady() {
2022         if (AudioSystem.systemReady() == AudioSystem.SUCCESS) {
2023             return;
2024         }
2025         sendMsg(mAudioHandler,
2026                 MSG_INDICATE_SYSTEM_READY,
2027                 SENDMSG_REPLACE,
2028                 0,
2029                 0,
2030                 null,
2031                 INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
2032     }
2033 
onAudioServerDied()2034     public void onAudioServerDied() {
2035         if (!mSystemReady ||
2036                 (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) {
2037             Log.e(TAG, "Audioserver died.");
2038             sLifecycleLogger.enqueue(new EventLogger.StringEvent(
2039                     "onAudioServerDied() audioserver died"));
2040             sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, SENDMSG_NOOP, 0, 0,
2041                     null, 500);
2042             return;
2043         }
2044         Log.i(TAG, "Audioserver started.");
2045         sLifecycleLogger.enqueue(new EventLogger.StringEvent(
2046                 "onAudioServerDied() audioserver started"));
2047 
2048         updateAudioHalPids();
2049 
2050         // indicate to audio HAL that we start the reconfiguration phase after a media
2051         // server crash
2052         // Note that we only execute this when the media server
2053         // process restarts after a crash, not the first time it is started.
2054         AudioSystem.setParameters("restarting=true");
2055 
2056         readAndSetLowRamDevice();
2057 
2058         mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported();
2059 
2060         // Restore device connection states, BT state
2061         mDeviceBroker.onAudioServerDied();
2062 
2063         // Restore call state
2064         synchronized (mDeviceBroker.mSetModeLock) {
2065             onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(),
2066                     mContext.getPackageName(), true /*force*/, false /*signal*/);
2067         }
2068 
2069         final int forSys = mCameraSoundForced.get()
2070                 ? AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE;
2071 
2072         mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, forSys, "onAudioServerDied");
2073 
2074         // Restore stream volumes
2075         onReinitVolumes("after audioserver restart");
2076 
2077         // Restore audio volume groups
2078         restoreVolumeGroups();
2079 
2080         // Restore mono mode
2081         updateMasterMono(mContentResolver);
2082 
2083         // Restore audio balance
2084         updateMasterBalance(mContentResolver);
2085 
2086         // Restore ringer mode
2087         setRingerModeInt(getRingerModeInternal(), false);
2088 
2089         // Reset device rotation (if monitored for this device)
2090         if (mMonitorRotation) {
2091             RotationHelper.updateOrientation();
2092         }
2093 
2094         // Restore setParameters and other queued setters.
2095         mRestorableParameters.restoreAll();
2096 
2097         final int forDock = mDockAudioMediaEnabled ?
2098                 AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE;
2099         mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, forDock, "onAudioServerDied");
2100         sendEncodedSurroundMode(mContentResolver, "onAudioServerDied");
2101         sendEnabledSurroundFormats(mContentResolver, true);
2102         AudioSystem.setRttEnabled(mRttEnabled.get());
2103         synchronized (mSettingsLock) {
2104             resetAssistantServicesUidsLocked();
2105         }
2106 
2107         synchronized (mAccessibilityServiceUidsLock) {
2108             AudioSystem.setA11yServicesUids(mAccessibilityServiceUids);
2109         }
2110         synchronized (mInputMethodServiceUidLock) {
2111             mAudioSystem.setCurrentImeUid(mInputMethodServiceUid);
2112         }
2113         synchronized (mHdmiClientLock) {
2114             if (mHdmiManager != null && mHdmiTvClient != null) {
2115                 setHdmiSystemAudioSupported(mHdmiSystemAudioSupported);
2116             }
2117         }
2118 
2119         synchronized (mSupportedSystemUsagesLock) {
2120             AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages);
2121         }
2122 
2123         synchronized (mAudioPolicies) {
2124             ArrayList<AudioPolicyProxy> invalidProxies = new ArrayList<>();
2125             for (AudioPolicyProxy policy : mAudioPolicies.values()) {
2126                 final int status = policy.connectMixes();
2127                 if (status != AudioSystem.SUCCESS) {
2128                     // note that PERMISSION_DENIED may also indicate trouble getting to APService
2129                     Log.e(TAG, "onAudioServerDied: error "
2130                             + AudioSystem.audioSystemErrorToString(status)
2131                             + " when connecting mixes for policy " + policy.toLogFriendlyString());
2132                     invalidProxies.add(policy);
2133                 } else {
2134                     final int deviceAffinitiesStatus = policy.setupDeviceAffinities();
2135                     if (deviceAffinitiesStatus != AudioSystem.SUCCESS) {
2136                         Log.e(TAG, "onAudioServerDied: error "
2137                                 + AudioSystem.audioSystemErrorToString(deviceAffinitiesStatus)
2138                                 + " when connecting device affinities for policy "
2139                                 + policy.toLogFriendlyString());
2140                         invalidProxies.add(policy);
2141                     }
2142                 }
2143             }
2144             invalidProxies.forEach((policy) -> policy.release());
2145 
2146         }
2147 
2148         // Restore capture policies
2149         synchronized (mPlaybackMonitor) {
2150             HashMap<Integer, Integer> allowedCapturePolicies =
2151                     mPlaybackMonitor.getAllAllowedCapturePolicies();
2152             for (HashMap.Entry<Integer, Integer> entry : allowedCapturePolicies.entrySet()) {
2153                 int result = mAudioSystem.setAllowedCapturePolicy(
2154                         entry.getKey(),
2155                         AudioAttributes.capturePolicyToFlags(entry.getValue(), 0x0));
2156                 if (result != AudioSystem.AUDIO_STATUS_OK) {
2157                     Log.e(TAG, "Failed to restore capture policy, uid: "
2158                             + entry.getKey() + ", capture policy: " + entry.getValue()
2159                             + ", result: " + result);
2160                     // When restoring capture policy failed, set the capture policy as
2161                     // ALLOW_CAPTURE_BY_ALL, which will result in removing the cached
2162                     // capture policy in PlaybackActivityMonitor.
2163                     mPlaybackMonitor.setAllowedCapturePolicy(
2164                             entry.getKey(), AudioAttributes.ALLOW_CAPTURE_BY_ALL);
2165                 }
2166             }
2167         }
2168 
2169         mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect);
2170 
2171         // Restore rotation information.
2172         if (mMonitorRotation) {
2173             RotationHelper.forceUpdate();
2174         }
2175 
2176         onIndicateSystemReady();
2177 
2178         // indicate the end of reconfiguration phase to audio HAL
2179         AudioSystem.setParameters("restarting=false");
2180 
2181         mSoundDoseHelper.reset(/*resetISoundDose=*/true);
2182 
2183         sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE,
2184                 SENDMSG_QUEUE, 1, 0, null, 0);
2185 
2186         setMicrophoneMuteNoCallerCheck(getCurrentUserId()); // will also update the mic mute cache
2187         setMicMuteFromSwitchInput();
2188 
2189         // Restore vibrator info
2190         updateVibratorInfos();
2191     }
2192 
onRemoveAssistantServiceUids(int[] uids)2193     private void onRemoveAssistantServiceUids(int[] uids) {
2194         synchronized (mSettingsLock) {
2195             removeAssistantServiceUidsLocked(uids);
2196         }
2197     }
2198 
2199     @GuardedBy("mSettingsLock")
removeAssistantServiceUidsLocked(int[] uids)2200     private void removeAssistantServiceUidsLocked(int[] uids) {
2201         boolean changed = false;
2202         for (int index = 0; index < uids.length; index++) {
2203             if (!mAssistantUids.remove(uids[index])) {
2204                 Slog.e(TAG, TextUtils.formatSimple(
2205                         "Cannot remove assistant service, uid(%d) not present", uids[index]));
2206                 continue;
2207             }
2208             changed = true;
2209         }
2210         if (changed) {
2211             updateAssistantServicesUidsLocked();
2212         }
2213     }
2214 
onAddAssistantServiceUids(int[] uids)2215     private void onAddAssistantServiceUids(int[] uids) {
2216         synchronized (mSettingsLock) {
2217             addAssistantServiceUidsLocked(uids);
2218         }
2219     }
2220 
2221     @GuardedBy("mSettingsLock")
addAssistantServiceUidsLocked(int[] uids)2222     private void addAssistantServiceUidsLocked(int[] uids) {
2223         boolean changed = false;
2224         for (int index = 0; index < uids.length; index++) {
2225             if (uids[index] == INVALID_UID) {
2226                 continue;
2227             }
2228             if (!mAssistantUids.add(uids[index])) {
2229                 Slog.e(TAG, TextUtils.formatSimple(
2230                                 "Cannot add assistant service, uid(%d) already present",
2231                                 uids[index]));
2232                 continue;
2233             }
2234             changed = true;
2235         }
2236         if (changed) {
2237             updateAssistantServicesUidsLocked();
2238         }
2239     }
2240 
2241     @GuardedBy("mSettingsLock")
resetAssistantServicesUidsLocked()2242     private void resetAssistantServicesUidsLocked() {
2243         mAssistantUids.clear();
2244         updateAssistantUIdLocked(/* forceUpdate= */ true);
2245     }
2246 
2247     @GuardedBy("mSettingsLock")
updateAssistantServicesUidsLocked()2248     private void updateAssistantServicesUidsLocked() {
2249         int[] assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray();
2250         AudioSystem.setAssistantServicesUids(assistantUids);
2251     }
2252 
updateActiveAssistantServiceUids()2253     private void updateActiveAssistantServiceUids() {
2254         int [] activeAssistantServiceUids;
2255         synchronized (mSettingsLock) {
2256             activeAssistantServiceUids = mActiveAssistantServiceUids;
2257         }
2258         AudioSystem.setActiveAssistantServicesUids(activeAssistantServiceUids);
2259     }
2260 
onReinitVolumes(@onNull String caller)2261     private void onReinitVolumes(@NonNull String caller) {
2262         final int numStreamTypes = AudioSystem.getNumStreamTypes();
2263         // keep track of any error during stream volume initialization
2264         int status = AudioSystem.AUDIO_STATUS_OK;
2265         for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
2266             VolumeStreamState streamState = getVssForStream(streamType);
2267             if (streamState == null) {
2268                 continue;
2269             }
2270             final int res = AudioSystem.initStreamVolume(
2271                     streamType, MIN_STREAM_VOLUME[streamType], MAX_STREAM_VOLUME[streamType]);
2272             if (res != AudioSystem.AUDIO_STATUS_OK) {
2273                 status = res;
2274                 Log.e(TAG, "Failed to initStreamVolume (" + res + ") for stream " + streamType);
2275                 // stream volume initialization failed, no need to try the others, it will be
2276                 // attempted again when MSG_REINIT_VOLUMES is handled
2277                 break;
2278             }
2279             streamState.applyAllVolumes();
2280         }
2281 
2282         // did it work? check based on status
2283         if (status != AudioSystem.AUDIO_STATUS_OK) {
2284             sLifecycleLogger.enqueue(new EventLogger.StringEvent(
2285                     caller + ": initStreamVolume failed with " + status + " will retry")
2286                     .printLog(ALOGE, TAG));
2287             sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0,
2288                     caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
2289             return;
2290         }
2291 
2292         synchronized (mCachedAbsVolDrivingStreamsLock) {
2293             mCachedAbsVolDrivingStreams.forEach((dev, stream) -> {
2294                 boolean enabled = true;
2295                 if (dev == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
2296                     enabled = mAvrcpAbsVolSupported;
2297                 }
2298                 final int result = mAudioSystem.setDeviceAbsoluteVolumeEnabled(dev, /*address=*/"",
2299                         enabled, stream);
2300                 if (result != AudioSystem.AUDIO_STATUS_OK) {
2301                     sVolumeLogger.enqueueAndSlog(
2302                             new VolumeEvent(VolumeEvent.VOL_ABS_DEVICE_ENABLED_ERROR,
2303                                     result, dev, enabled, stream).eventToString(), ALOGE, TAG);
2304                 }
2305             });
2306         }
2307 
2308         // did it work? check based on min/max values of some basic streams
2309         if (!checkVolumeRangeInitialization(caller)) {
2310             return;
2311         }
2312 
2313         // success
2314         sLifecycleLogger.enqueue(new EventLogger.StringEvent(
2315                 caller + ": initStreamVolume succeeded").printLog(ALOGI, TAG));
2316     }
2317 
2318     /**
2319      * Check volume ranges were properly initialized
2320      * @return true if volume ranges were successfully initialized
2321      */
checkVolumeRangeInitialization(String caller)2322     private boolean checkVolumeRangeInitialization(String caller) {
2323         boolean success = true;
2324         final int[] basicStreams = { AudioSystem.STREAM_ALARM, AudioSystem.STREAM_RING,
2325                 AudioSystem.STREAM_MUSIC, AudioSystem.STREAM_VOICE_CALL,
2326                 AudioSystem.STREAM_ACCESSIBILITY };
2327         for (int streamType : basicStreams) {
2328             final AudioAttributes aa = new AudioAttributes.Builder()
2329                     .setInternalLegacyStreamType(streamType).build();
2330             if (AudioSystem.getMaxVolumeIndexForAttributes(aa) < 0
2331                     || AudioSystem.getMinVolumeIndexForAttributes(aa) < 0) {
2332                 success = false;
2333                 break;
2334             }
2335         }
2336         if (!success) {
2337             sLifecycleLogger.enqueue(new EventLogger.StringEvent(
2338                     caller + ": initStreamVolume succeeded but invalid mix/max levels, will retry")
2339                     .printLog(ALOGW, TAG));
2340             sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0,
2341                     caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
2342         }
2343         return success;
2344     }
2345 
onDispatchAudioServerStateChange(boolean state)2346     private void onDispatchAudioServerStateChange(boolean state) {
2347         synchronized (mAudioServerStateListeners) {
2348             for (AsdProxy asdp : mAudioServerStateListeners.values()) {
2349                 try {
2350                     asdp.callback().dispatchAudioServerStateChange(state);
2351                 } catch (RemoteException e) {
2352                     Log.w(TAG, "Could not call dispatchAudioServerStateChange()", e);
2353                 }
2354             }
2355         }
2356     }
2357 
createAudioSystemThread()2358     private void createAudioSystemThread() {
2359         mAudioSystemThread = new AudioSystemThread();
2360         mAudioSystemThread.start();
2361         waitForAudioHandlerCreation();
2362     }
2363 
2364     /** Waits for the volume handler to be created by the other thread. */
waitForAudioHandlerCreation()2365     private void waitForAudioHandlerCreation() {
2366         synchronized(this) {
2367             while (mAudioHandler == null) {
2368                 try {
2369                     // Wait for mAudioHandler to be set by the other thread
2370                     wait();
2371                 } catch (InterruptedException e) {
2372                     Log.e(TAG, "Interrupted while waiting on volume handler.");
2373                 }
2374             }
2375         }
2376     }
2377 
2378     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
2379     /**
2380      * @see AudioManager#setSupportedSystemUsages(int[])
2381      */
setSupportedSystemUsages(@onNull @ttributeSystemUsage int[] systemUsages)2382     public void setSupportedSystemUsages(@NonNull @AttributeSystemUsage int[] systemUsages) {
2383         super.setSupportedSystemUsages_enforcePermission();
2384 
2385         verifySystemUsages(systemUsages);
2386 
2387         synchronized (mSupportedSystemUsagesLock) {
2388             AudioSystem.setSupportedSystemUsages(systemUsages);
2389             mSupportedSystemUsages = systemUsages;
2390         }
2391     }
2392 
2393     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
2394     /**
2395      * @see AudioManager#getSupportedSystemUsages()
2396      */
getSupportedSystemUsages()2397     public @NonNull @AttributeSystemUsage int[] getSupportedSystemUsages() {
2398         super.getSupportedSystemUsages_enforcePermission();
2399 
2400         synchronized (mSupportedSystemUsagesLock) {
2401             return Arrays.copyOf(mSupportedSystemUsages, mSupportedSystemUsages.length);
2402         }
2403     }
2404 
verifySystemUsages(@onNull int[] systemUsages)2405     private void verifySystemUsages(@NonNull int[] systemUsages) {
2406         for (int i = 0; i < systemUsages.length; i++) {
2407             if (!AudioAttributes.isSystemUsage(systemUsages[i])) {
2408                 throw new IllegalArgumentException("Non-system usage provided: " + systemUsages[i]);
2409             }
2410         }
2411     }
2412 
2413     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
2414     /**
2415      * @return the {@link android.media.audiopolicy.AudioProductStrategy} discovered from the
2416      * platform configuration file.
2417      */
2418     @NonNull
getAudioProductStrategies()2419     public List<AudioProductStrategy> getAudioProductStrategies() {
2420         // verify permissions
2421         super.getAudioProductStrategies_enforcePermission();
2422 
2423         return AudioProductStrategy.getAudioProductStrategies();
2424     }
2425 
2426     @android.annotation.EnforcePermission(anyOf = {
2427             MODIFY_AUDIO_SETTINGS_PRIVILEGED, MODIFY_AUDIO_ROUTING })
2428     /**
2429      * @return the List of {@link android.media.audiopolicy.AudioVolumeGroup} discovered from the
2430      * platform configuration file.
2431      */
2432     @NonNull
getAudioVolumeGroups()2433     public List<AudioVolumeGroup> getAudioVolumeGroups() {
2434         // verify permissions
2435         super.getAudioVolumeGroups_enforcePermission();
2436 
2437         return mAudioVolumeGroupHelper.getAudioVolumeGroups();
2438     }
2439 
checkAllAliasStreamVolumes()2440     private void checkAllAliasStreamVolumes() {
2441         synchronized (mSettingsLock) {
2442             synchronized (mVolumeStateLock) {
2443                 int numStreamTypes = AudioSystem.getNumStreamTypes();
2444                 for (int streamType = 0; streamType < numStreamTypes; streamType++) {
2445                     int streamAlias = sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound=*/-1);
2446                     final VolumeStreamState streamState = getVssForStream(streamType);
2447                     if (streamAlias != -1 && streamState != null) {
2448                         streamState.setAllIndexes(getVssForStream(streamAlias), TAG);
2449                         // apply stream volume
2450                         if (!streamState.mIsMuted) {
2451                             streamState.applyAllVolumes();
2452                         }
2453                     }
2454                 }
2455             }
2456         }
2457     }
2458 
2459 
2460     /**
2461      * Called from AudioDeviceBroker when DEVICE_OUT_HDMI is connected or disconnected.
2462      */
postCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)2463     /*package*/ void postCheckVolumeCecOnHdmiConnection(
2464             @AudioService.ConnectionState  int state, String caller) {
2465         sendMsg(mAudioHandler, MSG_HDMI_VOLUME_CHECK, SENDMSG_REPLACE,
2466                 state /*arg1*/, 0 /*arg2 ignored*/, caller /*obj*/, 0 /*delay*/);
2467     }
2468 
onCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)2469     private void onCheckVolumeCecOnHdmiConnection(
2470             @AudioService.ConnectionState int state, String caller) {
2471         if (state == AudioService.CONNECTION_STATE_CONNECTED) {
2472             // DEVICE_OUT_HDMI is now connected
2473             if (mSoundDoseHelper.safeDevicesContains(AudioSystem.DEVICE_OUT_HDMI)) {
2474                 mSoundDoseHelper.scheduleMusicActiveCheck();
2475             }
2476 
2477             if (isPlatformTelevision()) {
2478                 synchronized (mHdmiClientLock) {
2479                     if (mHdmiManager != null && mHdmiPlaybackClient != null) {
2480                         updateHdmiCecSinkLocked(
2481                                 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI));
2482                     }
2483                 }
2484             }
2485             sendEnabledSurroundFormats(mContentResolver, true);
2486         } else {
2487             // DEVICE_OUT_HDMI disconnected
2488             if (isPlatformTelevision()) {
2489                 synchronized (mHdmiClientLock) {
2490                     if (mHdmiManager != null) {
2491                         updateHdmiCecSinkLocked(
2492                                 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI));
2493                     }
2494                 }
2495             }
2496         }
2497     }
2498 
2499     /**
2500      * Asynchronously update volume states for the given device.
2501      *
2502      * @param device a single audio device, ensure that this is not a devices bitmask
2503      * @param caller caller of this method
2504      */
postUpdateVolumeStatesForAudioDevice(int device, String caller)2505     private void postUpdateVolumeStatesForAudioDevice(int device, String caller) {
2506         sendMsg(mAudioHandler,
2507                 MSG_UPDATE_VOLUME_STATES_FOR_DEVICE,
2508                 SENDMSG_QUEUE, device /*arg1*/, 0 /*arg2*/, caller /*obj*/,
2509                 0 /*delay*/);
2510     }
2511 
2512     /**
2513      * Update volume states for the given device.
2514      *
2515      * This will initialize the volume index if no volume index is available.
2516      * If the device is the currently routed device, fixed/full volume policies will be applied.
2517      *
2518      * @param device a single audio device, ensure that this is not a devices bitmask
2519      * @param caller caller of this method
2520      */
onUpdateVolumeStatesForAudioDevice(int device, String caller)2521     private void onUpdateVolumeStatesForAudioDevice(int device, String caller) {
2522         final int numStreamTypes = AudioSystem.getNumStreamTypes();
2523         synchronized (mSettingsLock) {
2524             synchronized (mVolumeStateLock) {
2525                 for (int streamType = 0; streamType < numStreamTypes; streamType++) {
2526                     updateVolumeStates(device, streamType, caller);
2527                 }
2528             }
2529         }
2530     }
2531 
2532     /**
2533      * Update volume states for the given device and given stream.
2534      *
2535      * This will initialize the volume index if no volume index is available.
2536      * If the device is the currently routed device, fixed/full volume policies will be applied.
2537      *
2538      * @param device a single audio device, ensure that this is not a devices bitmask
2539      * @param streamType streamType to be updated
2540      * @param caller caller of this method
2541      */
updateVolumeStates(int device, int streamType, String caller)2542     private void updateVolumeStates(int device, int streamType, String caller) {
2543         if (replaceStreamBtSco() && streamType == AudioSystem.STREAM_BLUETOOTH_SCO) {
2544             return;
2545         }
2546 
2547         // Handle device volume aliasing of SPEAKER_SAFE.
2548         if (device == AudioSystem.DEVICE_OUT_SPEAKER_SAFE) {
2549             device = AudioSystem.DEVICE_OUT_SPEAKER;
2550         }
2551 
2552         final VolumeStreamState streamState = getVssForStream(streamType);
2553         if (streamState == null) {
2554             // nothing to update
2555             return;
2556         }
2557 
2558         if (!streamState.hasIndexForDevice(device)) {
2559             // set the default value, if device is affected by a full/fix/abs volume rule, it
2560             // will taken into account in checkFixedVolumeDevices()
2561             streamState.setIndex(getVssForStreamOrDefault(sStreamVolumeAlias.get(streamType))
2562                             .getIndex(AudioSystem.DEVICE_OUT_DEFAULT),
2563                     device, caller, true /*hasModifyAudioSettings*/);
2564         }
2565 
2566         // Check if device to be updated is routed for the given audio stream
2567         // This may include devices such as SPEAKER_SAFE.
2568         List<AudioDeviceAttributes> devicesForAttributes = getDevicesForAttributesInt(
2569                 new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build(),
2570                 true /* forVolume */);
2571         for (AudioDeviceAttributes deviceAttributes : devicesForAttributes) {
2572             if (deviceAttributes.getType() == AudioDeviceInfo.convertInternalDeviceToDeviceType(
2573                     device)) {
2574                 streamState.checkFixedVolumeDevices();
2575 
2576                 // Unmute streams if required and device is full volume
2577                 if (isStreamMute(streamType) && mFullVolumeDevices.contains(device)) {
2578                     streamState.mute(false, "updateVolumeStates(" + caller);
2579                 }
2580             }
2581         }
2582     }
2583 
checkAllFixedVolumeDevices()2584     private void checkAllFixedVolumeDevices()
2585     {
2586         int numStreamTypes = AudioSystem.getNumStreamTypes();
2587         for (int streamType = 0; streamType < numStreamTypes; streamType++) {
2588             final VolumeStreamState vss = getVssForStream(streamType);
2589             if (vss != null) {
2590                 vss.checkFixedVolumeDevices();
2591             }
2592         }
2593     }
2594 
checkAllFixedVolumeDevices(int streamType)2595     private void checkAllFixedVolumeDevices(int streamType) {
2596         final VolumeStreamState vss = getVssForStream(streamType);
2597         if (vss == null) {
2598             return;
2599         }
2600         vss.checkFixedVolumeDevices();
2601     }
2602 
checkMuteAffectedStreams()2603     private void checkMuteAffectedStreams() {
2604         // any stream with a min level > 0 is not muteable by definition
2605         // STREAM_VOICE_CALL and STREAM_BLUETOOTH_SCO can be muted by applications
2606         // that has the the MODIFY_PHONE_STATE permission.
2607         for (int i = 0; i < mStreamStates.size(); i++) {
2608             final VolumeStreamState vss = mStreamStates.valueAt(i);
2609             if (vss != null && vss.mIndexMin > 0
2610                     && (vss.mStreamType != AudioSystem.STREAM_VOICE_CALL
2611                     && vss.mStreamType != AudioSystem.STREAM_BLUETOOTH_SCO)) {
2612                 mMuteAffectedStreams &= ~(1 << vss.mStreamType);
2613             }
2614         }
2615         updateUserMutableStreams();
2616     }
2617 
createStreamStates()2618     private void createStreamStates() {
2619         int numStreamTypes = AudioSystem.getNumStreamTypes();
2620         mStreamStates = new SparseArray<>(numStreamTypes);
2621 
2622         for (int i = 0; i < numStreamTypes; i++) {
2623             final int streamAlias = sStreamVolumeAlias.get(i, /*valueIfKeyNotFound=*/-1);
2624             // a negative sStreamVolumeAlias value means the stream state type is not supported
2625             if (streamAlias >= 0) {
2626                 mStreamStates.set(i,
2627                         new VolumeStreamState(System.VOLUME_SETTINGS_INT[streamAlias], i));
2628             }
2629         }
2630 
2631         checkAllFixedVolumeDevices();
2632         checkAllAliasStreamVolumes();
2633         checkMuteAffectedStreams();
2634         updateDefaultVolumes();
2635     }
2636 
2637     /**
2638      * Update default indexes from aliased streams. Must be called after mStreamStates is created
2639      * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for default
2640      * index. Need to make default index configurable and independent of streams.
2641      * Fallback on music stream for default initialization to take benefit of property based default
2642      * initialization.
2643      * For other volume groups not linked to any streams, default music stream index is considered.
2644      */
updateDefaultVolumes()2645     private void updateDefaultVolumes() {
2646         for (int stream = 0; stream < mStreamStates.size(); stream++) {
2647             int streamType = mStreamStates.keyAt(stream);
2648             int streamVolumeAlias = sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound=*/-1);
2649             if (mUseVolumeGroupAliases) {
2650                 if (AudioSystem.DEFAULT_STREAM_VOLUME[streamType] != UNSET_INDEX) {
2651                     // Already initialized through default property based mecanism.
2652                     continue;
2653                 }
2654                 streamVolumeAlias = AudioSystem.STREAM_MUSIC;
2655                 int defaultAliasVolume = getUiDefaultRescaledIndex(streamVolumeAlias, streamType);
2656                 if ((defaultAliasVolume >= MIN_STREAM_VOLUME[streamType])
2657                         && (defaultAliasVolume <= MAX_STREAM_VOLUME[streamType])) {
2658                     AudioSystem.DEFAULT_STREAM_VOLUME[streamType] = defaultAliasVolume;
2659                     continue;
2660                 }
2661             }
2662             if (streamVolumeAlias >= 0 && streamType != streamVolumeAlias) {
2663                 AudioSystem.DEFAULT_STREAM_VOLUME[streamType] =
2664                         getUiDefaultRescaledIndex(streamVolumeAlias, streamType);
2665             }
2666         }
2667     }
2668 
getUiDefaultRescaledIndex(int srcStream, int dstStream)2669     private int getUiDefaultRescaledIndex(int srcStream, int dstStream) {
2670         return (rescaleIndex(AudioSystem.DEFAULT_STREAM_VOLUME[srcStream] * 10,
2671                 srcStream, dstStream) + 5) / 10;
2672     }
2673 
replaceBtScoStreamWithVoiceCall(int streamType, String caller)2674     private static int replaceBtScoStreamWithVoiceCall(int streamType, String caller) {
2675         if (replaceStreamBtSco() && streamType == AudioSystem.STREAM_BLUETOOTH_SCO) {
2676             if (DEBUG_VOL) {
2677                 Log.d(TAG,
2678                         "Deprecating STREAM_BLUETOOTH_SCO, using STREAM_VOICE_CALL instead for "
2679                                 + "caller: " + caller);
2680             }
2681             streamType = AudioSystem.STREAM_VOICE_CALL;
2682         }
2683         return streamType;
2684     }
2685 
isStreamBluetoothSco(int streamType)2686     private boolean isStreamBluetoothSco(int streamType) {
2687         if (replaceStreamBtSco()) {
2688             if (streamType == AudioSystem.STREAM_BLUETOOTH_SCO) {
2689                 // this should not happen, throwing exception
2690                 throw new IllegalArgumentException("STREAM_BLUETOOTH_SCO is deprecated");
2691             }
2692             return streamType == AudioSystem.STREAM_VOICE_CALL
2693                     && mBtCommDeviceActive.get() == BT_COMM_DEVICE_ACTIVE_SCO;
2694         } else {
2695             return streamType == AudioSystem.STREAM_BLUETOOTH_SCO;
2696         }
2697     }
2698 
isStreamBluetoothComm(int streamType)2699     private boolean isStreamBluetoothComm(int streamType) {
2700         return (streamType == AudioSystem.STREAM_VOICE_CALL && mBtCommDeviceActive.get() != 0)
2701                 || streamType == AudioSystem.STREAM_BLUETOOTH_SCO;
2702     }
2703 
dumpStreamStates(PrintWriter pw)2704     private void dumpStreamStates(PrintWriter pw) {
2705         pw.println("\nStream volumes (device: index)");
2706         int numStreamTypes = AudioSystem.getNumStreamTypes();
2707         for (int i = 0; i < numStreamTypes; i++) {
2708             if (replaceStreamBtSco() && i == AudioSystem.STREAM_BLUETOOTH_SCO) {
2709                 continue;
2710             }
2711             StringBuilder alias = new StringBuilder();
2712             final int streamAlias = sStreamVolumeAlias.get(i, /*valueIfKeyNotFound*/-1);
2713             if (streamAlias != i && streamAlias != -1) {
2714                 alias.append(" (aliased to: ")
2715                         .append(AudioSystem.STREAM_NAMES[streamAlias])
2716                         .append(")");
2717             }
2718             pw.println("- " + AudioSystem.STREAM_NAMES[i] + alias + ":");
2719             final VolumeStreamState vss = getVssForStream(i);
2720             if (vss != null) {
2721                 vss.dump(pw);
2722             }
2723             pw.println("");
2724         }
2725         pw.print("\n- mute affected streams = 0x");
2726         pw.println(Integer.toHexString(mMuteAffectedStreams));
2727         pw.print("\n- user mutable streams = 0x");
2728         pw.println(Integer.toHexString(mUserMutableStreams));
2729     }
2730 
initStreamVolumeAlias(int[] streamVolumeAlias)2731     private void initStreamVolumeAlias(int[] streamVolumeAlias) {
2732         sStreamVolumeAlias = new SparseIntArray(streamVolumeAlias.length);
2733         for (int i = 0; i < streamVolumeAlias.length; ++i) {
2734             sStreamVolumeAlias.put(i, streamVolumeAlias[i]);
2735         }
2736     }
2737 
updateStreamVolumeAlias(boolean updateVolumes, String caller)2738     private void updateStreamVolumeAlias(boolean updateVolumes, String caller) {
2739         int dtmfStreamAlias;
2740         final int a11yStreamAlias = sIndependentA11yVolume ?
2741                 AudioSystem.STREAM_ACCESSIBILITY : AudioSystem.STREAM_MUSIC;
2742         final int assistantStreamAlias = mContext.getResources().getBoolean(
2743                 com.android.internal.R.bool.config_useAssistantVolume) ?
2744                 AudioSystem.STREAM_ASSISTANT : AudioSystem.STREAM_MUSIC;
2745 
2746         if (mIsSingleVolume) {
2747             initStreamVolumeAlias(STREAM_VOLUME_ALIAS_TELEVISION);
2748             dtmfStreamAlias = AudioSystem.STREAM_MUSIC;
2749         } else if (mUseVolumeGroupAliases) {
2750             initStreamVolumeAlias(STREAM_VOLUME_ALIAS_NONE);
2751             dtmfStreamAlias = AudioSystem.STREAM_DTMF;
2752         } else {
2753             switch (mPlatformType) {
2754                 case AudioSystem.PLATFORM_VOICE:
2755                     initStreamVolumeAlias(STREAM_VOLUME_ALIAS_VOICE);
2756                     dtmfStreamAlias = AudioSystem.STREAM_RING;
2757                     break;
2758                 default:
2759                     initStreamVolumeAlias(STREAM_VOLUME_ALIAS_DEFAULT);
2760                     dtmfStreamAlias = AudioSystem.STREAM_MUSIC;
2761             }
2762             if (!mNotifAliasRing) {
2763                 sStreamVolumeAlias.put(AudioSystem.STREAM_NOTIFICATION,
2764                         AudioSystem.STREAM_NOTIFICATION);
2765             }
2766         }
2767 
2768         if (mIsSingleVolume) {
2769             mRingerModeAffectedStreams = 0;
2770         } else {
2771             if (isInCommunication()) {
2772                 dtmfStreamAlias = AudioSystem.STREAM_VOICE_CALL;
2773                 mRingerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF);
2774             } else {
2775                 mRingerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF);
2776             }
2777         }
2778 
2779         sStreamVolumeAlias.put(AudioSystem.STREAM_DTMF, dtmfStreamAlias);
2780         sStreamVolumeAlias.put(AudioSystem.STREAM_ACCESSIBILITY, a11yStreamAlias);
2781         sStreamVolumeAlias.put(AudioSystem.STREAM_ASSISTANT, assistantStreamAlias);
2782 
2783         if (replaceStreamBtSco()) {
2784             // we do not support STREAM_BLUETOOTH_SCO, this will lead to having
2785             // mStreanStates.get(STREAM_BLUETOOTH_SCO) == null
2786             sStreamVolumeAlias.delete(AudioSystem.STREAM_BLUETOOTH_SCO);
2787         }
2788 
2789         if (updateVolumes && mStreamStates != null) {
2790             updateDefaultVolumes();
2791 
2792             synchronized (mSettingsLock) {
2793                 synchronized (mVolumeStateLock) {
2794                     getVssForStreamOrDefault(AudioSystem.STREAM_DTMF)
2795                             .setAllIndexes(getVssForStreamOrDefault(dtmfStreamAlias), caller);
2796                     getVssForStreamOrDefault(AudioSystem.STREAM_ACCESSIBILITY).setSettingName(
2797                             System.VOLUME_SETTINGS_INT[a11yStreamAlias]);
2798                     getVssForStreamOrDefault(AudioSystem.STREAM_ACCESSIBILITY).setAllIndexes(
2799                             getVssForStreamOrDefault(a11yStreamAlias), caller);
2800                 }
2801             }
2802             if (sIndependentA11yVolume) {
2803                 // restore the a11y values from the settings
2804                 getVssForStreamOrDefault(AudioSystem.STREAM_ACCESSIBILITY).readSettings();
2805             }
2806 
2807             // apply stream mute states according to new value of mRingerModeAffectedStreams
2808             setRingerModeInt(getRingerModeInternal(), false);
2809             sendMsg(mAudioHandler,
2810                     MSG_SET_ALL_VOLUMES,
2811                     SENDMSG_QUEUE,
2812                     0,
2813                     0,
2814                     getVssForStreamOrDefault(AudioSystem.STREAM_DTMF), 0);
2815             sendMsg(mAudioHandler,
2816                     MSG_SET_ALL_VOLUMES,
2817                     SENDMSG_QUEUE,
2818                     0,
2819                     0,
2820                     getVssForStreamOrDefault(AudioSystem.STREAM_ACCESSIBILITY), 0);
2821         }
2822         dispatchStreamAliasingUpdate();
2823     }
2824 
readDockAudioSettings(ContentResolver cr)2825     private void readDockAudioSettings(ContentResolver cr)
2826     {
2827         mDockAudioMediaEnabled = mSettings.getGlobalInt(
2828                                         cr, Settings.Global.DOCK_AUDIO_MEDIA_ENABLED, 0) == 1;
2829 
2830         sendMsg(mAudioHandler,
2831                 MSG_SET_FORCE_USE,
2832                 SENDMSG_QUEUE,
2833                 AudioSystem.FOR_DOCK,
2834                 mDockAudioMediaEnabled ?
2835                         AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE,
2836                 new String("readDockAudioSettings"),
2837                 0);
2838 
2839     }
2840 
2841 
updateMasterMono(ContentResolver cr)2842     private void updateMasterMono(ContentResolver cr)
2843     {
2844         final boolean masterMono = mSettings.getSystemIntForUser(
2845                 cr, System.MASTER_MONO, 0 /* default */, UserHandle.USER_CURRENT) == 1;
2846         if (DEBUG_VOL) {
2847             Log.d(TAG, String.format("Master mono %b", masterMono));
2848         }
2849         AudioSystem.setMasterMono(masterMono);
2850     }
2851 
updateMasterBalance(ContentResolver cr)2852     private void updateMasterBalance(ContentResolver cr) {
2853         final float masterBalance = System.getFloatForUser(
2854                 cr, System.MASTER_BALANCE, 0.f /* default */, UserHandle.USER_CURRENT);
2855         if (DEBUG_VOL) {
2856             Log.d(TAG, String.format("Master balance %f", masterBalance));
2857         }
2858         if (AudioSystem.setMasterBalance(masterBalance) != 0) {
2859             Log.e(TAG, String.format("setMasterBalance failed for %f", masterBalance));
2860         }
2861     }
2862 
sendEncodedSurroundMode(ContentResolver cr, String eventSource)2863     private void sendEncodedSurroundMode(ContentResolver cr, String eventSource)
2864     {
2865         final int encodedSurroundMode = mSettings.getGlobalInt(
2866                 cr, Settings.Global.ENCODED_SURROUND_OUTPUT,
2867                 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
2868         sendEncodedSurroundMode(encodedSurroundMode, eventSource);
2869     }
2870 
sendEncodedSurroundMode(int encodedSurroundMode, String eventSource)2871     private void sendEncodedSurroundMode(int encodedSurroundMode, String eventSource)
2872     {
2873         // initialize to guaranteed bad value
2874         int forceSetting = AudioSystem.NUM_FORCE_CONFIG;
2875         switch (encodedSurroundMode) {
2876             case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO:
2877                 forceSetting = AudioSystem.FORCE_NONE;
2878                 break;
2879             case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER:
2880                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_NEVER;
2881                 break;
2882             case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS:
2883                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_ALWAYS;
2884                 break;
2885             case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL:
2886                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_MANUAL;
2887                 break;
2888             default:
2889                 Log.e(TAG, "updateSurroundSoundSettings: illegal value "
2890                         + encodedSurroundMode);
2891                 break;
2892         }
2893         if (forceSetting != AudioSystem.NUM_FORCE_CONFIG) {
2894             mDeviceBroker.setForceUse_Async(AudioSystem.FOR_ENCODED_SURROUND, forceSetting,
2895                     eventSource);
2896         }
2897     }
2898 
2899     @Override
onUnhandledException(int code, int flags, Exception e)2900     protected void onUnhandledException(int code, int flags, Exception e) {
2901         Slog.wtf(TAG, "Uncaught exception in AudioService: " + code + ", " + flags, e);
2902     }
2903 
2904     @Override // Binder call
onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)2905     public void onShellCommand(FileDescriptor in, FileDescriptor out,
2906             FileDescriptor err, String[] args, ShellCallback callback,
2907             ResultReceiver resultReceiver) {
2908         if (mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_AUDIO_POLICY)
2909                 != PackageManager.PERMISSION_GRANTED) {
2910             throw new SecurityException("Missing MANAGE_AUDIO_POLICY permission");
2911         }
2912         new AudioManagerShellCommand(AudioService.this).exec(this, in, out, err,
2913                 args, callback, resultReceiver);
2914     }
2915 
2916     @Override
getNativeInterface()2917     public IAudioManagerNative getNativeInterface() {
2918         return mNativeShim;
2919     }
2920 
2921     /** @see AudioManager#getSurroundFormats() */
2922     @Override
getSurroundFormats()2923     public Map<Integer, Boolean> getSurroundFormats() {
2924         Map<Integer, Boolean> surroundFormats = new HashMap<>();
2925         int status = AudioSystem.getSurroundFormats(surroundFormats);
2926         if (status != AudioManager.SUCCESS) {
2927             // fail and bail!
2928             Log.e(TAG, "getSurroundFormats failed:" + status);
2929             return new HashMap<>(); // Always return a map.
2930         }
2931         return surroundFormats;
2932     }
2933 
2934     /** @see AudioManager#getReportedSurroundFormats() */
2935     @Override
getReportedSurroundFormats()2936     public List<Integer> getReportedSurroundFormats() {
2937         ArrayList<Integer> reportedSurroundFormats = new ArrayList<>();
2938         int status = AudioSystem.getReportedSurroundFormats(reportedSurroundFormats);
2939         if (status != AudioManager.SUCCESS) {
2940             // fail and bail!
2941             Log.e(TAG, "getReportedSurroundFormats failed:" + status);
2942             return new ArrayList<>(); // Always return a list.
2943         }
2944         return reportedSurroundFormats;
2945     }
2946 
2947     /** @see AudioManager#isSurroundFormatEnabled(int) */
2948     @Override
isSurroundFormatEnabled(int audioFormat)2949     public boolean isSurroundFormatEnabled(int audioFormat) {
2950         if (!isSurroundFormat(audioFormat)) {
2951             Log.w(TAG, "audioFormat to enable is not a surround format.");
2952             return false;
2953         }
2954 
2955         final long token = Binder.clearCallingIdentity();
2956         try {
2957             synchronized (mSettingsLock) {
2958                 HashSet<Integer> enabledFormats = getEnabledFormats();
2959                 return enabledFormats.contains(audioFormat);
2960             }
2961         } finally {
2962             Binder.restoreCallingIdentity(token);
2963         }
2964     }
2965 
2966     /** @see AudioManager#setSurroundFormatEnabled(int, boolean) */
2967     @Override
setSurroundFormatEnabled(int audioFormat, boolean enabled)2968     public boolean setSurroundFormatEnabled(int audioFormat, boolean enabled) {
2969         if (!isSurroundFormat(audioFormat)) {
2970             Log.w(TAG, "audioFormat to enable is not a surround format.");
2971             return false;
2972         }
2973         if (mContext.checkCallingOrSelfPermission(WRITE_SETTINGS)
2974                 != PackageManager.PERMISSION_GRANTED) {
2975             throw new SecurityException("Missing WRITE_SETTINGS permission");
2976         }
2977 
2978         HashSet<Integer> enabledFormats = getEnabledFormats();
2979         if (enabled) {
2980             enabledFormats.add(audioFormat);
2981         } else {
2982             enabledFormats.remove(audioFormat);
2983         }
2984         final long token = Binder.clearCallingIdentity();
2985         try {
2986             synchronized (mSettingsLock) {
2987                 mSettings.putGlobalString(mContentResolver,
2988                         Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
2989                         TextUtils.join(",", enabledFormats));
2990             }
2991         } finally {
2992             Binder.restoreCallingIdentity(token);
2993         }
2994         return true;
2995     }
2996 
2997     @android.annotation.EnforcePermission(WRITE_SETTINGS)
2998     /** @see AudioManager#setEncodedSurroundMode(int) */
2999     @Override
setEncodedSurroundMode(@udioManager.EncodedSurroundOutputMode int mode)3000     public boolean setEncodedSurroundMode(@AudioManager.EncodedSurroundOutputMode int mode) {
3001         setEncodedSurroundMode_enforcePermission();
3002 
3003         final long token = Binder.clearCallingIdentity();
3004         try {
3005             synchronized (mSettingsLock) {
3006                 mSettings.putGlobalInt(mContentResolver,
3007                         Settings.Global.ENCODED_SURROUND_OUTPUT,
3008                         toEncodedSurroundSetting(mode));
3009             }
3010         } finally {
3011             Binder.restoreCallingIdentity(token);
3012         }
3013         return true;
3014     }
3015 
3016     /** @see AudioManager#getEncodedSurroundMode() */
3017     @Override
getEncodedSurroundMode(int targetSdkVersion)3018     public int getEncodedSurroundMode(int targetSdkVersion) {
3019         final long token = Binder.clearCallingIdentity();
3020         try {
3021             synchronized (mSettingsLock) {
3022                 int encodedSurroundSetting = mSettings.getGlobalInt(mContentResolver,
3023                         Settings.Global.ENCODED_SURROUND_OUTPUT,
3024                         AudioManager.ENCODED_SURROUND_OUTPUT_AUTO);
3025                 return toEncodedSurroundOutputMode(encodedSurroundSetting, targetSdkVersion);
3026             }
3027         } finally {
3028             Binder.restoreCallingIdentity(token);
3029         }
3030     }
3031 
3032     /** @return the formats that are enabled in global settings */
getEnabledFormats()3033     private HashSet<Integer> getEnabledFormats() {
3034         HashSet<Integer> formats = new HashSet<>();
3035         String enabledFormats = mSettings.getGlobalString(mContentResolver,
3036                 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
3037         if (enabledFormats != null) {
3038             try {
3039                 Arrays.stream(TextUtils.split(enabledFormats, ","))
3040                         .mapToInt(Integer::parseInt)
3041                         .forEach(formats::add);
3042             } catch (NumberFormatException e) {
3043                 Log.w(TAG, "ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS misformatted.", e);
3044             }
3045         }
3046         return formats;
3047     }
3048 
3049     @SuppressWarnings("AndroidFrameworkCompatChange")
3050     @AudioManager.EncodedSurroundOutputMode
toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion)3051     private int toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion) {
3052         if (targetSdkVersion <= Build.VERSION_CODES.S
3053                 && encodedSurroundSetting > Settings.Global.ENCODED_SURROUND_SC_MAX) {
3054             return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN;
3055         }
3056         switch (encodedSurroundSetting) {
3057             case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO:
3058                 return AudioManager.ENCODED_SURROUND_OUTPUT_AUTO;
3059             case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER:
3060                 return AudioManager.ENCODED_SURROUND_OUTPUT_NEVER;
3061             case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS:
3062                 return AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS;
3063             case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL:
3064                 return AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL;
3065             default:
3066                 return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN;
3067         }
3068     }
3069 
toEncodedSurroundSetting( @udioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode)3070     private int toEncodedSurroundSetting(
3071             @AudioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode) {
3072         switch (encodedSurroundOutputMode) {
3073             case AudioManager.ENCODED_SURROUND_OUTPUT_NEVER:
3074                 return Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER;
3075             case AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS:
3076                 return Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS;
3077             case AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL:
3078                 return Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL;
3079             default:
3080                 return Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO;
3081         }
3082     }
3083 
isSurroundFormat(int audioFormat)3084     private boolean isSurroundFormat(int audioFormat) {
3085         for (int sf : AudioFormat.SURROUND_SOUND_ENCODING) {
3086             if (sf == audioFormat) {
3087                 return true;
3088             }
3089         }
3090         return false;
3091     }
3092 
sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate)3093     private void sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate) {
3094         if (mEncodedSurroundMode != Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL) {
3095             // Manually enable surround formats only when the setting is in manual mode.
3096             return;
3097         }
3098         String enabledSurroundFormats = mSettings.getGlobalString(
3099                 cr, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
3100         if (enabledSurroundFormats == null) {
3101             // Never allow enabledSurroundFormats as a null, which could happen when
3102             // ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS is not appear in settings DB.
3103             enabledSurroundFormats = "";
3104         }
3105         if (!forceUpdate && TextUtils.equals(enabledSurroundFormats, mEnabledSurroundFormats)) {
3106             // Update enabled surround formats to AudioPolicyManager only when forceUpdate
3107             // is true or enabled surround formats changed.
3108             return;
3109         }
3110 
3111         mEnabledSurroundFormats = enabledSurroundFormats;
3112         String[] surroundFormats = TextUtils.split(enabledSurroundFormats, ",");
3113         ArrayList<Integer> formats = new ArrayList<>();
3114         for (String format : surroundFormats) {
3115             try {
3116                 int audioFormat = Integer.valueOf(format);
3117                 if (isSurroundFormat(audioFormat) && !formats.contains(audioFormat)) {
3118                     formats.add(audioFormat);
3119                 }
3120             } catch (Exception e) {
3121                 Log.e(TAG, "Invalid enabled surround format:" + format);
3122             }
3123         }
3124         // Set filtered surround formats to settings DB in case
3125         // there are invalid surround formats in original settings.
3126         mSettings.putGlobalString(mContext.getContentResolver(),
3127                 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
3128                 TextUtils.join(",", formats));
3129         sendMsg(mAudioHandler, MSG_ENABLE_SURROUND_FORMATS, SENDMSG_QUEUE, 0, 0, formats, 0);
3130     }
3131 
onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats)3132     private void onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats) {
3133         // Set surround format enabled accordingly.
3134         for (int surroundFormat : AudioFormat.SURROUND_SOUND_ENCODING) {
3135             boolean enabled = enabledSurroundFormats.contains(surroundFormat);
3136             int ret = AudioSystem.setSurroundFormatEnabled(surroundFormat, enabled);
3137             Log.i(TAG, "enable surround format:" + surroundFormat + " " + enabled + " " + ret);
3138         }
3139     }
3140 
3141     @GuardedBy("mSettingsLock")
updateAssistantUIdLocked(boolean forceUpdate)3142     private void updateAssistantUIdLocked(boolean forceUpdate) {
3143         int assistantUid = INVALID_UID;
3144         // Consider assistants in the following order of priority:
3145         // 1) apk in assistant role
3146         // 2) voice interaction service
3147         // 3) assistant service
3148 
3149         String packageName = "";
3150         if (mRoleObserver != null) {
3151             packageName = mRoleObserver.getAssistantRoleHolder();
3152         }
3153         if (TextUtils.isEmpty(packageName)) {
3154             String assistantName = mSettings.getSecureStringForUser(
3155                             mContentResolver,
3156                             Settings.Secure.VOICE_INTERACTION_SERVICE, UserHandle.USER_CURRENT);
3157             if (TextUtils.isEmpty(assistantName)) {
3158                 assistantName = mSettings.getSecureStringForUser(
3159                         mContentResolver,
3160                         Settings.Secure.ASSISTANT, UserHandle.USER_CURRENT);
3161             }
3162             if (!TextUtils.isEmpty(assistantName)) {
3163                 ComponentName componentName = ComponentName.unflattenFromString(assistantName);
3164                 if (componentName == null) {
3165                     Slog.w(TAG, "Invalid service name for "
3166                             + Settings.Secure.VOICE_INTERACTION_SERVICE + ": " + assistantName);
3167                     return;
3168                 }
3169                 packageName = componentName.getPackageName();
3170             }
3171         }
3172         if (!TextUtils.isEmpty(packageName)) {
3173             PackageManager pm = mContext.getPackageManager();
3174 
3175             if (pm.checkPermission(CAPTURE_AUDIO_HOTWORD, packageName)
3176                     == PackageManager.PERMISSION_GRANTED) {
3177                 try {
3178                     assistantUid = pm.getPackageUidAsUser(packageName, getCurrentUserId());
3179                 } catch (PackageManager.NameNotFoundException e) {
3180                     Log.e(TAG,
3181                             "updateAssistantUId() could not find UID for package: " + packageName);
3182                 }
3183             }
3184         }
3185         if ((mPrimaryAssistantUid != assistantUid) || forceUpdate) {
3186             mAssistantUids.remove(mPrimaryAssistantUid);
3187             mPrimaryAssistantUid = assistantUid;
3188             addAssistantServiceUidsLocked(new int[]{mPrimaryAssistantUid});
3189         }
3190     }
3191 
readPersistedSettings()3192     private void readPersistedSettings() {
3193         if (!mSystemServer.isPrivileged()) {
3194             return;
3195         }
3196         final ContentResolver cr = mContentResolver;
3197 
3198         int ringerModeFromSettings =
3199                 mSettings.getGlobalInt(
3200                         cr, Settings.Global.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
3201         int ringerMode = ringerModeFromSettings;
3202         // validity check in case the settings are restored from a device with incompatible
3203         // ringer modes
3204         if (!isValidRingerMode(ringerMode)) {
3205             ringerMode = AudioManager.RINGER_MODE_NORMAL;
3206         }
3207         if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) {
3208             ringerMode = AudioManager.RINGER_MODE_SILENT;
3209         }
3210         if (ringerMode != ringerModeFromSettings) {
3211             mSettings.putGlobalInt(cr, Settings.Global.MODE_RINGER, ringerMode);
3212         }
3213         if (mUseFixedVolume || mIsSingleVolume) {
3214             ringerMode = AudioManager.RINGER_MODE_NORMAL;
3215         }
3216         synchronized(mSettingsLock) {
3217             mRingerMode = ringerMode;
3218             if (mRingerModeExternal == -1) {
3219                 mRingerModeExternal = mRingerMode;
3220             }
3221 
3222             // System.VIBRATE_ON is not used any more but defaults for mVibrateSetting
3223             // are still needed while setVibrateSetting() and getVibrateSetting() are being
3224             // deprecated.
3225             mVibrateSetting = AudioSystem.getValueForVibrateSetting(0,
3226                                             AudioManager.VIBRATE_TYPE_NOTIFICATION,
3227                                             mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT
3228                                                             : AudioManager.VIBRATE_SETTING_OFF);
3229             mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting,
3230                                             AudioManager.VIBRATE_TYPE_RINGER,
3231                                             mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT
3232                                                             : AudioManager.VIBRATE_SETTING_OFF);
3233 
3234             updateRingerAndZenModeAffectedStreams();
3235             readDockAudioSettings(cr);
3236             sendEncodedSurroundMode(cr, "readPersistedSettings");
3237             sendEnabledSurroundFormats(cr, true);
3238             updateAssistantUIdLocked(/* forceUpdate= */ true);
3239             resetActiveAssistantUidsLocked();
3240         }
3241 
3242         AudioSystem.setRttEnabled(mRttEnabled.get());
3243 
3244         mMuteAffectedStreams = mSettings.getSystemIntForUser(cr,
3245                 System.MUTE_STREAMS_AFFECTED, AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED,
3246                 UserHandle.USER_CURRENT);
3247         updateUserMutableStreams();
3248 
3249         updateMasterMono(cr);
3250 
3251         updateMasterBalance(cr);
3252 
3253         // Each stream will read its own persisted settings
3254 
3255         // Broadcast the sticky intents
3256         synchronized (mSettingsLock) {
3257             broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, mRingerModeExternal);
3258             broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, mRingerMode);
3259         }
3260 
3261         // Broadcast vibrate settings
3262         broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
3263         broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION);
3264 
3265         // Load settings for the volume controller
3266         mVolumeController.loadSettings(cr);
3267     }
3268 
updateUserMutableStreams()3269     private void updateUserMutableStreams() {
3270         mUserMutableStreams = mMuteAffectedStreams;
3271         mUserMutableStreams &= ~(1 << AudioSystem.STREAM_VOICE_CALL);
3272         mUserMutableStreams &= ~(1 << AudioSystem.STREAM_BLUETOOTH_SCO);
3273     }
3274 
3275     @GuardedBy("mSettingsLock")
resetActiveAssistantUidsLocked()3276     private void resetActiveAssistantUidsLocked() {
3277         mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS;
3278         updateActiveAssistantServiceUids();
3279     }
3280 
readUserRestrictions()3281     private void readUserRestrictions() {
3282         if (!mSystemServer.isPrivileged()) {
3283             return;
3284         }
3285         final int currentUser = getCurrentUserId();
3286 
3287         if (mUseFixedVolume) {
3288             AudioSystem.setMasterVolume(1.0f);
3289         }
3290 
3291         // Check the current user restriction.
3292         boolean masterMute =
3293                 mUserManagerInternal.getUserRestriction(currentUser,
3294                         UserManager.DISALLOW_UNMUTE_DEVICE)
3295                         || mUserManagerInternal.getUserRestriction(currentUser,
3296                         UserManager.DISALLOW_ADJUST_VOLUME);
3297         setMasterMuteInternalNoCallerCheck(
3298                 masterMute, /* flags =*/ 0, currentUser, "readUserRestrictions");
3299 
3300         mMicMuteFromRestrictions = mUserManagerInternal.getUserRestriction(
3301                 currentUser, UserManager.DISALLOW_UNMUTE_MICROPHONE);
3302         if (DEBUG_VOL) {
3303             Log.d(TAG, String.format("Mic mute %b, user=%d", mMicMuteFromRestrictions,
3304                     currentUser));
3305         }
3306         setMicrophoneMuteNoCallerCheck(currentUser);
3307     }
3308 
getIndexRange(int streamType)3309     private int getIndexRange(int streamType) {
3310         return (getVssForStreamOrDefault(streamType).getMaxIndex() - getVssForStreamOrDefault(
3311                 streamType).getMinIndex());
3312     }
3313 
rescaleIndex(VolumeInfo volumeInfo, int dstStream)3314     private int rescaleIndex(VolumeInfo volumeInfo, int dstStream) {
3315         if (volumeInfo.getVolumeIndex() == VolumeInfo.INDEX_NOT_SET
3316                 || volumeInfo.getMinVolumeIndex() == VolumeInfo.INDEX_NOT_SET
3317                 || volumeInfo.getMaxVolumeIndex() == VolumeInfo.INDEX_NOT_SET) {
3318             Log.e(TAG, "rescaleIndex: volumeInfo has invalid index or range");
3319             return getVssForStreamOrDefault(dstStream).getMinIndex();
3320         }
3321         return rescaleIndex(volumeInfo.getVolumeIndex(),
3322                 volumeInfo.getMinVolumeIndex(), volumeInfo.getMaxVolumeIndex(),
3323                 getVssForStreamOrDefault(dstStream).getMinIndex(),
3324                 getVssForStreamOrDefault(dstStream).getMaxIndex());
3325     }
3326 
rescaleIndex(int index, int srcStream, VolumeInfo dstVolumeInfo)3327     private int rescaleIndex(int index, int srcStream, VolumeInfo dstVolumeInfo) {
3328         int dstMin = dstVolumeInfo.getMinVolumeIndex();
3329         int dstMax = dstVolumeInfo.getMaxVolumeIndex();
3330         // Don't rescale index if the VolumeInfo is missing a min or max index
3331         if (dstMin == VolumeInfo.INDEX_NOT_SET || dstMax == VolumeInfo.INDEX_NOT_SET) {
3332             return index;
3333         }
3334         return rescaleIndex(index,
3335                 getVssForStreamOrDefault(srcStream).getMinIndex(),
3336                 getVssForStreamOrDefault(srcStream).getMaxIndex(),
3337                 dstMin, dstMax);
3338     }
3339 
rescaleIndex(int index, int srcStream, int dstStream)3340     private int rescaleIndex(int index, int srcStream, int dstStream) {
3341         final VolumeStreamState srcVss = getVssForStreamOrDefault(srcStream);
3342         final VolumeStreamState dstVss = getVssForStreamOrDefault(dstStream);
3343         int newIndex = rescaleIndex(index, srcVss.getMinIndex(), srcVss.getMaxIndex(),
3344                 dstVss.getMinIndex(), dstVss.getMaxIndex());
3345         // only apply solution for DTMF stream to make sure that it is not muted when
3346         // re-aliasing to voice call stream. With ringMyCar flag enabled this will be
3347         // automatically solved since we are sending the mute state to APM
3348         // TODO(b/402542630): revisit stream aliasing logic with different min index
3349         //  values / mute states
3350         if (!ringMyCar() && dstStream == AudioSystem.STREAM_DTMF
3351                 && srcStream == AudioSystem.STREAM_VOICE_CALL
3352                 && srcVss.getMinIndex() > dstVss.getMinIndex()) {
3353             newIndex += srcVss.getMinIndex() - dstVss.getMinIndex();
3354             if (newIndex > dstVss.getMaxIndex()) {
3355                 newIndex = dstVss.getMaxIndex();
3356             }
3357         }
3358 
3359         return newIndex;
3360     }
3361 
rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax)3362     private int rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax) {
3363         int srcRange = srcMax - srcMin;
3364         int dstRange = dstMax - dstMin;
3365         if (srcRange == 0) {
3366             Log.e(TAG, "rescaleIndex : index range should not be zero");
3367             return dstMin;
3368         }
3369         return dstMin + ((index - srcMin) * dstRange + srcRange / 2) / srcRange;
3370     }
3371 
rescaleStep(int step, int srcStream, int dstStream)3372     private int rescaleStep(int step, int srcStream, int dstStream) {
3373         int srcRange = getIndexRange(srcStream);
3374         int dstRange = getIndexRange(dstStream);
3375         if (srcRange == 0) {
3376             Log.e(TAG, "rescaleStep : index range should not be zero");
3377             return 0;
3378         }
3379 
3380         return (step * dstRange + srcRange / 2) / srcRange;
3381     }
3382 
3383     ///////////////////////////////////////////////////////////////////////////
3384     // IPC methods
3385     ///////////////////////////////////////////////////////////////////////////
3386     /**
3387      * @see AudioManager#setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes)
3388      * @see AudioManager#setPreferredDevicesForStrategy(AudioProductStrategy,
3389      *                                                  List<AudioDeviceAttributes>)
3390      */
3391     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices)3392     public int setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices) {
3393         super.setPreferredDevicesForStrategy_enforcePermission();
3394         if (devices == null) {
3395             return AudioSystem.ERROR;
3396         }
3397 
3398         devices = retrieveBluetoothAddresses(devices);
3399 
3400         final String logString = String.format(
3401                 "setPreferredDevicesForStrategy u/pid:%d/%d strat:%d dev:%s",
3402                 Binder.getCallingUid(), Binder.getCallingPid(), strategy,
3403                 devices.stream().map(e -> e.toString()).collect(Collectors.joining(",")));
3404         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
3405         if (devices.stream().anyMatch(device ->
3406                 device.getRole() == AudioDeviceAttributes.ROLE_INPUT)) {
3407             Log.e(TAG, "Unsupported input routing in " + logString);
3408             return AudioSystem.ERROR;
3409         }
3410 
3411         final int status = mDeviceBroker.setPreferredDevicesForStrategySync(strategy, devices);
3412         if (status != AudioSystem.SUCCESS) {
3413             Log.e(TAG, String.format("Error %d in %s)", status, logString));
3414         }
3415 
3416         return status;
3417     }
3418 
3419     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
3420     /** @see AudioManager#removePreferredDeviceForStrategy(AudioProductStrategy) */
removePreferredDevicesForStrategy(int strategy)3421     public int removePreferredDevicesForStrategy(int strategy) {
3422         super.removePreferredDevicesForStrategy_enforcePermission();
3423 
3424         final String logString =
3425                 String.format("removePreferredDevicesForStrategy strat:%d", strategy);
3426         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
3427 
3428         final int status = mDeviceBroker.removePreferredDevicesForStrategySync(strategy);
3429         if (status != AudioSystem.SUCCESS && status != AudioSystem.BAD_VALUE) {
3430             Log.e(TAG, String.format("Error %d in %s)", status, logString));
3431         }
3432         return status;
3433     }
3434 
3435     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
3436     /**
3437      * @see AudioManager#getPreferredDeviceForStrategy(AudioProductStrategy)
3438      * @see AudioManager#getPreferredDevicesForStrategy(AudioProductStrategy)
3439      */
getPreferredDevicesForStrategy(int strategy)3440     public List<AudioDeviceAttributes> getPreferredDevicesForStrategy(int strategy) {
3441         super.getPreferredDevicesForStrategy_enforcePermission();
3442 
3443         List<AudioDeviceAttributes> devices = new ArrayList<>();
3444         int status = AudioSystem.SUCCESS;
3445         final long identity = Binder.clearCallingIdentity();
3446         try {
3447             status = AudioSystem.getDevicesForRoleAndStrategy(
3448                     strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
3449         } finally {
3450             Binder.restoreCallingIdentity(identity);
3451         }
3452         if (status != AudioSystem.SUCCESS) {
3453             Log.e(TAG, String.format("Error %d in getPreferredDeviceForStrategy(%d)",
3454                     status, strategy));
3455             return new ArrayList<AudioDeviceAttributes>();
3456         } else {
3457             return anonymizeAudioDeviceAttributesList(devices);
3458         }
3459     }
3460 
3461     /**
3462      * @see AudioManager#setDeviceAsNonDefaultForStrategy(AudioProductStrategy,
3463      *                                                    AudioDeviceAttributes)
3464      * @see AudioManager#setDeviceAsNonDefaultForStrategy(AudioProductStrategy,
3465      *                                                     List<AudioDeviceAttributes>)
3466      */
3467     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
setDeviceAsNonDefaultForStrategy(int strategy, @NonNull AudioDeviceAttributes device)3468     public int setDeviceAsNonDefaultForStrategy(int strategy,
3469                                                 @NonNull AudioDeviceAttributes device) {
3470         super.setDeviceAsNonDefaultForStrategy_enforcePermission();
3471         Objects.requireNonNull(device);
3472 
3473         device = retrieveBluetoothAddress(device);
3474 
3475         final String logString = String.format(
3476                 "setDeviceAsNonDefaultForStrategy u/pid:%d/%d strat:%d dev:%s",
3477                 Binder.getCallingUid(), Binder.getCallingPid(), strategy, device.toString());
3478         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
3479         if (device.getRole() == AudioDeviceAttributes.ROLE_INPUT) {
3480             Log.e(TAG, "Unsupported input routing in " + logString);
3481             return AudioSystem.ERROR;
3482         }
3483 
3484         final int status = mDeviceBroker.setDeviceAsNonDefaultForStrategySync(strategy, device);
3485         if (status != AudioSystem.SUCCESS) {
3486             Log.e(TAG, String.format("Error %d in %s)", status, logString));
3487         }
3488 
3489         return status;
3490     }
3491 
3492     /**
3493      * @see AudioManager#removeDeviceAsNonDefaultForStrategy(AudioProductStrategy,
3494      *                                                       AudioDeviceAttributes)
3495      */
3496     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
removeDeviceAsNonDefaultForStrategy(int strategy, AudioDeviceAttributes device)3497     public int removeDeviceAsNonDefaultForStrategy(int strategy,
3498                                                    AudioDeviceAttributes device) {
3499         super.removeDeviceAsNonDefaultForStrategy_enforcePermission();
3500         Objects.requireNonNull(device);
3501 
3502         device = retrieveBluetoothAddress(device);
3503 
3504         final String logString = String.format(
3505                 "removeDeviceAsNonDefaultForStrategy strat:%d dev:%s", strategy, device.toString());
3506         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
3507         if (device.getRole() == AudioDeviceAttributes.ROLE_INPUT) {
3508             Log.e(TAG, "Unsupported input routing in " + logString);
3509             return AudioSystem.ERROR;
3510         }
3511 
3512         final int status = mDeviceBroker.removeDeviceAsNonDefaultForStrategySync(strategy, device);
3513         if (status != AudioSystem.SUCCESS && status != AudioSystem.BAD_VALUE) {
3514             Log.e(TAG, String.format("Error %d in %s)", status, logString));
3515         }
3516         return status;
3517     }
3518 
3519     /**
3520      * @see AudioManager#getNonDefaultDevicesForStrategy(AudioProductStrategy)
3521      */
3522     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
getNonDefaultDevicesForStrategy(int strategy)3523     public List<AudioDeviceAttributes> getNonDefaultDevicesForStrategy(int strategy) {
3524         super.getNonDefaultDevicesForStrategy_enforcePermission();
3525         List<AudioDeviceAttributes> devices = new ArrayList<>();
3526         int status = AudioSystem.ERROR;
3527 
3528         try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
3529             status = AudioSystem.getDevicesForRoleAndStrategy(
3530                     strategy, AudioSystem.DEVICE_ROLE_DISABLED, devices);
3531         }
3532 
3533         if (status != AudioSystem.SUCCESS) {
3534             Log.e(TAG, String.format("Error %d in getNonDefaultDeviceForStrategy(%d)",
3535                     status, strategy));
3536             return new ArrayList<AudioDeviceAttributes>();
3537         } else {
3538             return anonymizeAudioDeviceAttributesList(devices);
3539         }
3540     }
3541 
3542     /** @see AudioManager#addOnPreferredDevicesForStrategyChangedListener(
3543      *               Executor, AudioManager.OnPreferredDevicesForStrategyChangedListener)
3544      */
registerStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)3545     public void registerStrategyPreferredDevicesDispatcher(
3546             @Nullable IStrategyPreferredDevicesDispatcher dispatcher) {
3547         if (dispatcher == null) {
3548             return;
3549         }
3550         enforceModifyAudioRoutingPermission();
3551         mDeviceBroker.registerStrategyPreferredDevicesDispatcher(
3552                 dispatcher, isBluetoothPrividged());
3553     }
3554 
3555     /** @see AudioManager#removeOnPreferredDevicesForStrategyChangedListener(
3556      *               AudioManager.OnPreferredDevicesForStrategyChangedListener)
3557      */
unregisterStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)3558     public void unregisterStrategyPreferredDevicesDispatcher(
3559             @Nullable IStrategyPreferredDevicesDispatcher dispatcher) {
3560         if (dispatcher == null) {
3561             return;
3562         }
3563         enforceModifyAudioRoutingPermission();
3564         mDeviceBroker.unregisterStrategyPreferredDevicesDispatcher(dispatcher);
3565     }
3566 
3567     /** @see AudioManager#addOnNonDefaultDevicesForStrategyChangedListener(
3568      *               Executor, AudioManager.OnNonDefaultDevicesForStrategyChangedListener)
3569      */
registerStrategyNonDefaultDevicesDispatcher( @ullable IStrategyNonDefaultDevicesDispatcher dispatcher)3570     public void registerStrategyNonDefaultDevicesDispatcher(
3571             @Nullable IStrategyNonDefaultDevicesDispatcher dispatcher) {
3572         if (dispatcher == null) {
3573             return;
3574         }
3575         enforceModifyAudioRoutingPermission();
3576         mDeviceBroker.registerStrategyNonDefaultDevicesDispatcher(
3577                 dispatcher, isBluetoothPrividged());
3578     }
3579 
3580     /** @see AudioManager#removeOnNonDefaultDevicesForStrategyChangedListener(
3581      *               AudioManager.OnNonDefaultDevicesForStrategyChangedListener)
3582      */
unregisterStrategyNonDefaultDevicesDispatcher( @ullable IStrategyNonDefaultDevicesDispatcher dispatcher)3583     public void unregisterStrategyNonDefaultDevicesDispatcher(
3584             @Nullable IStrategyNonDefaultDevicesDispatcher dispatcher) {
3585         if (dispatcher == null) {
3586             return;
3587         }
3588         enforceModifyAudioRoutingPermission();
3589         mDeviceBroker.unregisterStrategyNonDefaultDevicesDispatcher(dispatcher);
3590     }
3591 
3592     /**
3593      * @see AudioManager#setPreferredDevicesForCapturePreset(int, AudioDeviceAttributes)
3594      */
setPreferredDevicesForCapturePreset( int capturePreset, List<AudioDeviceAttributes> devices)3595     public int setPreferredDevicesForCapturePreset(
3596             int capturePreset, List<AudioDeviceAttributes> devices) {
3597         if (devices == null) {
3598             return AudioSystem.ERROR;
3599         }
3600         enforceModifyAudioRoutingPermission();
3601         final String logString = String.format(
3602                 "setPreferredDevicesForCapturePreset u/pid:%d/%d source:%d dev:%s",
3603                 Binder.getCallingUid(), Binder.getCallingPid(), capturePreset,
3604                 devices.stream().map(e -> e.toString()).collect(Collectors.joining(",")));
3605         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
3606         if (devices.stream().anyMatch(device ->
3607                 device.getRole() == AudioDeviceAttributes.ROLE_OUTPUT)) {
3608             Log.e(TAG, "Unsupported output routing in " + logString);
3609             return AudioSystem.ERROR;
3610         }
3611 
3612         devices = retrieveBluetoothAddresses(devices);
3613 
3614         final int status = mDeviceBroker.setPreferredDevicesForCapturePresetSync(
3615                 capturePreset, devices);
3616         if (status != AudioSystem.SUCCESS) {
3617             Log.e(TAG, String.format("Error %d in %s)", status, logString));
3618         }
3619 
3620         return status;
3621     }
3622 
3623     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
3624     /** @see AudioManager#clearPreferredDevicesForCapturePreset(int) */
clearPreferredDevicesForCapturePreset(int capturePreset)3625     public int clearPreferredDevicesForCapturePreset(int capturePreset) {
3626         super.clearPreferredDevicesForCapturePreset_enforcePermission();
3627 
3628         final String logString = String.format(
3629                 "removePreferredDeviceForCapturePreset source:%d", capturePreset);
3630         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
3631 
3632         final int status = mDeviceBroker.clearPreferredDevicesForCapturePresetSync(capturePreset);
3633         if (status != AudioSystem.SUCCESS && status != AudioSystem.BAD_VALUE) {
3634             Log.e(TAG, String.format("Error %d in %s", status, logString));
3635         }
3636         return status;
3637     }
3638 
3639     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
3640     /**
3641      * @see AudioManager#getPreferredDevicesForCapturePreset(int)
3642      */
getPreferredDevicesForCapturePreset(int capturePreset)3643     public List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int capturePreset) {
3644         super.getPreferredDevicesForCapturePreset_enforcePermission();
3645 
3646         List<AudioDeviceAttributes> devices = new ArrayList<>();
3647         int status = AudioSystem.SUCCESS;
3648         final long identity = Binder.clearCallingIdentity();
3649         try {
3650             status = AudioSystem.getDevicesForRoleAndCapturePreset(
3651                     capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
3652         } finally {
3653             Binder.restoreCallingIdentity(identity);
3654         }
3655         if (status != AudioSystem.SUCCESS) {
3656             Log.e(TAG, String.format("Error %d in getPreferredDeviceForCapturePreset(%d)",
3657                     status, capturePreset));
3658             return new ArrayList<AudioDeviceAttributes>();
3659         } else {
3660             return anonymizeAudioDeviceAttributesList(devices);
3661         }
3662     }
3663 
3664     /**
3665      * @see AudioManager#addOnPreferredDevicesForCapturePresetChangedListener(
3666      *              Executor, OnPreferredDevicesForCapturePresetChangedListener)
3667      */
registerCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)3668     public void registerCapturePresetDevicesRoleDispatcher(
3669             @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) {
3670         if (dispatcher == null) {
3671             return;
3672         }
3673         enforceModifyAudioRoutingPermission();
3674         mDeviceBroker.registerCapturePresetDevicesRoleDispatcher(
3675                 dispatcher, isBluetoothPrividged());
3676     }
3677 
3678     /**
3679      * @see AudioManager#removeOnPreferredDevicesForCapturePresetChangedListener(
3680      *              AudioManager.OnPreferredDevicesForCapturePresetChangedListener)
3681      */
unregisterCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)3682     public void unregisterCapturePresetDevicesRoleDispatcher(
3683             @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) {
3684         if (dispatcher == null) {
3685             return;
3686         }
3687         enforceModifyAudioRoutingPermission();
3688         mDeviceBroker.unregisterCapturePresetDevicesRoleDispatcher(dispatcher);
3689     }
3690 
3691     /** @see AudioManager#getDevicesForAttributes(AudioAttributes) */
getDevicesForAttributes( @onNull AudioAttributes attributes)3692     public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes(
3693             @NonNull AudioAttributes attributes) {
3694         enforceQueryStateOrModifyRoutingPermission();
3695 
3696         return new ArrayList<AudioDeviceAttributes>(anonymizeAudioDeviceAttributesList(
3697                 getDevicesForAttributesInt(attributes, false /* forVolume */)));
3698     }
3699 
3700     /** @see AudioManager#getAudioDevicesForAttributes(AudioAttributes)
3701      * This method is similar with AudioService#getDevicesForAttributes,
3702      * only it doesn't enforce permissions because it is used by an unprivileged public API
3703      * instead of the system API.
3704      */
getDevicesForAttributesUnprotected( @onNull AudioAttributes attributes)3705     public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesUnprotected(
3706             @NonNull AudioAttributes attributes) {
3707         return new ArrayList<AudioDeviceAttributes>(anonymizeAudioDeviceAttributesList(
3708                 getDevicesForAttributesInt(attributes, false /* forVolume */)));
3709     }
3710 
3711     /**
3712      * @see AudioManager#isMusicActive()
3713      * @param remotely true if query is for remote playback (cast), false for local playback.
3714      */
isMusicActive(boolean remotely)3715     public boolean isMusicActive(boolean remotely) {
3716         // no permission required
3717         final long token = Binder.clearCallingIdentity();
3718         try {
3719             if (remotely) {
3720                 return AudioSystem.isStreamActiveRemotely(AudioSystem.STREAM_MUSIC, 0);
3721             } else {
3722                 return AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0);
3723             }
3724         } finally {
3725             Binder.restoreCallingIdentity(token);
3726         }
3727     }
3728 
getDevicesForAttributesInt( @onNull AudioAttributes attributes, boolean forVolume)3729     protected @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesInt(
3730             @NonNull AudioAttributes attributes, boolean forVolume) {
3731         Objects.requireNonNull(attributes);
3732         return mAudioSystem.getDevicesForAttributes(attributes, forVolume);
3733     }
3734 
3735     /**
3736      * @see AudioManager#addOnDevicesForAttributesChangedListener(
3737      *      AudioAttributes, Executor, OnDevicesForAttributesChangedListener)
3738      */
3739     @android.annotation.EnforcePermission(anyOf = { MODIFY_AUDIO_ROUTING, QUERY_AUDIO_STATE })
addOnDevicesForAttributesChangedListener(AudioAttributes attributes, IDevicesForAttributesCallback callback)3740     public void addOnDevicesForAttributesChangedListener(AudioAttributes attributes,
3741             IDevicesForAttributesCallback callback) {
3742         super.addOnDevicesForAttributesChangedListener_enforcePermission();
3743         mAudioSystem.addOnDevicesForAttributesChangedListener(
3744                 attributes, false /* forVolume */, callback);
3745     }
3746 
3747     /**
3748      * @see AudioManager#removeOnDevicesForAttributesChangedListener(
3749      *      OnDevicesForAttributesChangedListener)
3750      */
removeOnDevicesForAttributesChangedListener( IDevicesForAttributesCallback callback)3751     public void removeOnDevicesForAttributesChangedListener(
3752             IDevicesForAttributesCallback callback) {
3753         mAudioSystem.removeOnDevicesForAttributesChangedListener(callback);
3754     }
3755 
3756     // pre-condition: event.getKeyCode() is one of KeyEvent.KEYCODE_VOLUME_UP,
3757     //                                   KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_MUTE
handleVolumeKey(@onNull KeyEvent event, boolean isOnTv, @NonNull String callingPackage, @NonNull String caller)3758     public void handleVolumeKey(@NonNull KeyEvent event, boolean isOnTv,
3759             @NonNull String callingPackage, @NonNull String caller) {
3760         int keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_NORMAL;
3761         if (isOnTv) {
3762             if (event.getAction() == KeyEvent.ACTION_DOWN) {
3763                 keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_START;
3764             } else { // may catch more than ACTION_UP, but will end vol adjustement
3765                 // the vol key is either released (ACTION_UP), or multiple keys are pressed
3766                 // (ACTION_MULTIPLE) and we don't know what to do for volume control on CEC, end
3767                 // the repeated volume adjustement
3768                 keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_END;
3769             }
3770         } else if (event.getAction() != KeyEvent.ACTION_DOWN) {
3771             return;
3772         }
3773 
3774         int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND
3775                 | AudioManager.FLAG_FROM_KEY;
3776 
3777         switch (event.getKeyCode()) {
3778             case KeyEvent.KEYCODE_VOLUME_UP:
3779                     adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE,
3780                             AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller,
3781                             Binder.getCallingUid(), Binder.getCallingPid(), true, keyEventMode);
3782                 break;
3783             case KeyEvent.KEYCODE_VOLUME_DOWN:
3784                     adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER,
3785                             AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller,
3786                             Binder.getCallingUid(), Binder.getCallingPid(), true, keyEventMode);
3787                 break;
3788             case KeyEvent.KEYCODE_VOLUME_MUTE:
3789                 if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
3790                     adjustSuggestedStreamVolume(AudioManager.ADJUST_TOGGLE_MUTE,
3791                             AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller,
3792                             Binder.getCallingUid(), Binder.getCallingPid(),
3793                             true, AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
3794                 }
3795                 break;
3796             default:
3797                 Log.e(TAG, "Invalid key code " + event.getKeyCode() + " sent by " + callingPackage);
3798                 return; // not needed but added if code gets added below this switch statement
3799         }
3800     }
3801 
setNavigationRepeatSoundEffectsEnabled(boolean enabled)3802     public void setNavigationRepeatSoundEffectsEnabled(boolean enabled) {
3803         mNavigationRepeatSoundEffectsEnabled = enabled;
3804     }
3805 
3806     /**
3807      * @return true if the fast scroll sound effects are enabled
3808      */
areNavigationRepeatSoundEffectsEnabled()3809     public boolean areNavigationRepeatSoundEffectsEnabled() {
3810         return mNavigationRepeatSoundEffectsEnabled;
3811     }
3812 
setHomeSoundEffectEnabled(boolean enabled)3813     public void setHomeSoundEffectEnabled(boolean enabled) {
3814         mHomeSoundEffectEnabled = enabled;
3815     }
3816 
3817     /**
3818      * @return true if the home sound effect is enabled
3819      */
isHomeSoundEffectEnabled()3820     public boolean isHomeSoundEffectEnabled() {
3821         return mHomeSoundEffectEnabled;
3822     }
3823 
3824     /** 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)3825     private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
3826             String callingPackage, String caller, int uid, int pid, boolean hasModifyAudioSettings,
3827             int keyEventMode) {
3828         if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream=" + suggestedStreamType
3829                 + ", flags=" + flags + ", caller=" + caller
3830                 + ", volControlStream=" + mVolumeControlStream
3831                 + ", userSelect=" + mUserSelectedVolumeControlStream);
3832         if (direction != AudioManager.ADJUST_SAME) {
3833             sVolumeLogger.enqueue(
3834                     new VolumeEvent(VolumeEvent.VOL_ADJUST_SUGG_VOL, suggestedStreamType,
3835                             direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage)
3836                             .append("/").append(caller).append(" uid:").append(uid).toString()));
3837         }
3838 
3839         boolean hasExternalVolumeController = notifyExternalVolumeController(direction);
3840 
3841         new MediaMetrics.Item(mMetricsId + "adjustSuggestedStreamVolume")
3842                 .setUid(Binder.getCallingUid())
3843                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage)
3844                 .set(MediaMetrics.Property.CLIENT_NAME, caller)
3845                 .set(MediaMetrics.Property.DIRECTION, direction > 0
3846                         ? MediaMetrics.Value.UP : MediaMetrics.Value.DOWN)
3847                 .set(MediaMetrics.Property.EXTERNAL, hasExternalVolumeController
3848                         ? MediaMetrics.Value.YES : MediaMetrics.Value.NO)
3849                 .set(MediaMetrics.Property.FLAGS, flags)
3850                 .record();
3851 
3852         if (hasExternalVolumeController) {
3853             return;
3854         }
3855 
3856         int streamType;
3857         synchronized (mForceControlStreamLock) {
3858             // Request lock in case mVolumeControlStream is changed by other thread.
3859             if (mUserSelectedVolumeControlStream) { // implies mVolumeControlStream != -1
3860                 streamType = mVolumeControlStream;
3861             } else {
3862                 // TODO discard activity on a muted stream?
3863                 final int maybeActiveStreamType = getActiveStreamType(suggestedStreamType);
3864                 final boolean activeForReal;
3865                 if (maybeActiveStreamType == AudioSystem.STREAM_RING
3866                         || maybeActiveStreamType == AudioSystem.STREAM_NOTIFICATION) {
3867                     activeForReal = wasStreamActiveRecently(maybeActiveStreamType, 0);
3868                 } else {
3869                     activeForReal = mAudioSystem.isStreamActive(maybeActiveStreamType, 0);
3870                 }
3871                 if (activeForReal || mVolumeControlStream == -1) {
3872                     streamType = maybeActiveStreamType;
3873                 } else {
3874                     streamType = mVolumeControlStream;
3875                 }
3876             }
3877         }
3878 
3879         final boolean isMute = isMuteAdjust(direction);
3880 
3881         streamType = replaceBtScoStreamWithVoiceCall(streamType, "adjustSuggestedStreamVolume");
3882 
3883         ensureValidStreamType(streamType);
3884         final int resolvedStream = sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound=*/-1);
3885         if (resolvedStream == -1) {
3886             Log.e(TAG, "adjustSuggestedStreamVolume: no stream vol alias for stream type "
3887                     + streamType);
3888             return;
3889         }
3890 
3891         // Play sounds on STREAM_RING only.
3892         if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 &&
3893                 resolvedStream != AudioSystem.STREAM_RING) {
3894             flags &= ~AudioManager.FLAG_PLAY_SOUND;
3895         }
3896 
3897         // For notifications/ring, show the ui before making any adjustments
3898         // Don't suppress mute/unmute requests
3899         // Don't suppress adjustments for single volume device
3900         if (mVolumeController.suppressAdjustment(resolvedStream, flags, isMute)
3901                 && !mIsSingleVolume) {
3902             direction = 0;
3903             flags &= ~AudioManager.FLAG_PLAY_SOUND;
3904             flags &= ~AudioManager.FLAG_VIBRATE;
3905             if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment");
3906         }
3907 
3908         adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid, pid,
3909                 null, hasModifyAudioSettings, keyEventMode);
3910     }
3911 
notifyExternalVolumeController(int direction)3912     private boolean notifyExternalVolumeController(int direction) {
3913         final IAudioPolicyCallback externalVolumeController;
3914         synchronized (mExtVolumeControllerLock) {
3915             externalVolumeController = mExtVolumeController;
3916         }
3917         if (externalVolumeController == null) {
3918             return false;
3919         }
3920 
3921         sendMsg(mAudioHandler, MSG_NOTIFY_VOL_EVENT, SENDMSG_QUEUE,
3922                 direction, 0 /*ignored*/,
3923                 externalVolumeController, 0 /*delay*/);
3924         return true;
3925     }
3926 
3927     /** Retain API for unsupported app usage */
adjustStreamVolume(int streamType, int direction, int flags, String callingPackage)3928     public void adjustStreamVolume(int streamType, int direction, int flags,
3929             String callingPackage) {
3930         adjustStreamVolumeWithAttribution(streamType, direction, flags, callingPackage, null);
3931     }
3932 
3933     /** @see AudioManager#adjustStreamVolume(int, int, int)
3934      * Part of service interface, check permissions here */
adjustStreamVolumeWithAttribution(int streamType, int direction, int flags, String callingPackage, String attributionTag)3935     public void adjustStreamVolumeWithAttribution(int streamType, int direction, int flags,
3936             String callingPackage, String attributionTag) {
3937         if (mHardeningEnforcer.blockVolumeMethod(
3938                 HardeningEnforcer.METHOD_AUDIO_MANAGER_ADJUST_STREAM_VOLUME,
3939                 callingPackage,
3940                 Binder.getCallingUid())) {
3941             return;
3942         }
3943         if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {
3944             Log.w(TAG, "Trying to call adjustStreamVolume() for a11y without"
3945                     + "CHANGE_ACCESSIBILITY_VOLUME / callingPackage=" + callingPackage);
3946             return;
3947         }
3948 
3949         final VolumeEvent evt = new VolumeEvent(VolumeEvent.VOL_ADJUST_STREAM_VOL, streamType,
3950                 direction/*val1*/, flags/*val2*/, callingPackage);
3951         sVolumeLogger.enqueue(evt);
3952         // also logging mute/unmute calls to the dedicated logger
3953         if (isMuteAdjust(direction)) {
3954             sMuteLogger.enqueue(evt);
3955         }
3956         adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage,
3957                 Binder.getCallingUid(), Binder.getCallingPid(), attributionTag,
3958                 callingHasAudioSettingsPermission(), AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
3959     }
3960 
adjustStreamVolume(int streamType, int direction, int flags, String callingPackage, String caller, int uid, int pid, String attributionTag, boolean hasModifyAudioSettings, int keyEventMode)3961     protected void adjustStreamVolume(int streamType, int direction, int flags,
3962             String callingPackage, String caller, int uid, int pid, String attributionTag,
3963             boolean hasModifyAudioSettings, int keyEventMode) {
3964         if (mUseFixedVolume) {
3965             return;
3966         }
3967         streamType = replaceBtScoStreamWithVoiceCall(streamType, "adjustStreamVolume");
3968 
3969         if (DEBUG_VOL) Log.d(TAG, "adjustStreamVolume() stream=" + streamType + ", dir=" + direction
3970                 + ", flags=" + flags + ", caller=" + caller);
3971 
3972         ensureValidDirection(direction);
3973         ensureValidStreamType(streamType);
3974 
3975         boolean isMuteAdjust = isMuteAdjust(direction);
3976 
3977         if (isMuteAdjust && !isStreamAffectedByMute(streamType)) {
3978             return;
3979         }
3980 
3981         // If adjust is mute and the stream is STREAM_VOICE_CALL or STREAM_BLUETOOTH_SCO, make sure
3982         // that the calling app have the MODIFY_PHONE_STATE permission.
3983         if (isMuteAdjust &&
3984             (streamType == AudioSystem.STREAM_VOICE_CALL ||
3985                 // TODO: when replaceStreamBtSco flag is rolled out remove next condition
3986                 isStreamBluetoothSco(streamType))
3987                 && mContext.checkPermission(MODIFY_PHONE_STATE, pid, uid)
3988                     != PackageManager.PERMISSION_GRANTED) {
3989             Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: adjustStreamVolume from pid="
3990                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
3991             return;
3992         }
3993 
3994         // If the stream is STREAM_ASSISTANT,
3995         // make sure that the calling app have the MODIFY_AUDIO_ROUTING permission.
3996         if (streamType == AudioSystem.STREAM_ASSISTANT &&
3997                 mContext.checkPermission(
3998                 MODIFY_AUDIO_ROUTING, pid, uid)
3999                     != PackageManager.PERMISSION_GRANTED) {
4000             Log.w(TAG, "MODIFY_AUDIO_ROUTING Permission Denial: adjustStreamVolume from pid="
4001                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
4002             return;
4003         }
4004 
4005         // use stream type alias here so that streams with same alias have the same behavior,
4006         // including with regard to silent mode control (e.g the use of STREAM_RING below and in
4007         // checkForRingerModeChange() in place of STREAM_RING or STREAM_NOTIFICATION)
4008         int streamTypeAlias = sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound=*/-1);
4009         if (streamTypeAlias == -1) {
4010             Log.e(TAG,
4011                     "adjustStreamVolume: no stream vol alias for stream type " + streamType);
4012         }
4013 
4014         VolumeStreamState streamState = getVssForStreamOrDefault(streamTypeAlias);
4015 
4016         final int device = getDeviceForStream(streamTypeAlias);
4017 
4018         int aliasIndex = streamState.getIndex(device);
4019         boolean adjustVolume = true;
4020         int step;
4021 
4022         // skip a2dp absolute volume control request when the device
4023         // is neither an a2dp device nor BLE device
4024         if ((!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
4025                 && !AudioSystem.DEVICE_OUT_ALL_BLE_SET.contains(device))
4026                 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) {
4027             return;
4028         }
4029 
4030         // If we are being called by the system (e.g. hardware keys) check for current user
4031         // so we handle user restrictions correctly.
4032         if (uid == android.os.Process.SYSTEM_UID) {
4033             uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid));
4034         }
4035         // validate calling package and app op
4036         if (!checkNoteAppOp(
4037                 STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage, attributionTag)) {
4038             return;
4039         }
4040 
4041         mSoundDoseHelper.invalidatePendingVolumeCommand();
4042 
4043         flags &= ~AudioManager.FLAG_FIXED_VOLUME;
4044         if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) {
4045             flags |= AudioManager.FLAG_FIXED_VOLUME;
4046 
4047             // Always toggle between max safe volume and 0 for fixed volume devices where safe
4048             // volume is enforced, and max and 0 for the others.
4049             // This is simulated by stepping by the full allowed volume range
4050             step = mSoundDoseHelper.getSafeMediaVolumeIndex(device);
4051             if (step < 0) {
4052                 step = streamState.getMaxIndex();
4053             }
4054             if (aliasIndex != 0) {
4055                 aliasIndex = step;
4056             }
4057         } else {
4058             // convert one UI step (+/-1) into a number of internal units on the stream alias
4059             step = rescaleStep((int) (10 * streamState.getIndexStepFactor()), streamType,
4060                     streamTypeAlias);
4061         }
4062 
4063         // If either the client forces allowing ringer modes for this adjustment,
4064         // or stream is used for UI sonification
4065         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
4066                 (isUiSoundsStreamType(streamTypeAlias))) {
4067             int ringerMode = getRingerModeInternal();
4068             // do not vibrate if already in vibrate mode
4069             if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
4070                 flags &= ~AudioManager.FLAG_VIBRATE;
4071             }
4072             // Check if the ringer mode handles this adjustment. If it does we don't
4073             // need to adjust the volume further.
4074             final int result = checkForRingerModeChange(aliasIndex, direction, step,
4075                     streamState.mIsMuted, callingPackage, flags);
4076             adjustVolume = (result & FLAG_ADJUST_VOLUME) != 0;
4077             // If suppressing a volume adjustment in silent mode, display the UI hint
4078             if ((result & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) {
4079                 flags |= AudioManager.FLAG_SHOW_SILENT_HINT;
4080             }
4081             // If suppressing a volume down adjustment in vibrate mode, display the UI hint
4082             if ((result & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) {
4083                 flags |= AudioManager.FLAG_SHOW_VIBRATE_HINT;
4084             }
4085         } else if (isStreamMutedByRingerOrZenMode(streamTypeAlias) && streamState.mIsMuted) {
4086             // if the stream is currently muted streams by ringer/zen mode
4087             // then it cannot be unmuted (without FLAG_ALLOW_RINGER_MODES) with an unmute or raise
4088             if (direction == AudioManager.ADJUST_TOGGLE_MUTE
4089                     || direction == AudioManager.ADJUST_UNMUTE
4090                     || direction == AudioManager.ADJUST_RAISE) {
4091                 adjustVolume = false;
4092             }
4093         }
4094 
4095         // If the ringer mode or zen is muting the stream, do not change stream unless
4096         // it'll cause us to exit dnd
4097         if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) {
4098             adjustVolume = false;
4099         }
4100         int oldIndex = getVssForStreamOrDefault(streamType).getIndex(device);
4101 
4102         // Check if the volume adjustment should be handled by an absolute volume controller instead
4103         if (isAbsoluteVolumeDevice(device) && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) {
4104             final AbsoluteVolumeDeviceInfo info = getAbsoluteVolumeDeviceInfo(device);
4105             if (info.mHandlesVolumeAdjustment) {
4106                 dispatchAbsoluteVolumeAdjusted(streamType, info, oldIndex, direction,
4107                         keyEventMode);
4108                 return;
4109             }
4110         }
4111 
4112         if (adjustVolume && (direction != AudioManager.ADJUST_SAME)
4113                 && (keyEventMode != AudioDeviceVolumeManager.ADJUST_MODE_END)) {
4114             mAudioHandler.removeMessages(MSG_UNMUTE_STREAM_ON_SINGLE_VOL_DEVICE);
4115 
4116             if (isMuteAdjust && !mFullVolumeDevices.contains(device)) {
4117                 boolean state;
4118                 if (direction == AudioManager.ADJUST_TOGGLE_MUTE) {
4119                     state = !streamState.mIsMuted;
4120                 } else {
4121                     state = direction == AudioManager.ADJUST_MUTE;
4122                 }
4123                 muteAliasStreams(streamTypeAlias, state);
4124             } else if ((direction == AudioManager.ADJUST_RAISE)
4125                     && mSoundDoseHelper.raiseVolumeDisplaySafeMediaVolume(streamTypeAlias,
4126                             aliasIndex + step, device, flags)) {
4127                 Log.e(TAG, "adjustStreamVolume() safe volume index = " + oldIndex);
4128             } else if (!isFullVolumeDevice(device)
4129                     && (streamState.adjustIndex(direction * step, device, caller,
4130                             hasModifyAudioSettings)
4131                             || streamState.mIsMuted)) {
4132                 // Post message to set system volume (it in turn will post a
4133                 // message to persist).
4134                 if (streamState.mIsMuted) {
4135                     // Unmute the stream if it was previously muted
4136                     if (direction == AudioManager.ADJUST_RAISE) {
4137                         // unmute immediately for volume up
4138                         muteAliasStreams(streamTypeAlias, false);
4139                     } else if (direction == AudioManager.ADJUST_LOWER) {
4140                         if (mIsSingleVolume) {
4141                             sendMsg(mAudioHandler, MSG_UNMUTE_STREAM_ON_SINGLE_VOL_DEVICE,
4142                                     SENDMSG_QUEUE, streamTypeAlias, flags, null,
4143                                     UNMUTE_STREAM_DELAY);
4144                         }
4145                     }
4146                 }
4147                 sendMsg(mAudioHandler,
4148                         MSG_SET_DEVICE_VOLUME,
4149                         SENDMSG_QUEUE,
4150                         device,
4151                         0,
4152                         streamState,
4153                         0);
4154             }
4155 
4156             int newIndex = getVssForStreamOrDefault(streamType).getIndex(device);
4157 
4158             // Check if volume update should be send to AVRCP
4159             if (streamTypeAlias == getBluetoothContextualVolumeStream()
4160                     && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
4161                     && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
4162                 if (DEBUG_VOL) {
4163                     Log.d(TAG, "adjustStreamVolume: postSetAvrcpAbsoluteVolumeIndex index="
4164                             + newIndex + "stream=" + streamType);
4165                 }
4166                 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(newIndex / 10);
4167             } else if (isAbsoluteVolumeDevice(device)
4168                     && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) {
4169                 final AbsoluteVolumeDeviceInfo info = getAbsoluteVolumeDeviceInfo(device);
4170                 dispatchAbsoluteVolumeChanged(streamType, info, newIndex);
4171             }
4172 
4173             if (AudioSystem.isLeAudioDeviceType(device)
4174                     && streamType == getBluetoothContextualVolumeStream()
4175                     && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
4176                 if (DEBUG_VOL) {
4177                     Log.d(TAG, "adjustStreamVolume postSetLeAudioVolumeIndex index="
4178                             + newIndex + " stream=" + streamType);
4179                 }
4180                 mDeviceBroker.postSetLeAudioVolumeIndex(newIndex,
4181                         getVssForStreamOrDefault(streamType).getMaxIndex(), streamType);
4182             }
4183 
4184             // Check if volume update should be send to Hearing Aid.
4185             // Only modify the hearing aid attenuation when the stream to modify matches
4186             // the one expected by the hearing aid.
4187             if (device == AudioSystem.DEVICE_OUT_HEARING_AID
4188                     && streamType == getBluetoothContextualVolumeStream()) {
4189                 if (DEBUG_VOL) {
4190                     Log.d(TAG, "adjustStreamVolume postSetHearingAidVolumeIndex index="
4191                             + newIndex + " stream=" + streamType);
4192                 }
4193                 int haIndex;
4194                 final VolumeStreamState vss = getVssForStreamOrDefault(streamType);
4195                 synchronized (mVolumeStateLock) {
4196                     haIndex = (int) (vss.getMinIndex() + (newIndex - vss.getMinIndex())
4197                             / vss.getIndexStepFactor());
4198                 }
4199                 mDeviceBroker.postSetHearingAidVolumeIndex(haIndex, streamType);
4200             }
4201         }
4202 
4203         final int newIndex = getVssForStreamOrDefault(streamType).getIndex(device);
4204         if (adjustVolume) {
4205             synchronized (mHdmiClientLock) {
4206                 if (mHdmiManager != null) {
4207                     // At most one of mHdmiPlaybackClient and mHdmiTvClient should be non-null
4208                     HdmiClient hdmiClient = mHdmiPlaybackClient;
4209                     if (mHdmiTvClient != null) {
4210                         hdmiClient = mHdmiTvClient;
4211                     }
4212 
4213                     boolean playbackDeviceConditions = mHdmiPlaybackClient != null
4214                             && isFullVolumeDevice(device);
4215                     boolean tvConditions = mHdmiTvClient != null
4216                             && mHdmiSystemAudioSupported
4217                             && !isAbsoluteVolumeDevice(device)
4218                             && !isA2dpAbsoluteVolumeDevice(device);
4219 
4220                     if ((playbackDeviceConditions || tvConditions)
4221                             && mHdmiCecVolumeControlEnabled
4222                             && streamTypeAlias == AudioSystem.STREAM_MUSIC) {
4223                         int keyCode = KeyEvent.KEYCODE_UNKNOWN;
4224                         switch (direction) {
4225                             case AudioManager.ADJUST_RAISE:
4226                                 keyCode = KeyEvent.KEYCODE_VOLUME_UP;
4227                                 break;
4228                             case AudioManager.ADJUST_LOWER:
4229                                 keyCode = KeyEvent.KEYCODE_VOLUME_DOWN;
4230                                 break;
4231                             case AudioManager.ADJUST_TOGGLE_MUTE:
4232                             case AudioManager.ADJUST_MUTE:
4233                             case AudioManager.ADJUST_UNMUTE:
4234                                 // Many CEC devices only support toggle mute. Therefore, we send the
4235                                 // same keycode for all three mute options.
4236                                 keyCode = KeyEvent.KEYCODE_VOLUME_MUTE;
4237                                 break;
4238                             default:
4239                                 break;
4240                         }
4241                         if (keyCode != KeyEvent.KEYCODE_UNKNOWN) {
4242                             final long ident = Binder.clearCallingIdentity();
4243                             try {
4244                                 switch (keyEventMode) {
4245                                     case AudioDeviceVolumeManager.ADJUST_MODE_NORMAL:
4246                                         hdmiClient.sendVolumeKeyEvent(keyCode, true);
4247                                         hdmiClient.sendVolumeKeyEvent(keyCode, false);
4248                                         break;
4249                                     case AudioDeviceVolumeManager.ADJUST_MODE_START:
4250                                         hdmiClient.sendVolumeKeyEvent(keyCode, true);
4251                                         break;
4252                                     case AudioDeviceVolumeManager.ADJUST_MODE_END:
4253                                         hdmiClient.sendVolumeKeyEvent(keyCode, false);
4254                                         break;
4255                                     default:
4256                                         Log.e(TAG, "Invalid keyEventMode " + keyEventMode);
4257                                 }
4258                             } finally {
4259                                 Binder.restoreCallingIdentity(ident);
4260                             }
4261                         }
4262                     }
4263 
4264                     if (streamTypeAlias == AudioSystem.STREAM_MUSIC
4265                             && (oldIndex != newIndex || isMuteAdjust)) {
4266                         maybeSendSystemAudioStatusCommand(isMuteAdjust);
4267                     }
4268                 }
4269             }
4270         }
4271         sendVolumeUpdate(streamType, oldIndex, newIndex, flags, device);
4272     }
4273 
4274     /**
4275      * Loops on aliased stream, update the mute cache attribute of each
4276      * {@see AudioService#VolumeStreamState}, and then apply the change.
4277      * It prevents to unnecessary {@see AudioSystem#setStreamVolume} done for each stream
4278      * and aliases before mute change changed and after.
4279      */
muteAliasStreams(int streamAlias, boolean state)4280     private void muteAliasStreams(int streamAlias, boolean state) {
4281         // Locking mSettingsLock to avoid inversion when calling doMute -> updateVolumeGroupIndex
4282         synchronized (mSettingsLock) {
4283             synchronized (mVolumeStateLock) {
4284                 List<Integer> streamsToMute = new ArrayList<>();
4285                 for (int streamIdx = 0; streamIdx < mStreamStates.size(); streamIdx++) {
4286                     final VolumeStreamState vss = mStreamStates.valueAt(streamIdx);
4287                     if (vss != null && streamAlias == sStreamVolumeAlias.get(vss.getStreamType())
4288                             && vss.isMutable()) {
4289                         if (!(mCameraSoundForced.get() && (vss.getStreamType()
4290                                 == AudioSystem.STREAM_SYSTEM_ENFORCED))) {
4291                             boolean changed = vss.mute(state, /* apply= */ false,
4292                                     "muteAliasStreams");
4293                             if (changed) {
4294                                 streamsToMute.add(vss.getStreamType());
4295                             }
4296                         }
4297                     }
4298                 }
4299                 streamsToMute.forEach(streamToMute -> {
4300                     getVssForStreamOrDefault(streamToMute).doMute();
4301                     broadcastMuteSetting(streamToMute, state);
4302                 });
4303             }
4304         }
4305     }
4306 
broadcastMuteSetting(int streamType, boolean isMuted)4307     private void broadcastMuteSetting(int streamType, boolean isMuted) {
4308         // Stream mute changed, fire the intent.
4309         Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION);
4310         intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, isMuted);
4311         if (replaceStreamBtSco() && isStreamBluetoothSco(streamType)) {
4312             intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE,
4313                     AudioSystem.STREAM_BLUETOOTH_SCO);
4314             // in this case broadcast for both sco and voice_call streams the mute status
4315             sendBroadcastToAll(intent, null /* options */);
4316         }
4317         intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, streamType);
4318         sendBroadcastToAll(intent, null /* options */);
4319     }
4320 
4321     // Called after a delay when volume down is pressed while muted
onUnmuteStreamOnSingleVolDevice(int streamAlias, int flags)4322     private void onUnmuteStreamOnSingleVolDevice(int streamAlias, int flags) {
4323         boolean wasMuted;
4324         // Locking mSettingsLock to avoid inversion when calling vss.mute -> vss.doMute ->
4325         // vss.updateVolumeGroupIndex
4326         synchronized (mSettingsLock) {
4327             synchronized (mVolumeStateLock) {
4328                 final VolumeStreamState streamState = getVssForStreamOrDefault(streamAlias);
4329                 // if unmuting causes a change, it was muted
4330                 wasMuted = streamState.mute(false, "onUnmuteStreamOnSingleVolDevice");
4331                 if (wasMuted) {
4332                     // Unmute all aliasted streams
4333                     muteAliasStreams(streamAlias, false);
4334                 }
4335                 final int device = getDeviceForStream(streamAlias);
4336                 final int index = streamState.getIndex(device);
4337                 sendVolumeUpdate(streamAlias, index, index, flags, device);
4338             }
4339             if (streamAlias == AudioSystem.STREAM_MUSIC && wasMuted) {
4340                 synchronized (mHdmiClientLock) {
4341                     maybeSendSystemAudioStatusCommand(true);
4342                 }
4343             }
4344         }
4345     }
4346 
4347     @GuardedBy("mHdmiClientLock")
maybeSendSystemAudioStatusCommand(boolean isMuteAdjust)4348     private void maybeSendSystemAudioStatusCommand(boolean isMuteAdjust) {
4349         if (mHdmiAudioSystemClient == null
4350                 || !mHdmiSystemAudioSupported
4351                 || !mHdmiCecVolumeControlEnabled) {
4352             return;
4353         }
4354 
4355         final long identity = Binder.clearCallingIdentity();
4356         try {
4357             mHdmiAudioSystemClient.sendReportAudioStatusCecCommand(
4358                     isMuteAdjust, getStreamVolume(AudioSystem.STREAM_MUSIC),
4359                     getStreamMaxVolume(AudioSystem.STREAM_MUSIC),
4360                     isStreamMute(AudioSystem.STREAM_MUSIC));
4361         } finally {
4362             Binder.restoreCallingIdentity(identity);
4363         }
4364     }
4365 
getNewRingerMode(int stream, int index, int flags)4366     private int getNewRingerMode(int stream, int index, int flags) {
4367         // setRingerMode does nothing if the device is single volume,so the value would be unchanged
4368         if (mIsSingleVolume) {
4369             return getRingerModeExternal();
4370         }
4371 
4372         // setting volume on ui sounds stream type also controls silent mode
4373         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
4374                 (stream == getUiSoundsStreamType())) {
4375             int newRingerMode;
4376             if (index == 0) {
4377                 newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE
4378                         : mVolumePolicy.volumeDownToEnterSilent ? AudioManager.RINGER_MODE_SILENT
4379                                 : AudioManager.RINGER_MODE_NORMAL;
4380             } else {
4381                 newRingerMode = AudioManager.RINGER_MODE_NORMAL;
4382             }
4383             return newRingerMode;
4384         }
4385         return getRingerModeExternal();
4386     }
4387 
isAndroidNPlus(String caller)4388     private boolean isAndroidNPlus(String caller) {
4389         try {
4390             final ApplicationInfo applicationInfo =
4391                     mContext.getPackageManager().getApplicationInfoAsUser(
4392                             caller, 0, UserHandle.getUserId(Binder.getCallingUid()));
4393             if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N) {
4394                 return true;
4395             }
4396             return false;
4397         } catch (PackageManager.NameNotFoundException e) {
4398             return true;
4399         }
4400     }
4401 
wouldToggleZenMode(int newMode)4402     private boolean wouldToggleZenMode(int newMode) {
4403         if (getRingerModeExternal() == AudioManager.RINGER_MODE_SILENT
4404                 && newMode != AudioManager.RINGER_MODE_SILENT) {
4405             return true;
4406         } else if (getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT
4407                 && newMode == AudioManager.RINGER_MODE_SILENT) {
4408             return true;
4409         }
4410         return false;
4411     }
4412 
4413     /**
4414      * Update stream volume, ringer mode and mute status after a volume index change
4415      * @param streamType
4416      * @param index
4417      * @param flags
4418      * @param device the device for which the volume is changed
4419      * @param caller
4420      * @param hasModifyAudioSettings
4421      * @param canChangeMute true if the origin of this event is one where the mute state should be
4422      *                      updated following the change in volume index
4423      */
onSetStreamVolume(int streamType, int index, int flags, int device, String caller, boolean hasModifyAudioSettings, boolean canChangeMute)4424     /*package*/ void onSetStreamVolume(int streamType, int index, int flags, int device,
4425             String caller, boolean hasModifyAudioSettings, boolean canChangeMute) {
4426         final int stream = sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound=*/-1);
4427         if (stream == -1) {
4428             Log.e(TAG, "onSetStreamVolume: no stream vol alias for stream type " + stream);
4429             return;
4430         }
4431         // setting volume on ui sounds stream type also controls silent mode
4432         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
4433                 (stream == getUiSoundsStreamType())) {
4434             setRingerMode(getNewRingerMode(stream, index, flags),
4435                     TAG + ".onSetStreamVolume", false /*external*/);
4436         }
4437         setStreamVolumeInt(stream, index, device, false, caller, hasModifyAudioSettings);
4438         // setting non-zero volume for a muted stream unmutes the stream and vice versa
4439         // except for BT SCO stream where only explicit mute is allowed to comply to BT requirements
4440         if (!isStreamBluetoothSco(streamType) && canChangeMute) {
4441             // As adjustStreamVolume with muteAdjust flags mute/unmutes stream and aliased streams.
4442             muteAliasStreams(stream, index == 0);
4443         }
4444     }
4445 
enforceModifyAudioRoutingPermission()4446     private void enforceModifyAudioRoutingPermission() {
4447         if (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING)
4448                 != PackageManager.PERMISSION_GRANTED) {
4449             throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission");
4450         }
4451     }
4452 
enforceQueryStateOrModifyRoutingPermission()4453     private void enforceQueryStateOrModifyRoutingPermission() {
4454         if (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING)
4455                 != PackageManager.PERMISSION_GRANTED
4456                 && mContext.checkCallingOrSelfPermission(QUERY_AUDIO_STATE)
4457                 != PackageManager.PERMISSION_GRANTED) {
4458             throw new SecurityException(
4459                     "Missing MODIFY_AUDIO_ROUTING or QUERY_AUDIO_STATE permissions");
4460         }
4461     }
4462 
4463     //================================
4464     // Audio Volume Change Dispatcher
4465     //================================
4466     private final AudioVolumeChangeHandler mAudioVolumeChangeHandler;
4467 
4468     /** @see AudioManager#registerVolumeGroupCallback(executor, callback) */
registerAudioVolumeCallback(IAudioVolumeChangeDispatcher callback)4469     public void registerAudioVolumeCallback(IAudioVolumeChangeDispatcher callback) {
4470         mAudioVolumeChangeHandler.registerListener(callback);
4471     }
4472 
4473     /** @see AudioManager#unregisterVolumeGroupCallback(callback) */
unregisterAudioVolumeCallback(IAudioVolumeChangeDispatcher callback)4474     public void unregisterAudioVolumeCallback(IAudioVolumeChangeDispatcher callback) {
4475         mAudioVolumeChangeHandler.unregisterListener(callback);
4476     }
4477 
4478     @Override
4479     @android.annotation.EnforcePermission(anyOf = {
4480             MODIFY_AUDIO_SETTINGS_PRIVILEGED, MODIFY_AUDIO_ROUTING })
4481     /** @see AudioManager#setVolumeGroupVolumeIndex(int, int, int) */
setVolumeGroupVolumeIndex(int groupId, int index, int flags, String callingPackage, String attributionTag)4482     public void setVolumeGroupVolumeIndex(int groupId, int index, int flags,
4483             String callingPackage, String attributionTag) {
4484         super.setVolumeGroupVolumeIndex_enforcePermission();
4485         if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
4486             Log.e(TAG, ": no volume group found for id " + groupId);
4487             return;
4488         }
4489         VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
4490 
4491         sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_GROUP_VOL, vgs.name(),
4492                 index, flags, callingPackage + ", user " + getCurrentUserId()));
4493 
4494         vgs.setVolumeIndex(index, flags);
4495 
4496         // For legacy reason, propagate to all streams associated to this volume group
4497         for (int groupedStream : vgs.getLegacyStreamTypes()) {
4498             try {
4499                 ensureValidStreamType(groupedStream);
4500             } catch (IllegalArgumentException e) {
4501                 Log.d(TAG, "volume group " + groupId + " has internal streams (" + groupedStream
4502                         + "), do not change associated stream volume");
4503                 continue;
4504             }
4505             setStreamVolume(groupedStream, index, flags, /*device*/ null,
4506                     callingPackage, callingPackage,
4507                     attributionTag, Binder.getCallingUid(), true /*hasModifyAudioSettings*/,
4508                     true /*canChangeMuteAndUpdateController*/);
4509         }
4510     }
4511 
4512     @Override
4513     @android.annotation.EnforcePermission(anyOf = {
4514             MODIFY_AUDIO_SETTINGS_PRIVILEGED, MODIFY_AUDIO_ROUTING })
4515     /** @see AudioManager#getVolumeGroupVolumeIndex(int) */
getVolumeGroupVolumeIndex(int groupId)4516     public int getVolumeGroupVolumeIndex(int groupId) {
4517         super.getVolumeGroupVolumeIndex_enforcePermission();
4518         synchronized (mVolumeStateLock) {
4519             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
4520                 Log.e(TAG, "No volume group for id " + groupId);
4521                 return 0;
4522             }
4523             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
4524             // Return 0 when muted, not min index since for e.g. Voice Call, it has a non zero
4525             // min but it mutable on permission condition.
4526             return vgs.isMuted() ? 0 : vgs.getVolumeIndex();
4527         }
4528     }
4529 
4530     /** @see AudioManager#getVolumeGroupMaxVolumeIndex(int) */
4531     @android.annotation.EnforcePermission(anyOf = {
4532             MODIFY_AUDIO_SETTINGS_PRIVILEGED, MODIFY_AUDIO_ROUTING })
getVolumeGroupMaxVolumeIndex(int groupId)4533     public int getVolumeGroupMaxVolumeIndex(int groupId) {
4534         super.getVolumeGroupMaxVolumeIndex_enforcePermission();
4535         synchronized (mVolumeStateLock) {
4536             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
4537                 Log.e(TAG, "No volume group for id " + groupId);
4538                 return 0;
4539             }
4540             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
4541             return vgs.getMaxIndex();
4542         }
4543     }
4544 
4545     /** @see AudioManager#getVolumeGroupMinVolumeIndex(int) */
4546     @android.annotation.EnforcePermission(anyOf = {
4547             MODIFY_AUDIO_SETTINGS_PRIVILEGED, MODIFY_AUDIO_ROUTING })
getVolumeGroupMinVolumeIndex(int groupId)4548     public int getVolumeGroupMinVolumeIndex(int groupId) {
4549         super.getVolumeGroupMinVolumeIndex_enforcePermission();
4550         synchronized (mVolumeStateLock) {
4551             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
4552                 Log.e(TAG, "No volume group for id " + groupId);
4553                 return 0;
4554             }
4555             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
4556             return vgs.getMinIndex();
4557         }
4558     }
4559 
4560     @Override
4561     @android.annotation.EnforcePermission(anyOf = {
4562             MODIFY_AUDIO_ROUTING, MODIFY_AUDIO_SETTINGS_PRIVILEGED })
4563     /** @see AudioDeviceVolumeManager#setDeviceVolume(VolumeInfo, AudioDeviceAttributes)
4564      * Part of service interface, check permissions and parameters here
4565      * Note calling package is for logging purposes only, not to be trusted
4566      */
setDeviceVolume(@onNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage)4567     public void setDeviceVolume(@NonNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada,
4568             @NonNull String callingPackage) {
4569         super.setDeviceVolume_enforcePermission();
4570         Objects.requireNonNull(vi);
4571         Objects.requireNonNull(ada);
4572         Objects.requireNonNull(callingPackage);
4573 
4574         if (!vi.hasStreamType()) {
4575             Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception());
4576             return;
4577         }
4578 
4579         int index = vi.getVolumeIndex();
4580         if (index == VolumeInfo.INDEX_NOT_SET && !vi.hasMuteCommand()) {
4581             throw new IllegalArgumentException(
4582                     "changing device volume requires a volume index or mute command");
4583         }
4584 
4585         // force a cache clear to force reevaluating stream type to audio device selection
4586         // that can interfere with the sending of the VOLUME_CHANGED_ACTION intent
4587         mAudioSystem.clearRoutingCache();
4588 
4589         int streamType = replaceBtScoStreamWithVoiceCall(vi.getStreamType(), "setDeviceVolume");
4590 
4591         final VolumeStreamState vss = getVssForStream(streamType);
4592 
4593         // log the current device that will be used when evaluating the sending of the
4594         // VOLUME_CHANGED_ACTION intent to see if the current device is the one being modified
4595         final int currDev = getDeviceForStream(streamType);
4596 
4597         final boolean skipping = (currDev == ada.getInternalType()) || (vss == null);
4598 
4599         AudioService.sVolumeLogger.enqueue(new DeviceVolumeEvent(streamType, index, ada,
4600                 currDev, callingPackage, skipping));
4601 
4602         if (skipping) {
4603             // setDeviceVolume was called on a device currently being used or stream state is null
4604             return;
4605         }
4606 
4607         // TODO handle unmuting of current audio device
4608         // if a stream is not muted but the VolumeInfo is for muting, set the volume index
4609         // for the device to min volume
4610         if (vi.hasMuteCommand() && vi.isMuted() && !isStreamMute(streamType)) {
4611             setStreamVolumeWithAttributionInt(streamType,
4612                     vss.getMinIndex(),
4613                     /*flags*/ 0,
4614                     ada, callingPackage, null,
4615                     //TODO handle unmuting of current audio device
4616                     false /*canChangeMuteAndUpdateController*/);
4617             return;
4618         }
4619 
4620         AudioService.sVolumeLogger.enqueueAndLog("setDeviceVolume" + " from:" + callingPackage
4621                 + " " + vi + " " + ada, EventLogger.Event.ALOGI, TAG);
4622 
4623         if (vi.getMinVolumeIndex() == VolumeInfo.INDEX_NOT_SET
4624                 || vi.getMaxVolumeIndex() == VolumeInfo.INDEX_NOT_SET) {
4625             // assume index meant to be in stream type range, validate
4626             if ((index * 10) < vss.getMinIndex()
4627                     || (index * 10) > vss.getMaxIndex()) {
4628                 throw new IllegalArgumentException("invalid volume index " + index
4629                         + " not between min/max for stream " + vi.getStreamType());
4630             }
4631         } else {
4632             // check if index needs to be rescaled
4633             final int min = (vss.getMinIndex() + 5) / 10;
4634             final int max = (vss.getMaxIndex() + 5) / 10;
4635             if (vi.getMinVolumeIndex() != min || vi.getMaxVolumeIndex() != max) {
4636                 index = rescaleIndex(index,
4637                         /*srcMin*/ vi.getMinVolumeIndex(), /*srcMax*/ vi.getMaxVolumeIndex(),
4638                         /*dstMin*/ min, /*dstMax*/ max);
4639             }
4640         }
4641         setStreamVolumeWithAttributionInt(streamType, index, /*flags*/ 0,
4642                 ada, callingPackage, null,
4643                 false /*canChangeMuteAndUpdateController*/);
4644     }
4645 
4646     /** Retain API for unsupported app usage */
setStreamVolume(int streamType, int index, int flags, String callingPackage)4647     public void setStreamVolume(int streamType, int index, int flags, String callingPackage) {
4648         setStreamVolumeWithAttribution(streamType, index, flags,
4649                 callingPackage, /*attributionTag*/ null);
4650     }
4651 
4652     /** @see AudioManager#adjustVolumeGroupVolume(int, int, int) */
adjustVolumeGroupVolume(int groupId, int direction, int flags, String callingPackage)4653     public void adjustVolumeGroupVolume(int groupId, int direction, int flags,
4654                                         String callingPackage) {
4655         ensureValidDirection(direction);
4656         if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
4657             Log.e(TAG, ": no volume group found for id " + groupId);
4658             return;
4659         }
4660         VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
4661         // For compatibility reason, use stream API if group linked to a valid stream
4662         boolean fallbackOnStream = false;
4663         for (int stream : vgs.getLegacyStreamTypes()) {
4664             try {
4665                 ensureValidStreamType(stream);
4666             } catch (IllegalArgumentException e) {
4667                 Log.d(TAG, "volume group " + groupId + " has internal streams (" + stream
4668                         + "), do not change associated stream volume");
4669                 continue;
4670             }
4671             // Note: Group and Stream does not share same convention, 0 is mute for stream,
4672             // min index is acting as mute for Groups
4673             if (vgs.isVssMuteBijective(stream)) {
4674                 adjustStreamVolume(stream, direction, flags, callingPackage);
4675                 if (isMuteAdjust(direction)) {
4676                     // will be propagated to all aliased streams
4677                     return;
4678                 }
4679                 fallbackOnStream = true;
4680             }
4681         }
4682         if (fallbackOnStream) {
4683             // Handled by at least one stream, will be propagated to group, bailing out.
4684             return;
4685         }
4686         sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_ADJUST_GROUP_VOL, vgs.name(),
4687                 direction, flags, callingPackage));
4688         vgs.adjustVolume(direction, flags);
4689     }
4690 
4691     /** @see AudioManager#getLastAudibleVolumeForVolumeGroup(int) */
4692     @android.annotation.EnforcePermission(QUERY_AUDIO_STATE)
getLastAudibleVolumeForVolumeGroup(int groupId)4693     public int getLastAudibleVolumeForVolumeGroup(int groupId) {
4694         super.getLastAudibleVolumeForVolumeGroup_enforcePermission();
4695         synchronized (mVolumeStateLock) {
4696             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
4697                 Log.e(TAG, ": no volume group found for id " + groupId);
4698                 return 0;
4699             }
4700             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
4701             return vgs.getVolumeIndex();
4702         }
4703     }
4704 
4705     /** @see AudioManager#isVolumeGroupMuted(int) */
isVolumeGroupMuted(int groupId)4706     public boolean isVolumeGroupMuted(int groupId) {
4707         synchronized (mVolumeStateLock) {
4708             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
4709                 Log.e(TAG, ": no volume group found for id " + groupId);
4710                 return false;
4711             }
4712             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
4713             return vgs.isMuted();
4714         }
4715     }
4716 
4717     /** @see AudioManager#setStreamVolume(int, int, int)
4718      * Part of service interface, check permissions here */
setStreamVolumeWithAttribution(int streamType, int index, int flags, String callingPackage, String attributionTag)4719     public void setStreamVolumeWithAttribution(int streamType, int index, int flags,
4720             String callingPackage, String attributionTag) {
4721         if (mHardeningEnforcer.blockVolumeMethod(
4722                 HardeningEnforcer.METHOD_AUDIO_MANAGER_SET_STREAM_VOLUME,
4723                 callingPackage,
4724                 Binder.getCallingUid())) {
4725             return;
4726         }
4727         setStreamVolumeWithAttributionInt(streamType, index, flags, /*device*/ null,
4728                 callingPackage, attributionTag, true /*canChangeMuteAndUpdateController*/);
4729     }
4730 
4731     /**
4732      * Internal method for a stream type volume change. Can be used to change the volume on a
4733      * given device only
4734      * @param streamType the stream type whose volume is to be changed
4735      * @param index the volume index
4736      * @param flags options for volume handling
4737      * @param device null when controlling volume for the current routing, otherwise the device
4738      *               for which volume is being changed
4739      * @param callingPackage client side-provided package name of caller, not to be trusted
4740      * @param attributionTag client side-provided attribution name, not to be trusted
4741      * @param canChangeMuteAndUpdateController true if the calling method is a path where
4742      *          the volume change is allowed to update the mute state as well as update
4743      *          the volume controller (the UI). This is intended to be true for a call coming
4744      *          from AudioManager.setStreamVolume (which is here
4745      *          {@link #setStreamVolumeForUid(int, int, int, String, int, int, UserHandle, int)},
4746      *          and false when coming from AudioDeviceVolumeManager.setDeviceVolume (which is here
4747      *          {@link #setDeviceVolume(VolumeInfo, AudioDeviceAttributes, String)}
4748      */
setStreamVolumeWithAttributionInt(int streamType, int index, int flags, @Nullable AudioDeviceAttributes ada, String callingPackage, String attributionTag, boolean canChangeMuteAndUpdateController)4749     protected void setStreamVolumeWithAttributionInt(int streamType, int index, int flags,
4750             @Nullable AudioDeviceAttributes ada,
4751             String callingPackage, String attributionTag,
4752             boolean canChangeMuteAndUpdateController) {
4753         streamType = replaceBtScoStreamWithVoiceCall(streamType,
4754                 "setStreamVolumeWithAttributionInt");
4755 
4756         if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {
4757             Log.w(TAG, "Trying to call setStreamVolume() for a11y without"
4758                     + " CHANGE_ACCESSIBILITY_VOLUME  callingPackage=" + callingPackage);
4759             return;
4760         }
4761         if ((streamType == AudioManager.STREAM_VOICE_CALL) && (index == 0)
4762                 && (mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE)
4763                     != PackageManager.PERMISSION_GRANTED) && !isStreamBluetoothSco(streamType)) {
4764             Log.w(TAG, "Trying to call setStreamVolume() for STREAM_VOICE_CALL and index 0 without"
4765                     + " MODIFY_PHONE_STATE  callingPackage=" + callingPackage);
4766             return;
4767         }
4768         if ((streamType == AudioManager.STREAM_ASSISTANT)
4769                 && (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING)
4770                     != PackageManager.PERMISSION_GRANTED)) {
4771             Log.w(TAG, "Trying to call setStreamVolume() for STREAM_ASSISTANT without"
4772                     + " MODIFY_AUDIO_ROUTING  callingPackage=" + callingPackage);
4773             return;
4774         }
4775 
4776         if (ada == null) {
4777             // call was already logged in setDeviceVolume()
4778             final int deviceType = getDeviceForStream(streamType);
4779             sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType,
4780                     index/*val1*/, flags/*val2*/, getStreamVolume(streamType, deviceType) /*val3*/,
4781                     callingPackage));
4782             ada = new AudioDeviceAttributes(deviceType /*nativeType*/, "" /*address*/);
4783         }
4784         setStreamVolume(streamType, index, flags, ada,
4785                 callingPackage, callingPackage, attributionTag,
4786                 Binder.getCallingUid(), callingOrSelfHasAudioSettingsPermission(),
4787                 canChangeMuteAndUpdateController);
4788     }
4789 
4790     @android.annotation.EnforcePermission(Manifest.permission.ACCESS_ULTRASOUND)
4791     /** @see AudioManager#isUltrasoundSupported() */
isUltrasoundSupported()4792     public boolean isUltrasoundSupported() {
4793         super.isUltrasoundSupported_enforcePermission();
4794 
4795         return AudioSystem.isUltrasoundSupported();
4796     }
4797 
4798     /** @see AudioManager#isHotwordStreamSupported(boolean)  */
4799     @android.annotation.EnforcePermission(CAPTURE_AUDIO_HOTWORD)
isHotwordStreamSupported(boolean lookbackAudio)4800     public boolean isHotwordStreamSupported(boolean lookbackAudio) {
4801         super.isHotwordStreamSupported_enforcePermission();
4802         try {
4803             return mAudioPolicy.isHotwordStreamSupported(lookbackAudio);
4804         } catch (IllegalStateException e) {
4805             // Suppress connection failure to APM, since the method is purely informative
4806             Log.e(TAG, "Suppressing exception calling into AudioPolicy", e);
4807             return false;
4808         }
4809     }
4810 
4811 
canChangeAccessibilityVolume()4812     private boolean canChangeAccessibilityVolume() {
4813         synchronized (mAccessibilityServiceUidsLock) {
4814             if (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
4815                     Manifest.permission.CHANGE_ACCESSIBILITY_VOLUME)) {
4816                 return true;
4817             }
4818             if (mAccessibilityServiceUids != null) {
4819                 int callingUid = Binder.getCallingUid();
4820                 for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
4821                     if (mAccessibilityServiceUids[i] == callingUid) {
4822                         return true;
4823                     }
4824                 }
4825             }
4826             return false;
4827         }
4828     }
4829 
4830     /** only public for mocking/spying, do not call outside of AudioService */
4831     @VisibleForTesting
getBluetoothContextualVolumeStream()4832     public int getBluetoothContextualVolumeStream() {
4833         return getBluetoothContextualVolumeStream(mMode.get());
4834     }
4835 
getBluetoothContextualVolumeStream(int mode)4836     private int getBluetoothContextualVolumeStream(int mode) {
4837         boolean voiceActivityCanOverride = true;
4838         switch (mode) {
4839             case AudioSystem.MODE_IN_COMMUNICATION:
4840             case AudioSystem.MODE_IN_CALL:
4841                 // TODO(b/382704431): remove to allow STREAM_VOICE_CALL to drive abs volume
4842                 //  over A2DP
4843                 if (getDeviceForStream(AudioSystem.STREAM_VOICE_CALL)
4844                         == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
4845                     return AudioSystem.STREAM_MUSIC;
4846                 }
4847                 return AudioSystem.STREAM_VOICE_CALL;
4848             case AudioSystem.MODE_CALL_SCREENING:
4849             case AudioSystem.MODE_COMMUNICATION_REDIRECT:
4850             case AudioSystem.MODE_CALL_REDIRECT:
4851                 voiceActivityCanOverride = false;
4852                 // intended fallthrough
4853             case AudioSystem.MODE_NORMAL:
4854             default:
4855                 // other conditions will influence the stream type choice, read on...
4856                 break;
4857         }
4858 
4859         if (voiceActivityCanOverride && mVoicePlaybackActive.get()) {
4860             // TODO(b/382704431): remove to allow STREAM_VOICE_CALL to drive abs volume over A2DP
4861             if (getDeviceForStream(AudioSystem.STREAM_VOICE_CALL)
4862                     == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
4863                 return AudioSystem.STREAM_MUSIC;
4864             }
4865             return AudioSystem.STREAM_VOICE_CALL;
4866         }
4867         return AudioSystem.STREAM_MUSIC;
4868     }
4869 
4870     private final AtomicBoolean mVoicePlaybackActive = new AtomicBoolean(false);
4871     private final AtomicBoolean mMediaPlaybackActive = new AtomicBoolean(false);
4872 
4873     private final IPlaybackConfigDispatcher mPlaybackActivityMonitor =
4874             new IPlaybackConfigDispatcher.Stub() {
4875         @Override
4876         public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs,
4877                                                  boolean flush) {
4878             sendMsg(mAudioHandler, MSG_PLAYBACK_CONFIG_CHANGE, SENDMSG_REPLACE,
4879                     0 /*arg1 ignored*/, 0 /*arg2 ignored*/,
4880                     configs /*obj*/, 0 /*delay*/);
4881         }
4882     };
4883 
onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs)4884     private void onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) {
4885         boolean voiceActive = false;
4886         boolean mediaActive = false;
4887         for (AudioPlaybackConfiguration config : configs) {
4888             final int usage = config.getAudioAttributes().getUsage();
4889             if (!config.isActive()) {
4890                 continue;
4891             }
4892             if (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION
4893                     || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING) {
4894                 voiceActive = true;
4895             }
4896             if (usage == AudioAttributes.USAGE_MEDIA || usage == AudioAttributes.USAGE_GAME
4897                     || usage == AudioAttributes.USAGE_UNKNOWN) {
4898                 mediaActive = true;
4899             }
4900         }
4901         if (mVoicePlaybackActive.getAndSet(voiceActive) != voiceActive) {
4902             postUpdateContextualVolumes();
4903         }
4904         if (mMediaPlaybackActive.getAndSet(mediaActive) != mediaActive && mediaActive) {
4905             mSoundDoseHelper.scheduleMusicActiveCheck();
4906         }
4907 
4908         mLoudnessCodecHelper.updateCodecParameters(configs);
4909 
4910         // Update playback active state for all apps in audio mode stack.
4911         // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE
4912         // and request an audio mode update immediately. Upon any other change, queue the message
4913         // and request an audio mode update after a grace period.
4914         updateAudioModeHandlers(
4915                 configs /* playbackConfigs */, null /* recordConfigs */);
4916         mDeviceBroker.updateCommunicationRouteClientsActivity(
4917                 configs /* playbackConfigs */, null /* recordConfigs */);
4918     }
4919 
updateAudioModeHandlers(List<AudioPlaybackConfiguration> playbackConfigs, List<AudioRecordingConfiguration> recordConfigs)4920     void updateAudioModeHandlers(List<AudioPlaybackConfiguration> playbackConfigs,
4921                                  List<AudioRecordingConfiguration> recordConfigs) {
4922         synchronized (mDeviceBroker.mSetModeLock) {
4923             boolean updateAudioMode = false;
4924             int existingMsgPolicy = SENDMSG_QUEUE;
4925             int delay = CHECK_MODE_FOR_UID_PERIOD_MS;
4926             for (SetModeDeathHandler h : mSetModeDeathHandlers) {
4927                 boolean wasActive = h.isActive();
4928                 if (playbackConfigs != null) {
4929                     h.setPlaybackActive(false);
4930                     for (AudioPlaybackConfiguration config : playbackConfigs) {
4931                         final int usage = config.getAudioAttributes().getUsage();
4932                         if (config.getClientUid() == h.getUid()
4933                                 && (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION
4934                                 || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING)
4935                                 && config.isActive()) {
4936                             h.setPlaybackActive(true);
4937                             break;
4938                         }
4939                     }
4940                 }
4941                 if (recordConfigs != null) {
4942                     h.setRecordingActive(false);
4943                     for (AudioRecordingConfiguration config : recordConfigs) {
4944                         if (config.getClientUid() == h.getUid() && !config.isClientSilenced()
4945                                 && config.getAudioSource() == AudioSource.VOICE_COMMUNICATION) {
4946                             h.setRecordingActive(true);
4947                             break;
4948                         }
4949                     }
4950                 }
4951                 if (wasActive != h.isActive()) {
4952                     updateAudioMode = true;
4953                     if (h.isActive() && h == getAudioModeOwnerHandler()) {
4954                         existingMsgPolicy = SENDMSG_REPLACE;
4955                         delay = 0;
4956                     }
4957                 }
4958             }
4959             if (updateAudioMode) {
4960                 postUpdateAudioMode(existingMsgPolicy, AudioSystem.MODE_CURRENT,
4961                         android.os.Process.myPid(), mContext.getPackageName(),
4962                         false /*signal*/, delay);
4963             }
4964         }
4965     }
4966 
4967     static class UpdateAudioModeInfo {
UpdateAudioModeInfo(int mode, int pid, String packageName)4968         UpdateAudioModeInfo(int mode, int pid, String packageName) {
4969             mMode = mode;
4970             mPid = pid;
4971             mPackageName = packageName;
4972         }
4973         private final int mMode;
4974         private final int mPid;
4975         private final String mPackageName;
4976 
getMode()4977         int getMode() {
4978             return mMode;
4979         }
getPid()4980         int getPid() {
4981             return mPid;
4982         }
getPackageName()4983         String getPackageName() {
4984             return mPackageName;
4985         }
4986     }
4987 
postUpdateAudioMode(int msgPolicy, int mode, int pid, String packageName, boolean signal, int delay)4988     void postUpdateAudioMode(int msgPolicy, int mode, int pid, String packageName,
4989             boolean signal, int delay) {
4990         synchronized (mAudioModeResetLock) {
4991             if (signal) {
4992                 mAudioModeResetCount++;
4993             }
4994             sendMsg(mAudioHandler, signal ? MSG_UPDATE_AUDIO_MODE_SIGNAL : MSG_UPDATE_AUDIO_MODE,
4995                     msgPolicy, 0, 0, new UpdateAudioModeInfo(mode, pid, packageName), delay);
4996         }
4997     }
4998 
4999     private final IRecordingConfigDispatcher mVoiceRecordingActivityMonitor =
5000             new IRecordingConfigDispatcher.Stub() {
5001         @Override
5002         public void dispatchRecordingConfigChange(List<AudioRecordingConfiguration> configs) {
5003             sendMsg(mAudioHandler, MSG_RECORDING_CONFIG_CHANGE, SENDMSG_REPLACE,
5004                     0 /*arg1 ignored*/, 0 /*arg2 ignored*/,
5005                     configs /*obj*/, 0 /*delay*/);
5006         }
5007     };
5008 
onRecordingConfigChange(List<AudioRecordingConfiguration> configs)5009     private void onRecordingConfigChange(List<AudioRecordingConfiguration> configs) {
5010         // Update recording active state for all apps in audio mode stack.
5011         // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE
5012         // and request an audio mode update immediately. Upon any other change, queue the message
5013         // and request an audio mode update after a grace period.
5014         updateAudioModeHandlers(
5015                 null /* playbackConfigs */, configs /* recordConfigs */);
5016         mDeviceBroker.updateCommunicationRouteClientsActivity(
5017                 null /* playbackConfigs */, configs /* recordConfigs */);
5018     }
5019 
dumpFlags(PrintWriter pw)5020     private void dumpFlags(PrintWriter pw) {
5021 
5022         pw.println("\nFun with Flags:");
5023         pw.println("\tcom.android.media.audio.as_device_connection_failure:"
5024                 + asDeviceConnectionFailure());
5025         pw.println("\tandroid.media.audio.autoPublicVolumeApiHardening:"
5026                 + autoPublicVolumeApiHardening());
5027         pw.println("\tandroid.media.audio.automaticBtDeviceType - EOL");
5028         pw.println("\tandroid.media.audio.featureSpatialAudioHeadtrackingLowLatency:"
5029                 + featureSpatialAudioHeadtrackingLowLatency());
5030         pw.println("\tandroid.media.audio.focusFreezeTestApi:"
5031                 + focusFreezeTestApi());
5032         pw.println("\tcom.android.media.audio.audioserverPermissions:"
5033                 + audioserverPermissions());
5034         pw.println("\tcom.android.media.audio.disablePrescaleAbsoluteVolume:"
5035                 + disablePrescaleAbsoluteVolume());
5036         pw.println("\tcom.android.media.audio.setStreamVolumeOrder - EOL");
5037         pw.println("\tandroid.media.audio.ringtoneUserUriCheck:"
5038                 + android.media.audio.Flags.ringtoneUserUriCheck());
5039         pw.println("\tandroid.media.audio.roForegroundAudioControl:"
5040                 + roForegroundAudioControl());
5041         pw.println("\tandroid.media.audio.scoManagedByAudio:"
5042                 + scoManagedByAudio());
5043         pw.println("\tcom.android.media.audio.absVolumeIndexFix - EOL");
5044         pw.println("\tcom.android.media.audio.vgsVssSyncMuteOrder - EOL");
5045         pw.println("\tcom.android.media.audio.replaceStreamBtSco:"
5046                 + replaceStreamBtSco());
5047         pw.println("\tcom.android.media.audio.equalScoLeaVcIndexRange:"
5048                 + equalScoLeaVcIndexRange());
5049         pw.println("\tcom.android.media.audio.ringMyCar:"
5050                 + ringMyCar());
5051         pw.println("\tandroid.media.audio.Flags.concurrentAudioRecordBypassPermission:"
5052                 + concurrentAudioRecordBypassPermission());
5053         pw.println("\tandroid.media.audio.Flags.cacheGetStreamMinMaxVolume:"
5054                 + cacheGetStreamMinMaxVolume());
5055         pw.println("\tandroid.media.audio.Flags.cacheGetStreamVolume:"
5056                 + cacheGetStreamVolume());
5057         pw.println("\tcom.android.media.audio.optimizeBtDeviceSwitch:"
5058                 + optimizeBtDeviceSwitch());
5059     }
5060 
dumpAudioMode(PrintWriter pw)5061     private void dumpAudioMode(PrintWriter pw) {
5062         pw.println("\nAudio mode: ");
5063         pw.println("- Requested mode = " + AudioSystem.modeToString(getMode()));
5064         pw.println("- Actual mode = " + AudioSystem.modeToString(mMode.get()));
5065         pw.println("- Mode owner: ");
5066         SetModeDeathHandler hdlr = getAudioModeOwnerHandler();
5067         if (hdlr != null) {
5068             hdlr.dump(pw, -1);
5069         } else {
5070             pw.println("   None");
5071         }
5072         pw.println("- Mode owner stack: ");
5073         if (mSetModeDeathHandlers.isEmpty()) {
5074             pw.println("   Empty");
5075         } else {
5076             for (int i = 0; i < mSetModeDeathHandlers.size(); i++) {
5077                 mSetModeDeathHandlers.get(i).dump(pw, i);
5078             }
5079         }
5080     }
5081 
5082 
5083     // delay between audio playback configuration update and checking
5084     // actual stream activity to take async playback stop into account
5085     private static final int UPDATE_CONTEXTUAL_VOLUME_DELAY_MS = 500;
5086 
postUpdateContextualVolumes()5087     /*package*/ void postUpdateContextualVolumes() {
5088         sendMsg(mAudioHandler, MSG_UPDATE_CONTEXTUAL_VOLUMES, SENDMSG_REPLACE,
5089                 /*arg1*/ 0, /*arg2*/ 0, TAG, UPDATE_CONTEXTUAL_VOLUME_DELAY_MS);
5090     }
5091 
onUpdateContextualVolumes()5092     private void onUpdateContextualVolumes() {
5093         final int streamType = getBluetoothContextualVolumeStream();
5094 
5095         Slog.i(TAG,
5096                 "onUpdateContextualVolumes: absolute volume driving streams " + streamType
5097                 + " avrcp supported: " + mAvrcpAbsVolSupported);
5098         synchronized (mCachedAbsVolDrivingStreamsLock) {
5099             mCachedAbsVolDrivingStreams.replaceAll((absDev, stream) -> {
5100                 boolean enabled = true;
5101                 if (absDev == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
5102                     enabled = mAvrcpAbsVolSupported;
5103                     if (!enabled) {
5104                         Slog.w(TAG, "Updating avrcp not supported in onUpdateContextualVolumes");
5105                     }
5106                 }
5107                 if (stream != streamType) {
5108                     final int result = mAudioSystem.setDeviceAbsoluteVolumeEnabled(absDev,
5109                             /*address=*/"", enabled, streamType);
5110                     if (result != AudioSystem.AUDIO_STATUS_OK) {
5111                         sVolumeLogger.enqueueAndSlog(
5112                                 new VolumeEvent(VolumeEvent.VOL_ABS_DEVICE_ENABLED_ERROR,
5113                                         result, absDev, enabled, streamType).eventToString(), ALOGE,
5114                                 TAG);
5115                     }
5116                 }
5117                 return streamType;
5118             });
5119         }
5120 
5121         final Set<Integer> deviceTypes = getDeviceSetForStreamDirect(streamType);
5122         Set<Integer> absVolumeDeviceTypes = new ArraySet<>(
5123                 AudioSystem.DEVICE_OUT_ALL_A2DP_SET);
5124         absVolumeDeviceTypes.addAll(mAbsVolumeMultiModeCaseDevices);
5125 
5126         final Set<Integer> absVolumeDevices =
5127                 AudioSystem.intersectionAudioDeviceTypes(absVolumeDeviceTypes, deviceTypes);
5128         if (absVolumeDevices.isEmpty()) {
5129             return;
5130         }
5131         if (absVolumeDevices.size() > 1) {
5132             Slog.w(TAG, "onUpdateContextualVolumes too many active devices: "
5133                     + absVolumeDevices.stream().map(AudioSystem::getOutputDeviceName)
5134                         .collect(Collectors.joining(","))
5135                     + ", for stream: " + streamType);
5136             return;
5137         }
5138 
5139         final int device = absVolumeDevices.toArray(new Integer[0])[0].intValue();
5140         final int index = (getVolumeForDeviceIgnoreMute(streamType, device) + 5) / 10;
5141 
5142         if (DEBUG_VOL) {
5143             Slog.i(TAG, "onUpdateContextualVolumes streamType: " + streamType
5144                     + ", device: " + AudioSystem.getOutputDeviceName(device)
5145                     + ", index: " + index);
5146         }
5147 
5148         if (AudioSystem.isLeAudioDeviceType(device)) {
5149             mDeviceBroker.postSetLeAudioVolumeIndex(index * 10,
5150                     getVssForStreamOrDefault(streamType).getMaxIndex(), streamType);
5151         } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
5152             int haIndex = index * 10;
5153             final VolumeStreamState vss = getVssForStreamOrDefault(streamType);
5154             synchronized (mVolumeStateLock) {
5155                 haIndex = (int) (vss.getMinIndex()
5156                         + (haIndex - vss.getMinIndex()) / vss.getIndexStepFactor());
5157             }
5158             mDeviceBroker.postSetHearingAidVolumeIndex(haIndex, streamType);
5159         } else if (AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)) {
5160             mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index);
5161         } else {
5162             return;
5163         }
5164 
5165         sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_CONTEXTUAL_VOLUME,
5166                 mVoicePlaybackActive.get(), streamType, index, device));
5167     }
5168 
setStreamVolume(int streamType, int index, int flags, @Nullable AudioDeviceAttributes ada, String callingPackage, String caller, String attributionTag, int uid, boolean hasModifyAudioSettings, boolean canChangeMuteAndUpdateController)5169     private void setStreamVolume(int streamType, int index, int flags,
5170             @Nullable AudioDeviceAttributes ada,
5171             String callingPackage, String caller, String attributionTag, int uid,
5172             boolean hasModifyAudioSettings,
5173             boolean canChangeMuteAndUpdateController) {
5174 
5175         if (DEBUG_VOL) {
5176             Log.d(TAG, "setStreamVolume(stream=" + streamType+", index=" + index
5177                     + ", dev=" + ada
5178                     + ", calling=" + callingPackage + ")");
5179         }
5180         if (mUseFixedVolume) {
5181             return;
5182         }
5183         streamType = replaceBtScoStreamWithVoiceCall(streamType, "setStreamVolume");
5184 
5185         ensureValidStreamType(streamType);
5186         int streamTypeAlias = sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound*/-1);
5187         if (streamTypeAlias == -1) {
5188             Log.e(TAG, "setStreamVolume: no stream vol alias for stream type " + streamType);
5189             return;
5190         }
5191         final VolumeStreamState streamState = getVssForStreamOrDefault(streamTypeAlias);
5192 
5193         if (!replaceStreamBtSco() && (streamType == AudioManager.STREAM_VOICE_CALL)
5194                 && isInCommunication() && mBtCommDeviceActive.get() == BT_COMM_DEVICE_ACTIVE_SCO) {
5195             Log.i(TAG, "setStreamVolume for STREAM_VOICE_CALL, switching to STREAM_BLUETOOTH_SCO");
5196             streamType = AudioManager.STREAM_BLUETOOTH_SCO;
5197         }
5198 
5199         final int device = (ada == null)
5200                 ? getDeviceForStream(streamType)
5201                 : ada.getInternalType();
5202         int oldIndex;
5203 
5204         // skip a2dp absolute volume control request when the device
5205         // is neither an a2dp device nor BLE device
5206         if ((!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
5207                 && !AudioSystem.DEVICE_OUT_ALL_BLE_SET.contains(device))
5208                 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) {
5209             return;
5210         }
5211         // If we are being called by the system (e.g. hardware keys) check for current user
5212         // so we handle user restrictions correctly.
5213         if (uid == android.os.Process.SYSTEM_UID) {
5214             uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid));
5215         }
5216         if (!checkNoteAppOp(
5217                 STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage, attributionTag)) {
5218             return;
5219         }
5220 
5221         if (isAndroidNPlus(callingPackage)
5222                 && wouldToggleZenMode(getNewRingerMode(streamTypeAlias, index, flags))
5223                 && !mNm.isNotificationPolicyAccessGrantedForPackage(callingPackage)) {
5224             throw new SecurityException("Not allowed to change Do Not Disturb state");
5225         }
5226 
5227         if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) {
5228             return;
5229         }
5230 
5231         mSoundDoseHelper.invalidatePendingVolumeCommand();
5232 
5233         oldIndex = streamState.getIndex(device);
5234 
5235         index = rescaleIndex(index * 10, streamType, streamTypeAlias);
5236 
5237         flags &= ~AudioManager.FLAG_FIXED_VOLUME;
5238         if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) {
5239             flags |= AudioManager.FLAG_FIXED_VOLUME;
5240 
5241             // volume is either 0 or max allowed for fixed volume devices
5242             if (index != 0) {
5243                 index = mSoundDoseHelper.getSafeMediaVolumeIndex(device);
5244                 if (index < 0) {
5245                     index = streamState.getMaxIndex();
5246                 }
5247             }
5248         }
5249 
5250         if (!mSoundDoseHelper.willDisplayWarningAfterCheckVolume(streamType, index, device,
5251                 flags)) {
5252             onSetStreamVolume(streamType, index, flags, device, caller, hasModifyAudioSettings,
5253                     // ada is non-null when called from setDeviceVolume,
5254                     // which shouldn't update the mute state
5255                     canChangeMuteAndUpdateController /*canChangeMute*/);
5256             index = getVssForStreamOrDefault(streamType).getIndex(device);
5257         }
5258 
5259         if (streamTypeAlias == getBluetoothContextualVolumeStream()
5260                 && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
5261                 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
5262             if (DEBUG_VOL) {
5263                 Log.d(TAG, "setStreamVolume postSetAvrcpAbsoluteVolumeIndex index=" + index
5264                         + "stream=" + streamType);
5265             }
5266             mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index / 10);
5267         } else if (isAbsoluteVolumeDevice(device)
5268                 && ((flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0)) {
5269             final AbsoluteVolumeDeviceInfo info = getAbsoluteVolumeDeviceInfo(device);
5270 
5271             dispatchAbsoluteVolumeChanged(streamType, info, index);
5272         }
5273 
5274         if (AudioSystem.isLeAudioDeviceType(device)
5275                 && streamType == getBluetoothContextualVolumeStream()
5276                 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
5277             if (DEBUG_VOL) {
5278                 Log.d(TAG, "setStreamVolume postSetLeAudioVolumeIndex index="
5279                         + index + " stream=" + streamType);
5280             }
5281             mDeviceBroker.postSetLeAudioVolumeIndex(index,
5282                     getVssForStreamOrDefault(streamType).getMaxIndex(), streamType);
5283         }
5284 
5285         if (device == AudioSystem.DEVICE_OUT_HEARING_AID
5286                 && streamType == getBluetoothContextualVolumeStream()) {
5287             Log.i(TAG, "setStreamVolume postSetHearingAidVolumeIndex index=" + index
5288                     + " stream=" + streamType);
5289             int haIndex;
5290             final VolumeStreamState vss = getVssForStreamOrDefault(streamType);
5291             synchronized (mVolumeStateLock) {
5292                 haIndex = (int) (vss.getMinIndex()
5293                         + (index - vss.getMinIndex()) / vss.getIndexStepFactor());
5294             }
5295             mDeviceBroker.postSetHearingAidVolumeIndex(haIndex, streamType);
5296         }
5297 
5298         synchronized (mHdmiClientLock) {
5299             if (streamTypeAlias == AudioSystem.STREAM_MUSIC
5300                     && (oldIndex != index)) {
5301                 maybeSendSystemAudioStatusCommand(false);
5302             }
5303         }
5304         if (canChangeMuteAndUpdateController) {
5305             // only non-null when coming here from setDeviceVolume
5306             // TODO change test to check early if device is current device or not
5307             sendVolumeUpdate(streamType, oldIndex, index, flags, device);
5308         }
5309     }
5310 
dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, int index)5311     private void dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo,
5312             int index) {
5313         VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType);
5314         if (volumeInfo != null) {
5315             try {
5316                 deviceInfo.mCallback.dispatchDeviceVolumeChanged(deviceInfo.mDevice,
5317                         new VolumeInfo.Builder(volumeInfo)
5318                                 .setVolumeIndex(rescaleIndex(index, streamType, volumeInfo))
5319                                 .build());
5320             } catch (RemoteException e) {
5321                 Log.w(TAG, "Couldn't dispatch absolute volume behavior volume change");
5322             }
5323         }
5324     }
5325 
dispatchAbsoluteVolumeAdjusted(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, int index, int direction, int mode)5326     private void dispatchAbsoluteVolumeAdjusted(int streamType,
5327             AbsoluteVolumeDeviceInfo deviceInfo, int index, int direction, int mode) {
5328         VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType);
5329         if (volumeInfo != null) {
5330             try {
5331                 deviceInfo.mCallback.dispatchDeviceVolumeAdjusted(deviceInfo.mDevice,
5332                         new VolumeInfo.Builder(volumeInfo)
5333                                 .setVolumeIndex(rescaleIndex(index, streamType, volumeInfo))
5334                                 .build(),
5335                         direction,
5336                         mode);
5337             } catch (RemoteException e) {
5338                 Log.w(TAG, "Couldn't dispatch absolute volume behavior volume adjustment");
5339             }
5340         }
5341     }
5342 
5343     // No ringer or zen muted stream volumes can be changed unless it'll exit dnd
volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags)5344     private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) {
5345         switch (mNm.getZenMode()) {
5346             case Settings.Global.ZEN_MODE_OFF:
5347                 return true;
5348             case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
5349             case Settings.Global.ZEN_MODE_ALARMS:
5350             case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
5351                 return !isStreamMutedByRingerOrZenMode(streamTypeAlias)
5352                         || isUiSoundsStreamType(streamTypeAlias)
5353                         || (flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0;
5354         }
5355 
5356         return true;
5357     }
5358 
5359     /** @see AudioManager#forceVolumeControlStream(int) */
forceVolumeControlStream(int streamType, IBinder cb)5360     public void forceVolumeControlStream(int streamType, IBinder cb) {
5361         if (mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE)
5362                 != PackageManager.PERMISSION_GRANTED) {
5363             return;
5364         }
5365 
5366         streamType = replaceBtScoStreamWithVoiceCall(streamType, "forceVolumeControlStream");
5367 
5368         if (DEBUG_VOL) { Log.d(TAG, String.format("forceVolumeControlStream(%d)", streamType)); }
5369         synchronized(mForceControlStreamLock) {
5370             if (mVolumeControlStream != -1 && streamType != -1) {
5371                 mUserSelectedVolumeControlStream = true;
5372             }
5373             mVolumeControlStream = streamType;
5374             if (mVolumeControlStream == -1) {
5375                 if (mForceControlStreamClient != null) {
5376                     mForceControlStreamClient.release();
5377                     mForceControlStreamClient = null;
5378                 }
5379                 mUserSelectedVolumeControlStream = false;
5380             } else {
5381                 if (null == mForceControlStreamClient) {
5382                     mForceControlStreamClient = new ForceControlStreamClient(cb);
5383                 } else {
5384                     if (mForceControlStreamClient.getBinder() == cb) {
5385                         Log.d(TAG, "forceVolumeControlStream cb:" + cb + " is already linked.");
5386                     } else {
5387                         mForceControlStreamClient.release();
5388                         mForceControlStreamClient = new ForceControlStreamClient(cb);
5389                     }
5390                 }
5391             }
5392         }
5393     }
5394 
5395     private class ForceControlStreamClient implements IBinder.DeathRecipient {
5396         private IBinder mCb; // To be notified of client's death
5397 
ForceControlStreamClient(IBinder cb)5398         ForceControlStreamClient(IBinder cb) {
5399             if (cb != null) {
5400                 try {
5401                     cb.linkToDeath(this, 0);
5402                 } catch (RemoteException e) {
5403                     // Client has died!
5404                     Log.w(TAG, "ForceControlStreamClient() could not link to "+cb+" binder death");
5405                     cb = null;
5406                 }
5407             }
5408             mCb = cb;
5409         }
5410 
binderDied()5411         public void binderDied() {
5412             synchronized(mForceControlStreamLock) {
5413                 Log.w(TAG, "SCO client died");
5414                 if (mForceControlStreamClient != this) {
5415                     Log.w(TAG, "unregistered control stream client died");
5416                 } else {
5417                     mForceControlStreamClient = null;
5418                     mVolumeControlStream = -1;
5419                     mUserSelectedVolumeControlStream = false;
5420                 }
5421             }
5422         }
5423 
release()5424         public void release() {
5425             if (mCb != null) {
5426                 mCb.unlinkToDeath(this, 0);
5427                 mCb = null;
5428             }
5429         }
5430 
getBinder()5431         public IBinder getBinder() {
5432             return mCb;
5433         }
5434     }
5435 
sendBroadcastToAll(Intent intent, Bundle options)5436     private void sendBroadcastToAll(Intent intent, Bundle options) {
5437         if (!mSystemServer.isPrivileged()) {
5438             return;
5439         }
5440         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
5441         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
5442         final long ident = Binder.clearCallingIdentity();
5443         try {
5444             mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
5445                     null /* receiverPermission */, options);
5446         } finally {
5447             Binder.restoreCallingIdentity(ident);
5448         }
5449     }
5450 
sendStickyBroadcastToAll(Intent intent)5451     private void sendStickyBroadcastToAll(Intent intent) {
5452         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
5453         final long ident = Binder.clearCallingIdentity();
5454         try {
5455             mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
5456         } finally {
5457             Binder.restoreCallingIdentity(ident);
5458         }
5459     }
5460 
getCurrentUserId()5461     private int getCurrentUserId() {
5462         final long ident = Binder.clearCallingIdentity();
5463         try {
5464             UserInfo currentUser = ActivityManager.getService().getCurrentUser();
5465             return currentUser.id;
5466         } catch (RemoteException e) {
5467             // Activity manager not running, nothing we can do assume user 0.
5468         } finally {
5469             Binder.restoreCallingIdentity(ident);
5470         }
5471         return UserHandle.USER_SYSTEM;
5472     }
5473 
5474     // UI update and Broadcast Intent
sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device)5475     protected void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device)
5476     {
5477         streamType = sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound=*/-1);
5478         if (streamType == -1) {
5479             Slog.e(TAG, "Invalid stream type. No update to IVolumeController", new Exception());
5480             return;
5481         }
5482 
5483         if (streamType == AudioSystem.STREAM_MUSIC && isFullVolumeDevice(device)) {
5484             flags &= ~AudioManager.FLAG_SHOW_UI;
5485         }
5486         mVolumeController.postVolumeChanged(streamType, flags);
5487     }
5488 
5489     // Don't show volume UI when:
5490     //  - Hdmi-CEC system audio mode is on and we are a TV panel
updateFlagsForTvPlatform(int flags)5491     private int updateFlagsForTvPlatform(int flags) {
5492         synchronized (mHdmiClientLock) {
5493             if (mHdmiTvClient != null && mHdmiSystemAudioSupported
5494                     && mHdmiCecVolumeControlEnabled) {
5495                 flags &= ~AudioManager.FLAG_SHOW_UI;
5496             }
5497         }
5498         return flags;
5499     }
5500     // UI update and Broadcast Intent
sendMasterMuteUpdate(boolean muted, int flags)5501     private void sendMasterMuteUpdate(boolean muted, int flags) {
5502         mVolumeController.postMasterMuteChanged(updateFlagsForTvPlatform(flags));
5503         sendMsg(mAudioHandler, MSG_BROADCAST_MASTER_MUTE,
5504                 SENDMSG_QUEUE, muted ? 1 : 0, 0, null, 0);
5505     }
5506 
5507 
5508     /**
5509      * Sets the stream state's index, and posts a message to set system volume.
5510      * This will not call out to the UI. Assumes a valid stream type.
5511      *
5512      * @param streamType Type of the stream
5513      * @param index Desired volume index of the stream
5514      * @param device the device whose volume must be changed
5515      * @param force If true, set the volume even if the desired volume is same
5516      * @param caller
5517      * @param hasModifyAudioSettings true if the caller is granted MODIFY_AUDIO_SETTINGS or
5518      *                              MODIFY_AUDIO_ROUTING permission
5519      * as the current volume.
5520      */
setStreamVolumeInt(int streamType, int index, int device, boolean force, String caller, boolean hasModifyAudioSettings)5521     private void setStreamVolumeInt(int streamType,
5522                                     int index,
5523                                     int device,
5524                                     boolean force,
5525                                     String caller, boolean hasModifyAudioSettings) {
5526         if (isFullVolumeDevice(device)) {
5527             return;
5528         }
5529         final VolumeStreamState streamState = getVssForStreamOrDefault(streamType);
5530 
5531         if (streamState.setIndex(index, device, caller, hasModifyAudioSettings) || force) {
5532             // Post message to set system volume (it in turn will post a message
5533             // to persist).
5534             sendMsg(mAudioHandler,
5535                     MSG_SET_DEVICE_VOLUME,
5536                     SENDMSG_QUEUE,
5537                     device,
5538                     0,
5539                     streamState,
5540                     0);
5541         }
5542     }
5543 
5544     /** get stream mute state. */
isStreamMute(int streamType)5545     public boolean isStreamMute(int streamType) {
5546         if (streamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
5547             streamType = getActiveStreamType(streamType);
5548         }
5549         streamType = replaceBtScoStreamWithVoiceCall(streamType, "isStreamMute");
5550 
5551         synchronized (mVolumeStateLock) {
5552             ensureValidStreamType(streamType);
5553             return getVssForStreamOrDefault(streamType).mIsMuted;
5554         }
5555     }
5556 
5557     private class RmtSbmxFullVolDeathHandler implements IBinder.DeathRecipient {
5558         private IBinder mICallback; // To be notified of client's death
5559 
RmtSbmxFullVolDeathHandler(IBinder cb)5560         RmtSbmxFullVolDeathHandler(IBinder cb) {
5561             mICallback = cb;
5562             try {
5563                 cb.linkToDeath(this, 0/*flags*/);
5564             } catch (RemoteException e) {
5565                 Log.e(TAG, "can't link to death", e);
5566             }
5567         }
5568 
isHandlerFor(IBinder cb)5569         boolean isHandlerFor(IBinder cb) {
5570             return mICallback.equals(cb);
5571         }
5572 
forget()5573         void forget() {
5574             try {
5575                 mICallback.unlinkToDeath(this, 0/*flags*/);
5576             } catch (NoSuchElementException e) {
5577                 Log.e(TAG, "error unlinking to death", e);
5578             }
5579         }
5580 
binderDied()5581         public void binderDied() {
5582             Log.w(TAG, "Recorder with remote submix at full volume died " + mICallback);
5583             forceRemoteSubmixFullVolume(false, mICallback);
5584         }
5585     }
5586 
5587     /**
5588      * call must be synchronized on mRmtSbmxFullVolDeathHandlers
5589      * @return true if there is a registered death handler, false otherwise */
discardRmtSbmxFullVolDeathHandlerFor(IBinder cb)5590     private boolean discardRmtSbmxFullVolDeathHandlerFor(IBinder cb) {
5591         Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator();
5592         while (it.hasNext()) {
5593             final RmtSbmxFullVolDeathHandler handler = it.next();
5594             if (handler.isHandlerFor(cb)) {
5595                 handler.forget();
5596                 mRmtSbmxFullVolDeathHandlers.remove(handler);
5597                 return true;
5598             }
5599         }
5600         return false;
5601     }
5602 
5603     /** call synchronized on mRmtSbmxFullVolDeathHandlers */
hasRmtSbmxFullVolDeathHandlerFor(IBinder cb)5604     private boolean hasRmtSbmxFullVolDeathHandlerFor(IBinder cb) {
5605         Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator();
5606         while (it.hasNext()) {
5607             if (it.next().isHandlerFor(cb)) {
5608                 return true;
5609             }
5610         }
5611         return false;
5612     }
5613 
5614     private int mRmtSbmxFullVolRefCount = 0;
5615     private final ArrayList<RmtSbmxFullVolDeathHandler> mRmtSbmxFullVolDeathHandlers =
5616             new ArrayList<RmtSbmxFullVolDeathHandler>();
5617 
forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb)5618     public void forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb) {
5619         if (cb == null) {
5620             return;
5621         }
5622         if ((PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
5623                         CAPTURE_AUDIO_OUTPUT))) {
5624             Log.w(TAG, "Trying to call forceRemoteSubmixFullVolume() without CAPTURE_AUDIO_OUTPUT");
5625             return;
5626         }
5627         synchronized(mRmtSbmxFullVolDeathHandlers) {
5628             boolean applyRequired = false;
5629             if (startForcing) {
5630                 if (!hasRmtSbmxFullVolDeathHandlerFor(cb)) {
5631                     mRmtSbmxFullVolDeathHandlers.add(new RmtSbmxFullVolDeathHandler(cb));
5632                     if (mRmtSbmxFullVolRefCount == 0) {
5633                         mFullVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
5634                         mFixedVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
5635                         applyRequired = true;
5636                     }
5637                     mRmtSbmxFullVolRefCount++;
5638                 }
5639             } else {
5640                 if (discardRmtSbmxFullVolDeathHandlerFor(cb) && (mRmtSbmxFullVolRefCount > 0)) {
5641                     mRmtSbmxFullVolRefCount--;
5642                     if (mRmtSbmxFullVolRefCount == 0) {
5643                         mFullVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
5644                         mFixedVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
5645                         applyRequired = true;
5646                     }
5647                 }
5648             }
5649             if (applyRequired) {
5650                 // Assumes only STREAM_MUSIC going through DEVICE_OUT_REMOTE_SUBMIX
5651                 checkAllFixedVolumeDevices(AudioSystem.STREAM_MUSIC);
5652                 getVssForStreamOrDefault(AudioSystem.STREAM_MUSIC).applyAllVolumes();
5653             }
5654         }
5655     }
5656 
setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, int userId, int pid, String attributionTag)5657     private void setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid,
5658             int userId, int pid, String attributionTag) {
5659         // If we are being called by the system check for user we are going to change
5660         // so we handle user restrictions correctly.
5661         if (uid == android.os.Process.SYSTEM_UID) {
5662             uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
5663         }
5664         // If OP_AUDIO_MASTER_VOLUME is set, disallow unmuting.
5665         if (!mute && !checkNoteAppOp(
5666                 AppOpsManager.OP_AUDIO_MASTER_VOLUME, uid, callingPackage, attributionTag)) {
5667             return;
5668         }
5669         if (userId != UserHandle.getCallingUserId() &&
5670                 mContext.checkPermission(INTERACT_ACROSS_USERS_FULL, pid, uid)
5671                 != PackageManager.PERMISSION_GRANTED) {
5672             return;
5673         }
5674         setMasterMuteInternalNoCallerCheck(mute, flags, userId, "setMasterMute");
5675     }
5676 
setMasterMuteInternalNoCallerCheck( boolean mute, int flags, int userId, String eventSource)5677     private void setMasterMuteInternalNoCallerCheck(
5678             boolean mute, int flags, int userId, String eventSource) {
5679         if (DEBUG_VOL) {
5680             Log.d(TAG, TextUtils.formatSimple("Master mute %s, flags 0x%x, userId=%d from %s",
5681                     mute, flags, userId, eventSource));
5682         }
5683 
5684         if (!isPlatformAutomotive() && mUseFixedVolume) {
5685             // If using fixed volume, we don't mute.
5686             // TODO: remove the isPlatformAutomotive check here.
5687             // The isPlatformAutomotive check is added for safety but may not be necessary.
5688             mute = false;
5689         }
5690         // For automotive,
5691         // - the car service is always running as system user
5692         // - foreground users are non-system users
5693         // Car service is in charge of dispatching the key event include global mute to Android.
5694         // Therefore, the getCurrentUser() is always different to the foreground user.
5695         if ((isPlatformAutomotive() && userId == UserHandle.USER_SYSTEM)
5696                 || (getCurrentUserId() == userId)) {
5697             if (mute != mMasterMute.getAndSet(mute)) {
5698                 sVolumeLogger.enqueue(new VolumeEvent(
5699                         VolumeEvent.VOL_MASTER_MUTE, mute));
5700                 mAudioSystem.setMasterMute(mute);
5701                 sendMasterMuteUpdate(mute, flags);
5702             }
5703         }
5704     }
5705 
5706     /** get global mute state. */
isMasterMute()5707     public boolean isMasterMute() {
5708         return mMasterMute.get();
5709     }
5710 
5711     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
5712     /** @see AudioManager#setMasterMute(boolean, int) */
setMasterMute(boolean mute, int flags, String callingPackage, int userId, String attributionTag)5713     public void setMasterMute(boolean mute, int flags, String callingPackage, int userId,
5714             String attributionTag) {
5715 
5716         super.setMasterMute_enforcePermission();
5717 
5718         setMasterMuteInternal(mute, flags, callingPackage,
5719                 Binder.getCallingUid(), userId, Binder.getCallingPid(), attributionTag);
5720     }
5721 
5722     /** @see AudioManager#getStreamVolume(int) */
getStreamVolume(int streamType)5723     public int getStreamVolume(int streamType) {
5724         streamType = replaceBtScoStreamWithVoiceCall(streamType, "getStreamVolume");
5725 
5726         ensureValidStreamType(streamType);
5727         int device = getDeviceForStream(streamType);
5728         return getStreamVolume(streamType, device);
5729     }
5730 
getStreamVolume(int streamType, int device)5731     private int getStreamVolume(int streamType, int device) {
5732         synchronized (mVolumeStateLock) {
5733             final VolumeStreamState vss = getVssForStreamOrDefault(streamType);
5734             int index = vss.getIndex(device);
5735 
5736             // by convention getStreamVolume() returns 0 when a stream is muted.
5737             if (vss.mIsMuted) {
5738                 index = 0;
5739             }
5740             if (index != 0 && (sStreamVolumeAlias.get(streamType) == AudioSystem.STREAM_MUSIC)
5741                     && isFixedVolumeDevice(device)) {
5742                 index = vss.getMaxIndex();
5743             }
5744             return (index + 5) / 10;
5745         }
5746     }
5747 
5748     @Override
5749     @android.annotation.EnforcePermission(anyOf = {
5750             MODIFY_AUDIO_ROUTING, MODIFY_AUDIO_SETTINGS_PRIVILEGED })
5751     /**
5752      * @see AudioDeviceVolumeManager#getDeviceVolume(VolumeInfo, AudioDeviceAttributes)
5753      */
getDeviceVolume(@onNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage)5754     public @NonNull VolumeInfo getDeviceVolume(@NonNull VolumeInfo vi,
5755             @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage) {
5756         super.getDeviceVolume_enforcePermission();
5757         Objects.requireNonNull(vi);
5758         Objects.requireNonNull(ada);
5759         Objects.requireNonNull(callingPackage);
5760         if (!vi.hasStreamType()) {
5761             Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception());
5762             return getDefaultVolumeInfo();
5763         }
5764 
5765         int streamType = replaceBtScoStreamWithVoiceCall(vi.getStreamType(), "getStreamMaxVolume");
5766         final VolumeInfo.Builder vib = new VolumeInfo.Builder(vi);
5767         final VolumeStreamState vss = getVssForStream(streamType);
5768         if (vss == null) {
5769             Log.w(TAG,
5770                     "getDeviceVolume unsupported stream type " + streamType + ". Return default");
5771             return getDefaultVolumeInfo();
5772         }
5773 
5774         vib.setMinVolumeIndex((vss.mIndexMin + 5) / 10);
5775         vib.setMaxVolumeIndex((vss.mIndexMax + 5) / 10);
5776         synchronized (mVolumeStateLock) {
5777             final int index;
5778             if (isFixedVolumeDevice(ada.getInternalType())) {
5779                 index = (vss.mIndexMax + 5) / 10;
5780             } else {
5781                 index = (vss.getIndex(ada.getInternalType()) + 5) / 10;
5782             }
5783             vib.setVolumeIndex(index);
5784             // only set as a mute command if stream muted
5785             if (vss.mIsMuted) {
5786                 vib.setMuted(true);
5787             }
5788             return vib.build();
5789         }
5790     }
5791 
5792     /** @see AudioManager#getStreamMaxVolume(int) */
getStreamMaxVolume(int streamType)5793     public int getStreamMaxVolume(int streamType) {
5794         streamType = replaceBtScoStreamWithVoiceCall(streamType, "getStreamMaxVolume");
5795         ensureValidStreamType(streamType);
5796         return (getVssForStreamOrDefault(streamType).getMaxIndex() + 5) / 10;
5797     }
5798 
5799     /** @see AudioManager#getStreamMinVolumeInt(int)
5800      * Part of service interface, check permissions here */
getStreamMinVolume(int streamType)5801     public int getStreamMinVolume(int streamType) {
5802         streamType = replaceBtScoStreamWithVoiceCall(streamType, "getStreamMinVolume");
5803         ensureValidStreamType(streamType);
5804         final boolean isPrivileged =
5805                 Binder.getCallingUid() == Process.SYSTEM_UID
5806                  || callingHasAudioSettingsPermission()
5807                  || (mContext.checkCallingPermission(MODIFY_AUDIO_ROUTING)
5808                         == PackageManager.PERMISSION_GRANTED);
5809         return (getVssForStreamOrDefault(streamType).getMinIndex(isPrivileged) + 5) / 10;
5810     }
5811 
5812     @android.annotation.EnforcePermission(QUERY_AUDIO_STATE)
5813     /** Get last audible volume before stream was muted. */
getLastAudibleStreamVolume(int streamType)5814     public int getLastAudibleStreamVolume(int streamType) {
5815         super.getLastAudibleStreamVolume_enforcePermission();
5816 
5817         streamType = replaceBtScoStreamWithVoiceCall(streamType, "getLastAudibleStreamVolume");
5818 
5819         ensureValidStreamType(streamType);
5820 
5821         int device = getDeviceForStream(streamType);
5822         return (getVssForStreamOrDefault(streamType).getIndex(device) + 5) / 10;
5823     }
5824 
5825     /**
5826      * Default VolumeInfo returned by {@link VolumeInfo#getDefaultVolumeInfo()}
5827      * Lazily initialized in {@link #getDefaultVolumeInfo()}
5828      */
5829     static VolumeInfo sDefaultVolumeInfo;
5830 
5831     /** @see VolumeInfo#getDefaultVolumeInfo() */
getDefaultVolumeInfo()5832     public VolumeInfo getDefaultVolumeInfo() {
5833         if (sDefaultVolumeInfo == null) {
5834             sDefaultVolumeInfo = new VolumeInfo.Builder(AudioSystem.STREAM_MUSIC)
5835                     .setMinVolumeIndex(getStreamMinVolume(AudioSystem.STREAM_MUSIC))
5836                     .setMaxVolumeIndex(getStreamMaxVolume(AudioSystem.STREAM_MUSIC))
5837                     .build();
5838         }
5839         return sDefaultVolumeInfo;
5840     }
5841 
5842     /**
5843      * list of callback dispatchers for stream aliasing updates
5844      */
5845     final RemoteCallbackList<IStreamAliasingDispatcher> mStreamAliasingDispatchers =
5846             new RemoteCallbackList<IStreamAliasingDispatcher>();
5847 
5848     /**
5849      * Register/unregister a callback for stream aliasing updates
5850      * @param isad the callback dispatcher
5851      * @param register whether this for a registration or unregistration
5852      * @see AudioManager#addOnStreamAliasingChangedListener(Executor, Runnable)
5853      * @see AudioManager#removeOnStreamAliasingChangedListener(Runnable)
5854      */
5855     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
registerStreamAliasingDispatcher(IStreamAliasingDispatcher isad, boolean register)5856     public void registerStreamAliasingDispatcher(IStreamAliasingDispatcher isad, boolean register) {
5857         super.registerStreamAliasingDispatcher_enforcePermission();
5858         Objects.requireNonNull(isad);
5859 
5860         if (register) {
5861             mStreamAliasingDispatchers.register(isad);
5862         } else {
5863             mStreamAliasingDispatchers.unregister(isad);
5864         }
5865     }
5866 
dispatchStreamAliasingUpdate()5867     protected void dispatchStreamAliasingUpdate() {
5868         final int nbDispatchers = mStreamAliasingDispatchers.beginBroadcast();
5869         for (int i = 0; i < nbDispatchers; i++) {
5870             try {
5871                 mStreamAliasingDispatchers.getBroadcastItem(i).dispatchStreamAliasingChanged();
5872             } catch (RemoteException e) {
5873                 Log.e(TAG, "Error on stream alias update dispatch", e);
5874             }
5875         }
5876         mStreamAliasingDispatchers.finishBroadcast();
5877     }
5878 
5879     /**
5880      * @see AudioManager#getIndependentStreamTypes()
5881      * @return the list of non-aliased stream types
5882      */
5883     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
getIndependentStreamTypes()5884     public ArrayList<Integer> getIndependentStreamTypes() {
5885         super.getIndependentStreamTypes_enforcePermission();
5886 
5887         if (mUseVolumeGroupAliases) {
5888             return new ArrayList<>(Arrays.stream(AudioManager.getPublicStreamTypes())
5889                     .boxed().toList());
5890         }
5891         ArrayList<Integer> res = new ArrayList<>(1);
5892         for (int streamIdx = 0; streamIdx < sStreamVolumeAlias.size(); ++streamIdx) {
5893             final int streamAlias = sStreamVolumeAlias.valueAt(streamIdx);
5894             if (!res.contains(streamAlias)) {
5895                 res.add(streamAlias);
5896             }
5897         }
5898         return res;
5899     }
5900 
5901     /**
5902      * @see AudioManager#getStreamTypeAlias(int)
5903      * @param sourceStreamType the stream type for which the alias is queried
5904      * @return the stream alias
5905      */
5906     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
5907     public @AudioManager.PublicStreamTypes
getStreamTypeAlias(@udioManager.PublicStreamTypes int sourceStreamType)5908     int getStreamTypeAlias(@AudioManager.PublicStreamTypes int sourceStreamType) {
5909         super.getStreamTypeAlias_enforcePermission();
5910 
5911         sourceStreamType = replaceBtScoStreamWithVoiceCall(sourceStreamType, "getStreamTypeAlias");
5912 
5913         // verify parameters
5914         ensureValidStreamType(sourceStreamType);
5915 
5916         return sStreamVolumeAlias.get(sourceStreamType, /*valueIfKeyNotFound=*/-1);
5917     }
5918 
5919     /**
5920      * @see AudioManager#isVolumeControlUsingVolumeGroups()
5921      * @return true when volume control is performed through volume groups, false if it uses
5922      *     stream types.
5923      */
5924     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
isVolumeControlUsingVolumeGroups()5925     public boolean isVolumeControlUsingVolumeGroups() {
5926         super.isVolumeControlUsingVolumeGroups_enforcePermission();
5927 
5928         return mUseVolumeGroupAliases;
5929     }
5930 
5931     /** @see AudioManager#getUiSoundsStreamType()
5932      * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for
5933      * UI Sounds identification.
5934      * Fallback on Voice configuration to ensure correct behavior of DnD feature.
5935      */
getUiSoundsStreamType()5936     public int getUiSoundsStreamType() {
5937         return mUseVolumeGroupAliases ? STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM]
5938                 : sStreamVolumeAlias.get(AudioSystem.STREAM_SYSTEM);
5939     }
5940 
5941     /**
5942      * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for
5943      * UI Sounds identification.
5944      * Fallback on Voice configuration to ensure correct behavior of DnD feature.
5945      */
isUiSoundsStreamType(int aliasStreamType)5946     private boolean isUiSoundsStreamType(int aliasStreamType) {
5947         return mUseVolumeGroupAliases
5948                 ? STREAM_VOLUME_ALIAS_VOICE[aliasStreamType]
5949                         == STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM]
5950                 : aliasStreamType == sStreamVolumeAlias.get(AudioSystem.STREAM_SYSTEM);
5951     }
5952 
5953     /**
5954      * @see AudioDeviceVolumeManager#setInputGainIndex(AudioDeviceAttributes, int)
5955      */
5956     @Override
5957     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setInputGainIndex(@onNull AudioDeviceAttributes ada, int index)5958     public void setInputGainIndex(@NonNull AudioDeviceAttributes ada, int index) {
5959         super.setInputGainIndex_enforcePermission();
5960 
5961         if (mInputDeviceVolumeHelper.setInputGainIndex(ada, index)) {
5962             // Post message to set system volume (it in turn will post a message
5963             // to persist).
5964             sendMsg(
5965                     mAudioHandler,
5966                     MSG_APPLY_INPUT_GAIN_INDEX,
5967                     SENDMSG_QUEUE,
5968                     /*arg1*/ index,
5969                     /*arg2*/ 0,
5970                     /*obj*/ ada,
5971                     /*delay*/ 0);
5972         }
5973     }
5974 
onApplyInputGainIndex(@onNull AudioDeviceAttributes ada, int index)5975     private void onApplyInputGainIndex(@NonNull AudioDeviceAttributes ada, int index) {
5976         // TODO(b/364923030): call AudioSystem to apply input gain in native layer.
5977 
5978         // Post a persist input gain msg.
5979         sendMsg(
5980                 mAudioHandler,
5981                 MSG_PERSIST_INPUT_GAIN_INDEX,
5982                 SENDMSG_REPLACE,
5983                 /*arg1*/ 0,
5984                 /*arg2*/ 0,
5985                 /*obj*/ ada,
5986                 PERSIST_DELAY);
5987     }
5988 
onPersistInputGainIndex(@onNull AudioDeviceAttributes ada)5989     private void onPersistInputGainIndex(@NonNull AudioDeviceAttributes ada) {
5990         mInputDeviceVolumeHelper.persistInputGainIndex(ada);
5991     }
5992 
5993     /**
5994      * @see AudioDeviceVolumeManager#getInputGainIndex(AudioDeviceAttributes)
5995      */
5996     @Override
5997     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
getInputGainIndex(@onNull AudioDeviceAttributes ada)5998     public int getInputGainIndex(@NonNull AudioDeviceAttributes ada) {
5999         super.getInputGainIndex_enforcePermission();
6000 
6001         return mInputDeviceVolumeHelper.getInputGainIndex(ada);
6002     }
6003 
6004     /**
6005      * @see AudioDeviceVolumeManager#getMaxInputGainIndex()
6006      */
6007     @Override
6008     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
getMaxInputGainIndex()6009     public int getMaxInputGainIndex() {
6010         super.getMaxInputGainIndex_enforcePermission();
6011 
6012         return mInputDeviceVolumeHelper.getMaxInputGainIndex();
6013     }
6014 
6015     /**
6016      * @see AudioDeviceVolumeManager#getMinInputGainIndex()
6017      */
6018     @Override
6019     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
getMinInputGainIndex()6020     public int getMinInputGainIndex() {
6021         super.getMinInputGainIndex_enforcePermission();
6022 
6023         return mInputDeviceVolumeHelper.getMinInputGainIndex();
6024     }
6025 
6026     /**
6027      * @see AudioDeviceVolumeManager#isInputGainFixed(AudioDeviceAttributes)
6028      */
6029     @Override
6030     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
isInputGainFixed(@onNull AudioDeviceAttributes ada)6031     public boolean isInputGainFixed(@NonNull AudioDeviceAttributes ada) {
6032         super.isInputGainFixed_enforcePermission();
6033 
6034         return mInputDeviceVolumeHelper.isInputGainFixed(ada);
6035     }
6036 
6037     /** @see AudioManager#setMicrophoneMute(boolean) */
6038     @Override
setMicrophoneMute(boolean on, String callingPackage, int userId, String attributionTag)6039     public void setMicrophoneMute(boolean on, String callingPackage, int userId,
6040             String attributionTag) {
6041         // If we are being called by the system check for user we are going to change
6042         // so we handle user restrictions correctly.
6043         int uid = Binder.getCallingUid();
6044         if (uid == android.os.Process.SYSTEM_UID) {
6045             uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
6046         }
6047         MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
6048                 .setUid(uid)
6049                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage)
6050                 .set(MediaMetrics.Property.EVENT, "setMicrophoneMute")
6051                 .set(MediaMetrics.Property.REQUEST, on
6052                         ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE);
6053 
6054         // If OP_MUTE_MICROPHONE is set, disallow unmuting.
6055         if (!on && !checkNoteAppOp(
6056                 AppOpsManager.OP_MUTE_MICROPHONE, uid, callingPackage, attributionTag)) {
6057             mmi.set(MediaMetrics.Property.EARLY_RETURN, "disallow unmuting").record();
6058             return;
6059         }
6060         if (!checkAudioSettingsPermission("setMicrophoneMute()")) {
6061             mmi.set(MediaMetrics.Property.EARLY_RETURN, "!checkAudioSettingsPermission").record();
6062             return;
6063         }
6064         if (userId != UserHandle.getCallingUserId() &&
6065                 mContext.checkCallingOrSelfPermission(INTERACT_ACROSS_USERS_FULL)
6066                 != PackageManager.PERMISSION_GRANTED) {
6067             mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission").record();
6068             return;
6069         }
6070         mMicMuteFromApi = on;
6071         mmi.record(); // record now, the no caller check will set the mute state.
6072         setMicrophoneMuteNoCallerCheck(userId);
6073     }
6074 
6075     /** @see AudioManager#setMicrophoneMuteFromSwitch(boolean) */
setMicrophoneMuteFromSwitch(boolean on)6076     public void setMicrophoneMuteFromSwitch(boolean on) {
6077         int callingUid = Binder.getCallingUid();
6078         if (callingUid != android.os.Process.SYSTEM_UID) {
6079             Log.e(TAG, "setMicrophoneMuteFromSwitch() called from non system user!");
6080             return;
6081         }
6082         mMicMuteFromSwitch = on;
6083         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
6084                 .setUid(callingUid)
6085                 .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteFromSwitch")
6086                 .set(MediaMetrics.Property.REQUEST, on
6087                         ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE)
6088                 .record();
6089         setMicrophoneMuteNoCallerCheck(UserHandle.getCallingUserId());
6090     }
6091 
setMicMuteFromSwitchInput()6092     private void setMicMuteFromSwitchInput() {
6093         InputManager im = mContext.getSystemService(InputManager.class);
6094         final int isMicMuted = im.isMicMuted();
6095         if (isMicMuted != InputManager.SWITCH_STATE_UNKNOWN) {
6096             setMicrophoneMuteFromSwitch(im.isMicMuted() != InputManager.SWITCH_STATE_OFF);
6097         }
6098     }
6099 
6100     /**
6101      * Returns the microphone mute state as seen from the native audio system
6102      * @return true if microphone is reported as muted by primary HAL
6103      */
isMicrophoneMuted()6104     public boolean isMicrophoneMuted() {
6105         return mMicMuteFromSystemCached
6106                 && (!mMicMuteFromPrivacyToggle
6107                         || mMicMuteFromApi || mMicMuteFromRestrictions || mMicMuteFromSwitch);
6108     }
6109 
isMicrophoneSupposedToBeMuted()6110     private boolean isMicrophoneSupposedToBeMuted() {
6111         return mMicMuteFromSwitch || mMicMuteFromRestrictions || mMicMuteFromApi
6112                 || mMicMuteFromPrivacyToggle;
6113     }
6114 
setMicrophoneMuteNoCallerCheck(int userId)6115     private void setMicrophoneMuteNoCallerCheck(int userId) {
6116         final boolean muted = isMicrophoneSupposedToBeMuted();
6117         if (DEBUG_VOL) {
6118             Log.d(TAG, String.format("Mic mute %b, user=%d", muted, userId));
6119         }
6120         // only mute for the current user or for the system user.
6121         if (getCurrentUserId() == userId || userId == UserHandle.USER_SYSTEM) {
6122             final boolean currentMute = mAudioSystem.isMicrophoneMuted();
6123             int callingUid = Binder.getCallingUid();
6124             final long identity = Binder.clearCallingIdentity();
6125             try {
6126                 final int ret = mAudioSystem.muteMicrophone(muted);
6127 
6128                 // update cache with the real state independently from what was set
6129                 mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted();
6130                 if (ret != AudioSystem.AUDIO_STATUS_OK) {
6131                     Log.e(TAG, "Error changing mic mute state to " + muted + " current:"
6132                             + mMicMuteFromSystemCached);
6133                 }
6134 
6135                 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
6136                         .setUid(callingUid)
6137                         .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteNoCallerCheck")
6138                         .set(MediaMetrics.Property.MUTE, mMicMuteFromSystemCached
6139                                 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
6140                         .set(MediaMetrics.Property.REQUEST, muted
6141                                 ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE)
6142                         .set(MediaMetrics.Property.STATUS, ret)
6143                         .record();
6144 
6145                 // send the intent even if there was a failure to change the actual mute state:
6146                 // the AudioManager.setMicrophoneMute API doesn't have a return value to
6147                 // indicate if the call failed to successfully change the mute state, and receiving
6148                 // the intent may be the only time an application can resynchronize its mic mute
6149                 // state with the actual system mic mute state
6150                 if (muted != currentMute) {
6151                     sendMsg(mAudioHandler, MSG_BROADCAST_MICROPHONE_MUTE,
6152                                 SENDMSG_NOOP, 0, 0, null, 0);
6153                 }
6154             } finally {
6155                 Binder.restoreCallingIdentity(identity);
6156             }
6157         }
6158     }
6159 
6160     @Override
getRingerModeExternal()6161     public int getRingerModeExternal() {
6162         synchronized(mSettingsLock) {
6163             return mRingerModeExternal;
6164         }
6165     }
6166 
6167     @Override
getRingerModeInternal()6168     public int getRingerModeInternal() {
6169         synchronized(mSettingsLock) {
6170             return mRingerMode;
6171         }
6172     }
6173 
ensureValidRingerMode(int ringerMode)6174     private void ensureValidRingerMode(int ringerMode) {
6175         if (!isValidRingerMode(ringerMode)) {
6176             throw new IllegalArgumentException("Bad ringer mode " + ringerMode);
6177         }
6178     }
6179 
6180     /** @see AudioManager#isValidRingerMode(int) */
isValidRingerMode(int ringerMode)6181     public boolean isValidRingerMode(int ringerMode) {
6182         return ringerMode >= 0 && ringerMode <= AudioManager.RINGER_MODE_MAX;
6183     }
6184 
setRingerModeExternal(int ringerMode, String caller)6185     public void setRingerModeExternal(int ringerMode, String caller) {
6186         if (mHardeningEnforcer.blockVolumeMethod(
6187                 HardeningEnforcer.METHOD_AUDIO_MANAGER_SET_RINGER_MODE,
6188                 getPackageNameForUid(Binder.getCallingUid()),
6189                 Binder.getCallingUid())) {
6190             return;
6191         }
6192         if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode)
6193                 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)) {
6194             throw new SecurityException("Not allowed to change Do Not Disturb state");
6195         }
6196 
6197         setRingerMode(ringerMode, caller, true /*external*/);
6198     }
6199 
setRingerModeInternal(int ringerMode, String caller)6200     public void setRingerModeInternal(int ringerMode, String caller) {
6201         enforceVolumeController("setRingerModeInternal");
6202         setRingerMode(ringerMode, caller, false /*external*/);
6203     }
6204 
silenceRingerModeInternal(String reason)6205     public void silenceRingerModeInternal(String reason) {
6206         VibrationEffect effect = null;
6207         int ringerMode = AudioManager.RINGER_MODE_SILENT;
6208         int toastText = 0;
6209 
6210         int silenceRingerSetting = Settings.Secure.VOLUME_HUSH_OFF;
6211         if (mContext.getResources()
6212                 .getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled)) {
6213             silenceRingerSetting = mSettings.getSecureIntForUser(mContentResolver,
6214                     Settings.Secure.VOLUME_HUSH_GESTURE, VOLUME_HUSH_OFF,
6215                     UserHandle.USER_CURRENT);
6216         }
6217 
6218         switch(silenceRingerSetting) {
6219             case VOLUME_HUSH_MUTE:
6220                 effect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK);
6221                 ringerMode = AudioManager.RINGER_MODE_SILENT;
6222                 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_silent;
6223                 break;
6224             case VOLUME_HUSH_VIBRATE:
6225                 effect = VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK);
6226                 ringerMode = AudioManager.RINGER_MODE_VIBRATE;
6227                 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_vibrate;
6228                 break;
6229         }
6230         maybeVibrate(effect, reason);
6231         setRingerModeInternal(ringerMode, reason);
6232         Toast.makeText(mContext, toastText, Toast.LENGTH_SHORT).show();
6233     }
6234 
maybeVibrate(VibrationEffect effect, String reason)6235     private boolean maybeVibrate(VibrationEffect effect, String reason) {
6236         if (!mHasVibrator) {
6237             return false;
6238         }
6239         if (effect == null) {
6240             return false;
6241         }
6242         mVibrator.vibrate(Binder.getCallingUid(), mContext.getOpPackageName(), effect,
6243                 reason, TOUCH_VIBRATION_ATTRIBUTES);
6244         return true;
6245     }
6246 
setRingerMode(int ringerMode, String caller, boolean external)6247     private void setRingerMode(int ringerMode, String caller, boolean external) {
6248         if (mUseFixedVolume || mIsSingleVolume || mUseVolumeGroupAliases) {
6249             return;
6250         }
6251         if (caller == null || caller.length() == 0) {
6252             throw new IllegalArgumentException("Bad caller: " + caller);
6253         }
6254         ensureValidRingerMode(ringerMode);
6255         if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) {
6256             ringerMode = AudioManager.RINGER_MODE_SILENT;
6257         }
6258         final long identity = Binder.clearCallingIdentity();
6259         try {
6260             synchronized (mSettingsLock) {
6261                 final int ringerModeInternal = getRingerModeInternal();
6262                 final int ringerModeExternal = getRingerModeExternal();
6263                 if (external) {
6264                     setRingerModeExt(ringerMode);
6265                     if (mRingerModeDelegate != null) {
6266                         ringerMode = mRingerModeDelegate.onSetRingerModeExternal(ringerModeExternal,
6267                                 ringerMode, caller, ringerModeInternal, mVolumePolicy);
6268                     }
6269                     if (ringerMode != ringerModeInternal) {
6270                         setRingerModeInt(ringerMode, true /*persist*/);
6271                     }
6272                 } else /*internal*/ {
6273                     if (ringerMode != ringerModeInternal) {
6274                         setRingerModeInt(ringerMode, true /*persist*/);
6275                     }
6276                     if (mRingerModeDelegate != null) {
6277                         ringerMode = mRingerModeDelegate.onSetRingerModeInternal(ringerModeInternal,
6278                                 ringerMode, caller, ringerModeExternal, mVolumePolicy);
6279                     }
6280                     setRingerModeExt(ringerMode);
6281                 }
6282             }
6283         } finally {
6284             Binder.restoreCallingIdentity(identity);
6285         }
6286     }
6287 
setRingerModeExt(int ringerMode)6288     private void setRingerModeExt(int ringerMode) {
6289         synchronized(mSettingsLock) {
6290             if (ringerMode == mRingerModeExternal) return;
6291             mRingerModeExternal = ringerMode;
6292         }
6293         // Send sticky broadcast
6294         broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, ringerMode);
6295     }
6296 
6297     @GuardedBy("mSettingsLock")
muteRingerModeStreams()6298     private void muteRingerModeStreams() {
6299         // Mute stream if not previously muted by ringer mode and (ringer mode
6300         // is not RINGER_MODE_NORMAL OR stream is zen muted) and stream is affected by ringer mode.
6301         // Unmute stream if previously muted by ringer/zen mode and ringer mode
6302         // is RINGER_MODE_NORMAL or stream is not affected by ringer mode.
6303         int numStreamTypes = AudioSystem.getNumStreamTypes();
6304 
6305         if (mNm == null) {
6306             mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
6307         }
6308 
6309         final int ringerMode = mRingerMode; // Read ringer mode as reading primitives is atomic
6310         final boolean ringerModeMute = ringerMode == AudioManager.RINGER_MODE_VIBRATE
6311                 || ringerMode == AudioManager.RINGER_MODE_SILENT;
6312         final boolean shouldRingSco = ringerMode == AudioManager.RINGER_MODE_VIBRATE
6313                 && mBtCommDeviceActive.get() == BT_COMM_DEVICE_ACTIVE_SCO;
6314         final boolean shouldRingBle = ringerMode == AudioManager.RINGER_MODE_VIBRATE
6315                 && (mBtCommDeviceActive.get() == BT_COMM_DEVICE_ACTIVE_BLE_HEADSET
6316                 || mBtCommDeviceActive.get() == BT_COMM_DEVICE_ACTIVE_BLE_SPEAKER);
6317         // Ask audio policy engine to force use Bluetooth SCO/BLE channel if needed
6318         final String eventSource = "muteRingerModeStreams() from u/pid:" + Binder.getCallingUid()
6319                 + "/" + Binder.getCallingPid();
6320         int forceUse = AudioSystem.FORCE_NONE;
6321         if (shouldRingSco) {
6322             forceUse = AudioSystem.FORCE_BT_SCO;
6323         } else if (shouldRingBle) {
6324             forceUse = AudioSystem.FORCE_BT_BLE;
6325         }
6326         sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, AudioSystem.FOR_VIBRATE_RINGING,
6327                 forceUse, eventSource, 0);
6328 
6329         for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
6330             final VolumeStreamState vss = getVssForStream(streamType);
6331             if (vss == null) {
6332                 continue;
6333             }
6334             final boolean isMuted = isStreamMutedByRingerOrZenMode(streamType);
6335             final boolean muteAllowedBySco =
6336                     !((shouldRingSco || shouldRingBle) && streamType == AudioSystem.STREAM_RING);
6337             final boolean shouldZenMute = isStreamAffectedByCurrentZen(streamType);
6338             final boolean shouldMute = shouldZenMute || (ringerModeMute
6339                     && isStreamAffectedByRingerMode(streamType) && muteAllowedBySco);
6340             if (isMuted == shouldMute) continue;
6341             if (!shouldMute) {
6342                 // unmute
6343                 // ring and notifications volume should never be 0 when not silenced
6344                 if (sStreamVolumeAlias.get(streamType) == AudioSystem.STREAM_RING
6345                         || sStreamVolumeAlias.get(streamType) == AudioSystem.STREAM_NOTIFICATION) {
6346                     synchronized (mVolumeStateLock) {
6347                         for (int i = 0; i < vss.mIndexMap.size(); i++) {
6348                             int device = vss.mIndexMap.keyAt(i);
6349                             int value = vss.mIndexMap.valueAt(i);
6350                             if (value == 0) {
6351                                 vss.setIndex(10, device, TAG, true /*hasModifyAudioSettings*/);
6352                             }
6353                         }
6354                         // Persist volume for stream ring when it is changed here
6355                       final int device = getDeviceForStream(streamType);
6356                       sendMsg(mAudioHandler,
6357                               MSG_PERSIST_VOLUME,
6358                               SENDMSG_QUEUE,
6359                               device,
6360                               0,
6361                               vss,
6362                               PERSIST_DELAY);
6363                     }
6364                 }
6365                 sRingerAndZenModeMutedStreams &= ~(1 << streamType);
6366                 vss.mute(false, "muteRingerModeStreams");
6367             } else {
6368                 // mute
6369                 sRingerAndZenModeMutedStreams |= (1 << streamType);
6370                 vss.mute(true, "muteRingerModeStreams");
6371             }
6372         }
6373         sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent(
6374                 sRingerAndZenModeMutedStreams, "muteRingerModeStreams"));
6375     }
6376 
isAlarm(int streamType)6377     private boolean isAlarm(int streamType) {
6378         return streamType == AudioSystem.STREAM_ALARM;
6379     }
6380 
isNotificationOrRinger(int streamType)6381     private boolean isNotificationOrRinger(int streamType) {
6382         return streamType == AudioSystem.STREAM_NOTIFICATION
6383                 || streamType == AudioSystem.STREAM_RING;
6384     }
6385 
isMedia(int streamType)6386     private boolean isMedia(int streamType) {
6387         return streamType == AudioSystem.STREAM_MUSIC;
6388     }
6389 
6390 
isSystem(int streamType)6391     private boolean isSystem(int streamType) {
6392         return streamType == AudioSystem.STREAM_SYSTEM;
6393     }
6394 
setRingerModeInt(int ringerMode, boolean persist)6395     private void setRingerModeInt(int ringerMode, boolean persist) {
6396         final boolean change;
6397         synchronized(mSettingsLock) {
6398             change = mRingerMode != ringerMode;
6399             mRingerMode = ringerMode;
6400             muteRingerModeStreams();
6401         }
6402 
6403         // Post a persist ringer mode msg
6404         if (persist) {
6405             sendMsg(mAudioHandler, MSG_PERSIST_RINGER_MODE,
6406                     SENDMSG_REPLACE, 0, 0, null, PERSIST_DELAY);
6407         }
6408         if (change) {
6409             // Send sticky broadcast
6410             broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, ringerMode);
6411         }
6412     }
6413 
postUpdateRingerModeServiceInt()6414     /*package*/ void postUpdateRingerModeServiceInt() {
6415         sendMsg(mAudioHandler, MSG_UPDATE_RINGER_MODE, SENDMSG_QUEUE, 0, 0, null, 0);
6416     }
6417 
onUpdateRingerModeServiceInt()6418     private void onUpdateRingerModeServiceInt() {
6419         setRingerModeInt(getRingerModeInternal(), false);
6420     }
6421 
6422     /** @see AudioManager#shouldVibrate(int) */
shouldVibrate(int vibrateType)6423     public boolean shouldVibrate(int vibrateType) {
6424         if (!mHasVibrator) return false;
6425 
6426         switch (getVibrateSetting(vibrateType)) {
6427 
6428             case AudioManager.VIBRATE_SETTING_ON:
6429                 return getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT;
6430 
6431             case AudioManager.VIBRATE_SETTING_ONLY_SILENT:
6432                 return getRingerModeExternal() == AudioManager.RINGER_MODE_VIBRATE;
6433 
6434             case AudioManager.VIBRATE_SETTING_OFF:
6435                 // return false, even for incoming calls
6436                 return false;
6437 
6438             default:
6439                 return false;
6440         }
6441     }
6442 
6443     /** @see AudioManager#getVibrateSetting(int) */
getVibrateSetting(int vibrateType)6444     public int getVibrateSetting(int vibrateType) {
6445         if (!mHasVibrator) return AudioManager.VIBRATE_SETTING_OFF;
6446         return (mVibrateSetting >> (vibrateType * 2)) & 3;
6447     }
6448 
6449     /** @see AudioManager#setVibrateSetting(int, int) */
setVibrateSetting(int vibrateType, int vibrateSetting)6450     public void setVibrateSetting(int vibrateType, int vibrateSetting) {
6451 
6452         if (!mHasVibrator) return;
6453 
6454         mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, vibrateType,
6455                 vibrateSetting);
6456 
6457         // Broadcast change
6458         broadcastVibrateSetting(vibrateType);
6459 
6460     }
6461 
6462     private class SetModeDeathHandler implements IBinder.DeathRecipient {
6463         private final IBinder mCb; // To be notified of client's death
6464         private final int mPid;
6465         private final int mUid;
6466         private final boolean mIsPrivileged;
6467         private final String mPackage;
6468         private int mMode;
6469         private long mUpdateTime;
6470         private boolean mPlaybackActive = false;
6471         private boolean mRecordingActive = false;
6472 
SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged, String caller, int mode)6473         SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged,
6474                             String caller, int mode) {
6475             mMode = mode;
6476             mCb = cb;
6477             mPid = pid;
6478             mUid = uid;
6479             mPackage = caller;
6480             mIsPrivileged = isPrivileged;
6481             mUpdateTime = java.lang.System.currentTimeMillis();
6482         }
6483 
binderDied()6484         public void binderDied() {
6485             synchronized (mDeviceBroker.mSetModeLock) {
6486                 Log.w(TAG, "SetModeDeathHandler client died");
6487                 int index = mSetModeDeathHandlers.indexOf(this);
6488                 if (index < 0) {
6489                     Log.w(TAG, "unregistered SetModeDeathHandler client died");
6490                 } else {
6491                     SetModeDeathHandler h = mSetModeDeathHandlers.get(index);
6492                     mSetModeDeathHandlers.remove(index);
6493                     postUpdateAudioMode(SENDMSG_QUEUE, AudioSystem.MODE_CURRENT,
6494                             android.os.Process.myPid(), mContext.getPackageName(),
6495                             false /*signal*/, 0);
6496                 }
6497             }
6498         }
6499 
getPid()6500         public int getPid() {
6501             return mPid;
6502         }
6503 
setMode(int mode)6504         public void setMode(int mode) {
6505             mMode = mode;
6506             mUpdateTime = java.lang.System.currentTimeMillis();
6507         }
6508 
getMode()6509         public int getMode() {
6510             return mMode;
6511         }
6512 
getBinder()6513         public IBinder getBinder() {
6514             return mCb;
6515         }
6516 
getUid()6517         public int getUid() {
6518             return mUid;
6519         }
6520 
getPackage()6521         public String getPackage() {
6522             return mPackage;
6523         }
6524 
isPrivileged()6525         public boolean isPrivileged() {
6526             return mIsPrivileged;
6527         }
6528 
getUpdateTime()6529         public long getUpdateTime() {
6530             return mUpdateTime;
6531         }
6532 
setPlaybackActive(boolean active)6533         public void setPlaybackActive(boolean active) {
6534             mPlaybackActive = active;
6535         }
6536 
setRecordingActive(boolean active)6537         public void setRecordingActive(boolean active) {
6538             mRecordingActive = active;
6539         }
6540 
6541         /**
6542          * An app is considered active if:
6543          * - It is privileged (has MODIFY_PHONE_STATE permission)
6544          *  or
6545          * - It requests mode MODE_IN_COMMUNICATION, and it is either playing
6546          * or recording for VOICE_COMMUNICATION.
6547          *   or
6548          * - It requests a mode different from MODE_IN_COMMUNICATION or MODE_NORMAL
6549          * Note: only privileged apps can request MODE_IN_CALL, MODE_CALL_REDIRECT
6550          * or MODE_COMMUNICATION_REDIRECT.
6551          */
isActive()6552         public boolean isActive() {
6553             return mIsPrivileged
6554                     || ((mMode == AudioSystem.MODE_IN_COMMUNICATION)
6555                         && (mRecordingActive || mPlaybackActive))
6556                     || mMode == AudioSystem.MODE_RINGTONE
6557                     || mMode == AudioSystem.MODE_CALL_SCREENING;
6558         }
6559 
dump(PrintWriter pw, int index)6560         public void dump(PrintWriter pw, int index) {
6561             SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm:ss:SSS");
6562 
6563             if (index >= 0) {
6564                 pw.println("  Requester # " + (index + 1) + ":");
6565             }
6566             pw.println("  - Mode: " + AudioSystem.modeToString(mMode));
6567             pw.println("  - Binder: " + mCb);
6568             pw.println("  - Pid: " + mPid);
6569             pw.println("  - Uid: " + mUid);
6570             pw.println("  - Package: " + mPackage);
6571             pw.println("  - Privileged: " + mIsPrivileged);
6572             pw.println("  - Active: " + isActive());
6573             pw.println("    Playback active: " + mPlaybackActive);
6574             pw.println("    Recording active: " + mRecordingActive);
6575             pw.println("  - update time: " + format.format(new Date(mUpdateTime)));
6576         }
6577     }
6578 
6579     @GuardedBy("mDeviceBroker.mSetModeLock")
getAudioModeOwnerHandler()6580     private SetModeDeathHandler getAudioModeOwnerHandler() {
6581         // The Audio mode owner is:
6582         // 1) the most recent privileged app in the stack
6583         // 2) the most recent active app in the tack
6584         SetModeDeathHandler modeOwner = null;
6585         SetModeDeathHandler privilegedModeOwner = null;
6586         for (SetModeDeathHandler h : mSetModeDeathHandlers) {
6587             if (h.isActive()) {
6588                 // privileged apps are always active
6589                 if (h.isPrivileged()) {
6590                     if (privilegedModeOwner == null
6591                             || h.getUpdateTime() > privilegedModeOwner.getUpdateTime()) {
6592                         privilegedModeOwner = h;
6593                     }
6594                 } else {
6595                     if (modeOwner == null
6596                             || h.getUpdateTime() > modeOwner.getUpdateTime()) {
6597                         modeOwner = h;
6598                     }
6599                 }
6600             }
6601         }
6602         return privilegedModeOwner != null ? privilegedModeOwner :  modeOwner;
6603     }
6604 
6605     /**
6606      * Return information on the current audio mode owner
6607      * @return 0 if nobody owns the mode
6608      */
6609     @GuardedBy("mDeviceBroker.mSetModeLock")
getAudioModeOwner()6610     /*package*/ AudioDeviceBroker.AudioModeInfo getAudioModeOwner() {
6611         SetModeDeathHandler hdlr = getAudioModeOwnerHandler();
6612         if (hdlr != null) {
6613             return new AudioDeviceBroker.AudioModeInfo(
6614                     hdlr.getMode(), hdlr.getPid(), hdlr.getUid());
6615         }
6616         return new AudioDeviceBroker.AudioModeInfo(AudioSystem.MODE_NORMAL, 0 , 0);
6617     }
6618 
6619     /**
6620      * Return the uid of the current audio mode owner
6621      * @return 0 if nobody owns the mode
6622      */
6623     @GuardedBy("mDeviceBroker.mSetModeLock")
getModeOwnerUid()6624     /*package*/ int getModeOwnerUid() {
6625         SetModeDeathHandler hdlr = getAudioModeOwnerHandler();
6626         if (hdlr != null) {
6627             return hdlr.getUid();
6628         }
6629         return 0;
6630     }
6631 
6632     /** @see AudioManager#setMode(int) */
setMode(int mode, IBinder cb, String callingPackage)6633     public void setMode(int mode, IBinder cb, String callingPackage) {
6634         int pid = Binder.getCallingPid();
6635         int uid = Binder.getCallingUid();
6636         if (DEBUG_MODE) {
6637             Log.v(TAG, "setMode(mode=" + mode + ", pid=" + pid
6638                     + ", uid=" + uid + ", caller=" + callingPackage + ")");
6639         }
6640         if (!checkAudioSettingsPermission("setMode()")) {
6641             return;
6642         }
6643         if (cb == null) {
6644             Log.e(TAG, "setMode() called with null binder");
6645             return;
6646         }
6647         if (mode < AudioSystem.MODE_CURRENT || mode >= AudioSystem.NUM_MODES) {
6648             Log.w(TAG, "setMode() invalid mode: " + mode);
6649             return;
6650         }
6651 
6652         if (mode == AudioSystem.MODE_CURRENT) {
6653             mode = getMode();
6654         }
6655 
6656         if (mode == AudioSystem.MODE_CALL_SCREENING && !mIsCallScreeningModeSupported) {
6657             Log.w(TAG, "setMode(MODE_CALL_SCREENING) not permitted "
6658                     + "when call screening is not supported");
6659             return;
6660         }
6661 
6662         final boolean hasModifyPhoneStatePermission = mContext.checkCallingOrSelfPermission(
6663                 MODIFY_PHONE_STATE)
6664                 == PackageManager.PERMISSION_GRANTED;
6665         if ((mode == AudioSystem.MODE_IN_CALL
6666                 || mode == AudioSystem.MODE_CALL_REDIRECT
6667                 || mode == AudioSystem.MODE_COMMUNICATION_REDIRECT)
6668                 && !hasModifyPhoneStatePermission) {
6669             Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setMode("
6670                     + AudioSystem.modeToString(mode) + ") from pid=" + pid
6671                     + ", uid=" + Binder.getCallingUid());
6672             return;
6673         }
6674 
6675         SetModeDeathHandler currentModeHandler = null;
6676         synchronized (mDeviceBroker.mSetModeLock) {
6677             for (SetModeDeathHandler h : mSetModeDeathHandlers) {
6678                 if (h.getPid() == pid) {
6679                     currentModeHandler = h;
6680                     break;
6681                 }
6682             }
6683 
6684             if (mode == AudioSystem.MODE_NORMAL) {
6685                 if (currentModeHandler != null) {
6686                     if (!currentModeHandler.isPrivileged()
6687                             && currentModeHandler.getMode() == AudioSystem.MODE_IN_COMMUNICATION) {
6688                         mAudioHandler.removeEqualMessages(
6689                                 MSG_CHECK_MODE_FOR_UID, currentModeHandler);
6690                     }
6691                     mSetModeDeathHandlers.remove(currentModeHandler);
6692                     if (DEBUG_MODE) {
6693                         Log.v(TAG, "setMode(" + mode + ") removing hldr for pid: " + pid);
6694                     }
6695                     try {
6696                         currentModeHandler.getBinder().unlinkToDeath(currentModeHandler, 0);
6697                     } catch (NoSuchElementException e) {
6698                         Log.w(TAG, "setMode link does not exist ...");
6699                     }
6700                 }
6701             } else {
6702                 if (currentModeHandler != null) {
6703                     currentModeHandler.setMode(mode);
6704                     if (DEBUG_MODE) {
6705                         Log.v(TAG, "setMode(" + mode + ") updating hldr for pid: " + pid);
6706                     }
6707                 } else {
6708                     currentModeHandler = new SetModeDeathHandler(cb, pid, uid,
6709                             hasModifyPhoneStatePermission, callingPackage, mode);
6710                     // Register for client death notification
6711                     try {
6712                         cb.linkToDeath(currentModeHandler, 0);
6713                     } catch (RemoteException e) {
6714                         // Client has died!
6715                         Log.w(TAG, "setMode() could not link to " + cb + " binder death");
6716                         return;
6717                     }
6718                     mSetModeDeathHandlers.add(currentModeHandler);
6719                     if (DEBUG_MODE) {
6720                         Log.v(TAG, "setMode(" + mode + ") adding handler for pid=" + pid);
6721                     }
6722                 }
6723                 if (mode == AudioSystem.MODE_IN_COMMUNICATION) {
6724                     // Force active state when entering/updating the stack to avoid glitches when
6725                     // an app starts playing/recording after settng the audio mode,
6726                     // and send a reminder to check activity after a grace period.
6727                     if (!currentModeHandler.isPrivileged()) {
6728                         currentModeHandler.setPlaybackActive(true);
6729                         currentModeHandler.setRecordingActive(true);
6730                         sendMsg(mAudioHandler,
6731                                 MSG_CHECK_MODE_FOR_UID,
6732                                 SENDMSG_QUEUE,
6733                                 0,
6734                                 0,
6735                                 currentModeHandler,
6736                                 CHECK_MODE_FOR_UID_PERIOD_MS);
6737                     }
6738                 }
6739             }
6740 
6741             postUpdateAudioMode(SENDMSG_REPLACE, mode, pid, callingPackage,
6742                     hasModifyPhoneStatePermission && mode == AudioSystem.MODE_NORMAL, 0);
6743         }
6744     }
6745 
6746     @GuardedBy("mDeviceBroker.mSetModeLock")
onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage, boolean force, boolean signal)6747     void onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage,
6748                            boolean force, boolean signal) {
6749         if (requestedMode == AudioSystem.MODE_CURRENT) {
6750             requestedMode = getMode();
6751         }
6752         int mode = AudioSystem.MODE_NORMAL;
6753         int uid = 0;
6754         int pid = 0;
6755         SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler();
6756         if (currentModeHandler != null) {
6757             mode = currentModeHandler.getMode();
6758             uid = currentModeHandler.getUid();
6759             pid = currentModeHandler.getPid();
6760         }
6761         if (DEBUG_MODE) {
6762             Log.v(TAG, "onUpdateAudioMode() new mode: " + mode + ", current mode: "
6763                     + mMode.get() + " requested mode: " + requestedMode + " signal: " + signal);
6764         }
6765         if (mode != mMode.get() || force) {
6766             int status = AudioSystem.SUCCESS;
6767             final long identity = Binder.clearCallingIdentity();
6768             try {
6769                 status = mAudioSystem.setPhoneState(mode, uid);
6770             } finally {
6771                 Binder.restoreCallingIdentity(identity);
6772             }
6773             if (status == AudioSystem.AUDIO_STATUS_OK) {
6774                 if (DEBUG_MODE) {
6775                     Log.v(TAG, "onUpdateAudioMode: mode successfully set to " + mode);
6776                 }
6777                 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_MODE, SENDMSG_REPLACE, mode, 0,
6778                         /*obj*/ null, /*delay*/ 0);
6779                 int previousMode = mMode.getAndSet(mode);
6780                 // Note: newModeOwnerPid is always 0 when actualMode is MODE_NORMAL
6781                 mModeLogger.enqueue(new PhoneStateEvent(requesterPackage, requesterPid,
6782                         requestedMode, pid, mode));
6783 
6784                 final int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
6785                 final int device = getDeviceForStream(streamType);
6786                 final int streamAlias = sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound=*/
6787                         -1);
6788                 if (streamAlias == -1) {
6789                     Log.e(TAG,
6790                             "onUpdateAudioMode: no stream vol alias for stream type " + streamType);
6791                 }
6792 
6793                 if (DEBUG_MODE) {
6794                     Log.v(TAG, "onUpdateAudioMode: streamType=" + streamType
6795                             + ", streamAlias=" + streamAlias);
6796                 }
6797 
6798                 final int index = getVssForStreamOrDefault(streamAlias).getIndex(device);
6799                 setStreamVolumeInt(streamAlias, index, device, true,
6800                         requesterPackage, true /*hasModifyAudioSettings*/);
6801 
6802                 updateStreamVolumeAlias(true /*updateVolumes*/, requesterPackage);
6803 
6804                 // change of mode may require volume to be re-applied on some devices
6805                 onUpdateContextualVolumes();
6806 
6807                 // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all SCO
6808                 // connections not started by the application changing the mode when pid changes
6809                 mDeviceBroker.postSetModeOwner(mode, pid, uid, signal);
6810             } else {
6811                 // reset here to avoid sticky out of sync condition (would have been reset
6812                 // by AudioDeviceBroker processing MSG_L_SET_MODE_OWNER_SIGNAL message)
6813                 resetAudioModeResetCount();
6814                 Log.w(TAG, "onUpdateAudioMode: failed to set audio mode to: " + mode);
6815             }
6816         }
6817     }
6818 
6819     /** @see AudioManager#getMode() */
getMode()6820     public int getMode() {
6821         synchronized (mDeviceBroker.mSetModeLock) {
6822             SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler();
6823             if (currentModeHandler != null) {
6824                 return currentModeHandler.getMode();
6825             }
6826             return AudioSystem.MODE_NORMAL;
6827         }
6828     }
6829 
6830     /** cached value read from audiopolicy manager after initialization. */
6831     private boolean mIsCallScreeningModeSupported = false;
6832 
6833     /** @see AudioManager#isCallScreeningModeSupported() */
isCallScreeningModeSupported()6834     public boolean isCallScreeningModeSupported() {
6835         return mIsCallScreeningModeSupported;
6836     }
6837 
dispatchMode(int mode)6838     protected void dispatchMode(int mode) {
6839         final int nbDispatchers = mModeDispatchers.beginBroadcast();
6840         for (int i = 0; i < nbDispatchers; i++) {
6841             try {
6842                 mModeDispatchers.getBroadcastItem(i).dispatchAudioModeChanged(mode);
6843             } catch (RemoteException e) {
6844             }
6845         }
6846         mModeDispatchers.finishBroadcast();
6847     }
6848 
6849     final RemoteCallbackList<IAudioModeDispatcher> mModeDispatchers =
6850             new RemoteCallbackList<IAudioModeDispatcher>();
6851 
6852     /**
6853      * @see {@link AudioManager#addOnModeChangedListener(Executor, AudioManager.OnModeChangedListener)}
6854      * @param dispatcher
6855      */
registerModeDispatcher( @onNull IAudioModeDispatcher dispatcher)6856     public void registerModeDispatcher(
6857             @NonNull IAudioModeDispatcher dispatcher) {
6858         mModeDispatchers.register(dispatcher);
6859     }
6860 
6861     /**
6862      * @see {@link AudioManager#removeOnModeChangedListener(AudioManager.OnModeChangedListener)}
6863      * @param dispatcher
6864      */
unregisterModeDispatcher( @onNull IAudioModeDispatcher dispatcher)6865     public void unregisterModeDispatcher(
6866             @NonNull IAudioModeDispatcher dispatcher) {
6867         mModeDispatchers.unregister(dispatcher);
6868     }
6869 
6870     @android.annotation.EnforcePermission(CALL_AUDIO_INTERCEPTION)
6871     /** @see AudioManager#isPstnCallAudioInterceptable() */
isPstnCallAudioInterceptable()6872     public boolean isPstnCallAudioInterceptable() {
6873 
6874         super.isPstnCallAudioInterceptable_enforcePermission();
6875 
6876         boolean uplinkDeviceFound = false;
6877         boolean downlinkDeviceFound = false;
6878         AudioDeviceInfo[] devices = AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_ALL);
6879         for (AudioDeviceInfo device : devices) {
6880             if (device.getInternalType() == AudioSystem.DEVICE_OUT_TELEPHONY_TX) {
6881                 uplinkDeviceFound = true;
6882             } else if (device.getInternalType() == AudioSystem.DEVICE_IN_TELEPHONY_RX) {
6883                 downlinkDeviceFound = true;
6884             }
6885             if (uplinkDeviceFound && downlinkDeviceFound) {
6886                 return true;
6887             }
6888         }
6889         return false;
6890     }
6891 
6892     /** @see AudioManager#setRttEnabled(boolean)  */
6893     @Override
setRttEnabled(boolean rttEnabled)6894     public void setRttEnabled(boolean rttEnabled) {
6895         if (mContext.checkCallingOrSelfPermission(
6896                 MODIFY_PHONE_STATE)
6897                 != PackageManager.PERMISSION_GRANTED) {
6898             Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setRttEnabled from pid="
6899                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
6900             return;
6901         }
6902         synchronized (this) {
6903             mRttEnabled.set(rttEnabled);
6904             final long identity = Binder.clearCallingIdentity();
6905             try {
6906                 AudioSystem.setRttEnabled(rttEnabled);
6907             } finally {
6908                 Binder.restoreCallingIdentity(identity);
6909             }
6910         }
6911     }
6912 
6913     @VisibleForTesting(visibility = PACKAGE)
isRttEnabled()6914     protected boolean isRttEnabled() {
6915         return mRttEnabled.get();
6916     }
6917 
6918     /** @see AudioManager#adjustSuggestedStreamVolumeForUid(int, int, int, String, int, int, int) */
6919     @Override
adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6920     public void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags,
6921             @NonNull String packageName, int uid, int pid, UserHandle userHandle,
6922             int targetSdkVersion) {
6923         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
6924             throw new SecurityException("Should only be called from system process");
6925         }
6926 
6927         // direction and stream type swap here because the public
6928         // adjustSuggested has a different order than the other methods.
6929         adjustSuggestedStreamVolume(direction, streamType, flags, packageName, packageName,
6930                 uid, pid, hasAudioSettingsPermission(uid, pid),
6931                 AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
6932     }
6933 
6934     /** @see AudioManager#adjustStreamVolumeForUid(int, int, int, String, int, int, int) */
6935     @Override
adjustStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6936     public void adjustStreamVolumeForUid(int streamType, int direction, int flags,
6937             @NonNull String packageName, int uid, int pid, UserHandle userHandle,
6938             int targetSdkVersion) {
6939         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
6940             throw new SecurityException("Should only be called from system process");
6941         }
6942 
6943         if (direction != AudioManager.ADJUST_SAME) {
6944             sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_ADJUST_VOL_UID, streamType,
6945                     direction/*val1*/, flags/*val2*/,
6946                     new StringBuilder(packageName).append(" uid:").append(uid)
6947                     .toString()));
6948         }
6949 
6950         adjustStreamVolume(streamType, direction, flags, packageName, packageName, uid, pid,
6951                 null, hasAudioSettingsPermission(uid, pid),
6952                 AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
6953     }
6954 
6955     /**
6956       * @see AudioManager#adjustVolume(int, int)
6957       * This method is redirected from AudioManager to AudioService for API hardening rules
6958       * enforcement then to MediaSession for implementation.
6959       */
6960     @Override
adjustVolume(int direction, int flags)6961     public void adjustVolume(int direction, int flags) {
6962         if (mHardeningEnforcer.blockVolumeMethod(
6963                 HardeningEnforcer.METHOD_AUDIO_MANAGER_ADJUST_VOLUME,
6964                 getPackageNameForUid(Binder.getCallingUid()),
6965                 Binder.getCallingUid())) {
6966             return;
6967         }
6968         getMediaSessionManager().dispatchAdjustVolume(AudioManager.USE_DEFAULT_STREAM_TYPE,
6969                     direction, flags);
6970     }
6971 
6972     /**
6973      * @see AudioManager#adjustSuggestedStreamVolume(int, int, int)
6974      * This method is redirected from AudioManager to AudioService for API hardening rules
6975      * enforcement then to MediaSession for implementation.
6976      */
6977     @Override
adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags)6978     public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags) {
6979         if (mHardeningEnforcer.blockVolumeMethod(
6980                 HardeningEnforcer.METHOD_AUDIO_MANAGER_ADJUST_SUGGESTED_STREAM_VOLUME,
6981                 getPackageNameForUid(Binder.getCallingUid()),
6982                 Binder.getCallingUid())) {
6983             return;
6984         }
6985         getMediaSessionManager().dispatchAdjustVolume(suggestedStreamType, direction, flags);
6986     }
6987 
6988     /** @see AudioManager#setStreamVolumeForUid(int, int, int, String, int, int, int) */
6989     @Override
setStreamVolumeForUid(int streamType, int index, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6990     public void setStreamVolumeForUid(int streamType, int index, int flags,
6991             @NonNull String packageName, int uid, int pid, UserHandle userHandle,
6992             int targetSdkVersion) {
6993         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
6994             throw new SecurityException("Should only be called from system process");
6995         }
6996 
6997         setStreamVolume(streamType, index, flags, /*device*/ null,
6998                 packageName, packageName, null, uid,
6999                 hasAudioSettingsPermission(uid, pid),
7000                 true /*canChangeMuteAndUpdateController*/);
7001     }
7002 
7003     //==========================================================================================
7004     // Sound Effects
7005     //==========================================================================================
7006     private static final class LoadSoundEffectReply
7007             implements SoundEffectsHelper.OnEffectsLoadCompleteHandler {
7008         private static final int SOUND_EFFECTS_LOADING = 1;
7009         private static final int SOUND_EFFECTS_LOADED = 0;
7010         private static final int SOUND_EFFECTS_ERROR = -1;
7011         private static final int SOUND_EFFECTS_LOAD_TIMEOUT_MS = 5000;
7012 
7013         private int mStatus = SOUND_EFFECTS_LOADING;
7014 
7015         @Override
run(boolean success)7016         public synchronized void run(boolean success) {
7017             mStatus = success ? SOUND_EFFECTS_LOADED : SOUND_EFFECTS_ERROR;
7018             notify();
7019         }
7020 
waitForLoaded(int attempts)7021         public synchronized boolean waitForLoaded(int attempts) {
7022             while ((mStatus == SOUND_EFFECTS_LOADING) && (attempts-- > 0)) {
7023                 try {
7024                     wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS);
7025                 } catch (InterruptedException e) {
7026                     Log.w(TAG, "Interrupted while waiting sound pool loaded.");
7027                 }
7028             }
7029             return mStatus == SOUND_EFFECTS_LOADED;
7030         }
7031     }
7032 
7033     /** @see AudioManager#playSoundEffect(int, int) */
playSoundEffect(int effectType, int userId)7034     public void playSoundEffect(int effectType, int userId) {
7035         if (querySoundEffectsEnabled(userId)) {
7036             playSoundEffectVolume(effectType, -1.0f);
7037         }
7038     }
7039 
7040     /**
7041      * Settings has an in memory cache, so this is fast.
7042      */
querySoundEffectsEnabled(int user)7043     private boolean querySoundEffectsEnabled(int user) {
7044         return mSettings.getSystemIntForUser(getContentResolver(),
7045                 Settings.System.SOUND_EFFECTS_ENABLED, 0, user) != 0;
7046     }
7047 
7048     /** @see AudioManager#playSoundEffect(int, float) */
playSoundEffectVolume(int effectType, float volume)7049     public void playSoundEffectVolume(int effectType, float volume) {
7050         // do not try to play the sound effect if the system stream is muted
7051         if (isStreamMute(STREAM_SYSTEM)) {
7052             return;
7053         }
7054 
7055         if (effectType >= AudioManager.NUM_SOUND_EFFECTS || effectType < 0) {
7056             Log.w(TAG, "AudioService effectType value " + effectType + " out of range");
7057             return;
7058         }
7059 
7060         sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SENDMSG_QUEUE,
7061                 effectType, (int) (volume * 1000), null, 0);
7062     }
7063 
7064     /**
7065      * Loads samples into the soundpool.
7066      * This method must be called at first when sound effects are enabled
7067      */
loadSoundEffects()7068     public boolean loadSoundEffects() {
7069         LoadSoundEffectReply reply = new LoadSoundEffectReply();
7070         sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, reply, 0);
7071         return reply.waitForLoaded(3 /*attempts*/);
7072     }
7073 
7074     /**
7075      * Schedule loading samples into the soundpool.
7076      * This method can be overridden to schedule loading at a later time.
7077      */
scheduleLoadSoundEffects()7078     protected void scheduleLoadSoundEffects() {
7079         sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0);
7080     }
7081 
7082     /**
7083      *  Unloads samples from the sound pool.
7084      *  This method can be called to free some memory when
7085      *  sound effects are disabled.
7086      */
unloadSoundEffects()7087     public void unloadSoundEffects() {
7088         sendMsg(mAudioHandler, MSG_UNLOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0);
7089     }
7090 
7091     /** @see AudioManager#reloadAudioSettings() */
reloadAudioSettings()7092     public void reloadAudioSettings() {
7093         readAudioSettings(false /*userSwitch*/);
7094     }
7095 
readAudioSettings(boolean userSwitch)7096     private void readAudioSettings(boolean userSwitch) {
7097         // restore ringer mode, ringer mode affected streams, mute affected streams and vibrate settings
7098         readPersistedSettings();
7099         readUserRestrictions();
7100 
7101         // restore volume settings
7102         int numStreamTypes = AudioSystem.getNumStreamTypes();
7103         for (int streamType = 0; streamType < numStreamTypes; streamType++) {
7104             final VolumeStreamState streamState = getVssForStream(streamType);
7105 
7106             if (streamState == null) {
7107                 continue;
7108             }
7109 
7110             if (userSwitch && sStreamVolumeAlias.get(streamType) == AudioSystem.STREAM_MUSIC) {
7111                 continue;
7112             }
7113 
7114             streamState.readSettings();
7115             synchronized (mVolumeStateLock) {
7116                 // unmute stream that was muted but is not affect by mute anymore
7117                 if (streamState.mIsMuted && ((!isStreamAffectedByMute(streamType) &&
7118                         !isStreamMutedByRingerOrZenMode(streamType)) || mUseFixedVolume)) {
7119                     streamState.mIsMuted = false;
7120                 }
7121             }
7122             if (cacheGetStreamVolume()) {
7123                 if (DEBUG_VOL) {
7124                     Log.d(TAG,
7125                             "Clear volume cache after possibly changing mute in readAudioSettings");
7126                 }
7127                 AudioManager.clearVolumeCache(AudioManager.VOLUME_CACHING_API);
7128             }
7129         }
7130 
7131         readVolumeGroupsSettings(userSwitch);
7132 
7133         // apply new ringer mode before checking volume for alias streams so that streams
7134         // muted by ringer mode have the correct volume
7135         setRingerModeInt(getRingerModeInternal(), false);
7136 
7137         checkAllFixedVolumeDevices();
7138         checkAllAliasStreamVolumes();
7139         checkMuteAffectedStreams();
7140 
7141         mSoundDoseHelper.restoreMusicActiveMs();
7142         mSoundDoseHelper.enforceSafeMediaVolumeIfActive(TAG);
7143 
7144         if (DEBUG_VOL) {
7145             Log.d(TAG, "Restoring device volume behavior");
7146         }
7147         restoreDeviceVolumeBehavior();
7148     }
7149 
7150     /** @see AudioManager#getAvailableCommunicationDevices(int) */
getAvailableCommunicationDeviceIds()7151     public int[] getAvailableCommunicationDeviceIds() {
7152         List<AudioDeviceInfo> commDevices = AudioDeviceBroker.getAvailableCommunicationDevices();
7153         return commDevices.stream().mapToInt(AudioDeviceInfo::getId).toArray();
7154     }
7155 
7156     /**
7157      * @see AudioManager#setCommunicationDevice(int)
7158      * @see AudioManager#clearCommunicationDevice()
7159      */
setCommunicationDevice(IBinder cb, int portId, @NonNull AttributionSource attributionSource)7160     public boolean setCommunicationDevice(IBinder cb, int portId,
7161             @NonNull AttributionSource attributionSource) {
7162         if (attributionSource == null) {
7163             return false;
7164         }
7165         final int uid = attributionSource.getUid();
7166         final int pid = attributionSource.getPid();
7167 
7168         AudioDeviceInfo device = null;
7169         if (portId != 0) {
7170             device = AudioManager.getDeviceForPortId(portId, AudioManager.GET_DEVICES_OUTPUTS);
7171             if (device == null) {
7172                 Log.w(TAG, "setCommunicationDevice: invalid portID " + portId);
7173                 return false;
7174             }
7175             if (!AudioDeviceBroker.isValidCommunicationDevice(device)) {
7176                 if (!device.isSink()) {
7177                     throw new IllegalArgumentException("device must have sink role");
7178                 } else {
7179                     throw new IllegalArgumentException("invalid device type: " + device.getType());
7180                 }
7181             }
7182         }
7183         final String eventSource = new StringBuilder()
7184                 .append(device == null ? "clearCommunicationDevice(" : "setCommunicationDevice(")
7185                 .append(") from u/pid:").append(uid).append("/")
7186                 .append(pid).toString();
7187 
7188         int deviceType = AudioSystem.DEVICE_OUT_DEFAULT;
7189         String deviceAddress = null;
7190         if (device != null) {
7191             deviceType = device.getPort().type();
7192             deviceAddress = device.getAddress();
7193         } else {
7194             AudioDeviceInfo curDevice = mDeviceBroker.getCommunicationDevice();
7195             if (curDevice != null) {
7196                 deviceType = curDevice.getPort().type();
7197                 deviceAddress = curDevice.getAddress();
7198             }
7199         }
7200         // do not log metrics if clearing communication device while no communication device
7201         // was selected
7202         if (deviceType != AudioSystem.DEVICE_OUT_DEFAULT) {
7203             new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
7204                     + MediaMetrics.SEPARATOR + "setCommunicationDevice")
7205                     .set(MediaMetrics.Property.DEVICE,
7206                             AudioSystem.getDeviceName(deviceType))
7207                     .set(MediaMetrics.Property.ADDRESS, deviceAddress)
7208                     .set(MediaMetrics.Property.STATE, device != null
7209                             ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED)
7210                     .record();
7211         }
7212         final boolean isPrivileged = mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE)
7213                 == PackageManager.PERMISSION_GRANTED;
7214         final long ident = Binder.clearCallingIdentity();
7215         try {
7216             return mDeviceBroker.setCommunicationDevice(
7217                     cb, attributionSource, device, isPrivileged, eventSource);
7218         } finally {
7219             Binder.restoreCallingIdentity(ident);
7220         }
7221     }
7222 
7223     /** @see AudioManager#getCommunicationDevice() */
getCommunicationDevice()7224     public int getCommunicationDevice() {
7225         int deviceId = 0;
7226         final long ident = Binder.clearCallingIdentity();
7227         try {
7228             AudioDeviceInfo device = mDeviceBroker.getCommunicationDevice();
7229             deviceId = device != null ? device.getId() : 0;
7230         } finally {
7231             Binder.restoreCallingIdentity(ident);
7232         }
7233         return deviceId;
7234     }
7235 
7236     /** @see AudioManager#addOnCommunicationDeviceChangedListener(
7237      *               Executor, AudioManager.OnCommunicationDeviceChangedListener)
7238      */
registerCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)7239     public void registerCommunicationDeviceDispatcher(
7240             @Nullable ICommunicationDeviceDispatcher dispatcher) {
7241         if (dispatcher == null) {
7242             return;
7243         }
7244         mDeviceBroker.registerCommunicationDeviceDispatcher(dispatcher);
7245     }
7246 
7247     /** @see AudioManager#removeOnCommunicationDeviceChangedListener(
7248      *               AudioManager.OnCommunicationDeviceChangedListener)
7249      */
unregisterCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)7250     public void unregisterCommunicationDeviceDispatcher(
7251             @Nullable ICommunicationDeviceDispatcher dispatcher) {
7252         if (dispatcher == null) {
7253             return;
7254         }
7255         mDeviceBroker.unregisterCommunicationDeviceDispatcher(dispatcher);
7256     }
7257 
7258     /** @see AudioManager#setSpeakerphoneOn(boolean) */
setSpeakerphoneOn(IBinder cb, boolean on, @NonNull AttributionSource attributionSource)7259     public void setSpeakerphoneOn(IBinder cb, boolean on,
7260             @NonNull AttributionSource attributionSource) {
7261         if (attributionSource == null) {
7262             return;
7263         }
7264         if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) {
7265             return;
7266         }
7267         final boolean isPrivileged = mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE)
7268                 == PackageManager.PERMISSION_GRANTED;
7269 
7270         // for logging only
7271         final int uid = attributionSource.getUid();
7272         final int pid = attributionSource.getPid();
7273 
7274         final String eventSource = new StringBuilder("setSpeakerphoneOn(").append(on)
7275                 .append(") from u/pid:").append(uid).append("/")
7276                 .append(pid).toString();
7277         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
7278                 + MediaMetrics.SEPARATOR + "setSpeakerphoneOn")
7279                 .setUid(uid)
7280                 .setPid(pid)
7281                 .set(MediaMetrics.Property.STATE, on
7282                         ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
7283                 .record();
7284 
7285         final long ident = Binder.clearCallingIdentity();
7286         try {
7287             mDeviceBroker.setSpeakerphoneOn(cb, attributionSource, on, isPrivileged, eventSource);
7288         } finally {
7289             Binder.restoreCallingIdentity(ident);
7290         }
7291     }
7292 
7293     /** @see AudioManager#isSpeakerphoneOn() */
isSpeakerphoneOn()7294     public boolean isSpeakerphoneOn() {
7295         return mDeviceBroker.isSpeakerphoneOn();
7296     }
7297 
7298 
7299     /** BT SCO audio state seen by apps using the deprecated API setBluetoothScoOn().
7300      * @see isBluetoothScoOn() */
7301     private boolean mBtScoOnByApp;
7302 
7303     /** @see AudioManager#setBluetoothScoOn(boolean) */
setBluetoothScoOn(boolean on)7304     public void setBluetoothScoOn(boolean on) {
7305         if (!checkAudioSettingsPermission("setBluetoothScoOn()")) {
7306             return;
7307         }
7308 
7309         // Only enable calls from system components
7310         if (UserHandle.getCallingAppId() >= FIRST_APPLICATION_UID) {
7311             mBtScoOnByApp = on;
7312             return;
7313         }
7314 
7315         // for logging only
7316         final int uid = Binder.getCallingUid();
7317         final int pid = Binder.getCallingPid();
7318         final String eventSource = new StringBuilder("setBluetoothScoOn(").append(on)
7319                 .append(") from u/pid:").append(uid).append("/").append(pid).toString();
7320 
7321         //bt sco
7322         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
7323                 + MediaMetrics.SEPARATOR + "setBluetoothScoOn")
7324                 .setUid(uid)
7325                 .setPid(pid)
7326                 .set(MediaMetrics.Property.STATE, on
7327                         ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
7328                 .record();
7329 
7330         mDeviceBroker.setBluetoothScoOn(on, eventSource);
7331     }
7332 
7333     /** @see AudioManager#setA2dpSuspended(boolean) */
7334     @android.annotation.EnforcePermission(BLUETOOTH_STACK)
setA2dpSuspended(boolean enable)7335     public void setA2dpSuspended(boolean enable) {
7336         super.setA2dpSuspended_enforcePermission();
7337         final String eventSource = new StringBuilder("setA2dpSuspended(").append(enable)
7338                 .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
7339                 .append(Binder.getCallingPid()).toString();
7340         mDeviceBroker.setA2dpSuspended(enable, false /*internal*/, eventSource);
7341     }
7342 
7343     /** @see AudioManager#setA2dpSuspended(boolean) */
7344     @android.annotation.EnforcePermission(BLUETOOTH_STACK)
setLeAudioSuspended(boolean enable)7345     public void setLeAudioSuspended(boolean enable) {
7346         super.setLeAudioSuspended_enforcePermission();
7347         final String eventSource = new StringBuilder("setLeAudioSuspended(").append(enable)
7348                 .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
7349                 .append(Binder.getCallingPid()).toString();
7350         mDeviceBroker.setLeAudioSuspended(enable, false /*internal*/, eventSource);
7351     }
7352 
7353     /** @see AudioManager#isBluetoothScoOn()
7354      * Note that it doesn't report internal state, but state seen by apps (which may have
7355      * called setBluetoothScoOn() */
isBluetoothScoOn()7356     public boolean isBluetoothScoOn() {
7357         return mBtScoOnByApp || mDeviceBroker.isBluetoothScoOn();
7358     }
7359 
7360     // TODO investigate internal users due to deprecation of SDK API
7361     /** @see AudioManager#setBluetoothA2dpOn(boolean) */
setBluetoothA2dpOn(boolean on)7362     public void setBluetoothA2dpOn(boolean on) {
7363         if (!checkAudioSettingsPermission("setBluetoothA2dpOn()")) {
7364             return;
7365         }
7366 
7367         // for logging only
7368         final int uid = Binder.getCallingUid();
7369         final int pid = Binder.getCallingPid();
7370         final String eventSource = new StringBuilder("setBluetoothA2dpOn(").append(on)
7371                 .append(") from u/pid:").append(uid).append("/")
7372                 .append(pid).append(" src:AudioService.setBtA2dpOn").toString();
7373 
7374         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
7375                 + MediaMetrics.SEPARATOR + "setBluetoothA2dpOn")
7376                 .setUid(uid)
7377                 .setPid(pid)
7378                 .set(MediaMetrics.Property.STATE, on
7379                         ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
7380                 .record();
7381 
7382         mDeviceBroker.setBluetoothA2dpOn_Async(on, eventSource);
7383     }
7384 
7385     /** @see AudioManager#isBluetoothA2dpOn() */
isBluetoothA2dpOn()7386     public boolean isBluetoothA2dpOn() {
7387         return mDeviceBroker.isBluetoothA2dpOn();
7388     }
7389 
7390     /** @see AudioManager#startBluetoothSco() */
startBluetoothSco(IBinder cb, int targetSdkVersion, @NonNull AttributionSource attributionSource)7391     public void startBluetoothSco(IBinder cb, int targetSdkVersion,
7392             @NonNull AttributionSource attributionSource) {
7393         if (attributionSource == null) {
7394             return;
7395         }
7396         if (!checkAudioSettingsPermission("startBluetoothSco()")) {
7397             return;
7398         }
7399 
7400         final int uid = attributionSource.getUid();
7401         final int pid = attributionSource.getPid();
7402         final int scoAudioMode =
7403                 (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ?
7404                         BtHelper.SCO_MODE_VIRTUAL_CALL : BtHelper.SCO_MODE_UNDEFINED;
7405         final String eventSource = new StringBuilder("startBluetoothSco()")
7406                 .append(") from u/pid:").append(uid).append("/")
7407                 .append(pid).toString();
7408 
7409         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
7410                 .setUid(uid)
7411                 .setPid(pid)
7412                 .set(MediaMetrics.Property.EVENT, "startBluetoothSco")
7413                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
7414                         BtHelper.scoAudioModeToString(scoAudioMode))
7415                 .record();
7416         startBluetoothScoInt(cb, attributionSource, scoAudioMode, eventSource);
7417 
7418     }
7419 
7420     /** @see AudioManager#startBluetoothScoVirtualCall() */
startBluetoothScoVirtualCall(IBinder cb, @NonNull AttributionSource attributionSource)7421     public void startBluetoothScoVirtualCall(IBinder cb,
7422             @NonNull AttributionSource attributionSource) {
7423         if (attributionSource == null) {
7424             return;
7425         }
7426         if (!checkAudioSettingsPermission("startBluetoothScoVirtualCall()")) {
7427             return;
7428         }
7429 
7430         final int uid = attributionSource.getUid();
7431         final int pid = attributionSource.getPid();
7432         final String eventSource = new StringBuilder("startBluetoothScoVirtualCall()")
7433                 .append(") from u/pid:").append(uid).append("/")
7434                 .append(pid).toString();
7435 
7436         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
7437                 .setUid(uid)
7438                 .setPid(pid)
7439                 .set(MediaMetrics.Property.EVENT, "startBluetoothScoVirtualCall")
7440                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
7441                         BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_VIRTUAL_CALL))
7442                 .record();
7443         startBluetoothScoInt(cb, attributionSource, BtHelper.SCO_MODE_VIRTUAL_CALL, eventSource);
7444     }
7445 
startBluetoothScoInt(IBinder cb, AttributionSource attributionSource, int scoAudioMode, @NonNull String eventSource)7446     void startBluetoothScoInt(IBinder cb, AttributionSource attributionSource,
7447             int scoAudioMode, @NonNull String eventSource) {
7448         MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
7449                 .set(MediaMetrics.Property.EVENT, "startBluetoothScoInt")
7450                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
7451                         BtHelper.scoAudioModeToString(scoAudioMode));
7452 
7453         if (!checkAudioSettingsPermission("startBluetoothSco()") ||
7454                 !mSystemReady) {
7455             mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission or systemReady").record();
7456             return;
7457         }
7458         final boolean isPrivileged = mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE)
7459                 == PackageManager.PERMISSION_GRANTED;
7460         final long ident = Binder.clearCallingIdentity();
7461         try {
7462             mDeviceBroker.startBluetoothScoForClient(
7463                     cb, attributionSource, scoAudioMode, isPrivileged, eventSource);
7464         } finally {
7465             Binder.restoreCallingIdentity(ident);
7466         }
7467         mmi.record();
7468     }
7469 
7470     /** @see AudioManager#stopBluetoothSco() */
stopBluetoothSco(IBinder cb, @NonNull AttributionSource attributionSource)7471     public void stopBluetoothSco(IBinder cb,
7472             @NonNull AttributionSource attributionSource) {
7473         if (attributionSource == null) {
7474             return;
7475         }
7476         if (!checkAudioSettingsPermission("stopBluetoothSco()") ||
7477                 !mSystemReady) {
7478             return;
7479         }
7480         final int uid = attributionSource.getUid();
7481         final int pid = attributionSource.getPid();
7482         final String eventSource =  new StringBuilder("stopBluetoothSco()")
7483                 .append(") from u/pid:").append(uid).append("/")
7484                 .append(pid).toString();
7485         final boolean isPrivileged = mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE)
7486                 == PackageManager.PERMISSION_GRANTED;
7487         final long ident = Binder.clearCallingIdentity();
7488         try {
7489             mDeviceBroker.stopBluetoothScoForClient(
7490                     cb, attributionSource, isPrivileged, eventSource);
7491         } finally {
7492             Binder.restoreCallingIdentity(ident);
7493         }
7494         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
7495                 .setUid(uid)
7496                 .setPid(pid)
7497                 .set(MediaMetrics.Property.EVENT, "stopBluetoothSco")
7498                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
7499                         BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_UNDEFINED))
7500                 .record();
7501     }
7502 
7503 
getContentResolver()7504     /*package*/ ContentResolver getContentResolver() {
7505         return mContentResolver;
7506     }
7507 
7508     @VisibleForTesting(visibility = PACKAGE)
getSettings()7509     public SettingsAdapter getSettings() {
7510         return mSettings;
7511     }
7512 
7513     ///////////////////////////////////////////////////////////////////////////
7514     // Internal methods
7515     ///////////////////////////////////////////////////////////////////////////
7516 
7517     /**
7518      * Checks if the adjustment should change ringer mode instead of just
7519      * adjusting volume. If so, this will set the proper ringer mode and volume
7520      * indices on the stream states.
7521      */
checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted, String caller, int flags)7522     private int checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted,
7523             String caller, int flags) {
7524         int result = FLAG_ADJUST_VOLUME;
7525         if (isPlatformTelevision() || mIsSingleVolume) {
7526             return result;
7527         }
7528 
7529         int ringerMode = getRingerModeInternal();
7530 
7531         switch (ringerMode) {
7532         case RINGER_MODE_NORMAL:
7533             if (direction == AudioManager.ADJUST_LOWER) {
7534                 if (mHasVibrator) {
7535                     // "step" is the delta in internal index units corresponding to a
7536                     // change of 1 in UI index units.
7537                     // Because of rounding when rescaling from one stream index range to its alias
7538                     // index range, we cannot simply test oldIndex == step:
7539                     //   (step <= oldIndex < 2 * step) is equivalent to: (old UI index == 1)
7540                     if (step <= oldIndex && oldIndex < 2 * step) {
7541                         ringerMode = RINGER_MODE_VIBRATE;
7542                         mLoweredFromNormalToVibrateTime = SystemClock.uptimeMillis();
7543                     }
7544                 } else {
7545                     if (oldIndex == step && mVolumePolicy.volumeDownToEnterSilent) {
7546                         ringerMode = RINGER_MODE_SILENT;
7547                     }
7548                 }
7549             }
7550             break;
7551         case RINGER_MODE_VIBRATE:
7552             if (!mHasVibrator) {
7553                 Log.e(TAG, "checkForRingerModeChange() current ringer mode is vibrate" +
7554                         "but no vibrator is present");
7555                 break;
7556             }
7557             if (direction == AudioManager.ADJUST_LOWER) {
7558                 if (mPrevVolDirection != AudioManager.ADJUST_LOWER) {
7559                     if (mVolumePolicy.volumeDownToEnterSilent) {
7560                         final long diff = SystemClock.uptimeMillis()
7561                                 - mLoweredFromNormalToVibrateTime;
7562                         if (diff > mVolumePolicy.vibrateToSilentDebounce
7563                                 && mRingerModeDelegate.canVolumeDownEnterSilent()) {
7564                             ringerMode = RINGER_MODE_SILENT;
7565                         }
7566                     } else {
7567                         result |= AudioManager.FLAG_SHOW_VIBRATE_HINT;
7568                     }
7569                 }
7570             } else if (direction == AudioManager.ADJUST_RAISE
7571                     || direction == AudioManager.ADJUST_TOGGLE_MUTE
7572                     || direction == AudioManager.ADJUST_UNMUTE) {
7573                 ringerMode = RINGER_MODE_NORMAL;
7574             }
7575             result &= ~FLAG_ADJUST_VOLUME;
7576             break;
7577         case RINGER_MODE_SILENT:
7578             if (direction == AudioManager.ADJUST_RAISE
7579                     || direction == AudioManager.ADJUST_TOGGLE_MUTE
7580                     || direction == AudioManager.ADJUST_UNMUTE) {
7581                 if (!mVolumePolicy.volumeUpToExitSilent) {
7582                     result |= AudioManager.FLAG_SHOW_SILENT_HINT;
7583                 } else {
7584                   if (mHasVibrator && direction == AudioManager.ADJUST_RAISE) {
7585                       ringerMode = RINGER_MODE_VIBRATE;
7586                   } else {
7587                       // If we don't have a vibrator or they were toggling mute
7588                       // go straight back to normal.
7589                       ringerMode = RINGER_MODE_NORMAL;
7590                   }
7591                 }
7592             }
7593             result &= ~FLAG_ADJUST_VOLUME;
7594             break;
7595         default:
7596             Log.e(TAG, "checkForRingerModeChange() wrong ringer mode: "+ringerMode);
7597             break;
7598         }
7599 
7600         if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode)
7601                 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)
7602                 && (flags & AudioManager.FLAG_FROM_KEY) == 0) {
7603             throw new SecurityException("Not allowed to change Do Not Disturb state");
7604         }
7605 
7606         setRingerMode(ringerMode, TAG + ".checkForRingerModeChange", false /*external*/);
7607 
7608         mPrevVolDirection = direction;
7609 
7610         return result;
7611     }
7612 
7613     @Override
isStreamAffectedByRingerMode(int streamType)7614     public boolean isStreamAffectedByRingerMode(int streamType) {
7615         streamType = replaceBtScoStreamWithVoiceCall(streamType, "isStreamAffectedByRingerMode");
7616         return (mRingerModeAffectedStreams & (1 << streamType)) != 0;
7617     }
7618 
isStreamAffectedByCurrentZen(int streamType)7619     public boolean isStreamAffectedByCurrentZen(int streamType) {
7620         streamType = replaceBtScoStreamWithVoiceCall(streamType, "isStreamAffectedByCurrentZen");
7621         return (mZenModeAffectedStreams & (1 << streamType)) != 0;
7622     }
7623 
isStreamMutedByRingerOrZenMode(int streamType)7624     private boolean isStreamMutedByRingerOrZenMode(int streamType) {
7625         streamType = replaceBtScoStreamWithVoiceCall(streamType, "isStreamMutedByRingerOrZenMode");
7626         return (sRingerAndZenModeMutedStreams & (1 << streamType)) != 0;
7627     }
7628 
7629     /**
7630      * Volume streams can be muted based on the current DND state:
7631      * DND total silence: ringer, notification, system, media and alarms streams muted by DND
7632      * DND alarms only:  ringer, notification, system streams muted by DND
7633      * DND priority only: alarms, media, system, ringer and notification streams can be muted by
7634      * DND.  The current applied zenPolicy determines which streams will be muted by DND.
7635      * @return true if changed, else false
7636      */
updateZenModeAffectedStreams()7637     private boolean updateZenModeAffectedStreams() {
7638         if (!mSystemReady) {
7639             return false;
7640         }
7641 
7642         // If DND is off, no streams are muted by DND
7643         int zenModeAffectedStreams = 0;
7644         final int zenMode = mNm.getZenMode();
7645 
7646         if (zenMode == Settings.Global.ZEN_MODE_NO_INTERRUPTIONS) {
7647             zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM;
7648             zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION;
7649             zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING;
7650             zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM;
7651             zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC;
7652         } else if (zenMode == Settings.Global.ZEN_MODE_ALARMS) {
7653             zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM;
7654             zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION;
7655             zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING;
7656         } else if (zenMode == Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
7657             NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy();
7658             if ((zenPolicy.priorityCategories
7659                     & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0) {
7660                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM;
7661             }
7662 
7663             if ((zenPolicy.priorityCategories
7664                     & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0) {
7665                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC;
7666             }
7667 
7668             // even if zen isn't muting the system stream, the ringer mode can still mute
7669             // the system stream
7670             if ((zenPolicy.priorityCategories
7671                     & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0) {
7672                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM;
7673             }
7674 
7675             if (ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(zenPolicy)) {
7676                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION;
7677                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING;
7678             }
7679         }
7680 
7681         if (mZenModeAffectedStreams != zenModeAffectedStreams) {
7682             mZenModeAffectedStreams = zenModeAffectedStreams;
7683             return true;
7684         }
7685 
7686         return false;
7687     }
7688 
7689     @GuardedBy("mSettingsLock")
updateRingerAndZenModeAffectedStreams()7690     private boolean updateRingerAndZenModeAffectedStreams() {
7691         boolean updatedZenModeAffectedStreams = updateZenModeAffectedStreams();
7692         int ringerModeAffectedStreams = mSettings.getSystemIntForUser(mContentResolver,
7693                 Settings.System.MODE_RINGER_STREAMS_AFFECTED,
7694                 ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
7695                  (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)),
7696                  UserHandle.USER_CURRENT);
7697         if (mIsSingleVolume) {
7698             ringerModeAffectedStreams = 0;
7699         } else if (mRingerModeDelegate != null) {
7700             ringerModeAffectedStreams = mRingerModeDelegate
7701                     .getRingerModeAffectedStreams(ringerModeAffectedStreams);
7702         }
7703         if (mCameraSoundForced.get()) {
7704             ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
7705         } else {
7706             ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
7707         }
7708         if (sStreamVolumeAlias.get(AudioSystem.STREAM_DTMF) == AudioSystem.STREAM_RING) {
7709             ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF);
7710         } else {
7711             ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF);
7712         }
7713 
7714         if (ringerModeAffectsAlarm()) {
7715             if (mRingerModeAffectsAlarm) {
7716                 boolean muteAlarmWithRinger =
7717                         mSettings.getGlobalInt(mContentResolver,
7718                         Settings.Global.MUTE_ALARM_STREAM_WITH_RINGER_MODE,
7719                         /* def= */ 0) != 0;
7720                 if (muteAlarmWithRinger) {
7721                     ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_ALARM);
7722                 } else {
7723                     ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_ALARM);
7724                 }
7725             }
7726         }
7727         if (ringerModeAffectedStreams != mRingerModeAffectedStreams) {
7728             mSettings.putSystemIntForUser(mContentResolver,
7729                     Settings.System.MODE_RINGER_STREAMS_AFFECTED,
7730                     ringerModeAffectedStreams,
7731                     UserHandle.USER_CURRENT);
7732             mRingerModeAffectedStreams = ringerModeAffectedStreams;
7733             return true;
7734         }
7735         return updatedZenModeAffectedStreams;
7736     }
7737 
7738     @Override
isStreamAffectedByMute(int streamType)7739     public boolean isStreamAffectedByMute(int streamType) {
7740         streamType = replaceBtScoStreamWithVoiceCall(streamType, "isStreamAffectedByMute");
7741         return (mMuteAffectedStreams & (1 << streamType)) != 0;
7742     }
7743 
7744     @Override
isStreamMutableByUi(int streamType)7745     public boolean isStreamMutableByUi(int streamType) {
7746         return (mUserMutableStreams & (1 << streamType)) != 0;
7747     }
7748 
ensureValidDirection(int direction)7749     private void ensureValidDirection(int direction) {
7750         switch (direction) {
7751             case AudioManager.ADJUST_LOWER:
7752             case AudioManager.ADJUST_RAISE:
7753             case AudioManager.ADJUST_SAME:
7754             case AudioManager.ADJUST_MUTE:
7755             case AudioManager.ADJUST_UNMUTE:
7756             case AudioManager.ADJUST_TOGGLE_MUTE:
7757                 break;
7758             default:
7759                 throw new IllegalArgumentException("Bad direction " + direction);
7760         }
7761     }
7762 
ensureValidStreamType(int streamType)7763     private void ensureValidStreamType(int streamType) {
7764         if (streamType < 0 || streamType >= AudioSystem.getNumStreamTypes()) {
7765             throw new IllegalArgumentException("Bad stream type " + streamType);
7766         }
7767     }
7768 
isMuteAdjust(int adjust)7769     private boolean isMuteAdjust(int adjust) {
7770         return adjust == AudioManager.ADJUST_MUTE || adjust == AudioManager.ADJUST_UNMUTE
7771                 || adjust == AudioManager.ADJUST_TOGGLE_MUTE;
7772     }
7773 
7774     /** only public for mocking/spying, do not call outside of AudioService */
7775     @VisibleForTesting
isInCommunication()7776     public boolean isInCommunication() {
7777         boolean IsInCall = false;
7778 
7779         TelecomManager telecomManager =
7780                 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
7781 
7782         final long ident = Binder.clearCallingIdentity();
7783         try {
7784             IsInCall = telecomManager.isInCall();
7785         } finally {
7786             Binder.restoreCallingIdentity(ident);
7787         }
7788 
7789         int mode = mMode.get();
7790         return (IsInCall
7791                 || mode == AudioManager.MODE_IN_COMMUNICATION
7792                 || mode == AudioManager.MODE_IN_CALL);
7793     }
7794 
7795     /**
7796      * For code clarity for getActiveStreamType(int)
7797      * @param delay_ms max time since last stream activity to consider
7798      * @return true if stream is active in streams handled by AudioFlinger now or
7799      *     in the last "delay_ms" ms.
7800      */
wasStreamActiveRecently(int stream, int delay_ms)7801     private boolean wasStreamActiveRecently(int stream, int delay_ms) {
7802         return mAudioSystem.isStreamActive(stream, delay_ms)
7803                 || mAudioSystem.isStreamActiveRemotely(stream, delay_ms);
7804     }
7805 
getActiveStreamType(int suggestedStreamType)7806     private int getActiveStreamType(int suggestedStreamType) {
7807         if (mIsSingleVolume
7808                 && suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
7809             return AudioSystem.STREAM_MUSIC;
7810         }
7811 
7812         switch (mPlatformType) {
7813         case AudioSystem.PLATFORM_VOICE:
7814             if (isInCommunication()
7815                     || mAudioSystem.isStreamActive(AudioManager.STREAM_VOICE_CALL, 0)) {
7816                 if (!replaceStreamBtSco()
7817                         && mBtCommDeviceActive.get() == BT_COMM_DEVICE_ACTIVE_SCO) {
7818                     if (DEBUG_VOL) {
7819                         Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO...");
7820                     }
7821                     return AudioSystem.STREAM_BLUETOOTH_SCO;
7822                 } else {
7823                     if (DEBUG_VOL) {
7824                         Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL...");
7825                     }
7826                     return AudioSystem.STREAM_VOICE_CALL;
7827                 }
7828             } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
7829                 if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
7830                     if (DEBUG_VOL)
7831                         Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active");
7832                     return AudioSystem.STREAM_RING;
7833                 } else if (wasStreamActiveRecently(
7834                         AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
7835                         if (DEBUG_VOL) {
7836                             Log.v(
7837                                     TAG,
7838                                     "getActiveStreamType: Forcing STREAM_NOTIFICATION stream"
7839                                             + " active");
7840                         }
7841                         return AudioSystem.STREAM_NOTIFICATION;
7842                 } else {
7843                     if (DEBUG_VOL) {
7844                         Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK("
7845                                 + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default");
7846                     }
7847                     return DEFAULT_VOL_STREAM_NO_PLAYBACK;
7848                 }
7849             } else if (
7850                     wasStreamActiveRecently(AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
7851                 if (DEBUG_VOL)
7852                     Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION stream active");
7853                 return AudioSystem.STREAM_NOTIFICATION;
7854             } else if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
7855                 if (DEBUG_VOL)
7856                     Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active");
7857                 return AudioSystem.STREAM_RING;
7858             }
7859         default:
7860             if (isInCommunication()
7861                     || mAudioSystem.isStreamActive(AudioManager.STREAM_VOICE_CALL, 0)) {
7862                 if (!replaceStreamBtSco()
7863                         && mBtCommDeviceActive.get() == BT_COMM_DEVICE_ACTIVE_SCO) {
7864                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO");
7865                     return AudioSystem.STREAM_BLUETOOTH_SCO;
7866                 } else {
7867                     if (DEBUG_VOL)  Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL");
7868                     return AudioSystem.STREAM_VOICE_CALL;
7869                 }
7870             } else if (mAudioSystem.isStreamActive(
7871                     AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
7872                 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION");
7873                 return AudioSystem.STREAM_NOTIFICATION;
7874             } else if (mAudioSystem.isStreamActive(
7875                     AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
7876                 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING");
7877                 return AudioSystem.STREAM_RING;
7878             } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
7879                 if (mAudioSystem.isStreamActive(
7880                         AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
7881                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION");
7882                     return AudioSystem.STREAM_NOTIFICATION;
7883                 }
7884                 if (mAudioSystem.isStreamActive(
7885                         AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
7886                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING");
7887                     return AudioSystem.STREAM_RING;
7888                 }
7889                 if (DEBUG_VOL) {
7890                     Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK("
7891                             + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default");
7892                 }
7893                 return DEFAULT_VOL_STREAM_NO_PLAYBACK;
7894             }
7895             break;
7896         }
7897 
7898         suggestedStreamType = replaceBtScoStreamWithVoiceCall(suggestedStreamType,
7899                 "getActiveStreamType");
7900 
7901         if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Returning suggested type "
7902                 + suggestedStreamType);
7903         return suggestedStreamType;
7904     }
7905 
broadcastRingerMode(String action, int ringerMode)7906     private void broadcastRingerMode(String action, int ringerMode) {
7907         if (!mSystemServer.isPrivileged()) {
7908             return;
7909         }
7910         // Send sticky broadcast
7911         Intent broadcast = new Intent(action);
7912         broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, ringerMode);
7913         broadcast.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
7914                 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
7915         sendStickyBroadcastToAll(broadcast);
7916     }
7917 
broadcastVibrateSetting(int vibrateType)7918     private void broadcastVibrateSetting(int vibrateType) {
7919         if (!mSystemServer.isPrivileged()) {
7920             return;
7921         }
7922         // Send broadcast
7923         if (mActivityManagerInternal.isSystemReady()) {
7924             Intent broadcast = new Intent(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
7925             broadcast.putExtra(AudioManager.EXTRA_VIBRATE_TYPE, vibrateType);
7926             broadcast.putExtra(AudioManager.EXTRA_VIBRATE_SETTING, getVibrateSetting(vibrateType));
7927             sendBroadcastToAll(broadcast, null /* options */);
7928         }
7929     }
7930 
7931     // Message helper methods
7932     /**
7933      * Queue a message on the given handler's message queue, after acquiring the service wake lock.
7934      * Note that the wake lock needs to be released after the message has been handled.
7935      */
queueMsgUnderWakeLock(Handler handler, int msg, int arg1, int arg2, Object obj, int delay)7936     private void queueMsgUnderWakeLock(Handler handler, int msg,
7937             int arg1, int arg2, Object obj, int delay) {
7938         final long ident = Binder.clearCallingIdentity();
7939         try {
7940             // Always acquire the wake lock as AudioService because it is released by the
7941             // message handler.
7942             mAudioEventWakeLock.acquire();
7943         } finally {
7944             Binder.restoreCallingIdentity(ident);
7945         }
7946         sendMsg(handler, msg, SENDMSG_QUEUE, arg1, arg2, obj, delay);
7947     }
7948 
sendMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, int delay)7949     private static void sendMsg(Handler handler, int msg,
7950             int existingMsgPolicy, int arg1, int arg2, Object obj, int delay) {
7951         if (existingMsgPolicy == SENDMSG_REPLACE) {
7952             handler.removeMessages(msg);
7953         } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) {
7954             return;
7955         }
7956 
7957         final long time = SystemClock.uptimeMillis() + delay;
7958         handler.sendMessageAtTime(handler.obtainMessage(msg, arg1, arg2, obj), time);
7959     }
7960 
sendBundleMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, Bundle bundle, int delay)7961     private static void sendBundleMsg(Handler handler, int msg,
7962             int existingMsgPolicy, int arg1, int arg2, Object obj, Bundle bundle, int delay) {
7963         if (existingMsgPolicy == SENDMSG_REPLACE) {
7964             handler.removeMessages(msg);
7965         } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) {
7966             return;
7967         }
7968 
7969         final long time = SystemClock.uptimeMillis() + delay;
7970         Message message = handler.obtainMessage(msg, arg1, arg2, obj);
7971         message.setData(bundle);
7972         handler.sendMessageAtTime(message, time);
7973     }
7974 
checkAudioSettingsPermission(String method)7975     boolean checkAudioSettingsPermission(String method) {
7976         if (callingOrSelfHasAudioSettingsPermission()) {
7977             return true;
7978         }
7979         String msg = "Audio Settings Permission Denial: " + method + " from pid="
7980                 + Binder.getCallingPid()
7981                 + ", uid=" + Binder.getCallingUid();
7982         Log.w(TAG, msg);
7983         return false;
7984     }
7985 
callingOrSelfHasAudioSettingsPermission()7986     private boolean callingOrSelfHasAudioSettingsPermission() {
7987         return mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_SETTINGS)
7988                 == PackageManager.PERMISSION_GRANTED;
7989     }
7990 
callingHasAudioSettingsPermission()7991     private boolean callingHasAudioSettingsPermission() {
7992         return mContext.checkCallingPermission(MODIFY_AUDIO_SETTINGS)
7993                 == PackageManager.PERMISSION_GRANTED;
7994     }
7995 
hasAudioSettingsPermission(int uid, int pid)7996     private boolean hasAudioSettingsPermission(int uid, int pid) {
7997         return mContext.checkPermission(MODIFY_AUDIO_SETTINGS, pid, uid)
7998                 == PackageManager.PERMISSION_GRANTED;
7999     }
8000 
8001     /**
8002      * Minimum attenuation that can be set for alarms over speaker by an application that
8003      * doesn't have the MODIFY_AUDIO_SETTINGS permission.
8004      */
8005     protected static final float MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB = -36.0f;
8006 
8007     /**
8008      * Configures the VolumeStreamState instances for minimum stream index that can be accessed
8009      * without MODIFY_AUDIO_SETTINGS permission.
8010      * Can only be done successfully once audio policy has finished reading its configuration files
8011      * for the volume curves. If not, getStreamVolumeDB will return NaN, and the min value will
8012      * remain at the stream min index value.
8013      */
initMinStreamVolumeWithoutModifyAudioSettings()8014     protected void initMinStreamVolumeWithoutModifyAudioSettings() {
8015         int idx;
8016         int deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER_SAFE;
8017         if (Float.isNaN(AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM,
8018                 MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM], deviceForAlarm))) {
8019             deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER;
8020         }
8021         for (idx = MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM];
8022                 idx >= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]; idx--) {
8023             if (AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM, idx, deviceForAlarm)
8024                     < MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB) {
8025                 break;
8026             }
8027         }
8028         final int safeIndex = idx <= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]
8029                 ? MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]
8030                 : Math.min(idx + 1, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]);
8031         // update the VolumeStreamState for STREAM_ALARM and its aliases
8032         for (int streamIdx = 0; streamIdx < sStreamVolumeAlias.size(); ++streamIdx) {
8033             final int streamAlias = sStreamVolumeAlias.valueAt(streamIdx);
8034             if (streamAlias == AudioSystem.STREAM_ALARM) {
8035                 getVssForStreamOrDefault(streamAlias).updateNoPermMinIndex(safeIndex);
8036             }
8037         }
8038     }
8039 
8040     /**
8041      * Returns device associated with the stream volume.
8042      *
8043      * Only public for mocking/spying, do not call outside of AudioService.
8044      * Device volume aliasing means DEVICE_OUT_SPEAKER may be returned for
8045      * DEVICE_OUT_SPEAKER_SAFE.
8046      */
8047     @VisibleForTesting
getDeviceForStream(int stream)8048     public int getDeviceForStream(int stream) {
8049         stream = replaceBtScoStreamWithVoiceCall(stream, "getDeviceForStream");
8050         return selectOneAudioDevice(getDeviceSetForStream(stream));
8051     }
8052 
8053     /*
8054      * Must match native apm_extract_one_audio_device() used in getDeviceForVolume()
8055      * or the wrong device volume may be adjusted.
8056      */
selectOneAudioDevice(Set<Integer> deviceSet)8057     private int selectOneAudioDevice(Set<Integer> deviceSet) {
8058         if (deviceSet.isEmpty()) {
8059             return AudioSystem.DEVICE_NONE;
8060         } else if (deviceSet.size() == 1) {
8061             return deviceSet.iterator().next();
8062         } else {
8063             // Multiple device selection is either:
8064             //  - dock + one other device: give priority to dock in this case.
8065             //  - speaker + one other device: give priority to speaker in this case.
8066             //  - one A2DP device + another device: happens with duplicated output. In this case
8067             // retain the device on the A2DP output as the other must not correspond to an active
8068             // selection if not the speaker.
8069             //  - HDMI-CEC system audio mode only output: give priority to available item in order.
8070 
8071             if (deviceSet.contains(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET)) {
8072                 return AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET;
8073             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPEAKER)) {
8074                 return AudioSystem.DEVICE_OUT_SPEAKER;
8075             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPEAKER_SAFE)) {
8076                 // Note: DEVICE_OUT_SPEAKER_SAFE not present in getDeviceSetForStreamDirect
8077                 return AudioSystem.DEVICE_OUT_SPEAKER_SAFE;
8078             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_HDMI_ARC)) {
8079                 return AudioSystem.DEVICE_OUT_HDMI_ARC;
8080             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_HDMI_EARC)) {
8081                 return AudioSystem.DEVICE_OUT_HDMI_EARC;
8082             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_AUX_LINE)) {
8083                 return AudioSystem.DEVICE_OUT_AUX_LINE;
8084             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPDIF)) {
8085                 return AudioSystem.DEVICE_OUT_SPDIF;
8086             } else {
8087                 // At this point, deviceSet should contain exactly one removable device;
8088                 // regardless, return the first removable device in numeric order.
8089                 // If there is no removable device, this falls through to log an error.
8090                 for (int deviceType : deviceSet) {
8091                     if (AudioSystem.DEVICE_OUT_PICK_FOR_VOLUME_SET.contains(deviceType)) {
8092                         return deviceType;
8093                     }
8094                 }
8095             }
8096         }
8097         Log.w(TAG, "selectOneAudioDevice returning DEVICE_NONE from invalid device combination "
8098                 + AudioSystem.deviceSetToString(deviceSet));
8099         return AudioSystem.DEVICE_NONE;
8100     }
8101 
8102     /**
8103      * @see AudioManager#getDevicesForStream(int)
8104      * @deprecated on {@link android.os.Build.VERSION_CODES#T} as new devices
8105      *              will have multi-bit device types since S.
8106      *              Use {@link #getDevicesForAttributes()} instead.
8107      */
8108     @Override
8109     @Deprecated
getDeviceMaskForStream(int streamType)8110     public int getDeviceMaskForStream(int streamType) {
8111         streamType = replaceBtScoStreamWithVoiceCall(streamType, "getDeviceMaskForStream");
8112 
8113         ensureValidStreamType(streamType);
8114         // no permission required
8115         final long token = Binder.clearCallingIdentity();
8116         try {
8117             return AudioSystem.getDeviceMaskFromSet(
8118                     getDeviceSetForStreamDirect(streamType));
8119         } finally {
8120             Binder.restoreCallingIdentity(token);
8121         }
8122     }
8123 
8124     /**
8125      * Returns the devices associated with a stream type.
8126      *
8127      * SPEAKER_SAFE will alias to SPEAKER.
8128      */
8129     @NonNull
getDeviceSetForStreamDirect(int stream)8130     private Set<Integer> getDeviceSetForStreamDirect(int stream) {
8131         final AudioAttributes attr =
8132                 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream);
8133         Set<Integer> deviceSet =
8134                 AudioSystem.generateAudioDeviceTypesSet(
8135                         getDevicesForAttributesInt(attr, true /* forVolume */));
8136         return deviceSet;
8137     }
8138 
8139     /**
8140      * Returns a reference to the list of devices for the stream, do not modify.
8141      *
8142      * The device returned may be aliased to the actual device whose volume curve
8143      * will be used.  For example DEVICE_OUT_SPEAKER_SAFE aliases to DEVICE_OUT_SPEAKER.
8144      */
8145     @NonNull
getDeviceSetForStream(int stream)8146     public Set<Integer> getDeviceSetForStream(int stream) {
8147         stream = replaceBtScoStreamWithVoiceCall(stream, "getDeviceSetForStream");
8148         ensureValidStreamType(stream);
8149         synchronized (mVolumeStateLock) {
8150             return getVssForStreamOrDefault(stream).observeDevicesForStream_syncVSS(true);
8151         }
8152     }
8153 
onObserveDevicesForAllStreams(int skipStream)8154     private void onObserveDevicesForAllStreams(int skipStream) {
8155         synchronized (mSettingsLock) {
8156             synchronized (mVolumeStateLock) {
8157                 for (int stream = 0; stream < mStreamStates.size(); stream++) {
8158                     final VolumeStreamState vss = mStreamStates.valueAt(stream);
8159                     if (vss != null && vss.getStreamType() != skipStream) {
8160                         Set<Integer> deviceSet =
8161                                 vss.observeDevicesForStream_syncVSS(false /*checkOthers*/);
8162                         for (Integer device : deviceSet) {
8163                             // Update volume states for devices routed for the stream
8164                             updateVolumeStates(device, vss.getStreamType(),
8165                                     "AudioService#onObserveDevicesForAllStreams");
8166                         }
8167                     }
8168                 }
8169             }
8170         }
8171     }
8172 
8173     /** only public for mocking/spying, do not call outside of AudioService */
8174     @VisibleForTesting
postObserveDevicesForAllStreams()8175     public void postObserveDevicesForAllStreams() {
8176         postObserveDevicesForAllStreams(-1);
8177     }
8178 
8179     /** only public for mocking/spying, do not call outside of AudioService */
8180     @VisibleForTesting
postObserveDevicesForAllStreams(int skipStream)8181     public void postObserveDevicesForAllStreams(int skipStream) {
8182         sendMsg(mAudioHandler,
8183                 MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS,
8184                 SENDMSG_QUEUE, skipStream /*arg1*/, 0 /*arg2*/, null /*obj*/,
8185                 0 /*delay*/);
8186     }
8187 
postBtCommDeviceActive(@tCommDeviceActiveType int btCommDeviceActive)8188     /*package*/ void postBtCommDeviceActive(@BtCommDeviceActiveType int btCommDeviceActive) {
8189         sendMsg(mAudioHandler,
8190                 MSG_BT_COMM_DEVICE_ACTIVE_UPDATE,
8191                 SENDMSG_QUEUE, btCommDeviceActive /*arg1*/, 0 /*arg2*/, null /*obj*/,
8192                 0 /*delay*/);
8193     }
8194 
onUpdateBtCommDeviceActive(@tCommDeviceActiveType int btCommDeviceActive)8195     private void onUpdateBtCommDeviceActive(@BtCommDeviceActiveType int btCommDeviceActive) {
8196         if (mBtCommDeviceActive.getAndSet(btCommDeviceActive) != btCommDeviceActive) {
8197             getVssForStreamOrDefault(AudioSystem.STREAM_VOICE_CALL).updateIndexFactors();
8198         }
8199     }
8200 
8201     /**
8202      * @see AudioDeviceVolumeManager#setDeviceAbsoluteMultiVolumeBehavior
8203      *
8204      * @param register Whether the listener is to be registered or unregistered. If false, the
8205      *                 device adopts variable volume behavior.
8206      */
8207     @RequiresPermission(anyOf = { MODIFY_AUDIO_ROUTING, BLUETOOTH_PRIVILEGED })
registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register, IAudioDeviceVolumeDispatcher cb, String packageName, AudioDeviceAttributes device, List<VolumeInfo> volumes, boolean handlesVolumeAdjustment, @AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior int deviceVolumeBehavior)8208     public void registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register,
8209             IAudioDeviceVolumeDispatcher cb, String packageName,
8210             AudioDeviceAttributes device, List<VolumeInfo> volumes,
8211             boolean handlesVolumeAdjustment,
8212             @AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior int deviceVolumeBehavior) {
8213         // verify permissions
8214         if (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING)
8215                 != PackageManager.PERMISSION_GRANTED
8216                 && mContext.checkCallingOrSelfPermission(BLUETOOTH_PRIVILEGED)
8217                 != PackageManager.PERMISSION_GRANTED) {
8218             throw new SecurityException(
8219                     "Missing MODIFY_AUDIO_ROUTING or BLUETOOTH_PRIVILEGED permissions");
8220         }
8221         // verify arguments
8222         Objects.requireNonNull(device);
8223         Objects.requireNonNull(volumes);
8224 
8225         int deviceOut = device.getInternalType();
8226         if (register) {
8227             AbsoluteVolumeDeviceInfo info = new AbsoluteVolumeDeviceInfo(this,
8228                     device, volumes, cb, handlesVolumeAdjustment, deviceVolumeBehavior);
8229             final AbsoluteVolumeDeviceInfo oldInfo = getAbsoluteVolumeDeviceInfo(deviceOut);
8230             addAudioSystemDeviceOutToAbsVolumeDevices(deviceOut, info);
8231 
8232             boolean volumeBehaviorChanged = (oldInfo == null)
8233                     || (oldInfo.mDeviceVolumeBehavior != deviceVolumeBehavior);
8234             if (volumeBehaviorChanged) {
8235                 removeAudioSystemDeviceOutFromFullVolumeDevices(deviceOut);
8236                 removeAudioSystemDeviceOutFromFixedVolumeDevices(deviceOut);
8237 
8238                 dispatchDeviceVolumeBehavior(device, deviceVolumeBehavior);
8239             }
8240             // Update stream volumes to the given device, if specified in a VolumeInfo.
8241             // Mute state is not updated because it is stream-wide - the only way to mute a
8242             // stream's output to a particular device is to set the volume index to zero.
8243             for (VolumeInfo volumeInfo : volumes) {
8244                 if (volumeInfo.getVolumeIndex() != VolumeInfo.INDEX_NOT_SET
8245                         && volumeInfo.getMinVolumeIndex() != VolumeInfo.INDEX_NOT_SET
8246                         && volumeInfo.getMaxVolumeIndex() != VolumeInfo.INDEX_NOT_SET) {
8247                     if (volumeInfo.hasStreamType()) {
8248                         setStreamVolumeInt(volumeInfo.getStreamType(),
8249                                 rescaleIndex(volumeInfo, volumeInfo.getStreamType()),
8250                                 deviceOut, false /*force*/, packageName,
8251                                 true /*hasModifyAudioSettings*/);
8252                     } else {
8253                         for (int streamType : volumeInfo.getVolumeGroup().getLegacyStreamTypes()) {
8254                             setStreamVolumeInt(streamType, rescaleIndex(volumeInfo, streamType),
8255                                     deviceOut, false /*force*/, packageName,
8256                                     true /*hasModifyAudioSettings*/);
8257                         }
8258                     }
8259                 }
8260             }
8261         } else {
8262             AbsoluteVolumeDeviceInfo deviceInfo = removeAudioSystemDeviceOutFromAbsVolumeDevices(
8263                     deviceOut);
8264             if (deviceInfo != null) {
8265                 deviceInfo.unlinkToDeath();
8266                 dispatchDeviceVolumeBehavior(device, AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE);
8267             }
8268         }
8269     }
8270 
8271     /**
8272      * @see AudioManager#setDeviceVolumeBehavior(AudioDeviceAttributes, int)
8273      * @param device the audio device to be affected
8274      * @param deviceVolumeBehavior one of the device behaviors
8275      */
8276     @android.annotation.EnforcePermission(anyOf = {
8277             MODIFY_AUDIO_ROUTING, MODIFY_AUDIO_SETTINGS_PRIVILEGED })
setDeviceVolumeBehavior(@onNull AudioDeviceAttributes device, @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName)8278     public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
8279             @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior,
8280             @Nullable String pkgName) {
8281         // verify permissions
8282         super.setDeviceVolumeBehavior_enforcePermission();
8283         // verify arguments
8284         Objects.requireNonNull(device);
8285         AudioDeviceVolumeManager.enforceValidVolumeBehavior(deviceVolumeBehavior);
8286 
8287         device = retrieveBluetoothAddress(device);
8288 
8289         sVolumeLogger.enqueue(new EventLogger.StringEvent("setDeviceVolumeBehavior: dev:"
8290                 + AudioSystem.getOutputDeviceName(device.getInternalType()) + " addr:"
8291                 + Utils.anonymizeBluetoothAddress(device.getAddress()) + " behavior:"
8292                 + AudioDeviceVolumeManager.volumeBehaviorName(deviceVolumeBehavior)
8293                 + " pack:" + pkgName).printLog(TAG));
8294         if (pkgName == null) {
8295             pkgName = "";
8296         }
8297         if (device.getType() == TYPE_BLUETOOTH_A2DP) {
8298             avrcpSupportsAbsoluteVolume(device.getAddress(),
8299                     deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
8300             return;
8301         }
8302 
8303         setDeviceVolumeBehaviorInternal(device, deviceVolumeBehavior, pkgName);
8304         persistDeviceVolumeBehavior(device.getInternalType(), deviceVolumeBehavior);
8305     }
8306 
setDeviceVolumeBehaviorInternal(@onNull AudioDeviceAttributes device, @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller)8307     private void setDeviceVolumeBehaviorInternal(@NonNull AudioDeviceAttributes device,
8308             @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior,
8309             @NonNull String caller) {
8310         int audioSystemDeviceOut = device.getInternalType();
8311         boolean volumeBehaviorChanged = false;
8312         // update device masks based on volume behavior
8313         switch (deviceVolumeBehavior) {
8314             case AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE:
8315                 volumeBehaviorChanged |=
8316                         removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut)
8317                         | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut)
8318                         | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut)
8319                                 != null);
8320                 break;
8321             case AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED:
8322                 volumeBehaviorChanged |=
8323                         removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut)
8324                         | addAudioSystemDeviceOutToFixedVolumeDevices(audioSystemDeviceOut)
8325                         | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut)
8326                                 != null);
8327                 break;
8328             case AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL:
8329                 volumeBehaviorChanged |=
8330                         addAudioSystemDeviceOutToFullVolumeDevices(audioSystemDeviceOut)
8331                         | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut)
8332                         | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut)
8333                                 != null);
8334                 break;
8335             case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE:
8336             case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY:
8337             case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE:
8338                 throw new IllegalArgumentException("Absolute volume unsupported for now");
8339         }
8340 
8341         if (volumeBehaviorChanged) {
8342             sendMsg(mAudioHandler, MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR, SENDMSG_QUEUE,
8343                     deviceVolumeBehavior, 0, device, /*delay*/ 0);
8344         }
8345 
8346         // log event and caller
8347         sDeviceLogger.enqueue(new EventLogger.StringEvent(
8348                 "Volume behavior " + deviceVolumeBehavior + " for dev=0x"
8349                       + Integer.toHexString(audioSystemDeviceOut) + " from:" + caller));
8350         // make sure we have a volume entry for this device, and that volume is updated according
8351         // to volume behavior
8352         postUpdateVolumeStatesForAudioDevice(audioSystemDeviceOut,
8353                 "setDeviceVolumeBehavior:" + caller);
8354     }
8355 
8356     /**
8357      * @see AudioManager#getDeviceVolumeBehavior(AudioDeviceAttributes)
8358      * @param device the audio output device type
8359      * @return the volume behavior for the device
8360      */
8361     @android.annotation.EnforcePermission(anyOf = {
8362             MODIFY_AUDIO_ROUTING, QUERY_AUDIO_STATE,  MODIFY_AUDIO_SETTINGS_PRIVILEGED
8363     })
8364     public @AudioDeviceVolumeManager.DeviceVolumeBehavior
getDeviceVolumeBehavior(@onNull AudioDeviceAttributes device)8365     int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
8366         // verify permissions
8367         super.getDeviceVolumeBehavior_enforcePermission();
8368         // verify parameters
8369         Objects.requireNonNull(device);
8370 
8371         device = retrieveBluetoothAddress(device);
8372 
8373         return getDeviceVolumeBehaviorInt(device);
8374     }
8375 
8376     private @AudioDeviceVolumeManager.DeviceVolumeBehavior
getDeviceVolumeBehaviorInt(@onNull AudioDeviceAttributes device)8377             int getDeviceVolumeBehaviorInt(@NonNull AudioDeviceAttributes device) {
8378         // Get the internal type set by the AudioDeviceAttributes constructor which is always more
8379         // exact (avoids double conversions) than a conversion from SDK type via
8380         // AudioDeviceInfo.convertDeviceTypeToInternalDevice()
8381         final int audioSystemDeviceOut = device.getInternalType();
8382 
8383         // setDeviceVolumeBehavior has not been explicitly called for the device type. Deduce the
8384         // current volume behavior.
8385         if (mFullVolumeDevices.contains(audioSystemDeviceOut)) {
8386             return AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL;
8387         }
8388         if (mFixedVolumeDevices.contains(audioSystemDeviceOut)) {
8389             return AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED;
8390         }
8391         if (mAbsVolumeMultiModeCaseDevices.contains(audioSystemDeviceOut)) {
8392             return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE;
8393         }
8394         synchronized (mAbsoluteVolumeDeviceInfoMapLock) {
8395             if (mAbsoluteVolumeDeviceInfoMap.containsKey(audioSystemDeviceOut)) {
8396                 final AbsoluteVolumeDeviceInfo deviceInfo = mAbsoluteVolumeDeviceInfoMap.get(
8397                         audioSystemDeviceOut);
8398                 if (deviceInfo != null) {
8399                     return deviceInfo.mDeviceVolumeBehavior;
8400                 }
8401 
8402                 Log.e(TAG,
8403                         "Null absolute volume device info stored for key " + audioSystemDeviceOut);
8404             }
8405         }
8406 
8407         if (isA2dpAbsoluteVolumeDevice(audioSystemDeviceOut)
8408                 || AudioSystem.isLeAudioDeviceType(audioSystemDeviceOut)) {
8409             return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE;
8410         }
8411         return AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE;
8412     }
8413 
8414     /**
8415      * @see AudioManager#isVolumeFixed()
8416      * Note there are no permission checks on this operation, as this is part of API 21
8417      * @return true if the current device's volume behavior for media is
8418      *         DEVICE_VOLUME_BEHAVIOR_FIXED
8419      */
isVolumeFixed()8420     public boolean isVolumeFixed() {
8421         if (mUseFixedVolume) {
8422             return true;
8423         }
8424         final AudioAttributes attributes = new AudioAttributes.Builder()
8425                 .setUsage(AudioAttributes.USAGE_MEDIA)
8426                 .build();
8427         // calling getDevice*Int to bypass permission check
8428         final List<AudioDeviceAttributes> devices =
8429                 getDevicesForAttributesInt(attributes, true /* forVolume */);
8430         for (AudioDeviceAttributes device : devices) {
8431             if (getDeviceVolumeBehaviorInt(device) == AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED) {
8432                 return true;
8433             }
8434         }
8435         return false;
8436     }
8437 
8438     /*package*/ static final int CONNECTION_STATE_DISCONNECTED = 0;
8439     /*package*/ static final int CONNECTION_STATE_CONNECTED = 1;
8440     /**
8441      * The states that can be used with AudioService.setWiredDeviceConnectionState()
8442      * Attention: those values differ from those in BluetoothProfile, follow annotations to
8443      * distinguish between @ConnectionState and @BtProfileConnectionState
8444      */
8445     @IntDef({
8446             CONNECTION_STATE_DISCONNECTED,
8447             CONNECTION_STATE_CONNECTED,
8448     })
8449     @Retention(RetentionPolicy.SOURCE)
8450     public @interface ConnectionState {}
8451 
8452     /**
8453      * Default SAD for a TV using ARC, used when the Amplifier didn't report any SADs.
8454      * Represents 2-channel LPCM including all defined sample rates and bit depths.
8455      * For the format definition, see Table 34 in the CEA standard CEA-861-D.
8456      */
8457     private static final byte[] DEFAULT_ARC_AUDIO_DESCRIPTOR = new byte[]{0x09, 0x7f, 0x07};
8458 
8459     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
8460     /**
8461      * see AudioManager.setWiredDeviceConnectionState()
8462      */
setWiredDeviceConnectionState(@onNull AudioDeviceAttributes attributes, @ConnectionState int state, String caller)8463     public void setWiredDeviceConnectionState(@NonNull AudioDeviceAttributes attributes,
8464             @ConnectionState int state, String caller) {
8465         super.setWiredDeviceConnectionState_enforcePermission();
8466         Objects.requireNonNull(attributes);
8467 
8468         attributes = retrieveBluetoothAddress(attributes);
8469 
8470         // When using ARC, a TV should use default 2 channel LPCM if the Amplifier didn't
8471         // report any SADs. See section 13.15.3 of the HDMI-CEC spec version 1.4b.
8472         if (attributes.getType() == AudioDeviceInfo.TYPE_HDMI_ARC
8473                 && attributes.getRole() == AudioDeviceAttributes.ROLE_OUTPUT
8474                 && attributes.getAudioDescriptors().isEmpty()) {
8475             attributes = new AudioDeviceAttributes(
8476                     attributes.getRole(),
8477                     attributes.getType(),
8478                     attributes.getAddress(),
8479                     attributes.getName(),
8480                     attributes.getAudioProfiles(),
8481                     new ArrayList<AudioDescriptor>(Collections.singletonList(
8482                             new AudioDescriptor(
8483                                     AudioDescriptor.STANDARD_EDID,
8484                                     AudioProfile.AUDIO_ENCAPSULATION_TYPE_NONE,
8485                                     DEFAULT_ARC_AUDIO_DESCRIPTOR
8486                             )
8487                     ))
8488             );
8489         }
8490 
8491         if (state != CONNECTION_STATE_CONNECTED
8492                 && state != CONNECTION_STATE_DISCONNECTED) {
8493             throw new IllegalArgumentException("Invalid state " + state);
8494         }
8495         new MediaMetrics.Item(mMetricsId + "setWiredDeviceConnectionState")
8496                 .set(MediaMetrics.Property.ADDRESS, attributes.getAddress())
8497                 .set(MediaMetrics.Property.CLIENT_NAME, caller)
8498                 .set(MediaMetrics.Property.DEVICE,
8499                         AudioSystem.getDeviceName(attributes.getInternalType()))
8500                 .set(MediaMetrics.Property.NAME, attributes.getName())
8501                 .set(MediaMetrics.Property.STATE,
8502                         state == CONNECTION_STATE_CONNECTED ? "connected" : "disconnected")
8503                 .record();
8504         mDeviceBroker.setWiredDeviceConnectionState(attributes, state, caller);
8505         // The Dynamic Soundbar mode feature introduces dynamic presence for an HDMI Audio System
8506         // Client. For example, the device can start with the Audio System Client unavailable.
8507         // When the feature is activated the client becomes available, therefore Audio Service
8508         // requests a new HDMI Audio System Client instance when the ARC status is changed.
8509         if (attributes.getInternalType() == AudioSystem.DEVICE_IN_HDMI_ARC) {
8510             updateHdmiAudioSystemClient();
8511         }
8512     }
8513 
8514     /**
8515      * Replace the current HDMI Audio System Client.
8516      * See {@link #setWiredDeviceConnectionState(AudioDeviceAttributes, int, String)}.
8517      */
updateHdmiAudioSystemClient()8518     private void updateHdmiAudioSystemClient() {
8519         Slog.d(TAG, "Hdmi Audio System Client is updated");
8520         synchronized (mHdmiClientLock) {
8521             mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient();
8522         }
8523     }
8524 
8525     /** @see AudioManager#setTestDeviceConnectionState(AudioDeviceAttributes, boolean) */
setTestDeviceConnectionState(@onNull AudioDeviceAttributes device, boolean connected)8526     public void setTestDeviceConnectionState(@NonNull AudioDeviceAttributes device,
8527             boolean connected) {
8528         Objects.requireNonNull(device);
8529         enforceModifyAudioRoutingPermission();
8530 
8531         device = retrieveBluetoothAddress(device);
8532 
8533         mDeviceBroker.setTestDeviceConnectionState(device,
8534                 connected ? CONNECTION_STATE_CONNECTED : CONNECTION_STATE_DISCONNECTED);
8535         // simulate a routing update from native
8536         sendMsg(mAudioHandler,
8537                 MSG_ROUTING_UPDATED,
8538                 SENDMSG_REPLACE, 0, 0, null,
8539                 /*delay*/ 0);
8540     }
8541 
8542     /**
8543      * @hide
8544      * The states that can be used with AudioService.setBluetoothHearingAidDeviceConnectionState()
8545      * and AudioService.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent()
8546      */
8547     @IntDef({
8548             BluetoothProfile.STATE_DISCONNECTED,
8549             BluetoothProfile.STATE_CONNECTED,
8550     })
8551     @Retention(RetentionPolicy.SOURCE)
8552     public @interface BtProfileConnectionState {}
8553 
8554     /**
8555      * @hide
8556      * The profiles that can be used with AudioService.handleBluetoothActiveDeviceChanged()
8557      */
8558     @IntDef({
8559             BluetoothProfile.HEARING_AID,
8560             BluetoothProfile.A2DP,
8561             BluetoothProfile.A2DP_SINK,
8562             BluetoothProfile.LE_AUDIO,
8563             BluetoothProfile.LE_AUDIO_BROADCAST,
8564     })
8565     @Retention(RetentionPolicy.SOURCE)
8566     public @interface BtProfile {}
8567 
8568 
8569     @android.annotation.EnforcePermission(BLUETOOTH_STACK)
8570     /**
8571      * See AudioManager.handleBluetoothActiveDeviceChanged(...)
8572      */
handleBluetoothActiveDeviceChanged(BluetoothDevice newDevice, BluetoothDevice previousDevice, @NonNull BluetoothProfileConnectionInfo info)8573     public void handleBluetoothActiveDeviceChanged(BluetoothDevice newDevice,
8574             BluetoothDevice previousDevice, @NonNull BluetoothProfileConnectionInfo info) {
8575         handleBluetoothActiveDeviceChanged_enforcePermission();
8576         if (info == null) {
8577             throw new IllegalArgumentException("Illegal null BluetoothProfileConnectionInfo for"
8578                     + " device " + previousDevice + " -> " + newDevice);
8579         }
8580         final int profile = info.getProfile();
8581         if (profile != BluetoothProfile.A2DP && profile != BluetoothProfile.A2DP_SINK
8582                 && profile != BluetoothProfile.LE_AUDIO
8583                 && profile != BluetoothProfile.LE_AUDIO_BROADCAST
8584                 && profile != BluetoothProfile.HEARING_AID
8585                 && !(mDeviceBroker.isScoManagedByAudio() && profile == BluetoothProfile.HEADSET)) {
8586             throw new IllegalArgumentException("Illegal BluetoothProfile profile for device "
8587                     + previousDevice + " -> " + newDevice + ". Got: " + profile);
8588         }
8589 
8590         sDeviceLogger.enqueue(new EventLogger.StringEvent("BluetoothActiveDeviceChanged for "
8591                 + BluetoothProfile.getProfileName(profile) + ", device update " + previousDevice
8592                 + " -> " + newDevice).printLog(TAG));
8593         AudioDeviceBroker.BtDeviceChangedData data =
8594                 new AudioDeviceBroker.BtDeviceChangedData(newDevice, previousDevice, info,
8595                         "AudioService");
8596         sendMsg(mAudioHandler, MSG_BT_DEV_CHANGED, SENDMSG_QUEUE, 0, 0,
8597                 /*obj*/ data, /*delay*/ 0);
8598     }
8599 
8600     /** only public for mocking/spying, do not call outside of AudioService */
8601     @VisibleForTesting
setMusicMute(boolean mute)8602     public void setMusicMute(boolean mute) {
8603         getVssForStreamOrDefault(AudioSystem.STREAM_MUSIC).muteInternally(mute);
8604     }
8605 
8606     private static final Set<Integer> DEVICE_MEDIA_UNMUTED_ON_PLUG_SET;
8607     static {
8608         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET = new HashSet<>();
8609         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADSET);
8610         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE);
8611         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_LINE);
8612         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_HEARING_AID);
8613         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_A2DP_SET);
8614         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_BLE_SET);
8615         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_USB_SET);
8616     }
8617 
8618     /** only public for mocking/spying, do not call outside of AudioService */
8619     @VisibleForTesting
postAccessoryPlugMediaUnmute(int newDevice)8620     public void postAccessoryPlugMediaUnmute(int newDevice) {
8621         sendMsg(mAudioHandler, MSG_ACCESSORY_PLUG_MEDIA_UNMUTE, SENDMSG_QUEUE,
8622                 newDevice, 0, null, 0);
8623     }
8624 
onAccessoryPlugMediaUnmute(int newDevice)8625     private void onAccessoryPlugMediaUnmute(int newDevice) {
8626         if (DEBUG_VOL) {
8627             Log.i(TAG, String.format("onAccessoryPlugMediaUnmute newDevice=%d [%s]",
8628                     newDevice, AudioSystem.getOutputDeviceName(newDevice)));
8629         }
8630 
8631         if (mNm.getZenMode() != Settings.Global.ZEN_MODE_NO_INTERRUPTIONS
8632                 && !isStreamMutedByRingerOrZenMode(AudioSystem.STREAM_MUSIC)
8633                 && DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.contains(newDevice)
8634                 && getVssForStreamOrDefault(AudioSystem.STREAM_MUSIC).mIsMuted
8635                 && getVssForStreamOrDefault(AudioSystem.STREAM_MUSIC).getIndex(newDevice) != 0
8636                 && getDeviceSetForStreamDirect(AudioSystem.STREAM_MUSIC).contains(newDevice)) {
8637             if (DEBUG_VOL) {
8638                 Log.i(TAG, String.format("onAccessoryPlugMediaUnmute unmuting device=%d [%s]",
8639                         newDevice, AudioSystem.getOutputDeviceName(newDevice)));
8640             }
8641             // Locking mSettingsLock to avoid inversion when calling vss.mute -> vss.doMute ->
8642             // vss.updateVolumeGroupIndex
8643             synchronized (mSettingsLock) {
8644                 getVssForStreamOrDefault(AudioSystem.STREAM_MUSIC).mute(false,
8645                         "onAccessoryPlugMediaUnmute");
8646             }
8647         }
8648     }
8649 
8650     /**
8651      * See AudioManager.hasHapticChannels(Context, Uri).
8652      */
hasHapticChannels(Uri uri)8653     public boolean hasHapticChannels(Uri uri) {
8654         return AudioManager.hasHapticChannelsImpl(mContext, uri);
8655     }
8656 
8657     ///////////////////////////////////////////////////////////////////////////
8658     // Inner classes
8659     ///////////////////////////////////////////////////////////////////////////
8660     /**
8661      * Key is the AudioManager VolumeGroupId
8662      * Value is the VolumeGroupState
8663      */
8664     private static final SparseArray<VolumeGroupState> sVolumeGroupStates = new SparseArray<>();
8665 
initVolumeGroupStates()8666     private void initVolumeGroupStates() {
8667         int btScoGroupId = -1;
8668         VolumeGroupState voiceCallGroup = null;
8669         for (final AudioVolumeGroup avg : getAudioVolumeGroups()) {
8670             try {
8671                 if (ensureValidVolumeGroup(avg)) {
8672                     final VolumeGroupState vgs = new VolumeGroupState(avg);
8673                     sVolumeGroupStates.append(avg.getId(), vgs);
8674                     if (vgs.isVoiceCall()) {
8675                         voiceCallGroup = vgs;
8676                     }
8677                 } else {
8678                     // invalid volume group will be reported for bt sco group with no other
8679                     // legacy stream type, we try to replace it in sVolumeGroupStates with the
8680                     // voice call volume group
8681                     btScoGroupId = avg.getId();
8682                 }
8683             } catch (IllegalArgumentException e) {
8684                 // Volume Groups without attributes are not controllable through set/get volume
8685                 // using attributes. Do not append them.
8686                 if (DEBUG_VOL) {
8687                     Log.d(TAG, "volume group " + avg.name() + " for internal policy needs");
8688                 }
8689             }
8690         }
8691 
8692         if (replaceStreamBtSco() && btScoGroupId >= 0 && voiceCallGroup != null) {
8693             // the bt sco group is deprecated, storing the voice call group instead
8694             // to keep the code backwards compatible when calling the volume group APIs
8695             sVolumeGroupStates.append(btScoGroupId, voiceCallGroup);
8696         }
8697 
8698         // need mSettingsLock for vgs.applyAllVolumes -> vss.setIndex which grabs this lock after
8699         // VSS.class. Locking order needs to be preserved
8700         synchronized (mSettingsLock) {
8701             for (int i = 0; i < sVolumeGroupStates.size(); i++) {
8702                 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
8703                 vgs.applyAllVolumes(/* userSwitch= */ false);
8704             }
8705         }
8706     }
8707 
8708     /**
8709      * Returns false if the legacy stream types only contains the deprecated
8710      * {@link AudioSystem#STREAM_BLUETOOTH_SCO}.
8711      *
8712      * @throws IllegalArgumentException if it has more than one non-default {@link AudioAttributes}
8713      *
8714      * @param avg the volume group to check
8715      */
ensureValidVolumeGroup(AudioVolumeGroup avg)8716     private boolean ensureValidVolumeGroup(AudioVolumeGroup avg) {
8717         boolean hasAtLeastOneValidAudioAttributes = avg.getAudioAttributes().stream()
8718                 .anyMatch(aa -> !aa.equals(AudioProductStrategy.getDefaultAttributes()));
8719         if (!hasAtLeastOneValidAudioAttributes) {
8720             throw new IllegalArgumentException("Volume Group " + avg.name()
8721                     + " has no valid audio attributes");
8722         }
8723         if (replaceStreamBtSco()) {
8724             // if there are multiple legacy stream types associated we can omit stream bt sco
8725             // otherwise this is not a valid volume group
8726             if (avg.getLegacyStreamTypes().length == 1
8727                     && avg.getLegacyStreamTypes()[0] == AudioSystem.STREAM_BLUETOOTH_SCO) {
8728                 return false;
8729             }
8730         }
8731         return true;
8732     }
8733 
shouldPreserveVolume(boolean userSwitch, VolumeGroupState vgs)8734     private boolean shouldPreserveVolume(boolean userSwitch, VolumeGroupState vgs) {
8735         // as for STREAM_MUSIC, preserve volume from one user to the next except
8736         // Android Automotive platform
8737         return (userSwitch && vgs.isMusic()) && !isPlatformAutomotive();
8738     }
8739 
readVolumeGroupsSettings(boolean userSwitch)8740     private void readVolumeGroupsSettings(boolean userSwitch) {
8741         synchronized (mSettingsLock) {
8742             synchronized (mVolumeStateLock) {
8743                 if (DEBUG_VOL) {
8744                     Log.d(TAG, "readVolumeGroupsSettings userSwitch=" + userSwitch);
8745                 }
8746                 for (int i = 0; i < sVolumeGroupStates.size(); i++) {
8747                     VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
8748                     if (!shouldPreserveVolume(userSwitch, vgs)) {
8749                         vgs.clearIndexCache();
8750                         vgs.readSettings();
8751                     }
8752                     vgs.applyAllVolumes(userSwitch);
8753                 }
8754             }
8755         }
8756     }
8757 
8758     // Called upon crash of AudioServer
restoreVolumeGroups()8759     private void restoreVolumeGroups() {
8760         if (DEBUG_VOL) {
8761             Log.v(TAG, "restoreVolumeGroups");
8762         }
8763 
8764         // need mSettingsLock for vgs.applyAllVolumes -> vss.setIndex which grabs this lock after
8765         // VSS.class. Locking order needs to be preserved
8766         synchronized (mSettingsLock) {
8767             for (int i = 0; i < sVolumeGroupStates.size(); i++) {
8768                 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
8769                 vgs.applyAllVolumes(false/*userSwitch*/);
8770             }
8771         }
8772     }
8773 
dumpVolumeGroups(PrintWriter pw)8774     private void dumpVolumeGroups(PrintWriter pw) {
8775         pw.println("\nVolume Groups (device: index)");
8776         for (int i = 0; i < sVolumeGroupStates.size(); i++) {
8777             final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
8778             vgs.dump(pw);
8779             pw.println("");
8780         }
8781     }
8782 
isCallStream(int stream)8783     private static boolean isCallStream(int stream) {
8784         return stream == AudioSystem.STREAM_VOICE_CALL
8785                 || stream == AudioSystem.STREAM_BLUETOOTH_SCO;
8786     }
8787 
getVolumeGroupForStreamType(int stream)8788     private static int getVolumeGroupForStreamType(int stream) {
8789         AudioAttributes attributes =
8790                 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream);
8791         if (attributes.equals(new AudioAttributes.Builder().build())) {
8792             return AudioVolumeGroup.DEFAULT_VOLUME_GROUP;
8793         }
8794         return AudioProductStrategy.getVolumeGroupIdForAudioAttributes(
8795                 attributes, /* fallbackOnDefault= */ false);
8796     }
8797 
8798     // NOTE: Locking order for synchronized objects related to volume management:
8799     //  1     mSettingsLock
8800     //  2       mVolumeStateLock
8801     private class VolumeGroupState {
8802         private final AudioVolumeGroup mAudioVolumeGroup;
8803         private final SparseIntArray mIndexMap = new SparseIntArray(8);
8804         private int mIndexMin;
8805         private int mIndexMax;
8806         private boolean mHasValidStreamType = false;
8807         private int mPublicStreamType = AudioSystem.STREAM_MUSIC;
8808         private AudioAttributes mAudioAttributes = AudioProductStrategy.getDefaultAttributes();
8809         private boolean mIsMuted = false;
8810         private String mSettingName;
8811 
8812         // No API in AudioSystem to get a device from strategy or from attributes.
8813         // Need a valid public stream type to use current API getDeviceForStream
getDeviceForVolume()8814         private int getDeviceForVolume() {
8815             return getDeviceForStream(mPublicStreamType);
8816         }
8817 
VolumeGroupState(AudioVolumeGroup avg)8818         private VolumeGroupState(AudioVolumeGroup avg) {
8819             mAudioVolumeGroup = avg;
8820             if (DEBUG_VOL) {
8821                 Log.v(TAG, "VolumeGroupState for " + avg.toString());
8822             }
8823             // mAudioAttributes is the default at this point
8824             for (AudioAttributes aa : avg.getAudioAttributes()) {
8825                 if (!aa.equals(mAudioAttributes)) {
8826                     mAudioAttributes = aa;
8827                     break;
8828                 }
8829             }
8830             int[] streamTypes = mAudioVolumeGroup.getLegacyStreamTypes();
8831             String streamSettingName = "";
8832             if (streamTypes.length != 0) {
8833                 // Uses already initialized MIN / MAX if a stream type is attached to group
8834                 for (int streamType : streamTypes) {
8835                     if (streamType != AudioSystem.STREAM_DEFAULT
8836                             && streamType < AudioSystem.getNumStreamTypes()) {
8837                         mPublicStreamType = streamType;
8838                         mHasValidStreamType = true;
8839                         streamSettingName = System.VOLUME_SETTINGS_INT[mPublicStreamType];
8840                         break;
8841                     }
8842                 }
8843 
8844                 if (replaceStreamBtSco()) {
8845                     mIndexMin = getVssForStreamOrDefault(mPublicStreamType).getMinIndex() / 10;
8846                     mIndexMax = getVssForStreamOrDefault(mPublicStreamType).getMaxIndex() / 10;
8847                 } else {
8848                     mIndexMin = MIN_STREAM_VOLUME[mPublicStreamType];
8849                     mIndexMax = MAX_STREAM_VOLUME[mPublicStreamType];
8850                 }
8851             } else if (!avg.getAudioAttributes().isEmpty()) {
8852                 mIndexMin = AudioSystem.getMinVolumeIndexForAttributes(mAudioAttributes);
8853                 mIndexMax = AudioSystem.getMaxVolumeIndexForAttributes(mAudioAttributes);
8854             } else {
8855                 throw new IllegalArgumentException("volume group: " + mAudioVolumeGroup.name()
8856                         + " has neither valid attributes nor valid stream types assigned");
8857             }
8858             mSettingName = !streamSettingName.isEmpty() ? streamSettingName : ("volume_" + name());
8859             // Load volume indexes from data base
8860             readSettings();
8861         }
8862 
getLegacyStreamTypes()8863         public @NonNull int[] getLegacyStreamTypes() {
8864             return mAudioVolumeGroup.getLegacyStreamTypes();
8865         }
8866 
name()8867         public String name() {
8868             return mAudioVolumeGroup.name();
8869         }
8870 
getId()8871         public int getId() {
8872             return mAudioVolumeGroup.getId();
8873         }
8874 
8875         /**
8876          * Volume group with non null minimum index are considered as non mutable, thus
8877          * bijectivity is broken with potential associated stream type.
8878          * VOICE_CALL stream has minVolumeIndex > 0  but can be muted directly by an
8879          * app that has MODIFY_PHONE_STATE permission.
8880          */
isVssMuteBijective(int stream)8881         private boolean isVssMuteBijective(int stream) {
8882             return isStreamAffectedByMute(stream)
8883                     && (getMinIndex() == (getVssForStreamOrDefault(stream).getMinIndex() + 5) / 10)
8884                     && (getMinIndex() == 0 || isCallStream(stream));
8885         }
8886 
isMutable()8887         private boolean isMutable() {
8888             return mIndexMin == 0 || (mHasValidStreamType && isVssMuteBijective(mPublicStreamType));
8889         }
8890         /**
8891          * Mute/unmute the volume group
8892          * @param muted the new mute state
8893          */
8894         @GuardedBy("AudioService.this.mVolumeStateLock")
mute(boolean muted)8895         public boolean mute(boolean muted) {
8896             if (!isMutable()) {
8897                 // Non mutable volume group
8898                 if (DEBUG_VOL) {
8899                     Log.d(TAG, "invalid mute on unmutable volume group " + name());
8900                 }
8901                 return false;
8902             }
8903             boolean changed = (mIsMuted != muted);
8904             // As for VSS, mute shall apply minIndex to all devices found in IndexMap and default.
8905             if (changed) {
8906                 mIsMuted = muted;
8907                 applyAllVolumes(false /*userSwitch*/);
8908             }
8909             return changed;
8910         }
8911 
isMuted()8912         public boolean isMuted() {
8913             return mIsMuted;
8914         }
8915 
adjustVolume(int direction, int flags)8916         public void adjustVolume(int direction, int flags) {
8917             synchronized (mSettingsLock) {
8918                 synchronized (mVolumeStateLock) {
8919                     int device = getDeviceForVolume();
8920                     int previousIndex = getIndex(device);
8921                     if (isMuteAdjust(direction) && !isMutable()) {
8922                         // Non mutable volume group
8923                         if (DEBUG_VOL) {
8924                             Log.d(TAG, "invalid mute on unmutable volume group " + name());
8925                         }
8926                         return;
8927                     }
8928 
8929                     float stepFactor = getVssForStreamOrDefault(
8930                             mPublicStreamType).getIndexStepFactor();
8931                     switch (direction) {
8932                         case AudioManager.ADJUST_TOGGLE_MUTE: {
8933                             // Note: If muted by volume 0, unmute will restore volume 0.
8934                             mute(!mIsMuted);
8935                             break;
8936                         }
8937                         case AudioManager.ADJUST_UNMUTE:
8938                             // Note: If muted by volume 0, unmute will restore volume 0.
8939                             mute(false);
8940                             break;
8941                         case AudioManager.ADJUST_MUTE:
8942                             // May be already muted by setvolume 0, prevent from setting same value
8943                             if (previousIndex != 0) {
8944                                 // bypass persist
8945                                 mute(true);
8946                             }
8947                             mIsMuted = true;
8948                             break;
8949                         case AudioManager.ADJUST_RAISE:
8950                             // As for stream, RAISE during mute will increment the index
8951                             setVolumeIndex(Math.min((int) ((previousIndex + 1) * stepFactor),
8952                                     mIndexMax), device, flags);
8953                             break;
8954                         case AudioManager.ADJUST_LOWER:
8955                             // For stream, ADJUST_LOWER on a muted VSS is a no-op
8956                             // If we decide to unmute on ADJUST_LOWER, cannot fallback on
8957                             // adjustStreamVolume for group associated to legacy stream type
8958                             if (isMuted() && previousIndex != 0) {
8959                                 mute(false);
8960                             } else {
8961                                 int newIndex = Math.max((int) ((previousIndex - 1) * stepFactor),
8962                                         mIndexMin);
8963                                 setVolumeIndex(newIndex, device, flags);
8964                             }
8965                             break;
8966                     }
8967                 }
8968             }
8969         }
8970 
getVolumeIndex()8971         public int getVolumeIndex() {
8972             synchronized (mVolumeStateLock) {
8973                 return getIndex(getDeviceForVolume());
8974             }
8975         }
8976 
setVolumeIndex(int index, int flags)8977         public void setVolumeIndex(int index, int flags) {
8978             synchronized (mSettingsLock) {
8979                 synchronized (mVolumeStateLock) {
8980                     if (mUseFixedVolume) {
8981                         return;
8982                     }
8983                     setVolumeIndex(index, getDeviceForVolume(), flags);
8984                 }
8985             }
8986         }
8987 
8988         @GuardedBy("AudioService.this.mVolumeStateLock")
setVolumeIndex(int index, int device, int flags)8989         private void setVolumeIndex(int index, int device, int flags) {
8990             // Update cache & persist (muted by volume 0 shall be persisted)
8991             updateVolumeIndex(index, device);
8992             // setting non-zero volume for a muted stream unmutes the stream and vice versa,
8993             boolean changed = mute(index == 0);
8994             if (!changed) {
8995                 // Set the volume index only if mute operation is a no-op
8996                 index = getValidIndex(index);
8997                 setVolumeIndexInt(index, device, flags);
8998             }
8999         }
9000 
9001         @GuardedBy("AudioService.this.mVolumeStateLock")
updateVolumeIndex(int index, int device)9002         public void updateVolumeIndex(int index, int device) {
9003             // Filter persistency if already exist and the index has not changed
9004             if (mIndexMap.indexOfKey(device) < 0 || mIndexMap.get(device) != index) {
9005                 // Update local cache
9006                 mIndexMap.put(device, getValidIndex(index));
9007 
9008                 // update data base - post a persist volume group msg
9009                 sendMsg(mAudioHandler,
9010                         MSG_PERSIST_VOLUME_GROUP,
9011                         SENDMSG_QUEUE,
9012                         device,
9013                         0,
9014                         this,
9015                         PERSIST_DELAY);
9016             }
9017         }
9018 
9019         @GuardedBy("AudioService.this.mVolumeStateLock")
setVolumeIndexInt(int index, int device, int flags)9020         private void setVolumeIndexInt(int index, int device, int flags) {
9021             // Reflect mute state of corresponding stream by forcing index to 0 if muted
9022             // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted.
9023             // This allows RX path muting by the audio HAL only when explicitly muted but not when
9024             // index is just set to 0 to repect BT requirements
9025             boolean muted = false;
9026             if (mHasValidStreamType && isVssMuteBijective(mPublicStreamType)
9027                     && getVssForStreamOrDefault(mPublicStreamType).isFullyMuted()) {
9028                 if (ringMyCar()) {
9029                     muted = true;
9030                 } else {
9031                     index = 0;
9032                 }
9033             } else if (isStreamBluetoothSco(mPublicStreamType) && index == 0) {
9034                 index = 1;
9035             }
9036 
9037             if (replaceStreamBtSco()) {
9038                 index = (int) (mIndexMin + (index - mIndexMin)
9039                         / getVssForStreamOrDefault(mPublicStreamType).getIndexStepFactor());
9040             }
9041 
9042 
9043             if (DEBUG_VOL) {
9044                 Log.d(TAG, "setVolumeIndexInt(" + mAudioVolumeGroup.getId() + ", " + index + ", "
9045                         + muted + ", " + device + ")");
9046             }
9047 
9048             // Set the volume index
9049             mAudioSystem.setVolumeIndexForAttributes(mAudioAttributes, index, muted, device);
9050         }
9051 
9052         @GuardedBy("AudioService.this.mVolumeStateLock")
getIndex(int device)9053         private int getIndex(int device) {
9054             int index = mIndexMap.get(device, -1);
9055             // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
9056             return (index != -1) ? index : mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT);
9057         }
9058 
9059         @GuardedBy("AudioService.this.mVolumeStateLock")
hasIndexForDevice(int device)9060         private boolean hasIndexForDevice(int device) {
9061             return (mIndexMap.get(device, -1) != -1);
9062         }
9063 
getMaxIndex()9064         public int getMaxIndex() {
9065             return mIndexMax;
9066         }
9067 
getMinIndex()9068         public int getMinIndex() {
9069             return mIndexMin;
9070         }
9071 
isValidStream(int stream)9072         private boolean isValidStream(int stream) {
9073             return (stream != AudioSystem.STREAM_DEFAULT) && getVssForStream(stream) != null;
9074         }
9075 
isMusic()9076         public boolean isMusic() {
9077             return mHasValidStreamType && mPublicStreamType == AudioSystem.STREAM_MUSIC;
9078         }
9079 
isVoiceCall()9080         public boolean isVoiceCall() {
9081             return mHasValidStreamType && mPublicStreamType == AudioSystem.STREAM_VOICE_CALL;
9082         }
9083 
applyAllVolumes(boolean userSwitch)9084         public void applyAllVolumes(boolean userSwitch) {
9085             String caller = "from vgs";
9086             synchronized (mVolumeStateLock) {
9087                 // apply device specific volumes first
9088                 for (int i = 0; i < mIndexMap.size(); i++) {
9089                     int device = mIndexMap.keyAt(i);
9090                     int index = mIndexMap.valueAt(i);
9091                     boolean synced = false;
9092                     if (device != AudioSystem.DEVICE_OUT_DEFAULT) {
9093                         for (int stream : getLegacyStreamTypes()) {
9094                             if (isValidStream(stream)) {
9095                                 final VolumeStreamState vss = getVssForStreamOrDefault(stream);
9096                                 boolean streamMuted = vss.mIsMuted;
9097                                 int deviceForStream = getDeviceForStream(stream);
9098                                 int indexForStream = (vss.getIndex(deviceForStream) + 5) / 10;
9099                                 if (device == deviceForStream) {
9100                                     if (indexForStream == index && (isMuted() == streamMuted)
9101                                             && isVssMuteBijective(stream)) {
9102                                         synced = true;
9103                                         continue;
9104                                     }
9105                                     if ((isMuted() != streamMuted) && isVssMuteBijective(stream)) {
9106                                         vss.mute(isMuted(), "VGS.applyAllVolumes#1");
9107                                     }
9108                                     if (indexForStream != index) {
9109                                         vss.setIndex(index * 10, device,
9110                                                 caller, true /*hasModifyAudioSettings*/);
9111                                     }
9112                                 }
9113                             }
9114                         }
9115                         if (!synced) {
9116                             if (DEBUG_VOL) {
9117                                 Log.d(TAG, "applyAllVolumes: apply index " + index + ", group "
9118                                         + mAudioVolumeGroup.name() + " and device "
9119                                         + AudioSystem.getOutputDeviceName(device));
9120                             }
9121                             setVolumeIndexInt(isMuted() ? 0 : index, device, 0 /*flags*/);
9122                         }
9123                     }
9124                 }
9125                 // apply default volume last: by convention , default device volume will be used
9126                 // by audio policy manager if no explicit volume is present for a given device type
9127                 int index = getIndex(AudioSystem.DEVICE_OUT_DEFAULT);
9128                 boolean synced = false;
9129                 int deviceForVolume = getDeviceForVolume();
9130                 boolean forceDeviceSync = userSwitch && (mIndexMap.indexOfKey(deviceForVolume) < 0);
9131                 for (int stream : getLegacyStreamTypes()) {
9132                     if (isValidStream(stream)) {
9133                         final VolumeStreamState vss = getVssForStreamOrDefault(stream);
9134                         boolean streamMuted = vss.mIsMuted;
9135                         int defaultStreamIndex = (vss.getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)
9136                                 / 10;
9137                         if (forceDeviceSync) {
9138                             vss.setIndex(index * 10, deviceForVolume, caller,
9139                                     true /*hasModifyAudioSettings*/);
9140                         }
9141                         if (defaultStreamIndex == index && (isMuted() == streamMuted)
9142                                 && isVssMuteBijective(stream)) {
9143                             synced = true;
9144                             continue;
9145                         }
9146                         if (defaultStreamIndex != index) {
9147                             vss.setIndex(index * 10, AudioSystem.DEVICE_OUT_DEFAULT, caller,
9148                                     true /*hasModifyAudioSettings*/);
9149                         }
9150                         if ((isMuted() != streamMuted) && isVssMuteBijective(stream)) {
9151                             vss.mute(isMuted(), "VGS.applyAllVolumes#2");
9152                         }
9153                     }
9154                 }
9155                 if (!synced) {
9156                     if (DEBUG_VOL) {
9157                         Log.d(TAG, "applyAllVolumes: apply default device index " + index
9158                                 + ", group " + mAudioVolumeGroup.name());
9159                     }
9160                     setVolumeIndexInt(
9161                             isMuted() ? 0 : index, AudioSystem.DEVICE_OUT_DEFAULT, 0 /*flags*/);
9162                 }
9163                 if (forceDeviceSync) {
9164                     if (DEBUG_VOL) {
9165                         Log.d(TAG, "applyAllVolumes: forceDeviceSync index " + index
9166                                 + ", device " + AudioSystem.getOutputDeviceName(deviceForVolume)
9167                                 + ", group " + mAudioVolumeGroup.name());
9168                     }
9169                     setVolumeIndexInt(isMuted() ? 0 : index, deviceForVolume, 0);
9170                 }
9171             }
9172         }
9173 
clearIndexCache()9174         public void clearIndexCache() {
9175             mIndexMap.clear();
9176         }
9177 
getVolumePersistenceUserId()9178         private @UserIdInt int getVolumePersistenceUserId() {
9179             return isMusic() && !isPlatformAutomotive()
9180                     ? UserHandle.USER_SYSTEM : UserHandle.USER_CURRENT;
9181         }
9182 
persistVolumeGroup(int device)9183         private void persistVolumeGroup(int device) {
9184             // No need to persist the index if the volume group is backed up
9185             // by a public stream type as this is redundant
9186             if (mUseFixedVolume || mHasValidStreamType) {
9187                 return;
9188             }
9189             synchronized (mVolumeStateLock) {
9190                 if (DEBUG_VOL) {
9191                     Log.v(TAG, "persistVolumeGroup: storing index " + getIndex(device)
9192                             + " for group " + mAudioVolumeGroup.name()
9193                             + ", device " + AudioSystem.getOutputDeviceName(device)
9194                             + " and User=" + getCurrentUserId()
9195                             + " mSettingName: " + mSettingName);
9196                 }
9197 
9198                 boolean success = mSettings.putSystemIntForUser(mContentResolver,
9199                         getSettingNameForDevice(device),
9200                         getIndex(device),
9201                         getVolumePersistenceUserId());
9202                 if (!success) {
9203                     Log.e(TAG, "persistVolumeGroup failed for group " +  mAudioVolumeGroup.name());
9204                 }
9205             }
9206         }
9207 
readSettings()9208         public void readSettings() {
9209             synchronized (mVolumeStateLock) {
9210                 // force maximum volume on all streams if fixed volume property is set
9211                 if (mUseFixedVolume) {
9212                     mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
9213                     return;
9214                 }
9215                 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
9216                     // retrieve current volume for device
9217                     // if no volume stored for current volume group and device, use default volume
9218                     // if default device, continue otherwise
9219                     int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT)
9220                             ? AudioSystem.DEFAULT_STREAM_VOLUME[mPublicStreamType] : -1;
9221                     int index;
9222                     String name = getSettingNameForDevice(device);
9223                     index = mSettings.getSystemIntForUser(
9224                             mContentResolver, name, defaultIndex,
9225                             getVolumePersistenceUserId());
9226                     if (index == -1) {
9227                         continue;
9228                     }
9229                     if (mPublicStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED
9230                             && mCameraSoundForced.get()) {
9231                         index = mIndexMax;
9232                     }
9233                     if (DEBUG_VOL) {
9234                         Log.v(TAG, "readSettings: found stored index " + getValidIndex(index)
9235                                  + " for group " + mAudioVolumeGroup.name() + ", device: " + name
9236                                  + ", User=" + getCurrentUserId());
9237                     }
9238                     mIndexMap.put(device, getValidIndex(index));
9239                 }
9240             }
9241         }
9242 
9243         @GuardedBy("AudioService.this.mVolumeStateLock")
getValidIndex(int index)9244         private int getValidIndex(int index) {
9245             if (index < mIndexMin) {
9246                 return mIndexMin;
9247             } else if (mUseFixedVolume || index > mIndexMax) {
9248                 return mIndexMax;
9249             }
9250             return index;
9251         }
9252 
getSettingNameForDevice(int device)9253         public @NonNull String getSettingNameForDevice(int device) {
9254             String suffix = AudioSystem.getOutputDeviceName(device);
9255             if (suffix.isEmpty()) {
9256                 return mSettingName;
9257             }
9258             return mSettingName + "_" + AudioSystem.getOutputDeviceName(device);
9259         }
9260 
setSettingName(String settingName)9261         void setSettingName(String settingName) {
9262             mSettingName = settingName;
9263         }
9264 
getSettingName()9265         String getSettingName() {
9266             return mSettingName;
9267         }
9268 
dump(PrintWriter pw)9269         private void dump(PrintWriter pw) {
9270             pw.println("- VOLUME GROUP " + mAudioVolumeGroup.name() + ":");
9271             pw.print("   Muted: ");
9272             pw.println(mIsMuted);
9273             pw.print("   Min: ");
9274             pw.println(mIndexMin);
9275             pw.print("   Max: ");
9276             pw.println(mIndexMax);
9277             pw.print("   Current: ");
9278             for (int i = 0; i < mIndexMap.size(); i++) {
9279                 if (i > 0) {
9280                     pw.print(", ");
9281                 }
9282                 int device = mIndexMap.keyAt(i);
9283                 pw.print(Integer.toHexString(device));
9284                 String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
9285                         : AudioSystem.getOutputDeviceName(device);
9286                 if (!deviceName.isEmpty()) {
9287                     pw.print(" (");
9288                     pw.print(deviceName);
9289                     pw.print(")");
9290                 }
9291                 pw.print(": ");
9292                 pw.print(mIndexMap.valueAt(i));
9293             }
9294             pw.println();
9295             pw.print("   Devices: ");
9296             int n = 0;
9297             int devices = getDeviceForVolume();
9298             for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
9299                 if ((devices & device) == device) {
9300                     if (n++ > 0) {
9301                         pw.print(", ");
9302                     }
9303                     pw.print(AudioSystem.getOutputDeviceName(device));
9304                 }
9305             }
9306             pw.println();
9307             pw.print("   Streams: ");
9308             Arrays.stream(getLegacyStreamTypes())
9309                     .forEach(stream -> pw.print(AudioSystem.streamToString(stream) + " "));
9310         }
9311     }
9312 
9313     // NOTE: Locking order for synchronized objects related to volume or ringer mode management:
9314     //  1 mScoclient OR mSafeMediaVolumeState
9315     //  2   mSetModeLock
9316     //  3     mSettingsLock
9317     //  4       mVolumeStateLock
9318     /*package*/ class VolumeStreamState {
9319         private final int mStreamType;
9320         private VolumeGroupState mVolumeGroupState = null;
9321         private int mIndexMin;
9322         // min index when user doesn't have permission to change audio settings
9323         private int mIndexMinNoPerm;
9324         private int mIndexMax;
9325 
9326         /**
9327          * Variable used to determine the size of an incremental step when calling the
9328          * adjustStreamVolume methods with raise/lower adjustments. This can change dynamically
9329          * for some streams.
9330          *
9331          * <p>STREAM_VOICE_CALL has a different step value when is streaming on a SCO device.
9332          * Internally we are using the same volume range but through the step factor we force the
9333          * number of UI volume steps.
9334          */
9335         private float mIndexStepFactor = 1.f;
9336 
9337         private boolean mIsMuted = false;
9338         private boolean mIsMutedInternally = false;
9339         private String mVolumeIndexSettingName;
9340         @NonNull private Set<Integer> mObservedDeviceSet = new TreeSet<>();
9341 
9342         private final SparseIntArray mIndexMap = new SparseIntArray(8) {
9343             @Override
9344             public void put(int key, int value) {
9345                 super.put(key, value);
9346                 record("put", key, value);
9347                 if (cacheGetStreamVolume()) {
9348                     if (DEBUG_VOL) {
9349                         Log.d(TAG, "Clear volume cache after update index map");
9350                     }
9351                     AudioManager.clearVolumeCache(AudioManager.VOLUME_CACHING_API);
9352                 }
9353             }
9354             @Override
9355             public void setValueAt(int index, int value) {
9356                 super.setValueAt(index, value);
9357                 record("setValueAt", keyAt(index), value);
9358                 if (cacheGetStreamVolume()) {
9359                     if (DEBUG_VOL) {
9360                         Log.d(TAG, "Clear volume cache after update index map");
9361                     }
9362                     AudioManager.clearVolumeCache(AudioManager.VOLUME_CACHING_API);
9363                 }
9364             }
9365 
9366             // Record all changes in the VolumeStreamState
9367             private void record(String event, int key, int value) {
9368                 final String device = key == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
9369                         : AudioSystem.getOutputDeviceName(key);
9370                 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_VOLUME + MediaMetrics.SEPARATOR
9371                         + AudioSystem.streamToString(mStreamType)
9372                         + "." + device)
9373                         .set(MediaMetrics.Property.EVENT, event)
9374                         .set(MediaMetrics.Property.INDEX, value)
9375                         .set(MediaMetrics.Property.MIN_INDEX, mIndexMin)
9376                         .set(MediaMetrics.Property.MAX_INDEX, mIndexMax)
9377                         .record();
9378             }
9379         };
9380         private final Intent mVolumeChanged;
9381         private final Bundle mVolumeChangedOptions;
9382         private final Intent mStreamDevicesChanged;
9383         private final Bundle mStreamDevicesChangedOptions;
9384 
VolumeStreamState(String settingName, int streamType)9385         private VolumeStreamState(String settingName, int streamType) {
9386             mVolumeIndexSettingName = settingName;
9387 
9388             mStreamType = streamType;
9389             mIndexMin = MIN_STREAM_VOLUME[streamType] * 10;
9390             mIndexMax = MAX_STREAM_VOLUME[streamType] * 10;
9391 
9392             updateIndexFactors();
9393             mIndexMinNoPerm = mIndexMin; // may be overwritten later in updateNoPermMinIndex()
9394 
9395             readSettings();
9396             mVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION);
9397             mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
9398             final BroadcastOptions volumeChangedOptions = BroadcastOptions.makeBasic();
9399             // This allows us to discard older broadcasts still waiting to be delivered
9400             // which have the same namespace (VOLUME_CHANGED_ACTION) and key (mStreamType).
9401             volumeChangedOptions.setDeliveryGroupPolicy(DELIVERY_GROUP_POLICY_MOST_RECENT);
9402             volumeChangedOptions.setDeliveryGroupMatchingKey(
9403                     AudioManager.VOLUME_CHANGED_ACTION, String.valueOf(mStreamType));
9404             volumeChangedOptions.setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE);
9405             mVolumeChangedOptions = volumeChangedOptions.toBundle();
9406 
9407             mStreamDevicesChanged = new Intent(AudioManager.STREAM_DEVICES_CHANGED_ACTION);
9408             mStreamDevicesChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
9409             final BroadcastOptions streamDevicesChangedOptions = BroadcastOptions.makeBasic();
9410             streamDevicesChangedOptions.setDeliveryGroupPolicy(DELIVERY_GROUP_POLICY_MOST_RECENT);
9411             streamDevicesChangedOptions.setDeliveryGroupMatchingKey(
9412                     AudioManager.STREAM_DEVICES_CHANGED_ACTION, String.valueOf(mStreamType));
9413             streamDevicesChangedOptions.setDeferralPolicy(
9414                     BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE);
9415             mStreamDevicesChangedOptions = streamDevicesChangedOptions.toBundle();
9416         }
9417 
updateIndexFactors()9418         public void updateIndexFactors() {
9419             if (!replaceStreamBtSco() && !equalScoLeaVcIndexRange()) {
9420                 return;
9421             }
9422 
9423             // index values sent to APM are in the stream type SDK range, not *10
9424             int indexMinVolCurve = MIN_STREAM_VOLUME[mStreamType];
9425             int indexMaxVolCurve = MAX_STREAM_VOLUME[mStreamType];
9426             synchronized (this) {
9427                 if (mStreamType == AudioSystem.STREAM_VOICE_CALL) {
9428                     if (MAX_STREAM_VOLUME[AudioSystem.STREAM_BLUETOOTH_SCO]
9429                             > MAX_STREAM_VOLUME[mStreamType]) {
9430                         mIndexMax = MAX_STREAM_VOLUME[AudioSystem.STREAM_BLUETOOTH_SCO] * 10;
9431                     }
9432 
9433                     if (!equalScoLeaVcIndexRange() && isStreamBluetoothSco(mStreamType)) {
9434                         // SCO devices have a different min index
9435                         mIndexMin = MIN_STREAM_VOLUME[AudioSystem.STREAM_BLUETOOTH_SCO] * 10;
9436                         indexMinVolCurve = MIN_STREAM_VOLUME[AudioSystem.STREAM_BLUETOOTH_SCO];
9437                         indexMaxVolCurve = MAX_STREAM_VOLUME[AudioSystem.STREAM_BLUETOOTH_SCO];
9438                         mIndexStepFactor = 1.f;
9439                     } else if (equalScoLeaVcIndexRange() && isStreamBluetoothComm(mStreamType)) {
9440                         // For non SCO devices the stream state does not change the min index
9441                         if (mBtCommDeviceActive.get() == BT_COMM_DEVICE_ACTIVE_SCO) {
9442                             mIndexMin = MIN_STREAM_VOLUME[AudioSystem.STREAM_BLUETOOTH_SCO] * 10;
9443                             indexMinVolCurve = MIN_STREAM_VOLUME[AudioSystem.STREAM_BLUETOOTH_SCO];
9444                             indexMaxVolCurve = MAX_STREAM_VOLUME[AudioSystem.STREAM_BLUETOOTH_SCO];
9445                         } else {
9446                             mIndexMin = MIN_STREAM_VOLUME[mStreamType] * 10;
9447                         }
9448                         mIndexStepFactor = 1.f;
9449                     } else {
9450                         mIndexMin = MIN_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] * 10;
9451                         mIndexStepFactor = (float) (mIndexMax - mIndexMin) / (float) (
9452                                 MAX_STREAM_VOLUME[mStreamType] * 10
9453                                         - MIN_STREAM_VOLUME[mStreamType] * 10);
9454                     }
9455 
9456                     if (mVolumeGroupState != null) {
9457                         mVolumeGroupState.mIndexMin = mIndexMin;
9458                     }
9459 
9460                     mIndexMinNoPerm = mIndexMin;
9461                 }
9462             }
9463             if (cacheGetStreamMinMaxVolume() && mStreamType == AudioSystem.STREAM_VOICE_CALL) {
9464                 if (DEBUG_VOL) {
9465                     Log.d(TAG, "Clear min volume cache from updateIndexFactors");
9466                 }
9467                 AudioManager.clearVolumeCache(AudioManager.VOLUME_MIN_CACHING_API);
9468             }
9469 
9470             final int status = AudioSystem.initStreamVolume(
9471                     mStreamType, indexMinVolCurve, indexMaxVolCurve);
9472             sVolumeLogger.enqueue(new EventLogger.StringEvent(
9473                     "updateIndexFactors() stream:" + mStreamType + " index min/max:"
9474                             + mIndexMin / 10 + "/" + mIndexMax / 10 + " indexStepFactor:"
9475                             + mIndexStepFactor).printSlog(ALOGI, TAG));
9476             if (status != AudioSystem.AUDIO_STATUS_OK) {
9477                 sVolumeLogger.enqueue(new EventLogger.StringEvent(
9478                         "Failed initStreamVolume with status=" + status).printSlog(ALOGE, TAG));
9479                 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0,
9480                         "updateIndexFactors()" /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
9481             }
9482         }
9483 
9484         /**
9485          * Associate a {@link volumeGroupState} on the {@link VolumeStreamState}.
9486          * <p> It helps to synchronize the index, mute attributes on the maching
9487          * {@link volumeGroupState}
9488          * @param volumeGroupState matching the {@link VolumeStreamState}
9489          */
setVolumeGroupState(VolumeGroupState volumeGroupState)9490         public void setVolumeGroupState(VolumeGroupState volumeGroupState) {
9491             mVolumeGroupState = volumeGroupState;
9492             if (mVolumeGroupState != null) {
9493                 mVolumeGroupState.setSettingName(mVolumeIndexSettingName);
9494             }
9495         }
9496 
getIndexStepFactor()9497         public float getIndexStepFactor() {
9498             return mIndexStepFactor;
9499         }
9500 
9501         /**
9502          * Update the minimum index that can be used without MODIFY_AUDIO_SETTINGS permission
9503          * @param index minimum index expressed in "UI units", i.e. no 10x factor
9504          */
updateNoPermMinIndex(int index)9505         public void updateNoPermMinIndex(int index) {
9506             boolean changedNoPermMinIndex =
9507                     cacheGetStreamMinMaxVolume() && (index * 10) != mIndexMinNoPerm;
9508             mIndexMinNoPerm = index * 10;
9509             if (mIndexMinNoPerm < mIndexMin) {
9510                 Log.e(TAG, "Invalid mIndexMinNoPerm for stream " + mStreamType);
9511                 mIndexMinNoPerm = mIndexMin;
9512             }
9513             if (changedNoPermMinIndex) {
9514                 if (DEBUG_VOL) {
9515                     Log.d(TAG, "Clear min volume cache from updateNoPermMinIndex");
9516                 }
9517                 AudioManager.clearVolumeCache(AudioManager.VOLUME_MIN_CACHING_API);
9518             }
9519         }
9520 
9521         /**
9522          * Returns a list of devices associated with the stream type.
9523          *
9524          * This is a reference to the local list, do not modify.
9525          */
9526         @GuardedBy("mVolumeStateLock")
9527         @NonNull
observeDevicesForStream_syncVSS( boolean checkOthers)9528         public Set<Integer> observeDevicesForStream_syncVSS(
9529                 boolean checkOthers) {
9530             if (!mSystemServer.isPrivileged()) {
9531                 return new TreeSet<Integer>();
9532             }
9533             final Set<Integer> deviceSet =
9534                     getDeviceSetForStreamDirect(mStreamType);
9535             if (deviceSet.equals(mObservedDeviceSet)) {
9536                 return mObservedDeviceSet;
9537             }
9538 
9539             // Use legacy bit masks for message signalling.
9540             // TODO(b/185386781): message needs update since it uses devices bit-mask.
9541             final int devices = AudioSystem.getDeviceMaskFromSet(deviceSet);
9542             final int prevDevices = AudioSystem.getDeviceMaskFromSet(mObservedDeviceSet);
9543 
9544             mObservedDeviceSet = deviceSet;
9545             if (checkOthers) {
9546                 // one stream's devices have changed, check the others
9547                 postObserveDevicesForAllStreams(mStreamType);
9548             }
9549             // log base stream changes to the event log
9550             if (sStreamVolumeAlias.get(mStreamType, /*valueIfKeyNotFound=*/-1) == mStreamType) {
9551                 EventLogTags.writeStreamDevicesChanged(mStreamType, prevDevices, devices);
9552             }
9553             // send STREAM_DEVICES_CHANGED_ACTION on the message handler so it is scheduled after
9554             // the postObserveDevicesForStreams is handled
9555             final SomeArgs args = SomeArgs.obtain();
9556             args.arg1 = mStreamDevicesChanged;
9557             args.arg2 = mStreamDevicesChangedOptions;
9558             sendMsg(mAudioHandler,
9559                     MSG_STREAM_DEVICES_CHANGED,
9560                     SENDMSG_QUEUE, prevDevices /*arg1*/, devices /*arg2*/,
9561                     // ok to send reference to this object, it is final
9562                     args /*obj*/, 0 /*delay*/);
9563             return mObservedDeviceSet;
9564         }
9565 
getSettingNameForDevice(int device)9566         public @Nullable String getSettingNameForDevice(int device) {
9567             if (!hasValidSettingsName()) {
9568                 return null;
9569             }
9570             final String suffix = AudioSystem.getOutputDeviceName(device);
9571             if (suffix.isEmpty()) {
9572                 return mVolumeIndexSettingName;
9573             }
9574             return mVolumeIndexSettingName + "_" + suffix;
9575         }
9576 
hasValidSettingsName()9577         private boolean hasValidSettingsName() {
9578             return (mVolumeIndexSettingName != null && !mVolumeIndexSettingName.isEmpty());
9579         }
9580 
setSettingName(String settingName)9581         void setSettingName(String settingName) {
9582             mVolumeIndexSettingName = settingName;
9583             if (mVolumeGroupState != null) {
9584                 mVolumeGroupState.setSettingName(mVolumeIndexSettingName);
9585             }
9586         }
9587 
getSettingName()9588         String getSettingName() {
9589             return mVolumeIndexSettingName;
9590         }
9591 
readSettings()9592         public void readSettings() {
9593             synchronized (mVolumeStateLock) {
9594                 // force maximum volume on all streams if fixed volume property is set
9595                 if (mUseFixedVolume) {
9596                     mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
9597                     return;
9598                 }
9599                 // do not read system stream volume from settings: this stream is always aliased
9600                 // to another stream type and its volume is never persisted. Values in settings can
9601                 // only be stale values
9602                 if ((mStreamType == AudioSystem.STREAM_SYSTEM)
9603                         || (mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED)) {
9604                     int index = 10 * AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType];
9605                     if (mCameraSoundForced.get()) {
9606                         index = mIndexMax;
9607                     }
9608                     mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, index);
9609                     return;
9610                 }
9611 
9612                 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
9613 
9614                     // retrieve current volume for device
9615                     // if no volume stored for current stream and device, use default volume if default
9616                     // device, continue otherwise
9617                     int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) ?
9618                             AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType] : -1;
9619                     int index;
9620                     if (!hasValidSettingsName()) {
9621                         index = defaultIndex;
9622                     } else {
9623                         String name = getSettingNameForDevice(device);
9624                         index = mSettings.getSystemIntForUser(
9625                                 mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT);
9626                     }
9627                     if (index == -1) {
9628                         continue;
9629                     }
9630 
9631                     mIndexMap.put(device, getValidIndex(10 * index,
9632                             true /*hasModifyAudioSettings*/));
9633                 }
9634             }
9635         }
9636 
9637         /**
9638          * Sends the new volume index on the given device to native.
9639          *
9640          * <p>Make sure the index is consistent with the muting state. When ringMyCar is enabled
9641          * will send the non-zero index together with muted state. Otherwise, index 0  will be sent
9642          * to native for signalising a muted stream.
9643          **/
9644         @GuardedBy("mVolumeStateLock")
setStreamVolumeIndex(int index, int device)9645         private void setStreamVolumeIndex(int index, int device) {
9646             // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted.
9647             // This allows RX path muting by the audio HAL only when explicitly muted but not when
9648             // index is just set to 0 to respect BT requirements
9649             if (isStreamBluetoothSco(mStreamType) && index == 0 && !isFullyMuted()) {
9650                 index = 1;
9651             }
9652 
9653             if (replaceStreamBtSco() && index != 0) {
9654                 index = (int) (mIndexMin + (index * 10 - mIndexMin) / getIndexStepFactor() + 5)
9655                         / 10;
9656             }
9657 
9658             boolean muted = ringMyCar() ? isFullyMuted() : false;
9659             if (DEBUG_VOL) {
9660                 Log.d(TAG, "setStreamVolumeIndexAS(streamType=" + mStreamType + ", index=" + index
9661                         + ", muted=" + muted + ", device=" + device + ")");
9662             }
9663             mAudioSystem.setStreamVolumeIndexAS(mStreamType, index, muted, device);
9664         }
9665 
9666         // must be called while synchronized mVolumeStateLock
9667         @GuardedBy("mVolumeStateLock")
applyDeviceVolume_syncVSS(int device)9668         /*package*/ void applyDeviceVolume_syncVSS(int device) {
9669             int index;
9670             if (isFullyMuted() && !ringMyCar()) {
9671                 index = 0;
9672             } else if (isAbsoluteVolumeDevice(device)
9673                     || isA2dpAbsoluteVolumeDevice(device)
9674                     || AudioSystem.isLeAudioDeviceType(device)) {
9675                 // do not change the volume logic for dynamic abs behavior devices like HDMI
9676                 if (isAbsoluteVolumeDevice(device)) {
9677                     index = (mIndexMax + 5) / 10;
9678                 } else {
9679                     index = (getIndex(device) + 5) / 10;
9680                 }
9681             } else if (isFullVolumeDevice(device)) {
9682                 index = (mIndexMax + 5)/10;
9683             } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
9684                 index = (getIndex(device) + 5) / 10;
9685             } else {
9686                 index = (getIndex(device) + 5)/10;
9687             }
9688 
9689             setStreamVolumeIndex(index, device);
9690         }
9691 
applyAllVolumes()9692         public void applyAllVolumes() {
9693             synchronized (mVolumeStateLock) {
9694                 // apply device specific volumes first
9695                 int index;
9696                 boolean isAbsoluteVolume = false;
9697                 for (int i = 0; i < mIndexMap.size(); i++) {
9698                     final int device = mIndexMap.keyAt(i);
9699                     if (device != AudioSystem.DEVICE_OUT_DEFAULT) {
9700                         if (isFullyMuted() && !ringMyCar()) {
9701                             index = 0;
9702                         } else if (isAbsoluteVolumeDevice(device)
9703                                 || isA2dpAbsoluteVolumeDevice(device)
9704                                 || AudioSystem.isLeAudioDeviceType(device)) {
9705                             isAbsoluteVolume = true;
9706                             // do not change the volume logic for dynamic abs behavior devices
9707                             // like HDMI
9708                             if (isAbsoluteVolumeDevice(device)) {
9709                                 index = (mIndexMax + 5) / 10;
9710                             } else {
9711                                 index = (getIndex(device) + 5) / 10;
9712                             }
9713                         } else if (isFullVolumeDevice(device)) {
9714                             index = (mIndexMax + 5)/10;
9715                         } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
9716                             isAbsoluteVolume = true;
9717                             index = (getIndex(device) + 5) / 10;
9718                         } else {
9719                             index = (mIndexMap.valueAt(i) + 5)/10;
9720                         }
9721 
9722                         if (mStreamType == AudioSystem.STREAM_MUSIC) {
9723                             sendMsg(mAudioHandler, SoundDoseHelper.MSG_CSD_UPDATE_ATTENUATION,
9724                                     SENDMSG_QUEUE, device, isAbsoluteVolume ? 1 : 0, this,
9725                                     /*delay=*/0);
9726                         }
9727 
9728                         setStreamVolumeIndex(index, device);
9729                     }
9730                 }
9731                 // apply default volume last: by convention , default device volume will be used
9732                 // by audio policy manager if no explicit volume is present for a given device type
9733                 if (isFullyMuted() && !ringMyCar()) {
9734                     index = 0;
9735                 } else {
9736                     index = (getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)/10;
9737                 }
9738                 setStreamVolumeIndex(index, AudioSystem.DEVICE_OUT_DEFAULT);
9739             }
9740         }
9741 
adjustIndex(int deltaIndex, int device, String caller, boolean hasModifyAudioSettings)9742         public boolean adjustIndex(int deltaIndex, int device, String caller,
9743                 boolean hasModifyAudioSettings) {
9744             return setIndex(getIndex(device) + deltaIndex, device, caller,
9745                     hasModifyAudioSettings);
9746         }
9747 
setIndex(int index, int device, String caller, boolean hasModifyAudioSettings)9748         public boolean setIndex(int index, int device, String caller,
9749                 boolean hasModifyAudioSettings) {
9750             boolean changed;
9751             int oldIndex;
9752             final boolean isCurrentDevice;
9753             final StringBuilder aliasStreamIndexes = new StringBuilder();
9754             synchronized (mSettingsLock) {
9755                 synchronized (mVolumeStateLock) {
9756                     oldIndex = getIndex(device);
9757                     index = getValidIndex(index, hasModifyAudioSettings);
9758                     // for STREAM_SYSTEM_ENFORCED, do not sync aliased streams on the enforced index
9759                     int aliasIndex = index;
9760                     if ((mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED)
9761                             && mCameraSoundForced.get()) {
9762                         index = mIndexMax;
9763                     }
9764                     mIndexMap.put(device, index);
9765 
9766                     changed = oldIndex != index;
9767                     // Apply change to all streams using this one as alias if:
9768                     // - the index actually changed OR
9769                     // - there is no volume index stored for this device on alias stream.
9770                     // If changing volume of current device, also change volume of current
9771                     // device on aliased stream
9772                     isCurrentDevice = (device == getDeviceForStream(mStreamType));
9773                     final int numStreamTypes = AudioSystem.getNumStreamTypes();
9774                     for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
9775                         final VolumeStreamState aliasStreamState = getVssForStream(streamType);
9776                         if (aliasStreamState != null && streamType != mStreamType
9777                                 && sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound*/-1)
9778                                 == mStreamType && (changed || !aliasStreamState.hasIndexForDevice(
9779                                 device))) {
9780                             final int scaledIndex =
9781                                     rescaleIndex(aliasIndex, mStreamType, streamType);
9782                             boolean changedAlias = aliasStreamState.setIndex(scaledIndex, device,
9783                                     caller, hasModifyAudioSettings);
9784                             if (isCurrentDevice) {
9785                                 changedAlias |= aliasStreamState.setIndex(scaledIndex,
9786                                         getDeviceForStream(streamType), caller,
9787                                         hasModifyAudioSettings);
9788                             }
9789                             if (changedAlias) {
9790                                 aliasStreamIndexes.append(AudioSystem.streamToString(streamType))
9791                                         .append(":").append((scaledIndex + 5) / 10).append(" ");
9792                             }
9793                         }
9794                     }
9795                     // Mirror changes in SPEAKER ringtone volume on SCO when
9796                     if (changed && mStreamType == AudioSystem.STREAM_RING
9797                             && device == AudioSystem.DEVICE_OUT_SPEAKER) {
9798                         for (int i = 0; i < mIndexMap.size(); i++) {
9799                             int otherDevice = mIndexMap.keyAt(i);
9800                             if (AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(otherDevice)) {
9801                                 mIndexMap.put(otherDevice, index);
9802                             }
9803                         }
9804                     }
9805                     if (changed) {
9806                         // If associated to volume group, update group cache
9807                         updateVolumeGroupIndex(device, /* forceMuteState= */ false);
9808 
9809                         oldIndex = (oldIndex + 5) / 10;
9810                         index = (index + 5) / 10;
9811                         // log base stream changes to the event log
9812                         if (sStreamVolumeAlias.get(mStreamType, /*valueIfKeyNotFound=*/-1)
9813                                 == mStreamType) {
9814                             if (caller == null) {
9815                                 Log.w(TAG, "No caller for volume_changed event", new Throwable());
9816                             }
9817                             EventLogTags.writeVolumeChanged(
9818                                     mStreamType, oldIndex, index, mIndexMax / 10, caller);
9819                         }
9820                         // fire changed intents for all streams, but only when the device it changed
9821                         // on
9822                         //  is the current device
9823                         if ((index != oldIndex) && isCurrentDevice) {
9824                             // for single volume devices, only send the volume change broadcast
9825                             // on the alias stream
9826                             final int streamAlias =
9827                                     sStreamVolumeAlias.get(mStreamType, /*valueIfKeyNotFound=*/-1);
9828                             if (!mIsSingleVolume || streamAlias == mStreamType) {
9829                                 mVolumeChanged.putExtra(
9830                                         AudioManager.EXTRA_VOLUME_STREAM_VALUE, index);
9831                                 mVolumeChanged.putExtra(
9832                                         AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex);
9833                                 int extraStreamType = mStreamType;
9834                                 // TODO: remove this when deprecating STREAM_BLUETOOTH_SCO
9835                                 if (isStreamBluetoothSco(mStreamType)) {
9836                                     mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE,
9837                                             AudioSystem.STREAM_BLUETOOTH_SCO);
9838                                     extraStreamType = AudioSystem.STREAM_BLUETOOTH_SCO;
9839                                 } else {
9840                                     mVolumeChanged.putExtra(
9841                                             AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
9842                                 }
9843                                 mVolumeChanged.putExtra(
9844                                         AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS, streamAlias);
9845 
9846                                 if (mStreamType == streamAlias) {
9847                                     String aliasStreamIndexesString = "";
9848                                     if (!aliasStreamIndexes.isEmpty()) {
9849                                         aliasStreamIndexesString =
9850                                                 " aliased streams: " + aliasStreamIndexes;
9851                                     }
9852                                     AudioService.sVolumeLogger.enqueue(
9853                                             new VolChangedBroadcastEvent(extraStreamType,
9854                                                     aliasStreamIndexesString, index, oldIndex));
9855                                     if (extraStreamType != mStreamType) {
9856                                         AudioService.sVolumeLogger.enqueue(
9857                                                 new VolChangedBroadcastEvent(mStreamType,
9858                                                         aliasStreamIndexesString, index, oldIndex));
9859                                     }
9860                                 }
9861                                 sendBroadcastToAll(mVolumeChanged, mVolumeChangedOptions);
9862                                 if (extraStreamType != mStreamType) {
9863                                     // send multiple intents in case we merged voice call and bt sco
9864                                     // streams
9865                                     mVolumeChanged.putExtra(
9866                                             AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
9867                                     // do not use the options in thid case which could discard
9868                                     // the previous intent
9869                                     sendBroadcastToAll(mVolumeChanged, null);
9870                                 }
9871                             }
9872                         }
9873                     }
9874                     return changed;
9875                 }
9876             }
9877         }
9878 
getIndex(int device)9879         public int getIndex(int device) {
9880             synchronized (mVolumeStateLock) {
9881                 int index = mIndexMap.get(device, -1);
9882                 if (index == -1) {
9883                     // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
9884                     index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT);
9885                 }
9886                 return index;
9887             }
9888         }
9889 
getVolumeInfo(int device)9890         public @NonNull VolumeInfo getVolumeInfo(int device) {
9891             synchronized (mVolumeStateLock) {
9892                 int index = mIndexMap.get(device, -1);
9893                 if (index == -1) {
9894                     // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
9895                     index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT);
9896                 }
9897                 final VolumeInfo vi = new VolumeInfo.Builder(mStreamType)
9898                         .setMinVolumeIndex(getMinIndex())
9899                         .setMaxVolumeIndex(getMaxIndex())
9900                         .setVolumeIndex(index)
9901                         .setMuted(isFullyMuted())
9902                         .build();
9903                 return vi;
9904             }
9905         }
9906 
hasIndexForDevice(int device)9907         public boolean hasIndexForDevice(int device) {
9908             synchronized (mVolumeStateLock) {
9909                 return (mIndexMap.get(device, -1) != -1);
9910             }
9911         }
9912 
getMaxIndex()9913         public int getMaxIndex() {
9914             return mIndexMax;
9915         }
9916 
9917         /**
9918          * @return the lowest index regardless of permissions
9919          */
getMinIndex()9920         public int getMinIndex() {
9921             return mIndexMin;
9922         }
9923 
9924         /**
9925          * @param isPrivileged true if the caller is privileged and not subject to minimum
9926          *                     volume index thresholds
9927          * @return the lowest index that this caller can set or adjust to
9928          */
getMinIndex(boolean isPrivileged)9929         public int getMinIndex(boolean isPrivileged) {
9930             return isPrivileged ? mIndexMin : mIndexMinNoPerm;
9931         }
9932 
9933         /**
9934          * Copies all device/index pairs from the given VolumeStreamState after initializing
9935          * them with the volume for DEVICE_OUT_DEFAULT. No-op if the source VolumeStreamState
9936          * has the same stream type as this instance.
9937          * @param srcStream
9938          * @param caller
9939          */
9940         // must be sync'd on mSettingsLock before mVolumeStateLock
9941         @GuardedBy("mVolumeStateLock")
setAllIndexes(VolumeStreamState srcStream, String caller)9942         public void setAllIndexes(VolumeStreamState srcStream, String caller) {
9943             if (srcStream == null || mStreamType == srcStream.mStreamType) {
9944                 return;
9945             }
9946             int srcStreamType = srcStream.getStreamType();
9947             // apply default device volume from source stream to all devices first in case
9948             // some devices are present in this stream state but not in source stream state
9949             int index = srcStream.getIndex(AudioSystem.DEVICE_OUT_DEFAULT);
9950             index = rescaleIndex(index, srcStreamType, mStreamType);
9951             for (int i = 0; i < mIndexMap.size(); i++) {
9952                 mIndexMap.put(mIndexMap.keyAt(i), index);
9953             }
9954             // Now apply actual volume for devices in source stream state
9955             SparseIntArray srcMap = srcStream.mIndexMap;
9956             for (int i = 0; i < srcMap.size(); i++) {
9957                 int device = srcMap.keyAt(i);
9958                 index = srcMap.valueAt(i);
9959                 index = rescaleIndex(index, srcStreamType, mStreamType);
9960 
9961                 setIndex(index, device, caller, true /*hasModifyAudioSettings*/);
9962             }
9963         }
9964 
9965         // must be sync'd on mSettingsLock before mVolumeStateLock
9966         @GuardedBy("mVolumeStateLock")
setAllIndexesToMax()9967         public void setAllIndexesToMax() {
9968             for (int i = 0; i < mIndexMap.size(); i++) {
9969                 mIndexMap.put(mIndexMap.keyAt(i), mIndexMax);
9970             }
9971         }
9972 
9973         // If associated to volume group, update group cache
updateVolumeGroupIndex(int device, boolean forceMuteState)9974         private void updateVolumeGroupIndex(int device, boolean forceMuteState) {
9975             // need mSettingsLock when called from setIndex for vgs.mute -> vgs.applyAllVolumes ->
9976             // vss.setIndex which grabs this lock after VSS.class. Locking order needs to be
9977             // preserved
9978             synchronized (mSettingsLock) {
9979                 synchronized (mVolumeStateLock) {
9980                     if (mVolumeGroupState != null) {
9981                         int groupIndex = (getIndex(device) + 5) / 10;
9982                         if (DEBUG_VOL) {
9983                             Log.d(TAG, "updateVolumeGroupIndex for stream " + mStreamType
9984                                     + ", muted=" + mIsMuted + ", device=" + device + ", index="
9985                                     + getIndex(device) + ", group " + mVolumeGroupState.name()
9986                                     + " Muted=" + mVolumeGroupState.isMuted() + ", Index="
9987                                     + groupIndex + ", forceMuteState=" + forceMuteState);
9988                         }
9989                         mVolumeGroupState.updateVolumeIndex(groupIndex, device);
9990                         // Only propage mute of stream when applicable
9991                         if (isMutable()) {
9992                             // For call stream, align mute only when muted, not when index is set to
9993                             // 0
9994                             mVolumeGroupState.mute(
9995                                     forceMuteState ? mIsMuted :
9996                                             (groupIndex == 0 && !isCallStream(mStreamType))
9997                                                     || mIsMuted);
9998                         }
9999                     }
10000                 }
10001             }
10002         }
10003 
10004         /**
10005          * Mute/unmute the stream
10006          * @param state the new mute state
10007          * @return true if the mute state was changed
10008          */
mute(boolean state, String source)10009         public boolean mute(boolean state, String source) {
10010             boolean changed = false;
10011             synchronized (mVolumeStateLock) {
10012                 changed = mute(state, true, source);
10013             }
10014             if (changed) {
10015                 broadcastMuteSetting(mStreamType, state);
10016             }
10017             return changed;
10018         }
10019 
10020         /**
10021          * Mute/unmute the stream by AudioService
10022          * @param state the new mute state
10023          * @return true if the mute state was changed
10024          */
muteInternally(boolean state)10025         public boolean muteInternally(boolean state) {
10026             boolean changed = false;
10027             synchronized (mVolumeStateLock) {
10028                 if (state != mIsMutedInternally) {
10029                     changed = true;
10030                     mIsMutedInternally = state;
10031                     // mute immediately to avoid delay and preemption when using a message.
10032                     applyAllVolumes();
10033                 }
10034             }
10035             if (changed) {
10036                 sVolumeLogger.enqueue(new VolumeEvent(
10037                         VolumeEvent.VOL_MUTE_STREAM_INT, mStreamType, state));
10038             }
10039             return changed;
10040         }
10041 
10042         @GuardedBy("mVolumeStateLock")
isFullyMuted()10043         public boolean isFullyMuted() {
10044             return mIsMuted || mIsMutedInternally;
10045         }
10046 
10047 
isMutable()10048         private boolean isMutable() {
10049             return isStreamAffectedByMute(mStreamType)
10050                     && (mIndexMin == 0 || isCallStream(mStreamType));
10051         }
10052 
10053         /**
10054          * Mute/unmute the stream
10055          * @param state the new mute state
10056          * @param apply true to propagate to HW, or false just to update the cache. May be needed
10057          * to mute a stream and its aliases as applyAllVolume will force settings to aliases.
10058          * It prevents unnecessary calls to {@see AudioSystem#setStreamVolume}
10059          * @return true if the mute state was changed
10060          */
mute(boolean state, boolean apply, String src)10061         public boolean mute(boolean state, boolean apply, String src) {
10062             boolean changed;
10063             synchronized (mVolumeStateLock) {
10064                 changed = state != mIsMuted;
10065                 if (changed) {
10066                     sMuteLogger.enqueue(
10067                             new AudioServiceEvents.StreamMuteEvent(mStreamType, state, src));
10068                     // check to see if unmuting should not have happened due to ringer muted streams
10069                     if (!state && isStreamMutedByRingerOrZenMode(mStreamType)) {
10070                         Slog.e(TAG, "Attempt to unmute stream " + mStreamType
10071                                 + " despite ringer-zen muted stream 0x"
10072                                 + Integer.toHexString(AudioService.sRingerAndZenModeMutedStreams),
10073                                 new Exception()); // this will put a stack trace in the logs
10074                         sMuteLogger.enqueue(new AudioServiceEvents.StreamUnmuteErrorEvent(
10075                                 mStreamType, AudioService.sRingerAndZenModeMutedStreams));
10076                         // do not change mute state
10077                         return false;
10078                     }
10079                     mIsMuted = state;
10080                     if (apply) {
10081                         doMute();
10082                     }
10083                 }
10084             }
10085 
10086             if (cacheGetStreamVolume() && changed) {
10087                 if (DEBUG_VOL) {
10088                     Log.d(TAG, "Clear volume cache after changing mute state");
10089                 }
10090                 AudioManager.clearVolumeCache(AudioManager.VOLUME_CACHING_API);
10091             }
10092 
10093             return changed;
10094         }
10095 
doMute()10096         public void doMute() {
10097             synchronized (mVolumeStateLock) {
10098                 // If associated to volume group, update group cache
10099                 updateVolumeGroupIndex(getDeviceForStream(mStreamType), /* forceMuteState= */true);
10100 
10101                 // Set the new mute volume. This propagates the values to
10102                 // the audio system, otherwise the volume won't be changed
10103                 // at the lower level.
10104                 sendMsg(mAudioHandler,
10105                         MSG_SET_ALL_VOLUMES,
10106                         SENDMSG_QUEUE,
10107                         0,
10108                         0,
10109                         this, 0);
10110             }
10111         }
10112 
getStreamType()10113         public int getStreamType() {
10114             return mStreamType;
10115         }
10116 
checkFixedVolumeDevices()10117         public void checkFixedVolumeDevices() {
10118             synchronized (mVolumeStateLock) {
10119                 // ignore settings for fixed volume devices: volume should always be at max or 0
10120                 if (sStreamVolumeAlias.get(mStreamType) == AudioSystem.STREAM_MUSIC) {
10121                     for (int i = 0; i < mIndexMap.size(); i++) {
10122                         int device = mIndexMap.keyAt(i);
10123                         int index = mIndexMap.valueAt(i);
10124                         if (isFullVolumeDevice(device)
10125                                 || (isFixedVolumeDevice(device) && index != 0)) {
10126                             mIndexMap.put(device, mIndexMax);
10127                         }
10128                         applyDeviceVolume_syncVSS(device);
10129                     }
10130                 }
10131             }
10132         }
10133 
getValidIndex(int index, boolean hasModifyAudioSettings)10134         private int getValidIndex(int index, boolean hasModifyAudioSettings) {
10135             final int indexMin = hasModifyAudioSettings ? mIndexMin : mIndexMinNoPerm;
10136             if (index < indexMin) {
10137                 return indexMin;
10138             } else if (mUseFixedVolume || index > mIndexMax) {
10139                 return mIndexMax;
10140             }
10141 
10142             return index;
10143         }
10144 
dump(PrintWriter pw)10145         private void dump(PrintWriter pw) {
10146             pw.print("   Muted: ");
10147             pw.println(mIsMuted);
10148             pw.print("   Muted Internally: ");
10149             pw.println(mIsMutedInternally);
10150             pw.print("   Min: ");
10151             pw.print((mIndexMin + 5) / 10);
10152             if (mIndexMin != mIndexMinNoPerm) {
10153                 pw.print(" w/o perm:");
10154                 pw.println((mIndexMinNoPerm + 5) / 10);
10155             } else {
10156                 pw.println();
10157             }
10158             pw.print("   Max: ");
10159             pw.println((mIndexMax + 5) / 10);
10160             pw.print("   streamVolume:"); pw.println(getStreamVolume(mStreamType));
10161             pw.print("   Current: ");
10162             for (int i = 0; i < mIndexMap.size(); i++) {
10163                 if (i > 0) {
10164                     pw.print(", ");
10165                 }
10166                 final int device = mIndexMap.keyAt(i);
10167                 pw.print(Integer.toHexString(device));
10168                 final String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
10169                         : AudioSystem.getOutputDeviceName(device);
10170                 if (!deviceName.isEmpty()) {
10171                     pw.print(" (");
10172                     pw.print(deviceName);
10173                     pw.print(")");
10174                 }
10175                 pw.print(": ");
10176                 final int index = (mIndexMap.valueAt(i) + 5) / 10;
10177                 pw.print(index);
10178             }
10179             pw.println();
10180             pw.print("   Devices: ");
10181             pw.print(AudioSystem.deviceSetToString(getDeviceSetForStream(mStreamType)));
10182             pw.println();
10183             pw.print("   Volume Group: ");
10184             pw.println(mVolumeGroupState != null ? mVolumeGroupState.name() : "n/a");
10185         }
10186     }
10187 
10188     /** Thread that handles native AudioSystem control. */
10189     private class AudioSystemThread extends Thread {
AudioSystemThread()10190         AudioSystemThread() {
10191             super("AudioService");
10192         }
10193 
10194         @Override
run()10195         public void run() {
10196             // Set this thread up so the handler will work on it
10197             Looper.prepare();
10198 
10199             synchronized(AudioService.this) {
10200                 mAudioHandler = new AudioHandler();
10201 
10202                 // Notify that the handler has been created
10203                 AudioService.this.notify();
10204             }
10205 
10206             // Listen for volume change requests that are set by VolumePanel
10207             Looper.loop();
10208         }
10209     }
10210 
10211     private static final class DeviceVolumeUpdate {
10212         final int mStreamType;
10213         final int mDevice;
10214         final @NonNull String mCaller;
10215         private static final int NO_NEW_INDEX = -2049;
10216         private final int mVssVolIndex;
10217 
10218         // Constructor with volume index, meant to cause this volume to be set and applied for the
10219         // given stream type on the given device
DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller)10220         DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller) {
10221             mStreamType = streamType;
10222             mVssVolIndex = vssVolIndex;
10223             mDevice = device;
10224             mCaller = caller;
10225         }
10226 
10227         // Constructor with no volume index, meant to cause re-apply of volume for the given
10228         // stream type on the given device
DeviceVolumeUpdate(int streamType, int device, @NonNull String caller)10229         DeviceVolumeUpdate(int streamType, int device, @NonNull String caller) {
10230             mStreamType = streamType;
10231             mVssVolIndex = NO_NEW_INDEX;
10232             mDevice = device;
10233             mCaller = caller;
10234         }
10235 
hasVolumeIndex()10236         boolean hasVolumeIndex() {
10237             return mVssVolIndex != NO_NEW_INDEX;
10238         }
10239 
getVolumeIndex()10240         int getVolumeIndex() throws IllegalStateException {
10241             Preconditions.checkState(mVssVolIndex != NO_NEW_INDEX);
10242             return mVssVolIndex;
10243         }
10244     }
10245 
10246     /** only public for mocking/spying, do not call outside of AudioService */
10247     @VisibleForTesting
postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device, String caller)10248     public void postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device,
10249                                                 String caller) {
10250         sendMsg(mAudioHandler,
10251                 MSG_SET_DEVICE_STREAM_VOLUME,
10252                 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/,
10253                 new DeviceVolumeUpdate(streamType, vssVolIndex, device, caller),
10254                 0 /*delay*/);
10255     }
10256 
postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller)10257     /*package*/ void postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller) {
10258         sendMsg(mAudioHandler,
10259                 MSG_SET_DEVICE_STREAM_VOLUME,
10260                 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/,
10261                 new DeviceVolumeUpdate(streamType, device, caller),
10262                 0 /*delay*/);
10263     }
10264 
onSetVolumeIndexOnDevice(@onNull DeviceVolumeUpdate update)10265     private void onSetVolumeIndexOnDevice(@NonNull DeviceVolumeUpdate update) {
10266         final VolumeStreamState streamState = getVssForStream(update.mStreamType);
10267         if (streamState == null) {
10268             Log.w(TAG, "Invalid onSetVolumeIndexOnDevice for stream type " + update.mStreamType);
10269             return;
10270         }
10271         if (update.hasVolumeIndex()) {
10272             int index = update.getVolumeIndex();
10273             if (mSoundDoseHelper.checkSafeMediaVolume(update.mStreamType, index, update.mDevice)) {
10274                 index = mSoundDoseHelper.safeMediaVolumeIndex(update.mDevice);
10275             }
10276             streamState.setIndex(index, update.mDevice, update.mCaller,
10277                     // trusted as index is always validated before message is posted
10278                     true /*hasModifyAudioSettings*/);
10279             sVolumeLogger.enqueue(new EventLogger.StringEvent(update.mCaller + " dev:0x"
10280                     + Integer.toHexString(update.mDevice) + " volIdx:" + index));
10281         } else {
10282             sVolumeLogger.enqueue(new EventLogger.StringEvent(update.mCaller
10283                     + " update vol on dev:0x" + Integer.toHexString(update.mDevice)));
10284         }
10285         setDeviceVolume(streamState, update.mDevice);
10286     }
10287 
setDeviceVolume(VolumeStreamState streamState, int device)10288     /*package*/ void setDeviceVolume(VolumeStreamState streamState, int device) {
10289         synchronized (mVolumeStateLock) {
10290             sendMsg(mAudioHandler, SoundDoseHelper.MSG_CSD_UPDATE_ATTENUATION, SENDMSG_QUEUE,
10291                     device, (isAbsoluteVolumeDevice(device) || isA2dpAbsoluteVolumeDevice(device)
10292                             || AudioSystem.isLeAudioDeviceType(device) ? 1 : 0),
10293                     streamState, /*delay=*/0);
10294             // Apply volume
10295             streamState.applyDeviceVolume_syncVSS(device);
10296 
10297             // Apply change to all streams using this one as alias
10298             int numStreamTypes = AudioSystem.getNumStreamTypes();
10299             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
10300                 final VolumeStreamState vss = getVssForStream(streamType);
10301                 if (vss != null && streamType != streamState.mStreamType
10302                         && sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound=*/-1)
10303                                 == streamState.mStreamType) {
10304                     // Make sure volume is also maxed out on A2DP device for aliased stream
10305                     // that may have a different device selected
10306                     int streamDevice = getDeviceForStream(streamType);
10307                     if ((device != streamDevice)
10308                             && (isAbsoluteVolumeDevice(device)
10309                                 || isA2dpAbsoluteVolumeDevice(device)
10310                                 || AudioSystem.isLeAudioDeviceType(device))) {
10311                         vss.applyDeviceVolume_syncVSS(device);
10312                     }
10313                     vss.applyDeviceVolume_syncVSS(streamDevice);
10314                 }
10315             }
10316         }
10317         // Post a persist volume msg
10318         sendMsg(mAudioHandler,
10319                 MSG_PERSIST_VOLUME,
10320                 SENDMSG_QUEUE,
10321                 device,
10322                 0,
10323                 streamState,
10324                 PERSIST_DELAY);
10325 
10326     }
10327 
10328     /** Handles internal volume messages in separate volume thread. */
10329     /*package*/ class AudioHandler extends Handler {
10330 
AudioHandler()10331         AudioHandler() {
10332             super();
10333         }
10334 
AudioHandler(Looper looper)10335         AudioHandler(Looper looper) {
10336             super(looper);
10337         }
10338 
setAllVolumes(VolumeStreamState streamState)10339         private void setAllVolumes(VolumeStreamState streamState) {
10340 
10341             // Apply volume
10342             streamState.applyAllVolumes();
10343 
10344             // Apply change to all streams using this one as alias
10345             int numStreamTypes = AudioSystem.getNumStreamTypes();
10346             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
10347                 final VolumeStreamState vss = getVssForStream(streamType);
10348                 if (vss != null && streamType != streamState.mStreamType
10349                         && sStreamVolumeAlias.get(streamType, /*valueIfKeyNotFound=*/-1)
10350                                 == streamState.mStreamType) {
10351                     vss.applyAllVolumes();
10352                 }
10353             }
10354         }
10355 
persistVolume(VolumeStreamState streamState, int device)10356         private void persistVolume(VolumeStreamState streamState, int device) {
10357             if (mUseFixedVolume) {
10358                 return;
10359             }
10360             if (mIsSingleVolume && (streamState.mStreamType != AudioSystem.STREAM_MUSIC)) {
10361                 return;
10362             }
10363 
10364             // Persisting STREAM_SYSTEM_ENFORCED index is not needed as its alias (STREAM_RING)
10365             // is persisted. This can also be problematic when the enforcement is active as it will
10366             // override current SYSTEM_RING persisted value given they share the same settings name
10367             // (due to aliasing).
10368             if (streamState.mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED) {
10369                 return;
10370             }
10371             if (streamState.hasValidSettingsName()) {
10372                 mSettings.putSystemIntForUser(mContentResolver,
10373                         streamState.getSettingNameForDevice(device),
10374                         (streamState.getIndex(device) + 5) / 10,
10375                         UserHandle.USER_CURRENT);
10376             }
10377         }
10378 
persistRingerMode(int ringerMode)10379         private void persistRingerMode(int ringerMode) {
10380             if (mUseFixedVolume) {
10381                 return;
10382             }
10383             mSettings.putGlobalInt(mContentResolver, Settings.Global.MODE_RINGER, ringerMode);
10384         }
10385 
onNotifyVolumeEvent(@onNull IAudioPolicyCallback apc, @AudioManager.VolumeAdjustment int direction)10386         private void onNotifyVolumeEvent(@NonNull IAudioPolicyCallback apc,
10387                 @AudioManager.VolumeAdjustment int direction) {
10388             try {
10389                 apc.notifyVolumeAdjust(direction);
10390             } catch(Exception e) {
10391                 // nothing we can do about this. Do not log error, too much potential for spam
10392             }
10393         }
10394 
10395         @Override
handleMessage(Message msg)10396         public void handleMessage(Message msg) {
10397             switch (msg.what) {
10398 
10399                 case MSG_SET_DEVICE_VOLUME:
10400                     setDeviceVolume((VolumeStreamState) msg.obj, msg.arg1);
10401                     break;
10402 
10403                 case MSG_SET_ALL_VOLUMES:
10404                     setAllVolumes((VolumeStreamState) msg.obj);
10405                     break;
10406 
10407                 case MSG_PERSIST_VOLUME:
10408                     persistVolume((VolumeStreamState) msg.obj, msg.arg1);
10409                     break;
10410 
10411                 case MSG_PERSIST_VOLUME_GROUP:
10412                     final VolumeGroupState vgs = (VolumeGroupState) msg.obj;
10413                     vgs.persistVolumeGroup(msg.arg1);
10414                     break;
10415 
10416                 case MSG_APPLY_INPUT_GAIN_INDEX:
10417                     onApplyInputGainIndex((AudioDeviceAttributes) msg.obj, msg.arg1);
10418                     break;
10419 
10420                 case MSG_PERSIST_INPUT_GAIN_INDEX:
10421                     onPersistInputGainIndex((AudioDeviceAttributes) msg.obj);
10422                     break;
10423 
10424                 case MSG_PERSIST_RINGER_MODE:
10425                     // note that the value persisted is the current ringer mode, not the
10426                     // value of ringer mode as of the time the request was made to persist
10427                     persistRingerMode(getRingerModeInternal());
10428                     break;
10429 
10430                 case MSG_AUDIO_SERVER_DIED:
10431                     onAudioServerDied();
10432                     break;
10433 
10434                 case MSG_DISPATCH_AUDIO_SERVER_STATE:
10435                     onDispatchAudioServerStateChange(msg.arg1 == 1);
10436                     break;
10437 
10438                 case MSG_UNLOAD_SOUND_EFFECTS:
10439                     mSfxHelper.unloadSoundEffects();
10440                     break;
10441 
10442                 case MSG_LOAD_SOUND_EFFECTS:
10443                 {
10444                     LoadSoundEffectReply reply = (LoadSoundEffectReply) msg.obj;
10445                     if (mSystemReady) {
10446                         mSfxHelper.loadSoundEffects(reply);
10447                     } else {
10448                         Log.w(TAG, "[schedule]loadSoundEffects() called before boot complete");
10449                         if (reply != null) {
10450                             reply.run(false);
10451                         }
10452                     }
10453                 }
10454                     break;
10455 
10456                 case MSG_PLAY_SOUND_EFFECT:
10457                     mSfxHelper.playSoundEffect(msg.arg1, msg.arg2);
10458                     break;
10459 
10460                 case MSG_SET_FORCE_USE:
10461                 {
10462                     final String eventSource = (String) msg.obj;
10463                     final int useCase = msg.arg1;
10464                     final int config = msg.arg2;
10465                     if (useCase == AudioSystem.FOR_MEDIA) {
10466                         Log.wtf(TAG, "Invalid force use FOR_MEDIA in AudioService from "
10467                                 + eventSource);
10468                         break;
10469                     }
10470                     new MediaMetrics.Item(MediaMetrics.Name.AUDIO_FORCE_USE
10471                             + MediaMetrics.SEPARATOR + AudioSystem.forceUseUsageToString(useCase))
10472                             .set(MediaMetrics.Property.EVENT, "setForceUse")
10473                             .set(MediaMetrics.Property.FORCE_USE_DUE_TO, eventSource)
10474                             .set(MediaMetrics.Property.FORCE_USE_MODE,
10475                                     AudioSystem.forceUseConfigToString(config))
10476                             .record();
10477                     sForceUseLogger.enqueue(
10478                             new AudioServiceEvents.ForceUseEvent(useCase, config, eventSource));
10479                     mAudioSystem.setForceUse(useCase, config);
10480                 }
10481                     break;
10482 
10483                 case MSG_DISABLE_AUDIO_FOR_UID:
10484                     mPlaybackMonitor.disableAudioForUid( msg.arg1 == 1 /* disable */,
10485                             msg.arg2 /* uid */);
10486                     mAudioEventWakeLock.release();
10487                     break;
10488 
10489                 case MSG_INIT_STREAMS_VOLUMES:
10490                     onInitStreamsAndVolumes();
10491                     mAudioEventWakeLock.release();
10492                     break;
10493 
10494                 case MSG_INIT_INPUT_GAINS:
10495                     onInitInputGains();
10496                     mAudioEventWakeLock.release();
10497                     break;
10498 
10499                 case MSG_INIT_ADI_DEVICE_STATES:
10500                     onInitAdiDeviceStates();
10501                     mAudioEventWakeLock.release();
10502                     break;
10503 
10504                 case MSG_INIT_SPATIALIZER:
10505                     onInitSpatializer();
10506                     mAudioEventWakeLock.release();
10507                     break;
10508 
10509                 case MSG_INIT_HEADTRACKING_SENSORS:
10510                     mSpatializerHelper.onInitSensors();
10511                     break;
10512 
10513                 case MSG_RESET_SPATIALIZER:
10514                     mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect);
10515                     break;
10516 
10517                 case MSG_SYSTEM_READY:
10518                     onSystemReady();
10519                     break;
10520 
10521                 case MSG_INDICATE_SYSTEM_READY:
10522                     onIndicateSystemReady();
10523                     break;
10524 
10525                 case MSG_ACCESSORY_PLUG_MEDIA_UNMUTE:
10526                     onAccessoryPlugMediaUnmute(msg.arg1);
10527                     break;
10528 
10529                 case MSG_UNMUTE_STREAM_ON_SINGLE_VOL_DEVICE:
10530                     onUnmuteStreamOnSingleVolDevice(msg.arg1, msg.arg2);
10531                     break;
10532 
10533                 case MSG_DYN_POLICY_MIX_STATE_UPDATE:
10534                     onDynPolicyMixStateUpdate((String) msg.obj, msg.arg1);
10535                     break;
10536 
10537                 case MSG_NOTIFY_VOL_EVENT:
10538                     onNotifyVolumeEvent((IAudioPolicyCallback) msg.obj, msg.arg1);
10539                     break;
10540 
10541                 case MSG_ENABLE_SURROUND_FORMATS:
10542                     onEnableSurroundFormats((ArrayList<Integer>) msg.obj);
10543                     break;
10544 
10545                 case MSG_UPDATE_RINGER_MODE:
10546                     onUpdateRingerModeServiceInt();
10547                     break;
10548 
10549                 case MSG_SET_DEVICE_STREAM_VOLUME:
10550                     onSetVolumeIndexOnDevice((DeviceVolumeUpdate) msg.obj);
10551                     break;
10552 
10553                 case MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS:
10554                     onObserveDevicesForAllStreams(/*skipStream*/ msg.arg1);
10555                     break;
10556 
10557                 case MSG_HDMI_VOLUME_CHECK:
10558                     onCheckVolumeCecOnHdmiConnection(msg.arg1, (String) msg.obj);
10559                     break;
10560 
10561                 case MSG_PLAYBACK_CONFIG_CHANGE:
10562                     onPlaybackConfigChange((List<AudioPlaybackConfiguration>) msg.obj);
10563                     break;
10564                 case MSG_RECORDING_CONFIG_CHANGE:
10565                     onRecordingConfigChange((List<AudioRecordingConfiguration>) msg.obj);
10566                     break;
10567 
10568                 case MSG_BROADCAST_MICROPHONE_MUTE:
10569                     mSystemServer.sendMicrophoneMuteChangedIntent();
10570                     break;
10571 
10572                 case MSG_BROADCAST_MASTER_MUTE:
10573                     mSystemServer.broadcastMasterMuteStatus(msg.arg1 == 1);
10574                     break;
10575 
10576                 case MSG_CHECK_MODE_FOR_UID:
10577                     synchronized (mDeviceBroker.mSetModeLock) {
10578                         if (msg.obj == null) {
10579                             break;
10580                         }
10581                         // Update active playback/recording for apps requesting IN_COMMUNICATION
10582                         // mode after a grace period following the mode change
10583                         SetModeDeathHandler h = (SetModeDeathHandler) msg.obj;
10584                         if (mSetModeDeathHandlers.indexOf(h) < 0) {
10585                             break;
10586                         }
10587                         boolean wasActive = h.isActive();
10588                         h.setPlaybackActive(isPlaybackActiveForUid(h.getUid()));
10589                         h.setRecordingActive(isRecordingActiveForUid(h.getUid()));
10590                         if (wasActive != h.isActive()) {
10591                             onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(),
10592                                     mContext.getPackageName(), false /*force*/, false /*signal*/);
10593                         }
10594                     }
10595                     break;
10596 
10597                 case MSG_STREAM_DEVICES_CHANGED:
10598                     final SomeArgs args = (SomeArgs) msg.obj;
10599                     final Intent intent = (Intent) args.arg1;
10600                     final Bundle options = (Bundle) args.arg2;
10601                     args.recycle();
10602                     sendBroadcastToAll(intent
10603                             .putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_DEVICES, msg.arg1)
10604                             .putExtra(AudioManager.EXTRA_VOLUME_STREAM_DEVICES, msg.arg2),
10605                             options);
10606                     break;
10607 
10608                 case MSG_UPDATE_VOLUME_STATES_FOR_DEVICE:
10609                     onUpdateVolumeStatesForAudioDevice(msg.arg1, (String) msg.obj);
10610                     break;
10611 
10612                 case MSG_REINIT_VOLUMES:
10613                     onReinitVolumes((String) msg.obj);
10614                     break;
10615 
10616                 case MSG_UPDATE_A11Y_SERVICE_UIDS:
10617                     onUpdateAccessibilityServiceUids();
10618                     break;
10619 
10620                 case MSG_UPDATE_AUDIO_MODE:
10621                 case MSG_UPDATE_AUDIO_MODE_SIGNAL:
10622                     synchronized (mDeviceBroker.mSetModeLock) {
10623                         UpdateAudioModeInfo info = (UpdateAudioModeInfo) msg.obj;
10624                         onUpdateAudioMode(info.getMode(), info.getPid(), info.getPackageName(),
10625                                 false /*force*/, msg.what == MSG_UPDATE_AUDIO_MODE_SIGNAL);
10626                     }
10627                     break;
10628 
10629                 case MSG_BT_DEV_CHANGED:
10630                     mDeviceBroker.queueOnBluetoothActiveDeviceChanged(
10631                             (AudioDeviceBroker.BtDeviceChangedData) msg.obj);
10632                     break;
10633 
10634                 case MSG_DISPATCH_AUDIO_MODE:
10635                     dispatchMode(msg.arg1);
10636                     break;
10637 
10638                 case MSG_ROUTING_UPDATED:
10639                     onRoutingUpdatedFromAudioThread();
10640                     break;
10641 
10642                 case MSG_ADD_ASSISTANT_SERVICE_UID:
10643                     onAddAssistantServiceUids(new int[]{msg.arg1});
10644                     break;
10645 
10646                 case MSG_REMOVE_ASSISTANT_SERVICE_UID:
10647                     onRemoveAssistantServiceUids(new int[]{msg.arg1});
10648                     break;
10649                 case MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID:
10650                     updateActiveAssistantServiceUids();
10651                     break;
10652 
10653                 case MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR:
10654                     dispatchDeviceVolumeBehavior((AudioDeviceAttributes) msg.obj, msg.arg1);
10655                     break;
10656 
10657                 case MSG_ROTATION_UPDATE:
10658                     // rotation parameter format: "rotation=x" where x is one of 0, 90, 180, 270
10659                     mAudioSystem.setParameters((String) msg.obj);
10660                     break;
10661 
10662                 case MSG_FOLD_UPDATE:
10663                     // fold parameter format: "device_folded=x" where x is one of on, off
10664                     mAudioSystem.setParameters((String) msg.obj);
10665                     break;
10666 
10667                 case MSG_NO_LOG_FOR_PLAYER_I:
10668                     mPlaybackMonitor.ignorePlayerIId(msg.arg1);
10669                     break;
10670 
10671                 case MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES:
10672                     onDispatchPreferredMixerAttributesChanged(msg.getData(), msg.arg1);
10673                     break;
10674 
10675                 case MSG_CONFIGURATION_CHANGED:
10676                     onConfigurationChanged();
10677                     break;
10678 
10679                 case MSG_UPDATE_CONTEXTUAL_VOLUMES:
10680                     onUpdateContextualVolumes();
10681                     break;
10682 
10683                 case MSG_BT_COMM_DEVICE_ACTIVE_UPDATE:
10684                     onUpdateBtCommDeviceActive(msg.arg1);
10685                     break;
10686 
10687                 case MusicFxHelper.MSG_EFFECT_CLIENT_GONE:
10688                     mMusicFxHelper.handleMessage(msg);
10689                     break;
10690 
10691                 case SoundDoseHelper.MSG_CONFIGURE_SAFE_MEDIA:
10692                 case SoundDoseHelper.MSG_CONFIGURE_SAFE_MEDIA_FORCED:
10693                 case SoundDoseHelper.MSG_PERSIST_SAFE_VOLUME_STATE:
10694                 case SoundDoseHelper.MSG_PERSIST_MUSIC_ACTIVE_MS:
10695                 case SoundDoseHelper.MSG_PERSIST_CSD_VALUES:
10696                 case SoundDoseHelper.MSG_CSD_UPDATE_ATTENUATION:
10697                 case SoundDoseHelper.MSG_LOWER_VOLUME_TO_RS1:
10698                     mSoundDoseHelper.handleMessage(msg);
10699                     break;
10700 
10701                 default:
10702                     Log.e(TAG, "Unsupported msgId " + msg.what);
10703             }
10704         }
10705     }
10706 
10707     private class SettingsObserver extends ContentObserver {
10708 
SettingsObserver()10709         SettingsObserver() {
10710             super(new Handler());
10711             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
10712                     Settings.Global.ZEN_MODE), false, this);
10713             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
10714                     Settings.Global.ZEN_MODE_CONFIG_ETAG), false, this);
10715             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
10716                     Settings.Global.MUTE_ALARM_STREAM_WITH_RINGER_MODE), false, this);
10717             mContentResolver.registerContentObserver(Settings.System.getUriFor(
10718                 Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this);
10719             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
10720                 Settings.Global.DOCK_AUDIO_MEDIA_ENABLED), false, this);
10721             mContentResolver.registerContentObserver(Settings.System.getUriFor(
10722                     Settings.System.MASTER_MONO), false, this, UserHandle.USER_ALL);
10723             mContentResolver.registerContentObserver(Settings.System.getUriFor(
10724                     Settings.System.MASTER_BALANCE), false, this, UserHandle.USER_ALL);
10725 
10726             mEncodedSurroundMode = mSettings.getGlobalInt(
10727                     mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT,
10728                     Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
10729             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
10730                     Settings.Global.ENCODED_SURROUND_OUTPUT), false, this);
10731             mEnabledSurroundFormats = mSettings.getGlobalString(
10732                     mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
10733             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
10734                     Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS), false, this);
10735 
10736             mContentResolver.registerContentObserver(Settings.Secure.getUriFor(
10737                     Settings.Secure.VOICE_INTERACTION_SERVICE), false, this);
10738         }
10739 
10740         @Override
onChange(boolean selfChange)10741         public void onChange(boolean selfChange) {
10742             super.onChange(selfChange);
10743             // FIXME This synchronized is not necessary if mSettingsLock only protects mRingerMode.
10744             //       However there appear to be some missing locks around sRingerAndZenModeMutedStreams
10745             //       and mRingerModeAffectedStreams, so will leave this synchronized for now.
10746             //       sRingerAndZenModeMutedStreams and mMuteAffectedStreams are safe (only accessed once).
10747             synchronized (mSettingsLock) {
10748                 if (updateRingerAndZenModeAffectedStreams()) {
10749                     /*
10750                      * Ensure all stream types that should be affected by ringer mode
10751                      * are in the proper state.
10752                      */
10753                     setRingerModeInt(getRingerModeInternal(), false);
10754                 }
10755                 readDockAudioSettings(mContentResolver);
10756                 updateMasterMono(mContentResolver);
10757                 updateMasterBalance(mContentResolver);
10758                 updateEncodedSurroundOutput();
10759                 sendEnabledSurroundFormats(mContentResolver, mSurroundModeChanged);
10760                 updateAssistantUIdLocked(/* forceUpdate= */ false);
10761             }
10762         }
10763 
updateEncodedSurroundOutput()10764         private void updateEncodedSurroundOutput() {
10765             int newSurroundMode = mSettings.getGlobalInt(
10766                 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT,
10767                 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
10768             // Did it change?
10769             if (mEncodedSurroundMode != newSurroundMode) {
10770                 // Send to AudioPolicyManager
10771                 sendEncodedSurroundMode(newSurroundMode, "SettingsObserver");
10772                 mDeviceBroker.toggleHdmiIfConnected_Async();
10773                 mEncodedSurroundMode = newSurroundMode;
10774                 mSurroundModeChanged = true;
10775             } else {
10776                 mSurroundModeChanged = false;
10777             }
10778         }
10779     }
10780 
avrcpSupportsAbsoluteVolume(String address, boolean support)10781     private void avrcpSupportsAbsoluteVolume(String address, boolean support) {
10782         // address is not used for now, but may be used when multiple a2dp devices are supported
10783         sVolumeLogger.enqueue(new EventLogger.StringEvent("avrcpSupportsAbsoluteVolume addr="
10784                 + Utils.anonymizeBluetoothAddress(address) + " support=" + support).printLog(TAG));
10785         mDeviceBroker.setAvrcpAbsoluteVolumeSupported(support);
10786         setAvrcpAbsoluteVolumeSupported(support);
10787     }
10788 
setAvrcpAbsoluteVolumeSupported(boolean support)10789     /*package*/ void setAvrcpAbsoluteVolumeSupported(boolean support) {
10790         Log.i(TAG, "setAvrcpAbsoluteVolumeSupported support " + support);
10791         synchronized (mCachedAbsVolDrivingStreamsLock) {
10792             mAvrcpAbsVolSupported = support;
10793             int a2dpDev = AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP;
10794             mCachedAbsVolDrivingStreams.compute(a2dpDev, (dev, stream) -> {
10795                 if (!mAvrcpAbsVolSupported) {
10796                     final int result = mAudioSystem.setDeviceAbsoluteVolumeEnabled(
10797                             a2dpDev, /*address=*/"", /*enabled*/false,
10798                             AudioSystem.STREAM_DEFAULT);
10799                     if (result != AudioSystem.AUDIO_STATUS_OK) {
10800                         sVolumeLogger.enqueueAndSlog(
10801                                 new VolumeEvent(VolumeEvent.VOL_ABS_DEVICE_ENABLED_ERROR,
10802                                         result, a2dpDev, /*enabled=*/false,
10803                                         AudioSystem.STREAM_DEFAULT).eventToString(), ALOGE,
10804                                 TAG);
10805                     }
10806                     return null;
10807                 }
10808                 // For A2DP and AVRCP we need to set the driving stream based on the
10809                 // BT contextual stream. Hence, we need to make sure in adjustStreamVolume
10810                 // and setStreamVolume that the driving abs volume stream is consistent.
10811                 int streamToDriveAbs = getBluetoothContextualVolumeStream();
10812                 if (stream == null || stream != streamToDriveAbs) {
10813                     final int result = mAudioSystem.setDeviceAbsoluteVolumeEnabled(a2dpDev,
10814                             /*address=*/"", /*enabled*/true, streamToDriveAbs);
10815                     if (result != AudioSystem.AUDIO_STATUS_OK) {
10816                         sVolumeLogger.enqueueAndSlog(
10817                                 new VolumeEvent(VolumeEvent.VOL_ABS_DEVICE_ENABLED_ERROR,
10818                                         result, a2dpDev, /*enabled=*/true,
10819                                         streamToDriveAbs).eventToString(), ALOGE, TAG);
10820                     }
10821                 }
10822                 return streamToDriveAbs;
10823             });
10824         }
10825         sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE,
10826                     AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0,
10827                     getVssForStreamOrDefault(AudioSystem.STREAM_MUSIC), 0);
10828     }
10829 
10830     /**
10831      * @return true if there is currently a registered dynamic mixing policy that affects media
10832      * and is not a render + loopback policy
10833      */
10834     // only public for mocking/spying
10835     @VisibleForTesting
hasMediaDynamicPolicy()10836     public boolean hasMediaDynamicPolicy() {
10837         synchronized (mAudioPolicies) {
10838             if (mAudioPolicies.isEmpty()) {
10839                 return false;
10840             }
10841             final Collection<AudioPolicyProxy> appColl = mAudioPolicies.values();
10842             for (AudioPolicyProxy app : appColl) {
10843                 if (app.hasMixAffectingUsage(AudioAttributes.USAGE_MEDIA,
10844                         AudioMix.ROUTE_FLAG_LOOP_BACK_RENDER)) {
10845                     return true;
10846                 }
10847             }
10848             return false;
10849         }
10850     }
10851 
10852     /** only public for mocking/spying, do not call outside of AudioService */
10853     @VisibleForTesting
checkMusicActive(int deviceType, String caller)10854     public void checkMusicActive(int deviceType, String caller) {
10855         if (mSoundDoseHelper.safeDevicesContains(deviceType)) {
10856             mSoundDoseHelper.scheduleMusicActiveCheck();
10857         }
10858     }
10859 
10860     /**
10861      * Receiver for misc intent broadcasts the Phone app cares about.
10862      */
10863     private class AudioServiceBroadcastReceiver extends BroadcastReceiver {
10864         @Override
onReceive(Context context, Intent intent)10865         public void onReceive(Context context, Intent intent) {
10866             final String action = intent.getAction();
10867             int outDevice;
10868             int inDevice;
10869             int state;
10870 
10871             if (action.equals(Intent.ACTION_DOCK_EVENT)) {
10872                 int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
10873                         Intent.EXTRA_DOCK_STATE_UNDOCKED);
10874                 int config;
10875                 switch (dockState) {
10876                     case Intent.EXTRA_DOCK_STATE_DESK:
10877                         config = AudioSystem.FORCE_BT_DESK_DOCK;
10878                         break;
10879                     case Intent.EXTRA_DOCK_STATE_CAR:
10880                         config = AudioSystem.FORCE_BT_CAR_DOCK;
10881                         break;
10882                     case Intent.EXTRA_DOCK_STATE_LE_DESK:
10883                         config = AudioSystem.FORCE_ANALOG_DOCK;
10884                         break;
10885                     case Intent.EXTRA_DOCK_STATE_HE_DESK:
10886                         config = AudioSystem.FORCE_DIGITAL_DOCK;
10887                         break;
10888                     case Intent.EXTRA_DOCK_STATE_UNDOCKED:
10889                     default:
10890                         config = AudioSystem.FORCE_NONE;
10891                 }
10892                 // Low end docks have a menu to enable or disable audio
10893                 // (see mDockAudioMediaEnabled)
10894                 if (!((dockState == Intent.EXTRA_DOCK_STATE_LE_DESK)
10895                         || ((dockState == Intent.EXTRA_DOCK_STATE_UNDOCKED)
10896                                 && (mDockState == Intent.EXTRA_DOCK_STATE_LE_DESK)))) {
10897                     mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, config,
10898                             "ACTION_DOCK_EVENT intent");
10899                 }
10900                 mDockState = dockState;
10901             } else if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED)
10902                     || action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
10903                 mDeviceBroker.postReceiveBtEvent(intent);
10904             } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
10905                 if (mMonitorRotation) {
10906                     RotationHelper.enable();
10907                 }
10908                 AudioSystem.setParameters("screen_state=on");
10909             } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
10910                 if (mMonitorRotation) {
10911                     //reduce wakeups (save current) by only listening when display is on
10912                     RotationHelper.disable();
10913                 }
10914                 AudioSystem.setParameters("screen_state=off");
10915             } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
10916                 sendMsg(mAudioHandler,
10917                         MSG_CONFIGURATION_CHANGED,
10918                         SENDMSG_REPLACE,
10919                         0,
10920                         0,
10921                         null, 0);
10922             } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
10923                 // the current audio focus owner is likely no longer valid
10924                 final boolean audioDiscarded = mMediaFocusControl.maybeDiscardAudioFocusOwner();
10925                 if (audioDiscarded && mUserSwitchedReceived) {
10926                     // attempt to stop music playback for background user except on first user
10927                     // switch (i.e. first boot)
10928                     mDeviceBroker.postBroadcastBecomingNoisy();
10929                 }
10930                 mUserSwitchedReceived = true;
10931 
10932                 if (mSupportsMicPrivacyToggle) {
10933                     mMicMuteFromPrivacyToggle = mSensorPrivacyManagerInternal
10934                             .isSensorPrivacyEnabled(getCurrentUserId(),
10935                                     SensorPrivacyManager.Sensors.MICROPHONE);
10936                     setMicrophoneMuteNoCallerCheck(getCurrentUserId());
10937                 }
10938 
10939                 // load volume settings for new user
10940                 readAudioSettings(true /*userSwitch*/);
10941                 // preserve STREAM_MUSIC volume from one user to the next.
10942                 sendMsg(mAudioHandler,
10943                         MSG_SET_ALL_VOLUMES,
10944                         SENDMSG_QUEUE,
10945                         0,
10946                         0,
10947                         getVssForStreamOrDefault(AudioSystem.STREAM_MUSIC), 0);
10948             } else if (action.equals(Intent.ACTION_USER_BACKGROUND)) {
10949                 // Disable audio recording for the background user/profile
10950                 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
10951                 if (userId >= 0) {
10952                     // TODO Kill recording streams instead of killing processes holding permission
10953                     UserInfo userInfo = UserManagerService.getInstance().getUserInfo(userId);
10954                     killBackgroundUserProcessesWithRecordAudioPermission(userInfo);
10955                 }
10956                 try {
10957                     UserManagerService.getInstance().setUserRestriction(
10958                             UserManager.DISALLOW_RECORD_AUDIO, true, userId);
10959                 } catch (IllegalArgumentException e) {
10960                     Slog.w(TAG, "Failed to apply DISALLOW_RECORD_AUDIO restriction: " + e);
10961                 }
10962             } else if (action.equals(Intent.ACTION_USER_FOREGROUND)) {
10963                 // Enable audio recording for foreground user/profile
10964                 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
10965                 try {
10966                     UserManagerService.getInstance().setUserRestriction(
10967                             UserManager.DISALLOW_RECORD_AUDIO, false, userId);
10968                 } catch (IllegalArgumentException e) {
10969                     Slog.w(TAG, "Failed to apply DISALLOW_RECORD_AUDIO restriction: " + e);
10970                 }
10971             } else if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION) ||
10972                     action.equals(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION)) {
10973                 mMusicFxHelper.handleAudioEffectBroadcast(context, intent);
10974             } else if (action.equals(Intent.ACTION_PACKAGES_SUSPENDED)) {
10975                 final int[] suspendedUids = intent.getIntArrayExtra(Intent.EXTRA_CHANGED_UID_LIST);
10976                 final String[] suspendedPackages =
10977                         intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
10978                 if (suspendedPackages == null || suspendedUids == null
10979                         || suspendedPackages.length != suspendedUids.length) {
10980                     return;
10981                 }
10982                 for (int i = 0; i < suspendedUids.length; i++) {
10983                     if (!TextUtils.isEmpty(suspendedPackages[i])) {
10984                         mMediaFocusControl.noFocusForSuspendedApp(
10985                                 suspendedPackages[i], suspendedUids[i]);
10986                     }
10987                 }
10988             } else if (action.equals(ACTION_CHECK_MUSIC_ACTIVE)) {
10989                 mSoundDoseHelper.onCheckMusicActive(ACTION_CHECK_MUSIC_ACTIVE,
10990                         mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0));
10991             }
10992         }
10993     } // end class AudioServiceBroadcastReceiver
10994 
10995     private class AudioServiceUserRestrictionsListener implements UserRestrictionsListener {
10996 
10997         @Override
onUserRestrictionsChanged(int userId, Bundle newRestrictions, Bundle prevRestrictions)10998         public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
10999                 Bundle prevRestrictions) {
11000             // Update mic mute state.
11001             {
11002                 final boolean wasRestricted =
11003                         prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE);
11004                 final boolean isRestricted =
11005                         newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE);
11006                 if (wasRestricted != isRestricted) {
11007                     mMicMuteFromRestrictions = isRestricted;
11008                     setMicrophoneMuteNoCallerCheck(userId);
11009                 }
11010             }
11011 
11012             // Update speaker mute state.
11013             {
11014                 final boolean wasRestricted =
11015                         prevRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME)
11016                                 || prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE);
11017                 final boolean isRestricted =
11018                         newRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME)
11019                                 || newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE);
11020                 if (wasRestricted != isRestricted) {
11021                     setMasterMuteInternalNoCallerCheck(
11022                             isRestricted, /* flags =*/ 0, userId, "onUserRestrictionsChanged");
11023                 }
11024             }
11025         }
11026     } // end class AudioServiceUserRestrictionsListener
11027 
killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser)11028     private void killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser) {
11029         PackageManager pm = mContext.getPackageManager();
11030         // Find the home activity of the user. It should not be killed to avoid expensive restart,
11031         // when the user switches back. For managed profiles, we should kill all recording apps
11032         ComponentName homeActivityName = null;
11033         if (!oldUser.isManagedProfile()) {
11034             homeActivityName = LocalServices.getService(
11035                     ActivityTaskManagerInternal.class).getHomeActivityForUser(oldUser.id);
11036         }
11037         final String[] permissions = { Manifest.permission.RECORD_AUDIO };
11038         List<PackageInfo> packages;
11039         try {
11040             packages = AppGlobals.getPackageManager()
11041                     .getPackagesHoldingPermissions(permissions, 0, oldUser.id).getList();
11042         } catch (RemoteException e) {
11043             throw new AndroidRuntimeException(e);
11044         }
11045         for (int j = packages.size() - 1; j >= 0; j--) {
11046             PackageInfo pkg = packages.get(j);
11047             // Skip system processes
11048             if (UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID) {
11049                 continue;
11050             }
11051             // Skip packages that have permission to interact across users
11052             if (pm.checkPermission(Manifest.permission.INTERACT_ACROSS_USERS, pkg.packageName)
11053                     == PackageManager.PERMISSION_GRANTED) {
11054                 continue;
11055             }
11056             if (homeActivityName != null
11057                     && pkg.packageName.equals(homeActivityName.getPackageName())
11058                     && pkg.applicationInfo.isSystemApp()) {
11059                 continue;
11060             }
11061             try {
11062                 final int uid = pkg.applicationInfo.uid;
11063                 ActivityManager.getService().killUid(UserHandle.getAppId(uid),
11064                         UserHandle.getUserId(uid),
11065                         "killBackgroundUserProcessesWithAudioRecordPermission");
11066             } catch (RemoteException e) {
11067                 Log.w(TAG, "Error calling killUid", e);
11068             }
11069         }
11070     }
11071 
11072     /* Listen to permission invalidations for the PermissionProvider */
setupPermissionListener()11073     private void setupPermissionListener()  {
11074         // instanceof to simplify the construction requirements of AudioService for testing: no
11075         // delayed execution during unit tests.
11076         if (mAudioServerLifecycleExecutor instanceof ScheduledExecutorService exec) {
11077             // The order on the task list is an embedding on the scheduling order of the executor,
11078             // since we synchronously add the scheduled task to our local queue. This list should
11079             // almost always have only two elements, except in cases of serious system contention.
11080             Runnable task = () -> {
11081                 synchronized (mScheduledPermissionTasks) {
11082                     mScheduledPermissionTasks.add(exec.schedule(() -> {
11083                         try {
11084                             // Our goal is to remove all tasks which don't correspond to ourselves
11085                             // on this queue. Either they are already done (ahead of us), or we
11086                             // should cancel them (behind us), since their work is redundant after
11087                             // we fire.
11088                             // We must be the first non-completed task in the queue, since the
11089                             // execution order matches the queue order. Note, this task is the only
11090                             // writer on elements in the queue, and the task is serialized, so
11091                             //  => no in-flight cancellation
11092                             //  => exists at least one non-completed task (ourselves)
11093                             //  => the queue is non-empty (only completed tasks removed)
11094                             synchronized (mScheduledPermissionTasks) {
11095                                 final var iter = mScheduledPermissionTasks.iterator();
11096                                 while (iter.next().isDone()) {
11097                                     iter.remove();
11098                                 }
11099                                 // iter is on the first element which is not completed (us)
11100                                 while (iter.hasNext()) {
11101                                     if (!iter.next().cancel(false)) {
11102                                         throw new AssertionError(
11103                                                 "Cancel should be infallible since we" +
11104                                                 "cancel from the executor");
11105                                     }
11106                                     iter.remove();
11107                                 }
11108                             }
11109                             mPermissionProvider.onPermissionStateChanged();
11110                         } catch (Exception e) {
11111                             // Handle executor routing exceptions to nowhere
11112                             Thread.getDefaultUncaughtExceptionHandler()
11113                                     .uncaughtException(Thread.currentThread(), e);
11114                         }
11115                     }, getAudioPermissionsDelay(), TimeUnit.MILLISECONDS));
11116                 }
11117             };
11118             if (PropertyInvalidatedCache.separatePermissionNotificationsEnabled()) {
11119                 mCacheWatcher = new CacheWatcher(task);
11120                 mCacheWatcher.start();
11121             } else {
11122                 mSysPropListenerNativeHandle = mAudioSystem.listenForSystemPropertyChange(
11123                         PermissionManager.CACHE_KEY_PACKAGE_INFO_NOTIFY,
11124                         task);
11125             }
11126         } else {
11127             mAudioSystem.listenForSystemPropertyChange(
11128                     PermissionManager.CACHE_KEY_PACKAGE_INFO_NOTIFY,
11129                     () -> mAudioServerLifecycleExecutor.execute(
11130                                 mPermissionProvider::onPermissionStateChanged));
11131         }
11132     }
11133 
11134     /**
11135      * Listens for CACHE_KEY_PACKAGE_INFO_CACHE invalidations to trigger permission syncing
11136      */
11137     private static class CacheWatcher extends Thread {
11138 
11139         // The run/stop signal.
11140         private final AtomicBoolean mRunning = new AtomicBoolean(false);
11141 
11142         // The source of change information.
11143         private final PropertyInvalidatedCache.NonceWatcher mWatcher;
11144 
11145         // Task to trigger when cache changes
11146         private final Runnable mTask;
11147 
CacheWatcher(Runnable r)11148         public CacheWatcher(Runnable r) {
11149             mWatcher = PropertyInvalidatedCache.getNonceWatcher(
11150                     PermissionManager.CACHE_KEY_PACKAGE_INFO_CACHE);
11151             mTask = r;
11152         }
11153 
run()11154         public void run() {
11155             mRunning.set(true);
11156             while (mRunning.get()) {
11157                 doCheck();
11158                 try {
11159                     mWatcher.waitForChange();
11160                 } catch (InterruptedException e) {
11161                     Log.wtf(TAG, "Unexpected Interrupt", e);
11162                     // We don't know why the exception occurred but keep running until told to
11163                     // stop.
11164                     continue;
11165                 }
11166             }
11167         }
11168 
doCheck()11169         public synchronized void doCheck() {
11170             if (mWatcher.isChanged()) {
11171                 mTask.run();
11172             }
11173         }
11174 
11175         /**
11176          * Cause the thread to exit.  Running is set to false and the watcher is awakened.
11177          */
done()11178         public void done() {
11179             mRunning.set(false);
11180             mWatcher.wakeUp();
11181         }
11182     }
11183 
11184     //==========================================================================================
11185     // Audio Focus
11186     //==========================================================================================
11187     /**
11188      * Returns whether a focus request is eligible to force ducking.
11189      * Will return true if:
11190      * - the AudioAttributes have a usage of USAGE_ASSISTANCE_ACCESSIBILITY,
11191      * - the focus request is AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK,
11192      * - the associated Bundle has KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING set to true,
11193      * - the uid of the requester is a known accessibility service or root.
11194      * @param aa AudioAttributes of the focus request
11195      * @param uid uid of the focus requester
11196      * @return true if ducking is to be forced
11197      */
forceFocusDuckingForAccessibility(@ullable AudioAttributes aa, int request, int uid)11198     private boolean forceFocusDuckingForAccessibility(@Nullable AudioAttributes aa,
11199             int request, int uid) {
11200         if (aa == null || aa.getUsage() != AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY
11201                 || request != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) {
11202             return false;
11203         }
11204         final Bundle extraInfo = aa.getBundle();
11205         if (extraInfo == null ||
11206                 !extraInfo.getBoolean(AudioFocusRequest.KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING)) {
11207             return false;
11208         }
11209         if (uid == 0) {
11210             return true;
11211         }
11212         synchronized (mAccessibilityServiceUidsLock) {
11213             if (mAccessibilityServiceUids != null) {
11214                 int callingUid = Binder.getCallingUid();
11215                 for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
11216                     if (mAccessibilityServiceUids[i] == callingUid) {
11217                         return true;
11218                     }
11219                 }
11220             }
11221         }
11222         return false;
11223     }
11224 
isSupportedSystemUsage(@udioAttributes.AttributeUsage int usage)11225     private boolean isSupportedSystemUsage(@AudioAttributes.AttributeUsage int usage) {
11226         synchronized (mSupportedSystemUsagesLock) {
11227             for (int i = 0; i < mSupportedSystemUsages.length; i++) {
11228                 if (mSupportedSystemUsages[i] == usage) {
11229                     return true;
11230                 }
11231             }
11232             return false;
11233         }
11234     }
11235 
validateAudioAttributesUsage(@onNull AudioAttributes audioAttributes)11236     private void validateAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) {
11237         @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage();
11238         if (AudioAttributes.isSystemUsage(usage)) {
11239             if ((usage == AudioAttributes.USAGE_CALL_ASSISTANT
11240                     && (audioAttributes.getAllFlags() & AudioAttributes.FLAG_CALL_REDIRECTION) != 0
11241                     && callerHasPermission(CALL_AUDIO_INTERCEPTION))
11242                     || callerHasPermission(MODIFY_AUDIO_ROUTING)) {
11243                 if (!isSupportedSystemUsage(usage)) {
11244                     throw new IllegalArgumentException(
11245                             "Unsupported usage " + AudioAttributes.usageToString(usage));
11246                 }
11247             } else {
11248                 throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission");
11249             }
11250         }
11251     }
11252 
isValidAudioAttributesUsage(@onNull AudioAttributes audioAttributes)11253     private boolean isValidAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) {
11254         @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage();
11255         if (AudioAttributes.isSystemUsage(usage)) {
11256             return isSupportedSystemUsage(usage)
11257                     && ((usage == AudioAttributes.USAGE_CALL_ASSISTANT
11258                         && (audioAttributes.getAllFlags()
11259                             & AudioAttributes.FLAG_CALL_REDIRECTION) != 0
11260                         && callerHasPermission(CALL_AUDIO_INTERCEPTION))
11261                         || callerHasPermission(MODIFY_AUDIO_ROUTING));
11262         }
11263         return true;
11264     }
11265 
requestAudioFocus(AudioAttributes aa, int focusReqType, IBinder cb, IAudioFocusDispatcher fd, String clientId, String callingPackageName, String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk)11266     public int requestAudioFocus(AudioAttributes aa, int focusReqType, IBinder cb,
11267             IAudioFocusDispatcher fd, String clientId, String callingPackageName,
11268             String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk) {
11269         if ((flags & AudioManager.AUDIOFOCUS_FLAG_TEST) != 0) {
11270             throw new IllegalArgumentException("Invalid test flag");
11271         }
11272         final int uid = Binder.getCallingUid();
11273         MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus")
11274                 .setUid(uid)
11275                 //.putInt("focusReqType", focusReqType)
11276                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName)
11277                 .set(MediaMetrics.Property.CLIENT_NAME, clientId)
11278                 .set(MediaMetrics.Property.EVENT, "requestAudioFocus")
11279                 .set(MediaMetrics.Property.FLAGS, flags);
11280 
11281         // permission checks
11282         if (aa != null && !isValidAudioAttributesUsage(aa)) {
11283             final String reason = "Request using unsupported usage";
11284             Log.w(TAG, reason);
11285             mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
11286                     .record();
11287             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
11288         }
11289         if ((flags & AudioManager.AUDIOFOCUS_FLAG_LOCK) == AudioManager.AUDIOFOCUS_FLAG_LOCK) {
11290             if (AudioSystem.IN_VOICE_COMM_FOCUS_ID.equals(clientId)) {
11291                 if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
11292                             MODIFY_PHONE_STATE)) {
11293                     final String reason = "Invalid permission to (un)lock audio focus";
11294                     Log.e(TAG, reason, new Exception());
11295                     mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
11296                             .record();
11297                     return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
11298                 }
11299             } else {
11300                 // only a registered audio policy can be used to lock focus
11301                 synchronized (mAudioPolicies) {
11302                     if (!mAudioPolicies.containsKey(pcb.asBinder())) {
11303                         final String reason =
11304                                 "Invalid unregistered AudioPolicy to (un)lock audio focus";
11305                         Log.e(TAG, reason);
11306                         mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
11307                                 .record();
11308                         return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
11309                     }
11310                 }
11311             }
11312         }
11313 
11314         if (callingPackageName == null || clientId == null || aa == null) {
11315             final String reason = "Invalid null parameter to request audio focus";
11316             Log.e(TAG, reason);
11317             mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
11318                     .record();
11319             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
11320         }
11321 
11322         // does caller have system privileges to bypass HardeningEnforcer
11323         boolean permissionOverridesCheck = false;
11324         if ((mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
11325                 == PackageManager.PERMISSION_GRANTED)
11326                 || (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING)
11327                 == PackageManager.PERMISSION_GRANTED)) {
11328             permissionOverridesCheck = true;
11329         } else if (uid < UserHandle.AID_APP_START) {
11330             permissionOverridesCheck = true;
11331         }
11332 
11333         final long token = Binder.clearCallingIdentity();
11334         try {
11335             //TODO move inside HardeningEnforcer after refactor that moves permission checks
11336             //     in the blockFocusMethod
11337             if (permissionOverridesCheck) {
11338                 mHardeningEnforcer.metricsLogFocusReq(/*blocked*/ false, focusReqType, uid,
11339                         /*unblockedBySdk*/ false);
11340             }
11341             if (!permissionOverridesCheck && mHardeningEnforcer.blockFocusMethod(uid,
11342                     HardeningEnforcer.METHOD_AUDIO_MANAGER_REQUEST_AUDIO_FOCUS,
11343                     clientId, focusReqType, callingPackageName, attributionTag, sdk)) {
11344                 final String reason = "Audio focus request blocked by hardening";
11345                 Log.w(TAG, reason);
11346                 mmi.set(MediaMetrics.Property.EARLY_RETURN, reason).record();
11347                 return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
11348             }
11349         } finally {
11350             Binder.restoreCallingIdentity(token);
11351         }
11352 
11353         mmi.record();
11354         return mMediaFocusControl.requestAudioFocus(aa, focusReqType, cb, fd,
11355                 clientId, callingPackageName, flags, sdk,
11356                 forceFocusDuckingForAccessibility(aa, focusReqType, uid), -1 /*testUid, ignored*/,
11357                 permissionOverridesCheck);
11358     }
11359 
11360     /** see {@link AudioManager#requestAudioFocusForTest(AudioFocusRequest, String, int, int)} */
requestAudioFocusForTest(AudioAttributes aa, int focusReqType, IBinder cb, IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags, int fakeUid, int sdk)11361     public int requestAudioFocusForTest(AudioAttributes aa, int focusReqType, IBinder cb,
11362             IAudioFocusDispatcher fd, String clientId, String callingPackageName,
11363             int flags, int fakeUid, int sdk) {
11364         if (!enforceQueryAudioStateForTest("focus request")) {
11365             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
11366         }
11367         if (callingPackageName == null || clientId == null || aa == null) {
11368             final String reason = "Invalid null parameter to request audio focus";
11369             Log.e(TAG, reason);
11370             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
11371         }
11372         return mMediaFocusControl.requestAudioFocus(aa, focusReqType, cb, fd,
11373                 clientId, callingPackageName, flags,
11374                 sdk, false /*forceDuck*/, fakeUid, true /*permissionOverridesCheck*/);
11375     }
11376 
abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)11377     public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa,
11378             String callingPackageName) {
11379         MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus")
11380                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName)
11381                 .set(MediaMetrics.Property.CLIENT_NAME, clientId)
11382                 .set(MediaMetrics.Property.EVENT, "abandonAudioFocus");
11383 
11384         if (aa != null && !isValidAudioAttributesUsage(aa)) {
11385             Log.w(TAG, "Request using unsupported usage.");
11386             mmi.set(MediaMetrics.Property.EARLY_RETURN, "unsupported usage").record();
11387 
11388             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
11389         }
11390         mmi.record();
11391         //delay abandon focus requests from Telecom if an audio mode reset from Telecom
11392         // is still being processed
11393         final boolean abandonFromTelecom = (mContext.checkCallingOrSelfPermission(
11394                     MODIFY_PHONE_STATE) == PackageManager.PERMISSION_GRANTED)
11395                 && ((aa != null && aa.getUsage() == AudioAttributes.USAGE_VOICE_COMMUNICATION)
11396                         || AudioSystem.IN_VOICE_COMM_FOCUS_ID.equals(clientId));
11397         if (abandonFromTelecom) {
11398             synchronized (mAudioModeResetLock) {
11399                 final long start = java.lang.System.currentTimeMillis();
11400                 long elapsed = 0;
11401                 while (mAudioModeResetCount > 0) {
11402                     if (DEBUG_MODE) {
11403                         Log.i(TAG, "Abandon focus from Telecom, waiting for mode change");
11404                     }
11405                     try {
11406                         mAudioModeResetLock.wait(
11407                                 AUDIO_MODE_RESET_TIMEOUT_MS - elapsed);
11408                     } catch (InterruptedException e) {
11409                         Log.w(TAG, "Interrupted while waiting for audio mode reset");
11410                     }
11411                     elapsed = java.lang.System.currentTimeMillis() - start;
11412                     if (elapsed >= AUDIO_MODE_RESET_TIMEOUT_MS) {
11413                         Log.e(TAG, "Timeout waiting for audio mode reset");
11414                         // reset count to avoid sticky out of sync state.
11415                         resetAudioModeResetCount();
11416                         break;
11417                     }
11418                 }
11419                 if (DEBUG_MODE && elapsed != 0) {
11420                     Log.i(TAG, "Abandon focus from Telecom done waiting");
11421                 }
11422             }
11423         }
11424         return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName);
11425     }
11426 
11427     /** synchronization between setMode(NORMAL) and abandonAudioFocus() from Telecom */
11428     private static final long AUDIO_MODE_RESET_TIMEOUT_MS = 3000;
11429 
11430     private final Object mAudioModeResetLock = new Object();
11431 
11432     @GuardedBy("mAudioModeResetLock")
11433     private int mAudioModeResetCount = 0;
11434 
decrementAudioModeResetCount()11435     void decrementAudioModeResetCount() {
11436         synchronized (mAudioModeResetLock) {
11437             if (mAudioModeResetCount > 0) {
11438                 mAudioModeResetCount--;
11439             } else {
11440                 Log.w(TAG, "mAudioModeResetCount already 0");
11441             }
11442             mAudioModeResetLock.notify();
11443         }
11444     }
11445 
resetAudioModeResetCount()11446     private void resetAudioModeResetCount() {
11447         synchronized (mAudioModeResetLock) {
11448             mAudioModeResetCount = 0;
11449             mAudioModeResetLock.notify();
11450         }
11451     }
11452 
11453     /** see {@link AudioManager#abandonAudioFocusForTest(AudioFocusRequest, String)} */
abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)11454     public int abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId,
11455             AudioAttributes aa, String callingPackageName) {
11456         if (!enforceQueryAudioStateForTest("focus abandon")) {
11457             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
11458         }
11459         return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName);
11460     }
11461 
11462     /** see {@link AudioManager#getFocusDuckedUidsForTest()} */
11463     @Override
11464     @EnforcePermission(QUERY_AUDIO_STATE)
getFocusDuckedUidsForTest()11465     public @NonNull List<Integer> getFocusDuckedUidsForTest() {
11466         super.getFocusDuckedUidsForTest_enforcePermission();
11467         return mPlaybackMonitor.getFocusDuckedUids();
11468     }
11469 
unregisterAudioFocusClient(String clientId)11470     public void unregisterAudioFocusClient(String clientId) {
11471         new MediaMetrics.Item(mMetricsId + "focus")
11472                 .set(MediaMetrics.Property.CLIENT_NAME, clientId)
11473                 .set(MediaMetrics.Property.EVENT, "unregisterAudioFocusClient")
11474                 .record();
11475         mMediaFocusControl.unregisterAudioFocusClient(clientId);
11476     }
11477 
getCurrentAudioFocus()11478     public int getCurrentAudioFocus() {
11479         return mMediaFocusControl.getCurrentAudioFocus();
11480     }
11481 
getFocusRampTimeMs(int focusGain, AudioAttributes attr)11482     public int getFocusRampTimeMs(int focusGain, AudioAttributes attr) {
11483         return mMediaFocusControl.getFocusRampTimeMs(focusGain, attr);
11484     }
11485 
11486     /**
11487      * Test method to return the duration of the fade out applied on the players of a focus loser
11488      * @see AudioManager#getFocusFadeOutDurationForTest()
11489      * @return the fade out duration, in ms
11490      */
11491     @EnforcePermission(QUERY_AUDIO_STATE)
getFocusFadeOutDurationForTest()11492     public long getFocusFadeOutDurationForTest() {
11493         super.getFocusFadeOutDurationForTest_enforcePermission();
11494         return mMediaFocusControl.getFocusFadeOutDurationForTest();
11495     }
11496 
11497     /**
11498      * Test method to return the length of time after a fade out before the focus loser is unmuted
11499      * (and is faded back in).
11500      * @see AudioManager#getFocusUnmuteDelayAfterFadeOutForTest()
11501      * @return the time gap after a fade out completion on focus loss, and fade in start, in ms
11502      */
11503     @Override
11504     @EnforcePermission(QUERY_AUDIO_STATE)
getFocusUnmuteDelayAfterFadeOutForTest()11505     public long getFocusUnmuteDelayAfterFadeOutForTest() {
11506         super.getFocusUnmuteDelayAfterFadeOutForTest_enforcePermission();
11507         return mMediaFocusControl.getFocusUnmuteDelayAfterFadeOutForTest();
11508     }
11509 
11510     /**
11511      * Test method to start preventing applications from requesting audio focus during a test,
11512      * which could interfere with the testing of the functionality/behavior under test.
11513      * Calling this method needs to be paired with a call to {@link #exitAudioFocusFreezeForTest}
11514      * when the testing is done. If this is not the case (e.g. in case of a test crash),
11515      * a death observer mechanism will ensure the system is not left in a bad state, but this should
11516      * not be relied on when implementing tests.
11517      * @see AudioManager#enterAudioFocusFreezeForTest(List)
11518      * @param cb IBinder to track the death of the client of this method
11519      * @param exemptedUids a list of UIDs that are exempt from the freeze. This would for instance
11520      *                     be those of the test runner and other players used in the test
11521      * @return true if the focus freeze mode is successfully entered, false if there was an issue,
11522      *     such as another freeze currently used.
11523      */
11524     @Override
11525     @EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
enterAudioFocusFreezeForTest(IBinder cb, int[] exemptedUids)11526     public boolean enterAudioFocusFreezeForTest(IBinder cb, int[] exemptedUids) {
11527         super.enterAudioFocusFreezeForTest_enforcePermission();
11528         Objects.requireNonNull(exemptedUids);
11529         Objects.requireNonNull(cb);
11530         return mMediaFocusControl.enterAudioFocusFreezeForTest(cb, exemptedUids);
11531     }
11532 
11533     /**
11534      * Test method to end preventing applications from requesting audio focus during a test.
11535      * @see AudioManager#exitAudioFocusFreezeForTest()
11536      * @param cb IBinder identifying the client of this method
11537      * @return true if the focus freeze mode is successfully exited, false if there was an issue,
11538      *     such as the freeze already having ended, or not started.
11539      */
11540     @Override
11541     @EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
exitAudioFocusFreezeForTest(IBinder cb)11542     public boolean exitAudioFocusFreezeForTest(IBinder cb) {
11543         super.exitAudioFocusFreezeForTest_enforcePermission();
11544         Objects.requireNonNull(cb);
11545         return mMediaFocusControl.exitAudioFocusFreezeForTest(cb);
11546     }
11547 
11548     /** only public for mocking/spying, do not call outside of AudioService */
11549     @VisibleForTesting
hasAudioFocusUsers()11550     public boolean hasAudioFocusUsers() {
11551         return mMediaFocusControl.hasAudioFocusUsers();
11552     }
11553 
11554     /** see {@link AudioManager#getFadeOutDurationOnFocusLossMillis(AudioAttributes)} */
11555     @Override
getFadeOutDurationOnFocusLossMillis(AudioAttributes aa)11556     public long getFadeOutDurationOnFocusLossMillis(AudioAttributes aa) {
11557         if (!enforceQueryAudioStateForTest("fade out duration")) {
11558             return 0;
11559         }
11560         return mMediaFocusControl.getFadeOutDurationOnFocusLossMillis(aa);
11561     }
11562 
enforceQueryAudioStateForTest(String mssg)11563     private boolean enforceQueryAudioStateForTest(String mssg) {
11564         if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
11565                 Manifest.permission.QUERY_AUDIO_STATE)) {
11566             final String reason = "Doesn't have QUERY_AUDIO_STATE permission for "
11567                     + mssg + " test API";
11568             Log.e(TAG, reason, new Exception());
11569             return false;
11570         }
11571         return true;
11572     }
11573 
11574     //==========================================================================================
11575     private final @NonNull SpatializerHelper mSpatializerHelper;
11576     /**
11577      * Initialized from property ro.audio.spatializer_enabled
11578      * Should only be 1 when the device ships with a Spatializer effect
11579      */
11580     private final boolean mHasSpatializerEffect;
11581     /**
11582      * Default value for the spatial audio feature
11583      */
11584     private static final boolean SPATIAL_AUDIO_ENABLED_DEFAULT = true;
11585 
enforceModifyDefaultAudioEffectsPermission()11586     private void enforceModifyDefaultAudioEffectsPermission() {
11587         if (mContext.checkCallingOrSelfPermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11588                 != PackageManager.PERMISSION_GRANTED) {
11589             throw new SecurityException("Missing MODIFY_DEFAULT_AUDIO_EFFECTS permission");
11590         }
11591     }
11592 
11593     /**
11594      * Returns the immersive audio level that the platform is capable of
11595      * @see Spatializer#getImmersiveAudioLevel()
11596      */
getSpatializerImmersiveAudioLevel()11597     public int getSpatializerImmersiveAudioLevel() {
11598         return mSpatializerHelper.getCapableImmersiveAudioLevel();
11599     }
11600 
11601     /** @see Spatializer#isEnabled() */
isSpatializerEnabled()11602     public boolean isSpatializerEnabled() {
11603         return mSpatializerHelper.isEnabled();
11604     }
11605 
11606     /** @see Spatializer#isAvailable() */
isSpatializerAvailable()11607     public boolean isSpatializerAvailable() {
11608         return mSpatializerHelper.isAvailable();
11609     }
11610 
11611     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11612     /** @see Spatializer#isAvailableForDevice(AudioDeviceAttributes) */
isSpatializerAvailableForDevice(@onNull AudioDeviceAttributes device)11613     public boolean isSpatializerAvailableForDevice(@NonNull AudioDeviceAttributes device)  {
11614         super.isSpatializerAvailableForDevice_enforcePermission();
11615 
11616         return mSpatializerHelper.isAvailableForDevice(Objects.requireNonNull(device));
11617     }
11618 
11619     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11620     /** @see Spatializer#hasHeadTracker(AudioDeviceAttributes) */
hasHeadTracker(@onNull AudioDeviceAttributes device)11621     public boolean hasHeadTracker(@NonNull AudioDeviceAttributes device) {
11622         super.hasHeadTracker_enforcePermission();
11623 
11624         return mSpatializerHelper.hasHeadTracker(Objects.requireNonNull(device));
11625     }
11626 
11627     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11628     /** @see Spatializer#setHeadTrackerEnabled(boolean, AudioDeviceAttributes) */
setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device)11629     public void setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device) {
11630         super.setHeadTrackerEnabled_enforcePermission();
11631 
11632         mSpatializerHelper.setHeadTrackerEnabled(enabled, Objects.requireNonNull(device));
11633     }
11634 
11635     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11636     /** @see Spatializer#isHeadTrackerEnabled(AudioDeviceAttributes) */
isHeadTrackerEnabled(@onNull AudioDeviceAttributes device)11637     public boolean isHeadTrackerEnabled(@NonNull AudioDeviceAttributes device) {
11638         super.isHeadTrackerEnabled_enforcePermission();
11639 
11640         return mSpatializerHelper.isHeadTrackerEnabled(Objects.requireNonNull(device));
11641     }
11642 
11643     /** @see Spatializer#isHeadTrackerAvailable() */
isHeadTrackerAvailable()11644     public boolean isHeadTrackerAvailable() {
11645         return mSpatializerHelper.isHeadTrackerAvailable();
11646     }
11647 
11648     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11649     /** @see Spatializer#setSpatializerEnabled(boolean) */
setSpatializerEnabled(boolean enabled)11650     public void setSpatializerEnabled(boolean enabled) {
11651         super.setSpatializerEnabled_enforcePermission();
11652 
11653         mSpatializerHelper.setFeatureEnabled(enabled);
11654     }
11655 
11656     /** @see Spatializer#canBeSpatialized() */
canBeSpatialized( @onNull AudioAttributes attributes, @NonNull AudioFormat format)11657     public boolean canBeSpatialized(
11658             @NonNull AudioAttributes attributes, @NonNull AudioFormat format) {
11659         Objects.requireNonNull(attributes);
11660         Objects.requireNonNull(format);
11661         return mSpatializerHelper.canBeSpatialized(attributes, format);
11662     }
11663 
getSpatializedChannelMasks()11664     public @NonNull List<Integer> getSpatializedChannelMasks() {
11665         return mSpatializerHelper.getSpatializedChannelMasks();
11666     }
11667 
11668     /** @see Spatializer.SpatializerInfoDispatcherStub */
registerSpatializerCallback( @onNull ISpatializerCallback cb)11669     public void registerSpatializerCallback(
11670             @NonNull ISpatializerCallback cb) {
11671         Objects.requireNonNull(cb);
11672         mSpatializerHelper.registerStateCallback(cb);
11673     }
11674 
11675     /** @see Spatializer.SpatializerInfoDispatcherStub */
unregisterSpatializerCallback( @onNull ISpatializerCallback cb)11676     public void unregisterSpatializerCallback(
11677             @NonNull ISpatializerCallback cb) {
11678         Objects.requireNonNull(cb);
11679         mSpatializerHelper.unregisterStateCallback(cb);
11680     }
11681 
11682     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11683     /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */
registerSpatializerHeadTrackingCallback( @onNull ISpatializerHeadTrackingModeCallback cb)11684     public void registerSpatializerHeadTrackingCallback(
11685             @NonNull ISpatializerHeadTrackingModeCallback cb) {
11686         super.registerSpatializerHeadTrackingCallback_enforcePermission();
11687 
11688         Objects.requireNonNull(cb);
11689         mSpatializerHelper.registerHeadTrackingModeCallback(cb);
11690     }
11691 
11692     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11693     /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */
unregisterSpatializerHeadTrackingCallback( @onNull ISpatializerHeadTrackingModeCallback cb)11694     public void unregisterSpatializerHeadTrackingCallback(
11695             @NonNull ISpatializerHeadTrackingModeCallback cb) {
11696         super.unregisterSpatializerHeadTrackingCallback_enforcePermission();
11697 
11698         Objects.requireNonNull(cb);
11699         mSpatializerHelper.unregisterHeadTrackingModeCallback(cb);
11700     }
11701 
11702     /** @see Spatializer.SpatializerHeadTrackerAvailableDispatcherStub */
registerSpatializerHeadTrackerAvailableCallback( @onNull ISpatializerHeadTrackerAvailableCallback cb, boolean register)11703     public void registerSpatializerHeadTrackerAvailableCallback(
11704             @NonNull ISpatializerHeadTrackerAvailableCallback cb, boolean register) {
11705         Objects.requireNonNull(cb);
11706         mSpatializerHelper.registerHeadTrackerAvailableCallback(cb, register);
11707     }
11708 
11709     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11710     /** @see Spatializer#setOnHeadToSoundstagePoseUpdatedListener */
registerHeadToSoundstagePoseCallback( @onNull ISpatializerHeadToSoundStagePoseCallback cb)11711     public void registerHeadToSoundstagePoseCallback(
11712             @NonNull ISpatializerHeadToSoundStagePoseCallback cb) {
11713         super.registerHeadToSoundstagePoseCallback_enforcePermission();
11714 
11715         Objects.requireNonNull(cb);
11716         mSpatializerHelper.registerHeadToSoundstagePoseCallback(cb);
11717     }
11718 
11719     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11720     /** @see Spatializer#clearOnHeadToSoundstagePoseUpdatedListener */
unregisterHeadToSoundstagePoseCallback( @onNull ISpatializerHeadToSoundStagePoseCallback cb)11721     public void unregisterHeadToSoundstagePoseCallback(
11722             @NonNull ISpatializerHeadToSoundStagePoseCallback cb) {
11723         super.unregisterHeadToSoundstagePoseCallback_enforcePermission();
11724 
11725         Objects.requireNonNull(cb);
11726         mSpatializerHelper.unregisterHeadToSoundstagePoseCallback(cb);
11727     }
11728 
11729     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11730     /** @see Spatializer#getSpatializerCompatibleAudioDevices() */
getSpatializerCompatibleAudioDevices()11731     public @NonNull List<AudioDeviceAttributes> getSpatializerCompatibleAudioDevices() {
11732         super.getSpatializerCompatibleAudioDevices_enforcePermission();
11733 
11734         return mSpatializerHelper.getCompatibleAudioDevices();
11735     }
11736 
11737     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11738     /** @see Spatializer#addSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */
addSpatializerCompatibleAudioDevice(@onNull AudioDeviceAttributes ada)11739     public void addSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
11740         super.addSpatializerCompatibleAudioDevice_enforcePermission();
11741 
11742         Objects.requireNonNull(ada);
11743         mSpatializerHelper.addCompatibleAudioDevice(ada);
11744     }
11745 
11746     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11747     /** @see Spatializer#removeSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */
removeSpatializerCompatibleAudioDevice(@onNull AudioDeviceAttributes ada)11748     public void removeSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
11749         super.removeSpatializerCompatibleAudioDevice_enforcePermission();
11750 
11751         Objects.requireNonNull(ada);
11752         mSpatializerHelper.removeCompatibleAudioDevice(ada);
11753     }
11754 
11755     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11756     /** @see Spatializer#getSupportedHeadTrackingModes() */
getSupportedHeadTrackingModes()11757     public int[] getSupportedHeadTrackingModes() {
11758         super.getSupportedHeadTrackingModes_enforcePermission();
11759 
11760         return mSpatializerHelper.getSupportedHeadTrackingModes();
11761     }
11762 
11763     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11764     /** @see Spatializer#getHeadTrackingMode() */
getActualHeadTrackingMode()11765     public int getActualHeadTrackingMode() {
11766         super.getActualHeadTrackingMode_enforcePermission();
11767 
11768         return mSpatializerHelper.getActualHeadTrackingMode();
11769     }
11770 
11771     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11772     /** @see Spatializer#getDesiredHeadTrackingMode() */
getDesiredHeadTrackingMode()11773     public int getDesiredHeadTrackingMode() {
11774         super.getDesiredHeadTrackingMode_enforcePermission();
11775 
11776         return mSpatializerHelper.getDesiredHeadTrackingMode();
11777     }
11778 
11779     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11780     /** @see Spatializer#setGlobalTransform */
setSpatializerGlobalTransform(@onNull float[] transform)11781     public void setSpatializerGlobalTransform(@NonNull float[] transform) {
11782         super.setSpatializerGlobalTransform_enforcePermission();
11783 
11784         Objects.requireNonNull(transform);
11785         mSpatializerHelper.setGlobalTransform(transform);
11786     }
11787 
11788     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11789     /** @see Spatializer#recenterHeadTracker() */
recenterHeadTracker()11790     public void recenterHeadTracker() {
11791         super.recenterHeadTracker_enforcePermission();
11792 
11793         mSpatializerHelper.recenterHeadTracker();
11794     }
11795 
11796     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11797     /** @see Spatializer#setDesiredHeadTrackingMode */
setDesiredHeadTrackingMode(@patializer.HeadTrackingModeSet int mode)11798     public void setDesiredHeadTrackingMode(@Spatializer.HeadTrackingModeSet int mode) {
11799         super.setDesiredHeadTrackingMode_enforcePermission();
11800 
11801         switch(mode) {
11802             case Spatializer.HEAD_TRACKING_MODE_DISABLED:
11803             case Spatializer.HEAD_TRACKING_MODE_RELATIVE_WORLD:
11804             case Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE:
11805                 break;
11806             default:
11807                 return;
11808         }
11809         mSpatializerHelper.setDesiredHeadTrackingMode(mode);
11810     }
11811 
11812     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11813     /** @see Spatializer#setEffectParameter */
setSpatializerParameter(int key, @NonNull byte[] value)11814     public void setSpatializerParameter(int key, @NonNull byte[] value) {
11815         super.setSpatializerParameter_enforcePermission();
11816 
11817         Objects.requireNonNull(value);
11818         mSpatializerHelper.setEffectParameter(key, value);
11819     }
11820 
11821     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11822     /** @see Spatializer#getEffectParameter */
getSpatializerParameter(int key, @NonNull byte[] value)11823     public void getSpatializerParameter(int key, @NonNull byte[] value) {
11824         super.getSpatializerParameter_enforcePermission();
11825 
11826         Objects.requireNonNull(value);
11827         mSpatializerHelper.getEffectParameter(key, value);
11828     }
11829 
11830     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11831     /** @see Spatializer#getOutput */
getSpatializerOutput()11832     public int getSpatializerOutput() {
11833         super.getSpatializerOutput_enforcePermission();
11834 
11835         return mSpatializerHelper.getOutput();
11836     }
11837 
11838     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11839     /** @see Spatializer#setOnSpatializerOutputChangedListener */
registerSpatializerOutputCallback(ISpatializerOutputCallback cb)11840     public void registerSpatializerOutputCallback(ISpatializerOutputCallback cb) {
11841         super.registerSpatializerOutputCallback_enforcePermission();
11842 
11843         Objects.requireNonNull(cb);
11844         mSpatializerHelper.registerSpatializerOutputCallback(cb);
11845     }
11846 
11847     @android.annotation.EnforcePermission(MODIFY_DEFAULT_AUDIO_EFFECTS)
11848     /** @see Spatializer#clearOnSpatializerOutputChangedListener */
unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb)11849     public void unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb) {
11850         super.unregisterSpatializerOutputCallback_enforcePermission();
11851 
11852         Objects.requireNonNull(cb);
11853         mSpatializerHelper.unregisterSpatializerOutputCallback(cb);
11854     }
11855 
11856     /**
11857      * post a message to schedule init/release of head tracking sensors
11858      * whether to initialize or release sensors is based on the state of spatializer
11859      */
postInitSpatializerHeadTrackingSensors()11860     void postInitSpatializerHeadTrackingSensors() {
11861         sendMsg(mAudioHandler,
11862                 MSG_INIT_HEADTRACKING_SENSORS,
11863                 SENDMSG_REPLACE,
11864                 /*arg1*/ 0, /*arg2*/ 0, TAG, /*delay*/ 0);
11865     }
11866 
11867     /**
11868      * post a message to schedule a reset of the spatializer state
11869      */
postResetSpatializer()11870     void postResetSpatializer() {
11871         sendMsg(mAudioHandler,
11872                 MSG_RESET_SPATIALIZER,
11873                 SENDMSG_REPLACE,
11874                 /*arg1*/ 0, /*arg2*/ 0, TAG, /*delay*/ 0);
11875     }
11876 
onInitAdiDeviceStates()11877     void onInitAdiDeviceStates() {
11878         mDeviceBroker.onReadAudioDeviceSettings();
11879         mSoundDoseHelper.initCachedAudioDeviceCategories(
11880                 mDeviceBroker.getImmutableDeviceInventory());
11881     }
11882 
onInitSpatializer()11883     void onInitSpatializer() {
11884         mSpatializerHelper.init(/*effectExpected*/ mHasSpatializerEffect);
11885         mSpatializerHelper.setFeatureEnabled(mHasSpatializerEffect);
11886     }
11887 
isSADevice(AdiDeviceState deviceState)11888     /*package*/ boolean isSADevice(AdiDeviceState deviceState) {
11889         return mSpatializerHelper.isSADevice(deviceState);
11890     }
11891 
isBluetoothPrividged()11892     private boolean isBluetoothPrividged() {
11893         return PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
11894                 Manifest.permission.BLUETOOTH_CONNECT)
11895                 || Binder.getCallingUid() == Process.SYSTEM_UID;
11896     }
11897 
retrieveBluetoothAddresses(List<AudioDeviceAttributes> devices)11898     List<AudioDeviceAttributes> retrieveBluetoothAddresses(List<AudioDeviceAttributes> devices) {
11899         if (isBluetoothPrividged()) {
11900             return devices;
11901         }
11902 
11903         List<AudioDeviceAttributes> checkedDevices = new ArrayList<AudioDeviceAttributes>();
11904         for (AudioDeviceAttributes ada : devices) {
11905             if (ada == null) {
11906                 continue;
11907             }
11908             checkedDevices.add(retrieveBluetoothAddressUncheked(ada));
11909         }
11910         return checkedDevices;
11911     }
11912 
retrieveBluetoothAddress(@onNull AudioDeviceAttributes ada)11913     AudioDeviceAttributes retrieveBluetoothAddress(@NonNull AudioDeviceAttributes ada) {
11914         if (isBluetoothPrividged()) {
11915             return ada;
11916         }
11917         return retrieveBluetoothAddressUncheked(ada);
11918     }
11919 
retrieveBluetoothAddressUncheked(@onNull AudioDeviceAttributes ada)11920     AudioDeviceAttributes retrieveBluetoothAddressUncheked(@NonNull AudioDeviceAttributes ada) {
11921         Objects.requireNonNull(ada);
11922         if (AudioSystem.isBluetoothDevice(ada.getInternalType())) {
11923             String anonymizedAddress = Utils.anonymizeBluetoothAddress(ada.getAddress());
11924             for (AdiDeviceState ads : mDeviceBroker.getImmutableDeviceInventory()) {
11925                 if (!(AudioSystem.isBluetoothDevice(ads.getInternalDeviceType())
11926                         && (ada.getInternalType() == ads.getInternalDeviceType())
11927                         && anonymizedAddress.equals(Utils.anonymizeBluetoothAddress(
11928                                 ads.getDeviceAddress())))) {
11929                     continue;
11930                 }
11931                 ada.setAddress(ads.getDeviceAddress());
11932                 break;
11933             }
11934         }
11935         return ada;
11936     }
11937 
anonymizeAudioDeviceAttributesList( List<AudioDeviceAttributes> devices)11938     private List<AudioDeviceAttributes> anonymizeAudioDeviceAttributesList(
11939                 List<AudioDeviceAttributes> devices) {
11940         if (isBluetoothPrividged()) {
11941             return devices;
11942         }
11943         return anonymizeAudioDeviceAttributesListUnchecked(devices);
11944     }
11945 
anonymizeAudioDeviceAttributesListUnchecked( List<AudioDeviceAttributes> devices)11946     /* package */ List<AudioDeviceAttributes> anonymizeAudioDeviceAttributesListUnchecked(
11947             List<AudioDeviceAttributes> devices) {
11948         List<AudioDeviceAttributes> anonymizedDevices = new ArrayList<AudioDeviceAttributes>();
11949         for (AudioDeviceAttributes ada : devices) {
11950             anonymizedDevices.add(anonymizeAudioDeviceAttributesUnchecked(ada));
11951         }
11952         return anonymizedDevices;
11953     }
11954 
anonymizeAudioDeviceAttributesUnchecked( AudioDeviceAttributes ada)11955     private AudioDeviceAttributes anonymizeAudioDeviceAttributesUnchecked(
11956             AudioDeviceAttributes ada) {
11957         if (ada == null || !AudioSystem.isBluetoothDevice(ada.getInternalType())) {
11958             return ada;
11959         }
11960         AudioDeviceAttributes res = new AudioDeviceAttributes(ada);
11961         res.setAddress(Utils.anonymizeBluetoothAddress(ada.getAddress()));
11962         return res;
11963     }
11964 
anonymizeAudioDeviceAttributes(AudioDeviceAttributes ada)11965     private AudioDeviceAttributes anonymizeAudioDeviceAttributes(AudioDeviceAttributes ada) {
11966         if (isBluetoothPrividged()) {
11967             return ada;
11968         }
11969 
11970         return anonymizeAudioDeviceAttributesUnchecked(ada);
11971     }
11972 
11973     // ========================================================================================
11974     // LoudnessCodecConfigurator
11975 
11976     @Override
registerLoudnessCodecUpdatesDispatcher(ILoudnessCodecUpdatesDispatcher dispatcher)11977     public void registerLoudnessCodecUpdatesDispatcher(ILoudnessCodecUpdatesDispatcher dispatcher) {
11978         mLoudnessCodecHelper.registerLoudnessCodecUpdatesDispatcher(dispatcher);
11979     }
11980 
11981     @Override
unregisterLoudnessCodecUpdatesDispatcher( ILoudnessCodecUpdatesDispatcher dispatcher)11982     public void unregisterLoudnessCodecUpdatesDispatcher(
11983             ILoudnessCodecUpdatesDispatcher dispatcher) {
11984         mLoudnessCodecHelper.unregisterLoudnessCodecUpdatesDispatcher(dispatcher);
11985     }
11986 
11987     /** @see LoudnessCodecController#create(int) */
11988     @Override
startLoudnessCodecUpdates(int sessionId)11989     public void startLoudnessCodecUpdates(int sessionId) {
11990         mLoudnessCodecHelper.startLoudnessCodecUpdates(sessionId);
11991     }
11992 
11993     /** @see LoudnessCodecController#close() */
11994     @Override
stopLoudnessCodecUpdates(int sessionId)11995     public void stopLoudnessCodecUpdates(int sessionId) {
11996         mLoudnessCodecHelper.stopLoudnessCodecUpdates(sessionId);
11997     }
11998 
11999     /** @see LoudnessCodecController#addMediaCodec(MediaCodec) */
12000     @Override
addLoudnessCodecInfo(int sessionId, int mediaCodecHash, LoudnessCodecInfo codecInfo)12001     public void addLoudnessCodecInfo(int sessionId, int mediaCodecHash,
12002             LoudnessCodecInfo codecInfo) {
12003         mLoudnessCodecHelper.addLoudnessCodecInfo(sessionId, mediaCodecHash, codecInfo);
12004     }
12005 
12006     /** @see LoudnessCodecController#removeMediaCodec(MediaCodec) */
12007     @Override
removeLoudnessCodecInfo(int sessionId, LoudnessCodecInfo codecInfo)12008     public void removeLoudnessCodecInfo(int sessionId, LoudnessCodecInfo codecInfo) {
12009         mLoudnessCodecHelper.removeLoudnessCodecInfo(sessionId, codecInfo);
12010     }
12011 
12012     /** @see LoudnessCodecController#getLoudnessCodecParams(MediaCodec) */
12013     @Override
getLoudnessParams(LoudnessCodecInfo codecInfo)12014     public PersistableBundle getLoudnessParams(LoudnessCodecInfo codecInfo) {
12015         return mLoudnessCodecHelper.getLoudnessParams(codecInfo);
12016     }
12017 
12018     //==========================================================================================
12019 
12020     // camera sound is forced if any of the resources corresponding to one active SIM
12021     // demands it.
readCameraSoundForced()12022     private boolean readCameraSoundForced() {
12023         if (SystemProperties.getBoolean("audio.camerasound.force", false)
12024                 || mContext.getResources().getBoolean(
12025                         com.android.internal.R.bool.config_camera_sound_forced)) {
12026             return true;
12027         }
12028 
12029         SubscriptionManager subscriptionManager = mContext.getSystemService(
12030                 SubscriptionManager.class);
12031         if (subscriptionManager == null) {
12032             Log.e(TAG, "readCameraSoundForced cannot create SubscriptionManager!");
12033             return false;
12034         }
12035         int[] subscriptionIds = subscriptionManager.getActiveSubscriptionIdList(false);
12036         for (int subId : subscriptionIds) {
12037             if (SubscriptionManager.getResourcesForSubId(mContext, subId).getBoolean(
12038                     com.android.internal.R.bool.config_camera_sound_forced)) {
12039                 return true;
12040             }
12041         }
12042         return false;
12043     }
12044 
12045     //==========================================================================================
12046     private final Object mMuteAwaitConnectionLock = new Object();
12047 
12048     /**
12049      * The device that is expected to be connected soon, and causes players to be muted until
12050      * its connection, or it times out.
12051      * Null when no active muting command, or it has timed out.
12052      */
12053     @GuardedBy("mMuteAwaitConnectionLock")
12054     private AudioDeviceAttributes mMutingExpectedDevice;
12055     @GuardedBy("mMuteAwaitConnectionLock")
12056     private @Nullable int[] mMutedUsagesAwaitingConnection;
12057 
12058     /** @see AudioManager#muteAwaitConnection */
12059     @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection
muteAwaitConnection(@onNull int[] usages, @NonNull AudioDeviceAttributes device, long timeOutMs)12060     public void muteAwaitConnection(@NonNull int[] usages,
12061             @NonNull AudioDeviceAttributes device, long timeOutMs) {
12062         Objects.requireNonNull(usages);
12063         Objects.requireNonNull(device);
12064         enforceModifyAudioRoutingPermission();
12065 
12066         final AudioDeviceAttributes ada = retrieveBluetoothAddress(device);
12067 
12068         if (timeOutMs <= 0 || usages.length == 0) {
12069             throw new IllegalArgumentException("Invalid timeOutMs/usagesToMute");
12070         }
12071         Log.i(TAG, "muteAwaitConnection dev:" + device + " timeOutMs:" + timeOutMs
12072                 + " usages:" + Arrays.toString(usages));
12073 
12074         if (mDeviceBroker.isDeviceConnected(ada)) {
12075             // not throwing an exception as there could be a race between a connection (server-side,
12076             // notification of connection in flight) and a mute operation (client-side)
12077             Log.i(TAG, "muteAwaitConnection ignored, device (" + device + ") already connected");
12078             return;
12079         }
12080         synchronized (mMuteAwaitConnectionLock) {
12081             if (mMutingExpectedDevice != null) {
12082                 Log.e(TAG, "muteAwaitConnection ignored, another in progress for device:"
12083                         + mMutingExpectedDevice);
12084                 throw new IllegalStateException("muteAwaitConnection already in progress");
12085             }
12086             mMutingExpectedDevice = ada;
12087             mMutedUsagesAwaitingConnection = usages;
12088             mPlaybackMonitor.muteAwaitConnection(usages, ada, timeOutMs);
12089         }
12090         dispatchMuteAwaitConnection((cb, isPrivileged) -> {
12091             try {
12092                 AudioDeviceAttributes dev = ada;
12093                 if (!isPrivileged) {
12094                     dev = anonymizeAudioDeviceAttributesUnchecked(ada);
12095                 }
12096                 cb.dispatchOnMutedUntilConnection(dev, usages);
12097             } catch (RemoteException e) { }
12098         });
12099     }
12100 
12101     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
12102     /** @see AudioManager#getMutingExpectedDevice */
getMutingExpectedDevice()12103     public @Nullable AudioDeviceAttributes getMutingExpectedDevice() {
12104         super.getMutingExpectedDevice_enforcePermission();
12105 
12106         synchronized (mMuteAwaitConnectionLock) {
12107             return anonymizeAudioDeviceAttributes(mMutingExpectedDevice);
12108         }
12109     }
12110 
12111     /** @see AudioManager#cancelMuteAwaitConnection */
12112     @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection
cancelMuteAwaitConnection(@onNull AudioDeviceAttributes device)12113     public void cancelMuteAwaitConnection(@NonNull AudioDeviceAttributes device) {
12114         Objects.requireNonNull(device);
12115         enforceModifyAudioRoutingPermission();
12116 
12117         final AudioDeviceAttributes ada = retrieveBluetoothAddress(device);
12118 
12119         Log.i(TAG, "cancelMuteAwaitConnection for device:" + device);
12120         final int[] mutedUsages;
12121         synchronized (mMuteAwaitConnectionLock) {
12122             if (mMutingExpectedDevice == null) {
12123                 // not throwing an exception as there could be a race between a timeout
12124                 // (server-side) and a cancel operation (client-side)
12125                 Log.i(TAG, "cancelMuteAwaitConnection ignored, no expected device");
12126                 return;
12127             }
12128             if (!ada.equalTypeAddress(mMutingExpectedDevice)) {
12129                 Log.e(TAG, "cancelMuteAwaitConnection ignored, got " + device
12130                         + "] but expected device is" + mMutingExpectedDevice);
12131                 throw new IllegalStateException("cancelMuteAwaitConnection for wrong device");
12132             }
12133             mutedUsages = mMutedUsagesAwaitingConnection;
12134             mMutingExpectedDevice = null;
12135             mMutedUsagesAwaitingConnection = null;
12136             mPlaybackMonitor.cancelMuteAwaitConnection("cancelMuteAwaitConnection dev:" + device);
12137         }
12138         dispatchMuteAwaitConnection((cb, isPrivileged) -> {
12139             try {
12140                 AudioDeviceAttributes dev = ada;
12141                 if (!isPrivileged) {
12142                     dev = anonymizeAudioDeviceAttributesUnchecked(ada);
12143                 }
12144                 cb.dispatchOnUnmutedEvent(
12145                         AudioManager.MuteAwaitConnectionCallback.EVENT_CANCEL, dev, mutedUsages);
12146             } catch (RemoteException e) { } });
12147     }
12148 
12149     final RemoteCallbackList<IMuteAwaitConnectionCallback> mMuteAwaitConnectionDispatchers =
12150             new RemoteCallbackList<IMuteAwaitConnectionCallback>();
12151 
12152     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
12153     /** @see AudioManager#registerMuteAwaitConnectionCallback */
registerMuteAwaitConnectionDispatcher(@onNull IMuteAwaitConnectionCallback cb, boolean register)12154     public void registerMuteAwaitConnectionDispatcher(@NonNull IMuteAwaitConnectionCallback cb,
12155             boolean register) {
12156         super.registerMuteAwaitConnectionDispatcher_enforcePermission();
12157 
12158         if (register) {
12159             mMuteAwaitConnectionDispatchers.register(cb, isBluetoothPrividged());
12160         } else {
12161             mMuteAwaitConnectionDispatchers.unregister(cb);
12162         }
12163     }
12164 
12165     @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection
checkMuteAwaitConnection()12166     void checkMuteAwaitConnection() {
12167         final AudioDeviceAttributes device;
12168         final int[] mutedUsages;
12169         synchronized (mMuteAwaitConnectionLock) {
12170             if (mMutingExpectedDevice == null) {
12171                 return;
12172             }
12173             device = mMutingExpectedDevice;
12174             mutedUsages = mMutedUsagesAwaitingConnection;
12175             if (!mDeviceBroker.isDeviceConnected(device)) {
12176                 return;
12177             }
12178             mMutingExpectedDevice = null;
12179             mMutedUsagesAwaitingConnection = null;
12180             mPlaybackMonitor.cancelMuteAwaitConnection(
12181                     "checkMuteAwaitConnection device " + device + " connected, unmuting");
12182         }
12183         dispatchMuteAwaitConnection((cb, isPrivileged) -> {
12184             try {
12185                 AudioDeviceAttributes ada = device;
12186                 if (!isPrivileged) {
12187                     ada = anonymizeAudioDeviceAttributesUnchecked(device);
12188                 }
12189                 cb.dispatchOnUnmutedEvent(AudioManager.MuteAwaitConnectionCallback.EVENT_CONNECTION,
12190                         ada, mutedUsages);
12191             } catch (RemoteException e) { } });
12192     }
12193 
12194     /**
12195      * Called by PlaybackActivityMonitor when the timeout hit for the mute on device connection
12196      */
12197     @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection
onMuteAwaitConnectionTimeout(@onNull AudioDeviceAttributes timedOutDevice)12198     void onMuteAwaitConnectionTimeout(@NonNull AudioDeviceAttributes timedOutDevice) {
12199         final int[] mutedUsages;
12200         synchronized (mMuteAwaitConnectionLock) {
12201             if (!timedOutDevice.equals(mMutingExpectedDevice)) {
12202                 return;
12203             }
12204             Log.i(TAG, "muteAwaitConnection timeout, clearing expected device "
12205                     + mMutingExpectedDevice);
12206             mutedUsages = mMutedUsagesAwaitingConnection;
12207             mMutingExpectedDevice = null;
12208             mMutedUsagesAwaitingConnection = null;
12209         }
12210         dispatchMuteAwaitConnection((cb, isPrivileged) -> {
12211             try {
12212                 cb.dispatchOnUnmutedEvent(
12213                         AudioManager.MuteAwaitConnectionCallback.EVENT_TIMEOUT,
12214                         timedOutDevice, mutedUsages);
12215             } catch (RemoteException e) { } });
12216     }
12217 
dispatchMuteAwaitConnection( java.util.function.BiConsumer<IMuteAwaitConnectionCallback, Boolean> callback)12218     private void dispatchMuteAwaitConnection(
12219             java.util.function.BiConsumer<IMuteAwaitConnectionCallback, Boolean> callback) {
12220         final int nbDispatchers = mMuteAwaitConnectionDispatchers.beginBroadcast();
12221         // lazy initialization as errors unlikely
12222         ArrayList<IMuteAwaitConnectionCallback> errorList = null;
12223         for (int i = 0; i < nbDispatchers; i++) {
12224             try {
12225                 callback.accept(mMuteAwaitConnectionDispatchers.getBroadcastItem(i),
12226                         (Boolean) mMuteAwaitConnectionDispatchers.getBroadcastCookie(i));
12227             } catch (Exception e) {
12228                 if (errorList == null) {
12229                     errorList = new ArrayList<>(1);
12230                 }
12231                 errorList.add(mMuteAwaitConnectionDispatchers.getBroadcastItem(i));
12232             }
12233         }
12234         if (errorList != null) {
12235             for (IMuteAwaitConnectionCallback errorItem : errorList) {
12236                 mMuteAwaitConnectionDispatchers.unregister(errorItem);
12237             }
12238         }
12239         mMuteAwaitConnectionDispatchers.finishBroadcast();
12240     }
12241 
12242     final RemoteCallbackList<IDeviceVolumeBehaviorDispatcher> mDeviceVolumeBehaviorDispatchers =
12243             new RemoteCallbackList<IDeviceVolumeBehaviorDispatcher>();
12244 
12245     /**
12246      *  @see AudioDeviceVolumeManager#addOnDeviceVolumeBehaviorChangedListener and
12247      *  AudioDeviceVolumeManager#removeOnDeviceVolumeBehaviorChangedListener
12248      */
registerDeviceVolumeBehaviorDispatcher(boolean register, @NonNull IDeviceVolumeBehaviorDispatcher dispatcher)12249     public void registerDeviceVolumeBehaviorDispatcher(boolean register,
12250             @NonNull IDeviceVolumeBehaviorDispatcher dispatcher) {
12251         enforceQueryStateOrModifyRoutingPermission();
12252         Objects.requireNonNull(dispatcher);
12253         if (register) {
12254             mDeviceVolumeBehaviorDispatchers.register(dispatcher);
12255         } else {
12256             mDeviceVolumeBehaviorDispatchers.unregister(dispatcher);
12257         }
12258     }
12259 
dispatchDeviceVolumeBehavior(AudioDeviceAttributes device, int volumeBehavior)12260     private void dispatchDeviceVolumeBehavior(AudioDeviceAttributes device, int volumeBehavior) {
12261         final int dispatchers = mDeviceVolumeBehaviorDispatchers.beginBroadcast();
12262         for (int i = 0; i < dispatchers; i++) {
12263             try {
12264                 mDeviceVolumeBehaviorDispatchers.getBroadcastItem(i)
12265                         .dispatchDeviceVolumeBehaviorChanged(device, volumeBehavior);
12266             } catch (RemoteException e) {
12267             }
12268         }
12269         mDeviceVolumeBehaviorDispatchers.finishBroadcast();
12270     }
12271 
12272     //==========================================================================================
12273     // Device orientation
12274     //==========================================================================================
12275     /**
12276      * Handles device configuration changes that may map to a change in rotation.
12277      * Monitoring rotation is optional, and is defined by the definition and value
12278      * of the "ro.audio.monitorRotation" system property.
12279      */
onConfigurationChanged()12280     private void onConfigurationChanged() {
12281         try {
12282             // reading new configuration "safely" (i.e. under try catch) in case anything
12283             // goes wrong.
12284             Configuration config = mContext.getResources().getConfiguration();
12285             mSoundDoseHelper.configureSafeMedia(/*forced*/false, TAG);
12286 
12287             final boolean cameraSoundForced = readCameraSoundForced();
12288             final boolean cameraSoundForcedChanged =
12289                     (mCameraSoundForced.getAndSet(cameraSoundForced) != cameraSoundForced);
12290             synchronized (mSettingsLock) {
12291                 if (cameraSoundForcedChanged) {
12292                     if (!mIsSingleVolume) {
12293                         synchronized (mVolumeStateLock) {
12294                             final VolumeStreamState s = getVssForStreamOrDefault(
12295                                     AudioSystem.STREAM_SYSTEM_ENFORCED);
12296                             if (cameraSoundForced) {
12297                                 s.setAllIndexesToMax();
12298                                 mRingerModeAffectedStreams &=
12299                                         ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
12300                             } else {
12301                                 s.setAllIndexes(getVssForStreamOrDefault(AudioSystem.STREAM_SYSTEM),
12302                                         TAG);
12303                                 mRingerModeAffectedStreams |=
12304                                         (1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
12305                             }
12306                         }
12307                         // take new state into account for streams muted by ringer mode
12308                         setRingerModeInt(getRingerModeInternal(), false);
12309                     }
12310                     mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM,
12311                             cameraSoundForced ?
12312                                     AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE,
12313                             "onConfigurationChanged");
12314                     sendMsg(mAudioHandler,
12315                             MSG_SET_ALL_VOLUMES,
12316                             SENDMSG_QUEUE,
12317                             0,
12318                             0,
12319                             getVssForStreamOrDefault(AudioSystem.STREAM_SYSTEM_ENFORCED), 0);
12320                 }
12321             }
12322             mVolumeController.setLayoutDirection(config.getLayoutDirection());
12323         } catch (Exception e) {
12324             Log.e(TAG, "Error handling configuration change: ", e);
12325         }
12326     }
12327 
12328     @android.annotation.EnforcePermission(Manifest.permission.REMOTE_AUDIO_PLAYBACK)
12329     @Override
setRingtonePlayer(IRingtonePlayer player)12330     public void setRingtonePlayer(IRingtonePlayer player) {
12331         setRingtonePlayer_enforcePermission();
12332         mRingtonePlayer = player;
12333     }
12334 
12335     @Override
getRingtonePlayer()12336     public IRingtonePlayer getRingtonePlayer() {
12337         return mRingtonePlayer;
12338     }
12339 
12340     @Override
startWatchingRoutes(IAudioRoutesObserver observer)12341     public AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) {
12342         return mDeviceBroker.startWatchingRoutes(observer);
12343     }
12344 
12345     @Override
disableSafeMediaVolume(String callingPackage)12346     public void disableSafeMediaVolume(String callingPackage) {
12347         enforceVolumeController("disable the safe media volume");
12348         mSoundDoseHelper.disableSafeMediaVolume(callingPackage);
12349     }
12350 
12351     @Override
lowerVolumeToRs1(String callingPackage)12352     public void lowerVolumeToRs1(String callingPackage) {
12353         enforceVolumeController("lowerVolumeToRs1");
12354         postLowerVolumeToRs1();
12355     }
12356 
postLowerVolumeToRs1()12357     /*package*/ void postLowerVolumeToRs1() {
12358         sendMsg(mAudioHandler, SoundDoseHelper.MSG_LOWER_VOLUME_TO_RS1, SENDMSG_QUEUE,
12359                 // no params, no delay
12360                 0, 0, null, 0);
12361     }
12362 
12363     @Override
12364     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
getOutputRs2UpperBound()12365     public float getOutputRs2UpperBound() {
12366         super.getOutputRs2UpperBound_enforcePermission();
12367         return mSoundDoseHelper.getOutputRs2UpperBound();
12368     }
12369 
12370     @Override
12371     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setOutputRs2UpperBound(float rs2Value)12372     public void setOutputRs2UpperBound(float rs2Value) {
12373         super.setOutputRs2UpperBound_enforcePermission();
12374         mSoundDoseHelper.setOutputRs2UpperBound(rs2Value);
12375     }
12376 
12377     @Override
12378     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
getCsd()12379     public float getCsd() {
12380         super.getCsd_enforcePermission();
12381         return mSoundDoseHelper.getCsd();
12382     }
12383 
12384     @Override
12385     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setCsd(float csd)12386     public void setCsd(float csd) {
12387         super.setCsd_enforcePermission();
12388         if (csd < 0.0f) {
12389             mSoundDoseHelper.resetCsdTimeouts();
12390         } else {
12391             mSoundDoseHelper.setCsd(csd);
12392         }
12393     }
12394 
12395     @Override
12396     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
forceUseFrameworkMel(boolean useFrameworkMel)12397     public void forceUseFrameworkMel(boolean useFrameworkMel) {
12398         super.forceUseFrameworkMel_enforcePermission();
12399         mSoundDoseHelper.forceUseFrameworkMel(useFrameworkMel);
12400     }
12401 
12402     @Override
12403     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
forceComputeCsdOnAllDevices(boolean computeCsdOnAllDevices)12404     public void forceComputeCsdOnAllDevices(boolean computeCsdOnAllDevices) {
12405         super.forceComputeCsdOnAllDevices_enforcePermission();
12406         mSoundDoseHelper.forceComputeCsdOnAllDevices(computeCsdOnAllDevices);
12407     }
12408 
12409     @Override
12410     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
isCsdEnabled()12411     public boolean isCsdEnabled() {
12412         super.isCsdEnabled_enforcePermission();
12413         return mSoundDoseHelper.isCsdEnabled();
12414     }
12415 
12416     @Override
12417     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
isCsdAsAFeatureAvailable()12418     public boolean isCsdAsAFeatureAvailable() {
12419         super.isCsdAsAFeatureAvailable_enforcePermission();
12420         return mSoundDoseHelper.isCsdAsAFeatureAvailable();
12421     }
12422 
12423     @Override
12424     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
isCsdAsAFeatureEnabled()12425     public boolean isCsdAsAFeatureEnabled() {
12426         super.isCsdAsAFeatureEnabled_enforcePermission();
12427         return mSoundDoseHelper.isCsdAsAFeatureEnabled();
12428     }
12429 
12430     @Override
12431     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setCsdAsAFeatureEnabled(boolean csdToggleValue)12432     public void setCsdAsAFeatureEnabled(boolean csdToggleValue) {
12433         super.setCsdAsAFeatureEnabled_enforcePermission();
12434         mSoundDoseHelper.setCsdAsAFeatureEnabled(csdToggleValue);
12435     }
12436 
12437     @Override
12438     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setBluetoothAudioDeviceCategory(@onNull String address, @AudioDeviceCategory int btAudioDeviceCategory)12439     public boolean setBluetoothAudioDeviceCategory(@NonNull String address,
12440             @AudioDeviceCategory int btAudioDeviceCategory) {
12441         super.setBluetoothAudioDeviceCategory_enforcePermission();
12442 
12443         final String addr = Objects.requireNonNull(address);
12444         if (isBluetoothAudioDeviceCategoryFixed(addr)) {
12445             Log.w(TAG, "Cannot set fixed audio device type for address "
12446                     + Utils.anonymizeBluetoothAddress(address));
12447             return false;
12448         }
12449 
12450         mDeviceBroker.addAudioDeviceWithCategoryInInventoryIfNeeded(address, btAudioDeviceCategory);
12451 
12452         return true;
12453     }
12454 
12455     @Override
12456     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
12457     @AudioDeviceCategory
getBluetoothAudioDeviceCategory(@onNull String address)12458     public int getBluetoothAudioDeviceCategory(@NonNull String address) {
12459         super.getBluetoothAudioDeviceCategory_enforcePermission();
12460 
12461         return mDeviceBroker.getAndUpdateBtAdiDeviceStateCategoryForAddress(address);
12462     }
12463 
12464     @Override
12465     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
isBluetoothAudioDeviceCategoryFixed(@onNull String address)12466     public boolean isBluetoothAudioDeviceCategoryFixed(@NonNull String address) {
12467         super.isBluetoothAudioDeviceCategoryFixed_enforcePermission();
12468 
12469         return mDeviceBroker.isBluetoothAudioDeviceCategoryFixed(address);
12470     }
12471 
12472     /** Update the sound dose and spatializer state based on the new AdiDeviceState. */
12473     @VisibleForTesting(visibility = PACKAGE)
onUpdatedAdiDeviceState(AdiDeviceState deviceState, boolean initSA)12474     public void onUpdatedAdiDeviceState(AdiDeviceState deviceState, boolean initSA) {
12475         if (deviceState == null) {
12476             return;
12477         }
12478         mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes(), initSA);
12479         mSoundDoseHelper.setAudioDeviceCategory(deviceState.getDeviceAddress(),
12480                 deviceState.getInternalDeviceType(),
12481                 deviceState.getAudioDeviceCategory() == AUDIO_DEVICE_CATEGORY_HEADPHONES);
12482     }
12483 
12484     //==========================================================================================
12485     // Hdmi CEC:
12486     // - System audio mode:
12487     //     If Hdmi Cec's system audio mode is on, audio service should send the volume change
12488     //     to HdmiControlService so that the audio receiver can handle it.
12489     // - CEC sink:
12490     //     OUT_HDMI becomes a "full volume device", i.e. output is always at maximum level
12491     //     and volume changes won't be taken into account on this device. Volume adjustments
12492     //     are transformed into key events for the HDMI playback client.
12493     //==========================================================================================
12494 
12495     @GuardedBy("mHdmiClientLock")
updateHdmiCecSinkLocked(boolean hdmiCecSink)12496     private void updateHdmiCecSinkLocked(boolean hdmiCecSink) {
12497         if (!hasDeviceVolumeBehavior(AudioSystem.DEVICE_OUT_HDMI)) {
12498             if (hdmiCecSink) {
12499                 if (DEBUG_VOL) {
12500                     Log.d(TAG, "CEC sink: setting HDMI as full vol device");
12501                 }
12502                 setDeviceVolumeBehaviorInternal(
12503                         new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""),
12504                         AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL,
12505                         "AudioService.updateHdmiCecSinkLocked()");
12506             } else {
12507                 if (DEBUG_VOL) {
12508                     Log.d(TAG, "TV, no CEC: setting HDMI as regular vol device");
12509                 }
12510                 // Android TV devices without CEC service apply software volume on
12511                 // HDMI output
12512                 setDeviceVolumeBehaviorInternal(
12513                         new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""),
12514                         AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE,
12515                         "AudioService.updateHdmiCecSinkLocked()");
12516             }
12517             postUpdateVolumeStatesForAudioDevice(AudioSystem.DEVICE_OUT_HDMI,
12518                     "HdmiPlaybackClient.DisplayStatusCallback");
12519         }
12520     }
12521 
12522     private class MyHdmiControlStatusChangeListenerCallback
12523             implements HdmiControlManager.HdmiControlStatusChangeListener {
onStatusChange(@dmiControlManager.HdmiCecControl int isCecEnabled, boolean isCecAvailable)12524         public void onStatusChange(@HdmiControlManager.HdmiCecControl int isCecEnabled,
12525                 boolean isCecAvailable) {
12526             synchronized (mHdmiClientLock) {
12527                 if (mHdmiManager == null) return;
12528                 boolean cecEnabled = isCecEnabled == HdmiControlManager.HDMI_CEC_CONTROL_ENABLED;
12529                 updateHdmiCecSinkLocked(cecEnabled ? isCecAvailable : false);
12530             }
12531         }
12532     };
12533 
12534     private class MyHdmiCecVolumeControlFeatureListener
12535             implements HdmiControlManager.HdmiCecVolumeControlFeatureListener {
onHdmiCecVolumeControlFeature( @dmiControlManager.VolumeControl int hdmiCecVolumeControl)12536         public void onHdmiCecVolumeControlFeature(
12537                 @HdmiControlManager.VolumeControl int hdmiCecVolumeControl) {
12538             synchronized (mHdmiClientLock) {
12539                 if (mHdmiManager == null) return;
12540                 mHdmiCecVolumeControlEnabled =
12541                         hdmiCecVolumeControl == HdmiControlManager.VOLUME_CONTROL_ENABLED;
12542             }
12543         }
12544     };
12545 
12546     private final Object mHdmiClientLock = new Object();
12547 
12548     // If HDMI-CEC system audio is supported
12549     // Note that for CEC volume commands mHdmiCecVolumeControlEnabled will play a role on volume
12550     // commands
12551     private boolean mHdmiSystemAudioSupported = false;
12552     // Set only when device is tv.
12553     @GuardedBy("mHdmiClientLock")
12554     private HdmiTvClient mHdmiTvClient;
12555     // true if the device has system feature PackageManager.FEATURE_LEANBACK.
12556     // cached HdmiControlManager interface
12557     @GuardedBy("mHdmiClientLock")
12558     private HdmiControlManager mHdmiManager;
12559     // Set only when device is a set-top box.
12560     @GuardedBy("mHdmiClientLock")
12561     private HdmiPlaybackClient mHdmiPlaybackClient;
12562     // Set only when device is an audio system.
12563     @GuardedBy("mHdmiClientLock")
12564     private HdmiAudioSystemClient mHdmiAudioSystemClient;
12565     // True when volume control over HDMI CEC is used when CEC is enabled (meaningless otherwise)
12566     @GuardedBy("mHdmiClientLock")
12567     private boolean mHdmiCecVolumeControlEnabled;
12568 
12569     private MyHdmiControlStatusChangeListenerCallback mHdmiControlStatusChangeListenerCallback =
12570             new MyHdmiControlStatusChangeListenerCallback();
12571 
12572     private MyHdmiCecVolumeControlFeatureListener mMyHdmiCecVolumeControlFeatureListener =
12573             new MyHdmiCecVolumeControlFeatureListener();
12574 
12575     @Override
setHdmiSystemAudioSupported(boolean on)12576     public int setHdmiSystemAudioSupported(boolean on) {
12577         int device = AudioSystem.DEVICE_NONE;
12578         synchronized (mHdmiClientLock) {
12579             if (mHdmiManager != null) {
12580                 if (mHdmiTvClient == null && mHdmiAudioSystemClient == null) {
12581                     Log.w(TAG, "Only Hdmi-Cec enabled TV or audio system device supports"
12582                             + "system audio mode.");
12583                     return device;
12584                 }
12585                 if (mHdmiSystemAudioSupported != on) {
12586                     mHdmiSystemAudioSupported = on;
12587                     final int config = on ? AudioSystem.FORCE_HDMI_SYSTEM_AUDIO_ENFORCED :
12588                         AudioSystem.FORCE_NONE;
12589                     mDeviceBroker.setForceUse_Async(AudioSystem.FOR_HDMI_SYSTEM_AUDIO, config,
12590                             "setHdmiSystemAudioSupported");
12591                 }
12592                 // TODO(b/185386781): Update AudioManager API to use device list.
12593                 // So far, this value appears to be advisory for debug log.
12594                 device = getDeviceMaskForStream(AudioSystem.STREAM_MUSIC);
12595             }
12596         }
12597         return device;
12598     }
12599 
12600     @Override
isHdmiSystemAudioSupported()12601     public boolean isHdmiSystemAudioSupported() {
12602         return mHdmiSystemAudioSupported;
12603     }
12604 
12605     //==========================================================================================
12606     // Accessibility
12607 
initA11yMonitoring()12608     private void initA11yMonitoring() {
12609         final AccessibilityManager accessibilityManager =
12610                 (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
12611         updateDefaultStreamOverrideDelay(accessibilityManager.isTouchExplorationEnabled());
12612         updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive());
12613         accessibilityManager.addTouchExplorationStateChangeListener(this, null);
12614         accessibilityManager.addAccessibilityServicesStateChangeListener(this);
12615     }
12616 
12617     //---------------------------------------------------------------------------------
12618     // A11y: taking touch exploration into account for selecting the default
12619     //   stream override timeout when adjusting volume
12620     //---------------------------------------------------------------------------------
12621 
12622     // - STREAM_NOTIFICATION on tablets during this period after a notification stopped
12623     // - STREAM_RING on phones during this period after a notification stopped
12624     // - STREAM_MUSIC otherwise
12625 
12626     private static final int DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS = 0;
12627     private static final int TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS = 1000;
12628 
12629     private static int sStreamOverrideDelayMs;
12630 
12631     @Override
onTouchExplorationStateChanged(boolean enabled)12632     public void onTouchExplorationStateChanged(boolean enabled) {
12633         updateDefaultStreamOverrideDelay(enabled);
12634     }
12635 
updateDefaultStreamOverrideDelay(boolean touchExploreEnabled)12636     private void updateDefaultStreamOverrideDelay(boolean touchExploreEnabled) {
12637         if (touchExploreEnabled) {
12638             sStreamOverrideDelayMs = TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS;
12639         } else {
12640             sStreamOverrideDelayMs = DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS;
12641         }
12642         if (DEBUG_VOL) Log.d(TAG, "Touch exploration enabled=" + touchExploreEnabled
12643                 + " stream override delay is now " + sStreamOverrideDelayMs + " ms");
12644     }
12645 
12646     //---------------------------------------------------------------------------------
12647     // A11y: taking a11y state into account for the handling of a11y prompts volume
12648     //---------------------------------------------------------------------------------
12649 
12650     private static boolean sIndependentA11yVolume = false;
12651 
12652     // implementation of AccessibilityServicesStateChangeListener
12653     @Override
onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager)12654     public void onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager) {
12655         updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive());
12656     }
12657 
updateA11yVolumeAlias(boolean a11VolEnabled)12658     private void updateA11yVolumeAlias(boolean a11VolEnabled) {
12659         if (DEBUG_VOL) Log.d(TAG, "Accessibility volume enabled = " + a11VolEnabled);
12660         if (mIsSingleVolume) {
12661             if (DEBUG_VOL) Log.d(TAG, "Accessibility volume is not set on single volume device");
12662             return;
12663         }
12664         if (sIndependentA11yVolume != a11VolEnabled) {
12665             sIndependentA11yVolume = a11VolEnabled;
12666             // update the volume mapping scheme
12667             updateStreamVolumeAlias(true /*updateVolumes*/, TAG);
12668             // update the volume controller behavior
12669             mVolumeController.setA11yMode(sIndependentA11yVolume ?
12670                     VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME :
12671                         VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME);
12672             mVolumeController.postVolumeChanged(AudioManager.STREAM_ACCESSIBILITY, 0);
12673         }
12674     }
12675 
12676     //==========================================================================================
12677     // Camera shutter sound policy.
12678     // config_camera_sound_forced configuration option in config.xml defines if the camera shutter
12679     // sound is forced (sound even if the device is in silent mode) or not. This option is false by
12680     // default and can be overridden by country specific overlay in values-mccXXX/config.xml.
12681     //==========================================================================================
12682 
12683     // cached value of com.android.internal.R.bool.config_camera_sound_forced
12684     private AtomicBoolean mCameraSoundForced = new AtomicBoolean(false);
12685 
12686     // called by android.hardware.Camera to populate CameraInfo.canDisableShutterSound
isCameraSoundForced()12687     public boolean isCameraSoundForced() {
12688         return mCameraSoundForced.get();
12689     }
12690 
12691     //==========================================================================================
12692     // AudioService logging and dumpsys
12693     //==========================================================================================
12694     static final int LOG_NB_EVENTS_LIFECYCLE = 20;
12695     static final int LOG_NB_EVENTS_PHONE_STATE = 20;
12696     static final int LOG_NB_EVENTS_DEVICE_CONNECTION = 200;
12697     static final int LOG_NB_EVENTS_FORCE_USE = 20;
12698     static final int LOG_NB_EVENTS_VOLUME = 100;
12699     static final int LOG_NB_EVENTS_DYN_POLICY = 10;
12700     static final int LOG_NB_EVENTS_SPATIAL = 30;
12701     static final int LOG_NB_EVENTS_SOUND_DOSE = 50;
12702     static final int LOG_NB_EVENTS_HARDENING = 50;
12703 
12704     static final int LOG_NB_EVENTS_LOUDNESS_CODEC = 30;
12705 
12706     static final EventLogger
12707             sLifecycleLogger = new EventLogger(LOG_NB_EVENTS_LIFECYCLE,
12708             "audio services lifecycle");
12709 
12710     static final EventLogger sMuteLogger = new EventLogger(30,
12711             "mute commands");
12712 
12713     final private EventLogger
12714             mModeLogger = new EventLogger(LOG_NB_EVENTS_PHONE_STATE,
12715             "phone state (logged after successful call to AudioSystem.setPhoneState(int, int))");
12716 
12717     // logs for wired + A2DP device connections:
12718     // - wired: logged before onSetWiredDeviceConnectionState() is executed
12719     // - A2DP: logged at reception of method call
12720     /*package*/ static final EventLogger
12721             sDeviceLogger = new EventLogger(
12722             LOG_NB_EVENTS_DEVICE_CONNECTION, "wired/A2DP/hearing aid device connection");
12723 
12724     static final EventLogger
12725             sForceUseLogger = new EventLogger(
12726             LOG_NB_EVENTS_FORCE_USE,
12727             "force use (logged before setForceUse() is executed)");
12728 
12729     static final EventLogger
12730             sVolumeLogger = new EventLogger(LOG_NB_EVENTS_VOLUME,
12731             "volume changes (logged when command received by AudioService)");
12732 
12733     static final EventLogger
12734             sSpatialLogger = new EventLogger(LOG_NB_EVENTS_SPATIAL,
12735             "spatial audio");
12736 
12737     final private EventLogger
12738             mDynPolicyLogger = new EventLogger(LOG_NB_EVENTS_DYN_POLICY,
12739             "dynamic policy events (logged when command received by AudioService)");
12740 
12741     private final EventLogger mHardeningLogger = new EventLogger(
12742             LOG_NB_EVENTS_HARDENING, "Hardening enforcement");
12743 
12744     private static final String[] RINGER_MODE_NAMES = new String[] {
12745             "SILENT",
12746             "VIBRATE",
12747             "NORMAL"
12748     };
12749 
dumpRingerMode(PrintWriter pw)12750     private void dumpRingerMode(PrintWriter pw) {
12751         pw.println("\nRinger mode: ");
12752         pw.println("- mode (internal) = " + RINGER_MODE_NAMES[mRingerMode]);
12753         pw.println("- mode (external) = " + RINGER_MODE_NAMES[mRingerModeExternal]);
12754         pw.println("- zen mode:" + Settings.Global.zenModeToString(mNm.getZenMode()));
12755         dumpRingerModeStreams(pw, "affected", mRingerModeAffectedStreams);
12756         dumpRingerModeStreams(pw, "muted", sRingerAndZenModeMutedStreams);
12757         pw.print("- delegate = "); pw.println(mRingerModeDelegate);
12758     }
12759 
dumpRingerModeStreams(PrintWriter pw, String type, int streams)12760     private void dumpRingerModeStreams(PrintWriter pw, String type, int streams) {
12761         pw.print("- ringer mode "); pw.print(type); pw.print(" streams = 0x");
12762         pw.print(Integer.toHexString(streams));
12763         if (streams != 0) {
12764             pw.print(" (");
12765             boolean first = true;
12766             for (int i = 0; i < AudioSystem.STREAM_NAMES.length; i++) {
12767                 final int stream = (1 << i);
12768                 if ((streams & stream) != 0) {
12769                     if (!first) pw.print(',');
12770                     pw.print(AudioSystem.STREAM_NAMES[i]);
12771                     streams &= ~stream;
12772                     first = false;
12773                 }
12774             }
12775             if (streams != 0) {
12776                 if (!first) pw.print(',');
12777                 pw.print(streams);
12778             }
12779             pw.print(')');
12780         }
12781         pw.println();
12782     }
12783 
getAbsoluteVolumeDevicesWithBehavior(int behavior)12784     private Set<Integer> getAbsoluteVolumeDevicesWithBehavior(int behavior) {
12785         synchronized (mAbsoluteVolumeDeviceInfoMapLock) {
12786             return mAbsoluteVolumeDeviceInfoMap.entrySet().stream()
12787                     .filter(entry -> entry.getValue().mDeviceVolumeBehavior == behavior)
12788                     .map(Map.Entry::getKey)
12789                     .collect(Collectors.toSet());
12790         }
12791     }
12792 
dumpDeviceTypes(@onNull Set<Integer> deviceTypes)12793     private String dumpDeviceTypes(@NonNull Set<Integer> deviceTypes) {
12794         Iterator<Integer> it = deviceTypes.iterator();
12795         if (!it.hasNext()) {
12796             return "";
12797         }
12798         final StringBuilder sb = new StringBuilder();
12799         sb.append("0x" + Integer.toHexString(it.next()));
12800         while (it.hasNext()) {
12801             sb.append("," + "0x" + Integer.toHexString(it.next()));
12802         }
12803         return sb.toString();
12804     }
12805 
12806     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)12807     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12808         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
12809 
12810         sLifecycleLogger.dump(pw);
12811         if (mAudioHandler != null) {
12812             pw.println("\nMessage handler (watch for unhandled messages):");
12813             mAudioHandler.dump(new PrintWriterPrinter(pw), "  ");
12814         } else {
12815             pw.println("\nMessage handler is null");
12816         }
12817         dumpFlags(pw);
12818         mHardeningLogger.dump(pw);
12819         mMediaFocusControl.dump(pw);
12820         dumpStreamStates(pw);
12821         dumpVolumeGroups(pw);
12822         dumpRingerMode(pw);
12823         dumpAudioMode(pw);
12824         pw.println("\nAudio routes:");
12825         pw.print("  mMainType=0x"); pw.println(Integer.toHexString(
12826                 mDeviceBroker.getCurAudioRoutes().mainType));
12827         pw.print("  mBluetoothName="); pw.println(mDeviceBroker.getCurAudioRoutes().bluetoothName);
12828 
12829         pw.println("\nOther state:");
12830         pw.print("  mUseVolumeGroupAliases="); pw.println(mUseVolumeGroupAliases);
12831         pw.print("  mVolumeController="); pw.println(mVolumeController);
12832         mSoundDoseHelper.dump(pw);
12833         pw.print("  sIndependentA11yVolume="); pw.println(sIndependentA11yVolume);
12834         pw.print("  mCameraSoundForced="); pw.println(isCameraSoundForced());
12835         pw.print("  mHasVibrator="); pw.println(mHasVibrator);
12836         pw.print("  mVolumePolicy="); pw.println(mVolumePolicy);
12837         pw.print("  mAvrcpAbsVolSupported="); pw.println(mAvrcpAbsVolSupported);
12838         pw.print("  mBtScoOnByApp="); pw.println(mBtScoOnByApp);
12839         pw.print("  mIsSingleVolume="); pw.println(mIsSingleVolume);
12840         pw.print("  mUseFixedVolume="); pw.println(mUseFixedVolume);
12841         pw.print("  mNotifAliasRing="); pw.println(mNotifAliasRing);
12842         pw.print("  mFixedVolumeDevices="); pw.println(dumpDeviceTypes(mFixedVolumeDevices));
12843         pw.print("  mFullVolumeDevices="); pw.println(dumpDeviceTypes(mFullVolumeDevices));
12844         pw.print("  absolute volume devices="); pw.println(dumpDeviceTypes(
12845                 getAbsoluteVolumeDevicesWithBehavior(
12846                         AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE)));
12847         pw.print("  adjust-only absolute volume devices="); pw.println(dumpDeviceTypes(
12848                 getAbsoluteVolumeDevicesWithBehavior(
12849                         AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY)));
12850         pw.print("  pre-scale for bluetooth absolute volume ");
12851         if (disablePrescaleAbsoluteVolume()) {
12852             pw.println("= disabled");
12853         } else {
12854             pw.println("=" + mPrescaleAbsoluteVolume[0]
12855                     + ", " + mPrescaleAbsoluteVolume[1]
12856                     + ", " + mPrescaleAbsoluteVolume[2]);
12857         }
12858         pw.print("  mExtVolumeController="); pw.println(mExtVolumeController);
12859         pw.print("  mHdmiAudioSystemClient="); pw.println(mHdmiAudioSystemClient);
12860         pw.print("  mHdmiPlaybackClient="); pw.println(mHdmiPlaybackClient);
12861         pw.print("  mHdmiTvClient="); pw.println(mHdmiTvClient);
12862         pw.print("  mHdmiSystemAudioSupported="); pw.println(mHdmiSystemAudioSupported);
12863         synchronized (mHdmiClientLock) {
12864             pw.print("  mHdmiCecVolumeControlEnabled="); pw.println(mHdmiCecVolumeControlEnabled);
12865         }
12866         pw.print("  mIsCallScreeningModeSupported="); pw.println(mIsCallScreeningModeSupported);
12867         pw.println("  mic mute FromSwitch=" + mMicMuteFromSwitch
12868                         + " FromRestrictions=" + mMicMuteFromRestrictions
12869                         + " FromApi=" + mMicMuteFromApi
12870                         + " from system=" + mMicMuteFromSystemCached);
12871         pw.print("  mMasterMute="); pw.println(mMasterMute.get());
12872         dumpAccessibilityServiceUids(pw);
12873         dumpAssistantServicesUids(pw);
12874 
12875         pw.print("  supportsBluetoothVariableLatency=");
12876         pw.println(AudioSystem.supportsBluetoothVariableLatency());
12877         pw.print("  isBluetoothVariableLatencyEnabled=");
12878         pw.println(AudioSystem.isBluetoothVariableLatencyEnabled());
12879 
12880         dumpAudioPolicies(pw);
12881         mDynPolicyLogger.dump(pw);
12882         mPlaybackMonitor.dump(pw);
12883         mRecordMonitor.dump(pw);
12884 
12885         pw.println("\nAudioDeviceBroker:");
12886         mDeviceBroker.dump(pw, "  ");
12887         pw.println("\nSoundEffects:");
12888         mSfxHelper.dump(pw, "  ");
12889 
12890         pw.println("\n");
12891         pw.println("\nEvent logs:");
12892         mModeLogger.dump(pw);
12893         pw.println("\n");
12894         sDeviceLogger.dump(pw);
12895         pw.println("\n");
12896         sForceUseLogger.dump(pw);
12897         pw.println("\n");
12898         sVolumeLogger.dump(pw);
12899         pw.println("\n");
12900         sMuteLogger.dump(pw);
12901         pw.println("\n");
12902         dumpSupportedSystemUsage(pw);
12903 
12904         pw.println("\n");
12905         pw.println("\nSpatial audio:");
12906         pw.println("mHasSpatializerEffect:" + mHasSpatializerEffect + " (effect present)");
12907         pw.println("isSpatializerEnabled:" + isSpatializerEnabled() + " (routing dependent)");
12908         mSpatializerHelper.dump(pw);
12909         sSpatialLogger.dump(pw);
12910 
12911         pw.println("\n");
12912         pw.println("\nLoudness alignment:");
12913         mLoudnessCodecHelper.dump(pw);
12914 
12915         pw.println("\nAbsolute volume devices with their volume driving streams:");
12916         synchronized (mCachedAbsVolDrivingStreamsLock) {
12917             mCachedAbsVolDrivingStreams.forEach((dev, stream) -> pw.println(
12918                     "Device type: 0x" + Integer.toHexString(dev) + ", driving stream " + stream));
12919         }
12920 
12921         mAudioSystem.dump(pw);
12922     }
12923 
dumpSupportedSystemUsage(PrintWriter pw)12924     private void dumpSupportedSystemUsage(PrintWriter pw) {
12925         pw.println("Supported System Usages:");
12926         synchronized (mSupportedSystemUsagesLock) {
12927             for (int i = 0; i < mSupportedSystemUsages.length; i++) {
12928                 pw.printf("\t%s\n", AudioAttributes.usageToString(mSupportedSystemUsages[i]));
12929             }
12930         }
12931     }
12932 
dumpAssistantServicesUids(PrintWriter pw)12933     private void dumpAssistantServicesUids(PrintWriter pw) {
12934         synchronized (mSettingsLock) {
12935             if (mAssistantUids.size() > 0) {
12936                 pw.println("  Assistant service UIDs:");
12937                 for (int uid : mAssistantUids) {
12938                     pw.println("  - " + uid);
12939                 }
12940             } else {
12941                 pw.println("  No Assistant service Uids.");
12942             }
12943         }
12944     }
12945 
dumpAccessibilityServiceUids(PrintWriter pw)12946     private void dumpAccessibilityServiceUids(PrintWriter pw) {
12947         synchronized (mSupportedSystemUsagesLock) {
12948             if (mAccessibilityServiceUids != null && mAccessibilityServiceUids.length > 0) {
12949                 pw.println("  Accessibility service Uids:");
12950                 for (int uid : mAccessibilityServiceUids) {
12951                     pw.println("  - " + uid);
12952                 }
12953             } else {
12954                 pw.println("  No accessibility service Uids.");
12955             }
12956         }
12957     }
12958 
12959     /**
12960      * Audio Analytics ids.
12961      */
12962     private static final String mMetricsId = MediaMetrics.Name.AUDIO_SERVICE
12963             + MediaMetrics.SEPARATOR;
12964 
initializeAudioServerPermissionProvider( Context context, AudioPolicyFacade audioPolicy, Executor audioserverExecutor)12965     private static AudioServerPermissionProvider initializeAudioServerPermissionProvider(
12966             Context context, AudioPolicyFacade audioPolicy, Executor audioserverExecutor) {
12967         Collection<PackageState> packageStates = null;
12968         try (PackageManagerLocal.UnfilteredSnapshot snapshot =
12969                     LocalManagerRegistry.getManager(PackageManagerLocal.class)
12970                         .withUnfilteredSnapshot()) {
12971             packageStates = snapshot.getPackageStates().values();
12972         }
12973         var umi = LocalServices.getService(UserManagerInternal.class);
12974         var pmsi = LocalServices.getService(PermissionManagerServiceInternal.class);
12975         var provider = new AudioServerPermissionProvider(packageStates,
12976                 (Integer uid, String perm) -> ActivityManager.checkComponentPermission(perm, uid,
12977                         /* owningUid = */ -1, /* exported */true)
12978                     == PackageManager.PERMISSION_GRANTED,
12979                 () -> umi.getUserIds()
12980                 );
12981         audioPolicy.registerOnStartTask(() -> {
12982             provider.onServiceStart(audioPolicy.getPermissionController());
12983             sLifecycleLogger.enqueue(new EventLogger.StringEvent(
12984                     "Controller start task complete").printLog(ALOGI, TAG));
12985         });
12986 
12987         IntentFilter packageUpdateFilter = new IntentFilter();
12988         packageUpdateFilter.addAction(ACTION_PACKAGE_ADDED);
12989         packageUpdateFilter.addDataScheme("package");
12990 
12991         context.registerReceiverForAllUsers(new BroadcastReceiver() {
12992             @Override
12993             public void onReceive(Context context, Intent intent) {
12994                 String action = intent.getAction();
12995                 String pkgName = intent.getData().getEncodedSchemeSpecificPart();
12996                 int uid = intent.getIntExtra(Intent.EXTRA_UID, Process.INVALID_UID);
12997                 if (intent.getBooleanExtra(EXTRA_REPLACING, false) ||
12998                         intent.getBooleanExtra(EXTRA_ARCHIVAL, false)) return;
12999                 if (ACTION_PACKAGE_ADDED.equals(action)) {
13000                     audioserverExecutor.execute(() ->
13001                             provider.onModifyPackageState(uid, pkgName, false /* isRemoved */));
13002                 }
13003             }
13004         }, packageUpdateFilter, null, null); // main thread is fine, since dispatch on executor
13005         return provider;
13006     }
13007 
13008     // Inform AudioFlinger of our device's low RAM attribute
readAndSetLowRamDevice()13009     private static void readAndSetLowRamDevice()
13010     {
13011         boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic();
13012         long totalMemory = 1024 * 1024 * 1024; // 1GB is the default if ActivityManager fails.
13013 
13014         try {
13015             final ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();
13016             ActivityManager.getService().getMemoryInfo(info);
13017             totalMemory = info.totalMem;
13018         } catch (RemoteException e) {
13019             Log.w(TAG, "Cannot obtain MemoryInfo from ActivityManager, assume low memory device");
13020             isLowRamDevice = true;
13021         }
13022 
13023         final int status = AudioSystem.setLowRamDevice(isLowRamDevice, totalMemory);
13024         if (status != 0) {
13025             Log.w(TAG, "AudioFlinger informed of device's low RAM attribute; status " + status);
13026         }
13027     }
13028 
enforceVolumeController(String action)13029     private void enforceVolumeController(String action) {
13030         mContext.enforceCallingOrSelfPermission(Manifest.permission.STATUS_BAR_SERVICE,
13031                 "Only SystemUI can " + action);
13032     }
13033 
13034     @Override
setVolumeController(final IVolumeController controller)13035     public void setVolumeController(final IVolumeController controller) {
13036         enforceVolumeController("set the volume controller");
13037 
13038         // return early if things are not actually changing
13039         if (mVolumeController.isSameBinder(controller)) {
13040             return;
13041         }
13042 
13043         // dismiss the old volume controller
13044         mVolumeController.postDismiss();
13045         if (controller != null) {
13046             // we are about to register a new controller, listen for its death
13047             try {
13048                 controller.asBinder().linkToDeath(new DeathRecipient() {
13049                     @Override
13050                     public void binderDied() {
13051                         if (mVolumeController.isSameBinder(controller)) {
13052                             Log.w(TAG, "Current remote volume controller died, unregistering");
13053                             setVolumeController(null);
13054                         }
13055                     }
13056                 }, 0);
13057             } catch (RemoteException e) {
13058                 // noop
13059             }
13060         }
13061         mVolumeController.setController(controller);
13062         if (DEBUG_VOL) Log.d(TAG, "Volume controller: " + mVolumeController);
13063     }
13064 
13065     @Override
13066     @Nullable
getVolumeController()13067     public IVolumeController getVolumeController() {
13068         enforceVolumeController("get the volume controller");
13069         if (DEBUG_VOL) Log.d(TAG, "Volume controller: " + mVolumeController);
13070 
13071         return mVolumeController.getController();
13072     }
13073 
13074     @Override
notifyVolumeControllerVisible(final IVolumeController controller, boolean visible)13075     public void notifyVolumeControllerVisible(final IVolumeController controller, boolean visible) {
13076         enforceVolumeController("notify about volume controller visibility");
13077 
13078         // return early if the controller is not current
13079         if (!mVolumeController.isSameBinder(controller)) {
13080             return;
13081         }
13082 
13083         mVolumeController.setVisible(visible);
13084         if (DEBUG_VOL) Log.d(TAG, "Volume controller visible: " + visible);
13085     }
13086 
13087     /** @see AudioManager#setVolumeControllerLongPressTimeoutEnabled(boolean) */
13088     @Override
13089     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setVolumeControllerLongPressTimeoutEnabled(boolean enable)13090     public void setVolumeControllerLongPressTimeoutEnabled(boolean enable) {
13091         super.setVolumeControllerLongPressTimeoutEnabled_enforcePermission();
13092         mVolumeControllerLongPressEnabled.set(enable);
13093         Log.i(TAG, "Volume controller long press timeout enabled: " + enable);
13094     }
13095 
13096     @Override
setVolumePolicy(VolumePolicy policy)13097     public void setVolumePolicy(VolumePolicy policy) {
13098         enforceVolumeController("set volume policy");
13099         if (policy != null && !policy.equals(mVolumePolicy)) {
13100             mVolumePolicy = policy;
13101             if (DEBUG_VOL) Log.d(TAG, "Volume policy changed: " + mVolumePolicy);
13102         }
13103     }
13104 
13105     @Override
getVolumePolicy()13106     public VolumePolicy getVolumePolicy() {
13107         return mVolumePolicy;
13108     }
13109 
13110     /** Interface used for enforcing the safe hearing standard. */
13111     public interface ISafeHearingVolumeController {
13112         /** Displays an instructional safeguard as required by the safe hearing standard. */
postDisplaySafeVolumeWarning(int flags)13113         void postDisplaySafeVolumeWarning(int flags);
13114 
13115         /** Displays a warning about transient exposure to high level playback */
postDisplayCsdWarning(@udioManager.CsdWarning int csdEvent, int displayDurationMs)13116         void postDisplayCsdWarning(@AudioManager.CsdWarning int csdEvent, int displayDurationMs);
13117     }
13118 
13119     /** Wrapper which encapsulates the {@link IVolumeController} functionality. */
13120     public class VolumeController implements ISafeHearingVolumeController {
13121         private static final String TAG = "VolumeController";
13122 
13123         private IVolumeController mController;
13124         private boolean mVisible;
13125         private long mNextLongPress;
13126         private int mLongPressTimeout;
13127 
setController(IVolumeController controller)13128         public void setController(IVolumeController controller) {
13129             mController = controller;
13130             mVisible = false;
13131         }
13132 
getController()13133         public IVolumeController getController() {
13134             return mController;
13135         }
13136 
loadSettings(ContentResolver cr)13137         public void loadSettings(ContentResolver cr) {
13138             mLongPressTimeout = mSettings.getSecureIntForUser(cr,
13139                     Settings.Secure.LONG_PRESS_TIMEOUT, 500, UserHandle.USER_CURRENT);
13140         }
13141 
suppressAdjustment(int resolvedStream, int flags, boolean isMute)13142         public boolean suppressAdjustment(int resolvedStream, int flags, boolean isMute) {
13143             if (isMute) {
13144                 return false;
13145             }
13146             boolean suppress = false;
13147             // Intended behavior:
13148             // 1/ if the stream is not the default UI stream, do not suppress (as it is not involved
13149             //    in bringing up the UI)
13150             // 2/ if the resolved and default stream is MUSIC, and media is playing, do not suppress
13151             // 3/ otherwise suppress the first adjustments that occur during the "long press
13152             //    timeout" interval. Note this is true regardless of whether this is a "real long
13153             //    press" (where the user keeps pressing on the volume button), or repeated single
13154             //    presses (here we don't know if we are in a real long press, or repeated fast
13155             //    button presses).
13156             //    Once the long press timeout occurs (mNextLongPress reset to 0), do not suppress.
13157             // Example: for a default and resolved stream of MUSIC, this allows modifying rapidly
13158             // the volume when media is playing (whether by long press or repeated individual
13159             // presses), or to bring up the volume UI when media is not playing, in order to make
13160             // another change (e.g. switch ringer modes) without changing media volume.
13161             if (resolvedStream == DEFAULT_VOL_STREAM_NO_PLAYBACK && mController != null) {
13162                 // never suppress media vol adjustement during media playback
13163                 if (resolvedStream == AudioSystem.STREAM_MUSIC
13164                         && mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, mLongPressTimeout))
13165                 {
13166                     // media is playing, adjust the volume right away
13167                     return false;
13168                 }
13169 
13170                 final long now = SystemClock.uptimeMillis();
13171                 if ((flags & AudioManager.FLAG_SHOW_UI) != 0 && !mVisible) {
13172                     // UI is not visible yet, adjustment is ignored
13173                     if (mNextLongPress < now) {
13174                         mNextLongPress =
13175                                 now + (mVolumeControllerLongPressEnabled.get() ? mLongPressTimeout
13176                                         : 0);
13177                     }
13178                     suppress = true;
13179                 } else if (mNextLongPress > 0) {  // in a long-press
13180                     if (now > mNextLongPress) {
13181                         // long press triggered, no more suppression
13182                         mNextLongPress = 0;
13183                     } else {
13184                         // keep suppressing until the long press triggers
13185                         suppress = true;
13186                     }
13187                 }
13188             }
13189             return suppress;
13190         }
13191 
setVisible(boolean visible)13192         public void setVisible(boolean visible) {
13193             mVisible = visible;
13194         }
13195 
isSameBinder(IVolumeController controller)13196         public boolean isSameBinder(IVolumeController controller) {
13197             return Objects.equals(asBinder(), binder(controller));
13198         }
13199 
asBinder()13200         public IBinder asBinder() {
13201             return binder(mController);
13202         }
13203 
binder(IVolumeController controller)13204         private IBinder binder(IVolumeController controller) {
13205             return controller == null ? null : controller.asBinder();
13206         }
13207 
13208         @Override
toString()13209         public String toString() {
13210             return "VolumeController(" + asBinder() + ",mVisible=" + mVisible + ")";
13211         }
13212 
13213         @Override
postDisplaySafeVolumeWarning(int flags)13214         public void postDisplaySafeVolumeWarning(int flags) {
13215             if (mController == null)
13216                 return;
13217             flags = flags | AudioManager.FLAG_SHOW_UI;
13218             try {
13219                 mController.displaySafeVolumeWarning(flags);
13220             } catch (RemoteException e) {
13221                 Log.w(TAG, "Error calling displaySafeVolumeWarning", e);
13222             }
13223         }
13224 
13225         @Override
postDisplayCsdWarning( @udioManager.CsdWarning int csdWarning, int displayDurationMs)13226         public void postDisplayCsdWarning(
13227                 @AudioManager.CsdWarning int csdWarning, int displayDurationMs) {
13228             if (mController == null) {
13229                 Log.e(TAG, "Unable to display CSD warning, no controller");
13230                 return;
13231             }
13232             try {
13233                 mController.displayCsdWarning(csdWarning, displayDurationMs);
13234             } catch (RemoteException e) {
13235                 Log.w(TAG, "Error calling displayCsdWarning for warning " + csdWarning, e);
13236             }
13237         }
13238 
postVolumeChanged(int streamType, int flags)13239         public void postVolumeChanged(int streamType, int flags) {
13240             if (mController == null)
13241                 return;
13242             try {
13243                 mController.volumeChanged(streamType, flags);
13244             } catch (RemoteException e) {
13245                 Log.w(TAG, "Error calling volumeChanged", e);
13246             }
13247         }
13248 
postMasterMuteChanged(int flags)13249         public void postMasterMuteChanged(int flags) {
13250             if (mController == null)
13251                 return;
13252             try {
13253                 mController.masterMuteChanged(flags);
13254             } catch (RemoteException e) {
13255                 Log.w(TAG, "Error calling masterMuteChanged", e);
13256             }
13257         }
13258 
setLayoutDirection(int layoutDirection)13259         public void setLayoutDirection(int layoutDirection) {
13260             if (mController == null)
13261                 return;
13262             try {
13263                 mController.setLayoutDirection(layoutDirection);
13264             } catch (RemoteException e) {
13265                 Log.w(TAG, "Error calling setLayoutDirection", e);
13266             }
13267         }
13268 
postDismiss()13269         public void postDismiss() {
13270             if (mController == null)
13271                 return;
13272             try {
13273                 mController.dismiss();
13274             } catch (RemoteException e) {
13275                 Log.w(TAG, "Error calling dismiss", e);
13276             }
13277         }
13278 
setA11yMode(int a11yMode)13279         public void setA11yMode(int a11yMode) {
13280             if (mController == null)
13281                 return;
13282             try {
13283                 mController.setA11yMode(a11yMode);
13284             } catch (RemoteException e) {
13285                 Log.w(TAG, "Error calling setA11Mode", e);
13286             }
13287         }
13288     }
13289 
13290     /**
13291      * Interface for system components to get some extra functionality through
13292      * LocalServices.
13293      */
13294     final class AudioServiceInternal extends AudioManagerInternal {
13295         @Override
setRingerModeDelegate(RingerModeDelegate delegate)13296         public void setRingerModeDelegate(RingerModeDelegate delegate) {
13297             mRingerModeDelegate = delegate;
13298             if (mRingerModeDelegate != null) {
13299                 synchronized (mSettingsLock) {
13300                     updateRingerAndZenModeAffectedStreams();
13301                 }
13302                 setRingerModeInternal(getRingerModeInternal(), TAG + ".setRingerModeDelegate");
13303             }
13304         }
13305 
13306         @Override
getRingerModeInternal()13307         public int getRingerModeInternal() {
13308             return AudioService.this.getRingerModeInternal();
13309         }
13310 
13311         @Override
setRingerModeInternal(int ringerMode, String caller)13312         public void setRingerModeInternal(int ringerMode, String caller) {
13313             AudioService.this.setRingerModeInternal(ringerMode, caller);
13314         }
13315 
13316         @Override
silenceRingerModeInternal(String caller)13317         public void silenceRingerModeInternal(String caller) {
13318             AudioService.this.silenceRingerModeInternal(caller);
13319         }
13320 
13321         @Override
updateRingerModeAffectedStreamsInternal()13322         public void updateRingerModeAffectedStreamsInternal() {
13323             synchronized (mSettingsLock) {
13324                 if (updateRingerAndZenModeAffectedStreams()) {
13325                     setRingerModeInt(getRingerModeInternal(), false);
13326                 }
13327             }
13328         }
13329 
13330         @Override
addAssistantServiceUid(int uid, int owningUid)13331         public void addAssistantServiceUid(int uid, int owningUid) {
13332             if (audioserverPermissions()) {
13333                 mPermissionProvider.setIsolatedServiceUid(uid, owningUid);
13334             }
13335             sendMsg(mAudioHandler, MSG_ADD_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE,
13336                     uid, 0, null, 0);
13337         }
13338 
13339         @Override
removeAssistantServiceUid(int uid)13340         public void removeAssistantServiceUid(int uid) {
13341             if (audioserverPermissions()) {
13342                 mPermissionProvider.clearIsolatedServiceUid(uid);
13343             }
13344             sendMsg(mAudioHandler, MSG_REMOVE_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE,
13345                     uid, 0, null, 0);
13346         }
13347 
13348         @Override
setActiveAssistantServicesUids(IntArray activeUids)13349         public void setActiveAssistantServicesUids(IntArray activeUids) {
13350             synchronized (mSettingsLock) {
13351                 if (activeUids.size() == 0) {
13352                     mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS;
13353                 } else {
13354                     boolean changed = (mActiveAssistantServiceUids == null)
13355                             || (mActiveAssistantServiceUids.length != activeUids.size());
13356                     if (!changed) {
13357                         for (int i = 0; i < mActiveAssistantServiceUids.length; i++) {
13358                             if (activeUids.get(i) != mActiveAssistantServiceUids[i]) {
13359                                 changed = true;
13360                                 break;
13361                             }
13362                         }
13363                     }
13364                     if (changed) {
13365                         mActiveAssistantServiceUids = activeUids.toArray();
13366                     }
13367                 }
13368             }
13369             sendMsg(mAudioHandler, MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID, SENDMSG_REPLACE,
13370                     0, 0, null, 0);
13371         }
13372 
13373         @Override
setAccessibilityServiceUids(IntArray uids)13374         public void setAccessibilityServiceUids(IntArray uids) {
13375             // TODO(b/233287010): Fix voice interaction and a11y concurrency in audio policy service
13376             if (isPlatformAutomotive()) {
13377                 return;
13378             }
13379 
13380             synchronized (mAccessibilityServiceUidsLock) {
13381                 if (uids.size() == 0) {
13382                     mAccessibilityServiceUids = null;
13383                 } else {
13384                     boolean changed = (mAccessibilityServiceUids == null)
13385                             || (mAccessibilityServiceUids.length != uids.size());
13386                     if (!changed) {
13387                         for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
13388                             if (uids.get(i) != mAccessibilityServiceUids[i]) {
13389                                 changed = true;
13390                                 break;
13391                             }
13392                         }
13393                     }
13394                     if (changed) {
13395                         mAccessibilityServiceUids = uids.toArray();
13396                     }
13397                 }
13398                 sendMsg(mAudioHandler, MSG_UPDATE_A11Y_SERVICE_UIDS, SENDMSG_REPLACE,
13399                         0, 0, null, 0);
13400             }
13401         }
13402 
13403         /**
13404          * {@inheritDoc}
13405          */
13406         @Override
setInputMethodServiceUid(int uid)13407         public void setInputMethodServiceUid(int uid) {
13408             synchronized (mInputMethodServiceUidLock) {
13409                 if (mInputMethodServiceUid != uid) {
13410                     mAudioSystem.setCurrentImeUid(uid);
13411                     mInputMethodServiceUid = uid;
13412                 }
13413             }
13414         }
13415     }
13416 
onUpdateAccessibilityServiceUids()13417     private void onUpdateAccessibilityServiceUids() {
13418         int[] accessibilityServiceUids;
13419         synchronized (mAccessibilityServiceUidsLock) {
13420             accessibilityServiceUids = mAccessibilityServiceUids;
13421         }
13422         AudioSystem.setA11yServicesUids(accessibilityServiceUids);
13423     }
13424 
13425     //==========================================================================================
13426     // Audio policy management
13427     //==========================================================================================
registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection, AttributionSource attributionSource)13428     public String registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb,
13429             boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy,
13430             boolean isVolumeController, IMediaProjection projection,
13431             AttributionSource attributionSource) {
13432         Objects.requireNonNull(attributionSource);
13433         AudioSystem.setDynamicPolicyCallback(mDynPolicyCallback);
13434 
13435         if (!isPolicyRegisterAllowed(policyConfig,
13436                                      isFocusPolicy || isTestFocusPolicy || hasFocusListener,
13437                                      isVolumeController,
13438                                      projection)) {
13439             Slog.w(TAG, "Permission denied to register audio policy for pid "
13440                     + Binder.getCallingPid() + " / uid " + Binder.getCallingUid()
13441                     + ", need system permission or a MediaProjection that can project audio");
13442             return null;
13443         }
13444 
13445         String regId = null;
13446         synchronized (mAudioPolicies) {
13447             if (mAudioPolicies.containsKey(pcb.asBinder())) {
13448                 Slog.e(TAG, "Cannot re-register policy");
13449                 return null;
13450             }
13451             try {
13452                 AudioPolicyProxy app = new AudioPolicyProxy(policyConfig, pcb, hasFocusListener,
13453                         isFocusPolicy, isTestFocusPolicy, isVolumeController, projection,
13454                         attributionSource);
13455                 pcb.asBinder().linkToDeath(app, 0/*flags*/);
13456 
13457                 // logging after registration so we have the registration id
13458                 mDynPolicyLogger.enqueue((new EventLogger.StringEvent("registerAudioPolicy for "
13459                         + pcb.asBinder() + " u/pid:" + Binder.getCallingUid() + "/"
13460                         + Binder.getCallingPid() + " with config:" + app.toCompactLogString()))
13461                         .printLog(TAG));
13462 
13463                 regId = app.getRegistrationId();
13464                 mAudioPolicies.put(pcb.asBinder(), app);
13465             } catch (RemoteException e) {
13466                 // audio policy owner has already died!
13467                 Slog.w(TAG, "Audio policy registration failed, could not link to " + pcb +
13468                         " binder death", e);
13469                 return null;
13470             } catch (IllegalStateException e) {
13471                 Slog.w(TAG, "Audio policy registration failed for binder " + pcb, e);
13472                 return null;
13473             }
13474         }
13475         return regId;
13476     }
13477 
13478     /**
13479      * Called by an AudioPolicyProxy when the client dies.
13480      * Checks if an active playback for media use case is currently routed to one of the
13481      * remote submix devices owned by this dynamic policy and broadcasts a becoming noisy
13482      * intend in this case.
13483      * @param addresses list of remote submix device addresses to check.
13484      */
onPolicyClientDeath(List<String> addresses)13485     private void onPolicyClientDeath(List<String> addresses) {
13486         for (String address : addresses) {
13487             if (mPlaybackMonitor.hasActiveMediaPlaybackOnSubmixWithAddress(address)) {
13488                 mDeviceBroker.postBroadcastBecomingNoisy();
13489                 return;
13490             }
13491         }
13492     }
13493     /**
13494      * Apps with MODIFY_AUDIO_ROUTING can register any policy.
13495      * Apps with an audio capable MediaProjection are allowed to register a RENDER|LOOPBACK policy
13496      * as those policy do not modify the audio routing.
13497      */
isPolicyRegisterAllowed(AudioPolicyConfig policyConfig, boolean hasFocusAccess, boolean isVolumeController, IMediaProjection projection)13498     private boolean isPolicyRegisterAllowed(AudioPolicyConfig policyConfig,
13499                                             boolean hasFocusAccess,
13500                                             boolean isVolumeController,
13501                                             IMediaProjection projection) {
13502 
13503         boolean requireValidProjection = false;
13504         boolean requireCaptureAudioOrMediaOutputPerm = false;
13505         boolean requireModifyRouting = false;
13506         boolean requireCallAudioInterception = false;
13507         ArrayList<AudioMix> voiceCommunicationCaptureMixes = null;
13508 
13509 
13510         if (hasFocusAccess || isVolumeController) {
13511             requireModifyRouting |= true;
13512         } else if (policyConfig.getMixes().isEmpty()) {
13513             // An empty policy could be used to lock the focus or add mixes later
13514             requireModifyRouting |= true;
13515         }
13516         for (AudioMix mix : policyConfig.getMixes()) {
13517             // If mix is requesting privileged capture
13518             if (mix.getRule().allowPrivilegedMediaPlaybackCapture()) {
13519                 // then its format must be low quality enough
13520                 String privilegedMediaCaptureError =
13521                         mix.canBeUsedForPrivilegedMediaCapture(mix.getFormat());
13522                 if (privilegedMediaCaptureError != null) {
13523                     Log.e(TAG, privilegedMediaCaptureError);
13524                     return false;
13525                 }
13526                 // and it must have CAPTURE_MEDIA_OUTPUT or CAPTURE_AUDIO_OUTPUT permission
13527                 requireCaptureAudioOrMediaOutputPerm |= true;
13528 
13529             }
13530             // If mix is trying to explicitly capture USAGE_VOICE_COMMUNICATION
13531             if (mix.containsMatchAttributeRuleForUsage(
13532                     AudioAttributes.USAGE_VOICE_COMMUNICATION)
13533                     && (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER)) {
13534                 // It must have CAPTURE_USAGE_VOICE_COMMUNICATION_OUTPUT permission
13535                 // Note that for UID, USERID or EXCLDUE rules, the capture will be silenced
13536                 // in AudioPolicyMix
13537                 if (voiceCommunicationCaptureMixes == null) {
13538                     voiceCommunicationCaptureMixes = new ArrayList<AudioMix>();
13539                 }
13540                 voiceCommunicationCaptureMixes.add(mix);
13541             }
13542 
13543             // If mix is RENDER|LOOPBACK, then an audio MediaProjection is enough
13544             // otherwise MODIFY_AUDIO_ROUTING permission is required
13545             if (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER && projection != null) {
13546                 requireValidProjection |= true;
13547             } else if (mix.isForCallRedirection()) {
13548                 requireCallAudioInterception |= true;
13549             } else if (mix.containsMatchAttributeRuleForUsage(
13550                             AudioAttributes.USAGE_VOICE_COMMUNICATION)) {
13551                 requireModifyRouting |= true;
13552             }
13553         }
13554 
13555         if (requireCaptureAudioOrMediaOutputPerm
13556                 && !callerHasPermission(CAPTURE_MEDIA_OUTPUT)
13557                 && !callerHasPermission(CAPTURE_AUDIO_OUTPUT)) {
13558             Log.e(TAG, "Privileged audio capture requires CAPTURE_MEDIA_OUTPUT or "
13559                       + "CAPTURE_AUDIO_OUTPUT system permission");
13560             return false;
13561         }
13562 
13563         if (voiceCommunicationCaptureMixes != null && voiceCommunicationCaptureMixes.size() > 0) {
13564             if (!callerHasPermission(
13565                     Manifest.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT)) {
13566                 Log.e(TAG, "Audio capture for voice communication requires "
13567                         + "CAPTURE_VOICE_COMMUNICATION_OUTPUT system permission");
13568                 return false;
13569             }
13570 
13571             // If permission check succeeded, we set the flag in each of the mixing rules
13572             for (AudioMix mix : voiceCommunicationCaptureMixes) {
13573                 mix.getRule().setVoiceCommunicationCaptureAllowed(true);
13574             }
13575         }
13576 
13577         if (requireValidProjection && !canProjectAudio(projection)) {
13578             return false;
13579         }
13580 
13581         if (requireModifyRouting
13582                 && !callerHasPermission(MODIFY_AUDIO_ROUTING)) {
13583             Log.e(TAG, "Can not capture audio without MODIFY_AUDIO_ROUTING");
13584             return false;
13585         }
13586 
13587         if (requireCallAudioInterception && !callerHasPermission(CALL_AUDIO_INTERCEPTION)) {
13588             Log.e(TAG, "Can not capture audio without CALL_AUDIO_INTERCEPTION");
13589             return false;
13590         }
13591 
13592         return true;
13593     }
13594 
callerHasPermission(String permission)13595     private boolean callerHasPermission(String permission) {
13596         return mContext.checkCallingOrSelfPermission(permission)
13597                 == PackageManager.PERMISSION_GRANTED;
13598     }
13599 
13600     /** @return true if projection is a valid MediaProjection that can project audio. */
canProjectAudio(IMediaProjection projection)13601     private boolean canProjectAudio(IMediaProjection projection) {
13602         if (projection == null) {
13603             Log.e(TAG, "MediaProjection is null");
13604             return false;
13605         }
13606 
13607         IMediaProjectionManager projectionService = getProjectionService();
13608         if (projectionService == null) {
13609             Log.e(TAG, "Can't get service IMediaProjectionManager");
13610             return false;
13611         }
13612 
13613         final long token = Binder.clearCallingIdentity();
13614         try {
13615             if (!projectionService.isCurrentProjection(projection)) {
13616                 Log.w(TAG, "App passed invalid MediaProjection token");
13617                 return false;
13618             }
13619         } catch (RemoteException e) {
13620             Log.e(TAG, "Can't call .isCurrentProjection() on IMediaProjectionManager"
13621                     + projectionService.asBinder(), e);
13622             return false;
13623         } finally {
13624             Binder.restoreCallingIdentity(token);
13625         }
13626 
13627         try {
13628             if (!projection.canProjectAudio()) {
13629                 Log.w(TAG, "App passed MediaProjection that can not project audio");
13630                 return false;
13631             }
13632         } catch (RemoteException e) {
13633             Log.e(TAG, "Can't call .canProjectAudio() on valid IMediaProjection"
13634                     + projection.asBinder(), e);
13635             return false;
13636         }
13637 
13638         return true;
13639     }
13640 
getProjectionService()13641     private IMediaProjectionManager getProjectionService() {
13642         if (mProjectionService == null) {
13643             IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE);
13644             mProjectionService = IMediaProjectionManager.Stub.asInterface(b);
13645         }
13646         return mProjectionService;
13647     }
13648 
13649     /**
13650      * See {@link AudioManager#unregisterAudioPolicyAsync(AudioPolicy)}
13651      * Declared oneway
13652      * @param pcb nullable because on service interface
13653      */
unregisterAudioPolicyAsync(@ullable IAudioPolicyCallback pcb)13654     public void unregisterAudioPolicyAsync(@Nullable IAudioPolicyCallback pcb) {
13655         if (pcb == null) {
13656             return;
13657         }
13658         unregisterAudioPolicyInt(pcb, "unregisterAudioPolicyAsync");
13659     }
13660 
13661     /**
13662      * See {@link AudioManager#unregisterAudioPolicy(AudioPolicy)}
13663      * @param pcb nullable because on service interface
13664      */
unregisterAudioPolicy(@ullable IAudioPolicyCallback pcb)13665     public void unregisterAudioPolicy(@Nullable IAudioPolicyCallback pcb) {
13666         if (pcb == null) {
13667             return;
13668         }
13669         unregisterAudioPolicyInt(pcb, "unregisterAudioPolicy");
13670     }
13671 
13672 
unregisterAudioPolicyInt(@onNull IAudioPolicyCallback pcb, String operationName)13673     private void unregisterAudioPolicyInt(@NonNull IAudioPolicyCallback pcb, String operationName) {
13674         mDynPolicyLogger.enqueue((new EventLogger.StringEvent(operationName + " for "
13675                 + pcb.asBinder()).printLog(TAG)));
13676         synchronized (mAudioPolicies) {
13677             AudioPolicyProxy app = mAudioPolicies.remove(pcb.asBinder());
13678             if (app == null) {
13679                 Slog.w(TAG, "Trying to unregister unknown audio policy for pid "
13680                         + Binder.getCallingPid() + " / uid " + Binder.getCallingUid());
13681                 return;
13682             } else {
13683                 pcb.asBinder().unlinkToDeath(app, 0/*flags*/);
13684             }
13685             app.release();
13686         }
13687         // TODO implement clearing mix attribute matching info in native audio policy
13688     }
13689 
13690     /**
13691      * Checks whether caller has MODIFY_AUDIO_ROUTING permission, and the policy is registered.
13692      * @param errorMsg log warning if permission check failed.
13693      * @return null if the operation on the audio mixes should be cancelled.
13694      */
13695     @GuardedBy("mAudioPolicies")
checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg)13696     private AudioPolicyProxy checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg) {
13697         // permission check
13698         final boolean hasPermissionForPolicy =
13699                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
13700                         MODIFY_AUDIO_ROUTING));
13701         if (!hasPermissionForPolicy) {
13702             Slog.w(TAG, errorMsg + " for pid " +
13703                     + Binder.getCallingPid() + " / uid "
13704                     + Binder.getCallingUid() + ", need MODIFY_AUDIO_ROUTING");
13705             return null;
13706         }
13707         // policy registered?
13708         final AudioPolicyProxy app = mAudioPolicies.get(pcb.asBinder());
13709         if (app == null) {
13710             Slog.w(TAG, errorMsg + " for pid " +
13711                     + Binder.getCallingPid() + " / uid "
13712                     + Binder.getCallingUid() + ", unregistered policy");
13713             return null;
13714         }
13715         return app;
13716     }
13717 
13718     /**
13719      * Retrieves all audioMixes registered with the AudioPolicyManager
13720      * @return list of registered audio mixes
13721      */
getRegisteredPolicyMixes()13722     public List<AudioMix> getRegisteredPolicyMixes() {
13723         if (!android.media.audiopolicy.Flags.audioMixTestApi()) {
13724             return Collections.emptyList();
13725         }
13726 
13727         synchronized (mAudioPolicies) {
13728             return mAudioSystem.getRegisteredPolicyMixes();
13729         }
13730     }
13731 
addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)13732     public int addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) {
13733         if (DEBUG_AP) { Log.d(TAG, "addMixForPolicy for " + pcb.asBinder()
13734                 + " with config:" + policyConfig); }
13735         synchronized (mAudioPolicies) {
13736             final AudioPolicyProxy app =
13737                     checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy");
13738             if (app == null){
13739                 return AudioManager.ERROR;
13740             }
13741             return app.addMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS
13742                 ? AudioManager.SUCCESS : AudioManager.ERROR;
13743         }
13744     }
13745 
removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)13746     public int removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) {
13747         if (DEBUG_AP) { Log.d(TAG, "removeMixForPolicy for " + pcb.asBinder()
13748                 + " with config:" + policyConfig); }
13749         synchronized (mAudioPolicies) {
13750             final AudioPolicyProxy app =
13751                     checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy");
13752             if (app == null) {
13753                 return AudioManager.ERROR;
13754             }
13755             if (android.media.audiopolicy.Flags.audioMixOwnership()) {
13756                 for (AudioMix mix : policyConfig.getMixes()) {
13757                     if (!app.getMixes().contains(mix)) {
13758                         Slog.e(TAG,
13759                                 "removeMixForPolicy attempted to unregister AudioMix(es) not "
13760                                         + "belonging to the AudioPolicy");
13761                         return AudioManager.ERROR;
13762                     }
13763                 }
13764             }
13765             return app.removeMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS
13766                 ? AudioManager.SUCCESS : AudioManager.ERROR;
13767         }
13768     }
13769 
13770     /**
13771      * Update {@link AudioMixingRule}-s for already registered {@link AudioMix}-es.
13772      *
13773      * @param mixesToUpdate - array of already registered {@link AudioMix}-es to update.
13774      * @param updatedMixingRules - array of {@link AudioMixingRule}-s corresponding to
13775      *                           {@code mixesToUpdate} mixes. The array must be same size as
13776      *                           {@code mixesToUpdate} and i-th {@link AudioMixingRule} must
13777      *                           correspond to i-th {@link AudioMix} from mixesToUpdate array.
13778      * @param pcb - {@link IAudioPolicyCallback} corresponding to the registered
13779      *              {@link AudioPolicy} all {@link AudioMix}-es for {@code mixesToUpdate}
13780      *              are part of.
13781      * @return {@link AudioManager#SUCCESS} iff the mixing rules were updated successfully,
13782      *     {@link AudioManager#ERROR} otherwise.
13783      */
13784     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
updateMixingRulesForPolicy( @onNull AudioMix[] mixesToUpdate, @NonNull AudioMixingRule[] updatedMixingRules, @NonNull IAudioPolicyCallback pcb)13785     public int updateMixingRulesForPolicy(
13786             @NonNull AudioMix[] mixesToUpdate,
13787             @NonNull AudioMixingRule[] updatedMixingRules,
13788             @NonNull IAudioPolicyCallback pcb) {
13789         super.updateMixingRulesForPolicy_enforcePermission();
13790         Objects.requireNonNull(mixesToUpdate);
13791         Objects.requireNonNull(updatedMixingRules);
13792         Objects.requireNonNull(pcb);
13793         if (mixesToUpdate.length != updatedMixingRules.length) {
13794             Log.e(TAG, "Provided list of audio mixes to update and corresponding mixing rules "
13795                     + "have mismatching length (mixesToUpdate.length = " + mixesToUpdate.length
13796                     + ", updatedMixingRules.length = " + updatedMixingRules.length +  ").");
13797             return AudioManager.ERROR;
13798         }
13799         if (DEBUG_AP) {
13800             Log.d(TAG, "updateMixingRules for " + pcb.asBinder() + "with mix rules: ");
13801         }
13802         synchronized (mAudioPolicies) {
13803             final AudioPolicyProxy app =
13804                     checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy");
13805             if (app == null) {
13806                 return AudioManager.ERROR;
13807             }
13808             return app.updateMixingRules(mixesToUpdate, updatedMixingRules) == AudioSystem.SUCCESS
13809                     ? AudioManager.SUCCESS : AudioManager.ERROR;
13810         }
13811     }
13812 
13813     /** see AudioPolicy.setUidDeviceAffinity() */
setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)13814     public int setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid,
13815             @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) {
13816         if (DEBUG_AP) {
13817             Log.d(TAG, "setUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid);
13818         }
13819         synchronized (mAudioPolicies) {
13820             final AudioPolicyProxy app =
13821                     checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy");
13822             if (app == null) {
13823                 return AudioManager.ERROR;
13824             }
13825             if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) {
13826                 return AudioManager.ERROR;
13827             }
13828             return app.setUidDeviceAffinities(uid, deviceTypes, deviceAddresses);
13829         }
13830     }
13831 
13832     /** see AudioPolicy.setUserIdDeviceAffinity() */
setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)13833     public int setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId,
13834             @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) {
13835         if (DEBUG_AP) {
13836             Log.d(TAG, "setUserIdDeviceAffinity for " + pcb.asBinder() + " user:" + userId);
13837         }
13838 
13839         synchronized (mAudioPolicies) {
13840             final AudioPolicyProxy app =
13841                     checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy");
13842             if (app == null) {
13843                 return AudioManager.ERROR;
13844             }
13845             if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) {
13846                 return AudioManager.ERROR;
13847             }
13848             return app.setUserIdDeviceAffinities(userId, deviceTypes, deviceAddresses);
13849         }
13850     }
13851 
13852     /** see AudioPolicy.removeUidDeviceAffinity() */
removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid)13853     public int removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid) {
13854         if (DEBUG_AP) {
13855             Log.d(TAG, "removeUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid);
13856         }
13857         synchronized (mAudioPolicies) {
13858             final AudioPolicyProxy app =
13859                     checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy");
13860             if (app == null) {
13861                 return AudioManager.ERROR;
13862             }
13863             return app.removeUidDeviceAffinities(uid);
13864         }
13865     }
13866 
13867     /** see AudioPolicy.removeUserIdDeviceAffinity() */
removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId)13868     public int removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId) {
13869         if (DEBUG_AP) {
13870             Log.d(TAG, "removeUserIdDeviceAffinity for " + pcb.asBinder()
13871                     + " userId:" + userId);
13872         }
13873         synchronized (mAudioPolicies) {
13874             final AudioPolicyProxy app =
13875                     checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy");
13876             if (app == null) {
13877                 return AudioManager.ERROR;
13878             }
13879             return app.removeUserIdDeviceAffinities(userId);
13880         }
13881     }
13882 
setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb)13883     public int setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb) {
13884         if (DEBUG_AP) Log.d(TAG, "setFocusPropertiesForPolicy() duck behavior=" + duckingBehavior
13885                 + " policy " +  pcb.asBinder());
13886         synchronized (mAudioPolicies) {
13887             final AudioPolicyProxy app =
13888                     checkUpdateForPolicy(pcb, "Cannot change audio policy focus properties");
13889             if (app == null){
13890                 return AudioManager.ERROR;
13891             }
13892             if (!mAudioPolicies.containsKey(pcb.asBinder())) {
13893                 Slog.e(TAG, "Cannot change audio policy focus properties, unregistered policy");
13894                 return AudioManager.ERROR;
13895             }
13896             if (duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) {
13897                 // is there already one policy managing ducking?
13898                 for (AudioPolicyProxy policy : mAudioPolicies.values()) {
13899                     if (policy.mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) {
13900                         Slog.e(TAG, "Cannot change audio policy ducking behavior, already handled");
13901                         return AudioManager.ERROR;
13902                     }
13903                 }
13904             }
13905             app.mFocusDuckBehavior = duckingBehavior;
13906             mMediaFocusControl.setDuckingInExtPolicyAvailable(
13907                     duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY);
13908         }
13909         return AudioManager.SUCCESS;
13910     }
13911 
13912     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
13913     /* @see AudioPolicy#getFocusStack() */
getFocusStack()13914     public List<AudioFocusInfo> getFocusStack() {
13915         super.getFocusStack_enforcePermission();
13916 
13917         return mMediaFocusControl.getFocusStack();
13918     }
13919 
13920     /**
13921      * @param focusLoser non-null entry that may be in the stack
13922      * @see AudioPolicy#sendFocusLossAndUpdate(AudioFocusInfo)
13923      */
13924     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
sendFocusLossAndUpdate(@onNull AudioFocusInfo focusLoser, @NonNull IAudioPolicyCallback apcb)13925     public void sendFocusLossAndUpdate(@NonNull AudioFocusInfo focusLoser,
13926             @NonNull IAudioPolicyCallback apcb) {
13927         super.sendFocusLossAndUpdate_enforcePermission();
13928         Objects.requireNonNull(apcb);
13929         if (!mAudioPolicies.containsKey(apcb.asBinder())) {
13930             throw new IllegalStateException("Only registered AudioPolicy can change focus");
13931         }
13932         if (!mAudioPolicies.get(apcb.asBinder()).mHasFocusListener) {
13933             throw new IllegalStateException("AudioPolicy must have focus listener to change focus");
13934         }
13935 
13936         mMediaFocusControl.sendFocusLossAndUpdate(Objects.requireNonNull(focusLoser));
13937     }
13938 
13939     /* @see AudioPolicy#sendFocusLoss(AudioFocusInfo)  */
13940     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
sendFocusLoss(@onNull AudioFocusInfo focusLoser, @NonNull IAudioPolicyCallback apcb)13941     public boolean sendFocusLoss(@NonNull AudioFocusInfo focusLoser,
13942             @NonNull IAudioPolicyCallback apcb) {
13943         super.sendFocusLoss_enforcePermission();
13944         Objects.requireNonNull(focusLoser);
13945         Objects.requireNonNull(apcb);
13946         if (!mAudioPolicies.containsKey(apcb.asBinder())) {
13947             throw new IllegalStateException("Only registered AudioPolicy can change focus");
13948         }
13949         if (!mAudioPolicies.get(apcb.asBinder()).mHasFocusListener) {
13950             throw new IllegalStateException("AudioPolicy must have focus listener to change focus");
13951         }
13952         return mMediaFocusControl.sendFocusLoss(focusLoser);
13953     }
13954 
13955     /**
13956      * see {@link AudioPolicy#setFadeManagerConfigurationForFocusLoss(FadeManagerConfiguration)}
13957      */
13958     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setFadeManagerConfigurationForFocusLoss( @onNull FadeManagerConfiguration fmcForFocusLoss)13959     public int setFadeManagerConfigurationForFocusLoss(
13960             @NonNull FadeManagerConfiguration fmcForFocusLoss) {
13961         super.setFadeManagerConfigurationForFocusLoss_enforcePermission();
13962         ensureFadeManagerConfigIsEnabled();
13963         Objects.requireNonNull(fmcForFocusLoss,
13964                 "Fade manager config for focus loss cannot be null");
13965         validateFadeManagerConfiguration(fmcForFocusLoss);
13966 
13967         return mPlaybackMonitor.setFadeManagerConfiguration(AudioManager.AUDIOFOCUS_LOSS,
13968                 fmcForFocusLoss);
13969     }
13970 
13971     /**
13972      * see {@link AudioPolicy#clearFadeManagerConfigurationForFocusLoss()}
13973      */
13974     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
clearFadeManagerConfigurationForFocusLoss()13975     public int clearFadeManagerConfigurationForFocusLoss() {
13976         super.clearFadeManagerConfigurationForFocusLoss_enforcePermission();
13977         ensureFadeManagerConfigIsEnabled();
13978 
13979         return mPlaybackMonitor.clearFadeManagerConfiguration(AudioManager.AUDIOFOCUS_LOSS);
13980     }
13981 
13982     /**
13983      * see {@link AudioPolicy#getFadeManagerConfigurationForFocusLoss()}
13984      */
13985     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
getFadeManagerConfigurationForFocusLoss()13986     public FadeManagerConfiguration getFadeManagerConfigurationForFocusLoss() {
13987         super.getFadeManagerConfigurationForFocusLoss_enforcePermission();
13988         ensureFadeManagerConfigIsEnabled();
13989 
13990         return mPlaybackMonitor.getFadeManagerConfiguration(AudioManager.AUDIOFOCUS_LOSS);
13991     }
13992 
13993     /**
13994      * @see AudioManager#getHalVersion
13995      */
getHalVersion()13996     public @Nullable AudioHalVersionInfo getHalVersion() {
13997         for (AudioHalVersionInfo version : AudioHalVersionInfo.VERSIONS) {
13998             try {
13999                 String versionStr = version.getMajorVersion() + "." + version.getMinorVersion();
14000                 final String aidlStr = "android.hardware.audio.core.IModule/default";
14001                 final String hidlStr = String.format("android.hardware.audio@%s::IDevicesFactory",
14002                         versionStr);
14003                 if (null != ServiceManager.checkService(aidlStr)) {
14004                     return version;
14005                 } else {
14006                     HwBinder.getService(hidlStr, "default");
14007                     return version;
14008                 }
14009             } catch (NoSuchElementException e) {
14010                 // Ignore, the specified HAL interface is not found.
14011             } catch (RemoteException re) {
14012                 Log.e(TAG, "Remote exception when getting hardware audio service:", re);
14013             }
14014         }
14015         return null;
14016     }
14017 
14018     /** see AudioManager.hasRegisteredDynamicPolicy */
hasRegisteredDynamicPolicy()14019     public boolean hasRegisteredDynamicPolicy() {
14020         synchronized (mAudioPolicies) {
14021             return !mAudioPolicies.isEmpty();
14022         }
14023     }
14024 
14025     /**
14026      * @see AudioManager#setPreferredMixerAttributes(
14027      *      AudioAttributes, AudioDeviceInfo, AudioMixerAttributes)
14028      */
setPreferredMixerAttributes(AudioAttributes attributes, int portId, AudioMixerAttributes mixerAttributes)14029     public int setPreferredMixerAttributes(AudioAttributes attributes,
14030             int portId, AudioMixerAttributes mixerAttributes) {
14031         Objects.requireNonNull(attributes);
14032         Objects.requireNonNull(mixerAttributes);
14033         if (!checkAudioSettingsPermission("setPreferredMixerAttributes()")) {
14034             return AudioSystem.PERMISSION_DENIED;
14035         }
14036         final int uid = Binder.getCallingUid();
14037         final int pid = Binder.getCallingPid();
14038         int status = AudioSystem.SUCCESS;
14039         final long token = Binder.clearCallingIdentity();
14040         try {
14041             final String logString = TextUtils.formatSimple(
14042                     "setPreferredMixerAttributes u/pid:%d/%d attr:%s mixerAttributes:%s portId:%d",
14043                     uid, pid, attributes.toString(), mixerAttributes.toString(), portId);
14044             sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
14045 
14046             status = mAudioSystem.setPreferredMixerAttributes(
14047                     attributes, portId, uid, mixerAttributes);
14048             if (status == AudioSystem.SUCCESS) {
14049                 dispatchPreferredMixerAttributesChanged(attributes, portId, mixerAttributes);
14050             } else {
14051                 Log.e(TAG, TextUtils.formatSimple("Error %d in %s)", status, logString));
14052             }
14053         } finally {
14054             Binder.restoreCallingIdentity(token);
14055         }
14056         return status;
14057     }
14058 
14059     /**
14060      * @see AudioManager#clearPreferredMixerAttributes(AudioAttributes, AudioDeviceInfo)
14061      */
clearPreferredMixerAttributes(AudioAttributes attributes, int portId)14062     public int clearPreferredMixerAttributes(AudioAttributes attributes, int portId) {
14063         Objects.requireNonNull(attributes);
14064         if (!checkAudioSettingsPermission("clearPreferredMixerAttributes()")) {
14065             return AudioSystem.PERMISSION_DENIED;
14066         }
14067         final int uid = Binder.getCallingUid();
14068         final int pid = Binder.getCallingPid();
14069         int status = AudioSystem.SUCCESS;
14070         final long token = Binder.clearCallingIdentity();
14071         try {
14072             final String logString = TextUtils.formatSimple(
14073                     "clearPreferredMixerAttributes u/pid:%d/%d attr:%s",
14074                     uid, pid, attributes.toString());
14075             sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
14076 
14077             status = mAudioSystem.clearPreferredMixerAttributes(attributes, portId, uid);
14078             if (status == AudioSystem.SUCCESS) {
14079                 dispatchPreferredMixerAttributesChanged(attributes, portId, null /*mixerAttr*/);
14080             } else {
14081                 Log.e(TAG, TextUtils.formatSimple("Error %d in %s)", status, logString));
14082             }
14083         } finally {
14084             Binder.restoreCallingIdentity(token);
14085         }
14086         return status;
14087     }
14088 
dispatchPreferredMixerAttributesChanged( AudioAttributes attr, int deviceId, AudioMixerAttributes mixerAttr)14089     void dispatchPreferredMixerAttributesChanged(
14090             AudioAttributes attr, int deviceId, AudioMixerAttributes mixerAttr) {
14091         Bundle bundle = new Bundle();
14092         bundle.putParcelable(KEY_AUDIO_ATTRIBUTES, attr);
14093         bundle.putParcelable(KEY_AUDIO_MIXER_ATTRIBUTES, mixerAttr);
14094         sendBundleMsg(mAudioHandler, MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES, SENDMSG_QUEUE,
14095                 deviceId, 0, null, bundle, 0);
14096     }
14097 
14098     final RemoteCallbackList<IPreferredMixerAttributesDispatcher> mPrefMixerAttrDispatcher =
14099             new RemoteCallbackList<IPreferredMixerAttributesDispatcher>();
14100     private static final String KEY_AUDIO_ATTRIBUTES = "audio_attributes";
14101     private static final String KEY_AUDIO_MIXER_ATTRIBUTES = "audio_mixer_attributes";
14102 
14103     /** @see AudioManager#addOnPreferredMixerAttributesChangedListener(
14104      *       Executor, AudioManager.OnPreferredMixerAttributesChangedListener)
14105      */
registerPreferredMixerAttributesDispatcher( @ullable IPreferredMixerAttributesDispatcher dispatcher)14106     public void registerPreferredMixerAttributesDispatcher(
14107             @Nullable IPreferredMixerAttributesDispatcher dispatcher) {
14108         if (dispatcher == null) {
14109             return;
14110         }
14111         mPrefMixerAttrDispatcher.register(dispatcher);
14112     }
14113 
14114     /** @see AudioManager#removeOnPreferredMixerAttributesChangedListener(
14115      *       AudioManager.OnPreferredMixerAttributesChangedListener)
14116      */
unregisterPreferredMixerAttributesDispatcher( @ullable IPreferredMixerAttributesDispatcher dispatcher)14117     public void unregisterPreferredMixerAttributesDispatcher(
14118             @Nullable IPreferredMixerAttributesDispatcher dispatcher) {
14119         if (dispatcher == null) {
14120             return;
14121         }
14122         mPrefMixerAttrDispatcher.unregister(dispatcher);
14123     }
14124 
onDispatchPreferredMixerAttributesChanged(Bundle data, int deviceId)14125     protected void onDispatchPreferredMixerAttributesChanged(Bundle data, int deviceId) {
14126         final int nbDispathers = mPrefMixerAttrDispatcher.beginBroadcast();
14127         final AudioAttributes attr = data.getParcelable(
14128                 KEY_AUDIO_ATTRIBUTES, AudioAttributes.class);
14129         final AudioMixerAttributes mixerAttr = data.getParcelable(
14130                 KEY_AUDIO_MIXER_ATTRIBUTES, AudioMixerAttributes.class);
14131         for (int i = 0; i < nbDispathers; i++) {
14132             try {
14133                 mPrefMixerAttrDispatcher.getBroadcastItem(i)
14134                         .dispatchPrefMixerAttributesChanged(attr, deviceId, mixerAttr);
14135             } catch (RemoteException e) {
14136                 Log.e(TAG, "Can't call dispatchPrefMixerAttributesChanged() "
14137                         + "IPreferredMixerAttributesDispatcher "
14138                         + mPrefMixerAttrDispatcher.getBroadcastItem(i).asBinder(), e);
14139             }
14140         }
14141         mPrefMixerAttrDispatcher.finishBroadcast();
14142     }
14143 
14144 
14145     /** @see AudioManager#supportsBluetoothVariableLatency() */
14146     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
supportsBluetoothVariableLatency()14147     public boolean supportsBluetoothVariableLatency() {
14148         super.supportsBluetoothVariableLatency_enforcePermission();
14149         try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
14150             return AudioSystem.supportsBluetoothVariableLatency();
14151         }
14152     }
14153 
14154     /** @see AudioManager#setBluetoothVariableLatencyEnabled(boolean) */
14155     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
setBluetoothVariableLatencyEnabled(boolean enabled)14156     public void setBluetoothVariableLatencyEnabled(boolean enabled) {
14157         super.setBluetoothVariableLatencyEnabled_enforcePermission();
14158         try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
14159             AudioSystem.setBluetoothVariableLatencyEnabled(enabled);
14160         }
14161     }
14162 
14163     /** @see AudioManager#isBluetoothVariableLatencyEnabled(boolean) */
14164     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
isBluetoothVariableLatencyEnabled()14165     public boolean isBluetoothVariableLatencyEnabled() {
14166         super.isBluetoothVariableLatencyEnabled_enforcePermission();
14167         try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
14168             return AudioSystem.isBluetoothVariableLatencyEnabled();
14169         }
14170     }
14171 
14172     private final Object mExtVolumeControllerLock = new Object();
14173     private IAudioPolicyCallback mExtVolumeController;
setExtVolumeController(IAudioPolicyCallback apc)14174     private void setExtVolumeController(IAudioPolicyCallback apc) {
14175         if (!mContext.getResources().getBoolean(
14176                 com.android.internal.R.bool.config_handleVolumeKeysInWindowManager)) {
14177             Log.e(TAG, "Cannot set external volume controller: device not set for volume keys" +
14178                     " handled in PhoneWindowManager");
14179             return;
14180         }
14181         synchronized (mExtVolumeControllerLock) {
14182             if (mExtVolumeController != null && !mExtVolumeController.asBinder().pingBinder()) {
14183                 Log.e(TAG, "Cannot set external volume controller: existing controller");
14184             }
14185             mExtVolumeController = apc;
14186         }
14187     }
14188 
dumpAudioPolicies(PrintWriter pw)14189     private void dumpAudioPolicies(PrintWriter pw) {
14190         pw.println("\nAudio policies:");
14191         synchronized (mAudioPolicies) {
14192             for (AudioPolicyProxy policy : mAudioPolicies.values()) {
14193                 pw.println(policy.toLogFriendlyString());
14194             }
14195         }
14196     }
14197 
ensureFadeManagerConfigIsEnabled()14198     private void ensureFadeManagerConfigIsEnabled() {
14199         Preconditions.checkState(enableFadeManagerConfiguration(),
14200                 "Fade manager configuration not supported");
14201     }
14202 
validateFadeManagerConfiguration(FadeManagerConfiguration fmc)14203     private void validateFadeManagerConfiguration(FadeManagerConfiguration fmc) {
14204         // validate permission of audio attributes
14205         List<AudioAttributes> attrs = fmc.getAudioAttributesWithVolumeShaperConfigs();
14206         for (int index = 0; index < attrs.size(); index++) {
14207             validateAudioAttributesUsage(attrs.get(index));
14208         }
14209     }
14210 
14211     //======================
14212     // Audio policy callbacks from AudioSystem for dynamic policies
14213     //======================
14214     private final AudioSystem.DynamicPolicyCallback mDynPolicyCallback =
14215             new AudioSystem.DynamicPolicyCallback() {
14216         public void onDynamicPolicyMixStateUpdate(String regId, int state) {
14217             if (!TextUtils.isEmpty(regId)) {
14218                 sendMsg(mAudioHandler, MSG_DYN_POLICY_MIX_STATE_UPDATE, SENDMSG_QUEUE,
14219                         state /*arg1*/, 0 /*arg2 ignored*/, regId /*obj*/, 0 /*delay*/);
14220             }
14221         }
14222     };
14223 
onDynPolicyMixStateUpdate(String regId, int state)14224     private void onDynPolicyMixStateUpdate(String regId, int state) {
14225         if (DEBUG_AP) Log.d(TAG, "onDynamicPolicyMixStateUpdate("+ regId + ", " + state +")");
14226         synchronized (mAudioPolicies) {
14227             for (AudioPolicyProxy policy : mAudioPolicies.values()) {
14228                 for (AudioMix mix : policy.getMixes()) {
14229                     if (mix.getRegistration().equals(regId)) {
14230                         try {
14231                             policy.mPolicyCallback.notifyMixStateUpdate(regId, state);
14232                         } catch (RemoteException e) {
14233                             Log.e(TAG, "Can't call notifyMixStateUpdate() on IAudioPolicyCallback "
14234                                     + policy.mPolicyCallback.asBinder(), e);
14235                         }
14236                         return;
14237                     }
14238                 }
14239             }
14240         }
14241     }
14242 
14243     //======================
14244     // Audio policy callbacks from AudioSystem for recording configuration updates
14245     //======================
14246     private final RecordingActivityMonitor mRecordMonitor;
14247 
registerRecordingCallback(IRecordingConfigDispatcher rcdb)14248     public void registerRecordingCallback(IRecordingConfigDispatcher rcdb) {
14249         final boolean isPrivileged =
14250                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
14251                         MODIFY_AUDIO_ROUTING));
14252         mRecordMonitor.registerRecordingCallback(rcdb, isPrivileged);
14253     }
14254 
unregisterRecordingCallback(IRecordingConfigDispatcher rcdb)14255     public void unregisterRecordingCallback(IRecordingConfigDispatcher rcdb) {
14256         mRecordMonitor.unregisterRecordingCallback(rcdb);
14257     }
14258 
getActiveRecordingConfigurations()14259     public List<AudioRecordingConfiguration> getActiveRecordingConfigurations() {
14260         final boolean isPrivileged = Binder.getCallingUid() == Process.SYSTEM_UID
14261                 || (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
14262                         MODIFY_AUDIO_ROUTING));
14263         return mRecordMonitor.getActiveRecordingConfigurations(isPrivileged);
14264     }
14265 
14266     //======================
14267     // Audio recording state notification from clients
14268     //======================
14269     /**
14270      * Track a recorder provided by the client
14271      */
trackRecorder(IBinder recorder)14272     public int trackRecorder(IBinder recorder) {
14273         return mRecordMonitor.trackRecorder(recorder);
14274     }
14275 
14276     /**
14277      * Receive an event from the client about a tracked recorder
14278      */
recorderEvent(int riid, int event)14279     public void recorderEvent(int riid, int event) {
14280         mRecordMonitor.recorderEvent(riid, event);
14281     }
14282 
14283     /**
14284      * Stop tracking the recorder
14285      */
releaseRecorder(int riid)14286     public void releaseRecorder(int riid) {
14287         mRecordMonitor.releaseRecorder(riid);
14288     }
14289 
14290     //======================
14291     // Audio playback notification
14292     //======================
14293     private final PlaybackActivityMonitor mPlaybackMonitor;
14294 
registerPlaybackCallback(IPlaybackConfigDispatcher pcdb)14295     public void registerPlaybackCallback(IPlaybackConfigDispatcher pcdb) {
14296         final boolean isPrivileged =
14297                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
14298                         MODIFY_AUDIO_ROUTING));
14299         mPlaybackMonitor.registerPlaybackCallback(pcdb, isPrivileged);
14300     }
14301 
unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb)14302     public void unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb) {
14303         mPlaybackMonitor.unregisterPlaybackCallback(pcdb);
14304     }
14305 
getActivePlaybackConfigurations()14306     public List<AudioPlaybackConfiguration> getActivePlaybackConfigurations() {
14307         final boolean isPrivileged =
14308                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
14309                         MODIFY_AUDIO_ROUTING));
14310         return mPlaybackMonitor.getActivePlaybackConfigurations(isPrivileged);
14311     }
14312 
trackPlayer(PlayerBase.PlayerIdCard pic)14313     public int trackPlayer(PlayerBase.PlayerIdCard pic) {
14314         if (pic != null && pic.mAttributes != null) {
14315             validateAudioAttributesUsage(pic.mAttributes);
14316         }
14317         return mPlaybackMonitor.trackPlayer(pic);
14318     }
14319 
playerAttributes(int piid, AudioAttributes attr)14320     public void playerAttributes(int piid, AudioAttributes attr) {
14321         if (attr != null) {
14322             validateAudioAttributesUsage(attr);
14323         }
14324         mPlaybackMonitor.playerAttributes(piid, attr, Binder.getCallingUid());
14325     }
14326 
14327     /**
14328      * Update player session ID
14329      * @param piid Player id to update
14330      * @param sessionId The new audio session ID
14331      */
playerSessionId(int piid, int sessionId)14332     public void playerSessionId(int piid, int sessionId) {
14333         if (sessionId <= AudioSystem.AUDIO_SESSION_ALLOCATE) {
14334             throw new IllegalArgumentException("invalid session Id " + sessionId);
14335         }
14336         mPlaybackMonitor.playerSessionId(piid, sessionId, Binder.getCallingUid());
14337     }
14338 
14339     /**
14340      * Update player event
14341      * @param piid Player id to update
14342      * @param event The new player event
14343      * @param eventValues The values associated with this event
14344      */
playerEvent(int piid, int event, int[] eventValues)14345     public void playerEvent(int piid, int event, int[] eventValues) {
14346         mPlaybackMonitor.playerEvent(piid, event, eventValues, Binder.getCallingUid());
14347     }
14348 
14349     /**
14350      * Update event for port id
14351      * @param portId Port id to update
14352      * @param event The new event for the given port
14353      * @param extras Bundle of extra values to describe the event
14354      */
portEvent(int portId, int event, @Nullable PersistableBundle extras)14355     public void portEvent(int portId, int event, @Nullable PersistableBundle extras) {
14356         mPlaybackMonitor.portEvent(portId, event, extras, Binder.getCallingUid());
14357     }
14358 
playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio)14359     public void playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio) {
14360         mPlaybackMonitor.playerHasOpPlayAudio(piid, hasOpPlayAudio, Binder.getCallingUid());
14361     }
14362 
releasePlayer(int piid)14363     public void releasePlayer(int piid) {
14364         mPlaybackMonitor.releasePlayer(piid, Binder.getCallingUid());
14365     }
14366 
14367     /**
14368      * Specifies whether the audio played by this app may or may not be captured by other apps or
14369      * the system.
14370      *
14371      * @param capturePolicy one of
14372      *     {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL},
14373      *     {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM},
14374      *     {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}.
14375      * @return AudioSystem.AUDIO_STATUS_OK if set allowed capture policy succeed.
14376      * @throws IllegalArgumentException if the argument is not a valid value.
14377      */
setAllowedCapturePolicy(int capturePolicy)14378     public int setAllowedCapturePolicy(int capturePolicy) {
14379         int callingUid = Binder.getCallingUid();
14380         int flags = AudioAttributes.capturePolicyToFlags(capturePolicy, 0x0);
14381         final long identity = Binder.clearCallingIdentity();
14382         try {
14383             synchronized (mPlaybackMonitor) {
14384                 int result = mAudioSystem.setAllowedCapturePolicy(callingUid, flags);
14385                 if (result == AudioSystem.AUDIO_STATUS_OK) {
14386                     mPlaybackMonitor.setAllowedCapturePolicy(callingUid, capturePolicy);
14387                 }
14388                 return result;
14389             }
14390         } finally {
14391             Binder.restoreCallingIdentity(identity);
14392         }
14393     }
14394 
14395     /**
14396      * Return the capture policy.
14397      * @return the cached capture policy for the calling uid.
14398      */
getAllowedCapturePolicy()14399     public int getAllowedCapturePolicy() {
14400         int callingUid = Binder.getCallingUid();
14401         final long identity = Binder.clearCallingIdentity();
14402         try {
14403             return mPlaybackMonitor.getAllowedCapturePolicy(callingUid);
14404         } finally {
14405             Binder.restoreCallingIdentity(identity);
14406         }
14407     }
14408 
14409     /* package */
isPlaybackActiveForUid(int uid)14410     boolean isPlaybackActiveForUid(int uid) {
14411         return mPlaybackMonitor.isPlaybackActiveForUid(uid);
14412     }
14413 
14414     /* package */
isRecordingActiveForUid(int uid)14415     boolean isRecordingActiveForUid(int uid) {
14416         return mRecordMonitor.isRecordingActiveForUid(uid);
14417     }
14418 
14419     //======================
14420     // Audio device management
14421     //======================
14422     private final AudioDeviceBroker mDeviceBroker;
14423 
14424     //======================
14425     // Audio policy proxy
14426     //======================
14427     private static final class AudioDeviceArray {
14428         final @NonNull int[] mDeviceTypes;
14429         final @NonNull String[] mDeviceAddresses;
AudioDeviceArray(@onNull int[] types, @NonNull String[] addresses)14430         AudioDeviceArray(@NonNull int[] types,  @NonNull String[] addresses) {
14431             mDeviceTypes = types;
14432             mDeviceAddresses = addresses;
14433         }
14434     }
14435 
14436     /**
14437      * This internal class inherits from AudioPolicyConfig, each instance contains all the
14438      * mixes of an AudioPolicy and their configurations.
14439      */
14440     public class AudioPolicyProxy extends AudioPolicyConfig implements IBinder.DeathRecipient {
14441         private static final String TAG = "AudioPolicyProxy";
14442         final IAudioPolicyCallback mPolicyCallback;
14443         final AttributionSource mAttributionSource;
14444         final boolean mHasFocusListener;
14445         final boolean mIsVolumeController;
14446         final HashMap<Integer, AudioDeviceArray> mUidDeviceAffinities =
14447                 new HashMap<Integer, AudioDeviceArray>();
14448 
14449         final HashMap<Integer, AudioDeviceArray> mUserIdDeviceAffinities =
14450                 new HashMap<>();
14451 
14452         final IMediaProjection mProjection;
14453         private final class UnregisterOnStopCallback extends IMediaProjectionCallback.Stub {
onStop()14454             public void onStop() {
14455                 unregisterAudioPolicyAsync(mPolicyCallback);
14456             }
14457 
14458             @Override
onCapturedContentResize(int width, int height)14459             public void onCapturedContentResize(int width, int height) {
14460                 // Ignore resize of the captured content.
14461             }
14462 
14463             @Override
onCapturedContentVisibilityChanged(boolean isVisible)14464             public void onCapturedContentVisibilityChanged(boolean isVisible) {
14465                 // Ignore visibility changes of the captured content.
14466             }
14467         };
14468         UnregisterOnStopCallback mProjectionCallback;
14469 
14470         /**
14471          * Audio focus ducking behavior for an audio policy.
14472          * This variable reflects the value that was successfully set in
14473          * {@link AudioService#setFocusPropertiesForPolicy(int, IAudioPolicyCallback)}. This
14474          * implies that a value of FOCUS_POLICY_DUCKING_IN_POLICY means the corresponding policy
14475          * is handling ducking for audio focus.
14476          */
14477         int mFocusDuckBehavior = AudioPolicy.FOCUS_POLICY_DUCKING_DEFAULT;
14478         boolean mIsFocusPolicy = false;
14479         boolean mIsTestFocusPolicy = false;
14480 
AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection, AttributionSource attributionSource)14481         AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token,
14482                 boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy,
14483                 boolean isVolumeController, IMediaProjection projection,
14484                 AttributionSource attributionSource) {
14485             super(config);
14486             setRegistration(new String(config.hashCode() + ":ap:" + mAudioPolicyCounter++));
14487             mPolicyCallback = token;
14488             mAttributionSource = attributionSource;
14489             mHasFocusListener = hasFocusListener;
14490             mIsVolumeController = isVolumeController;
14491             mProjection = projection;
14492             if (mHasFocusListener) {
14493                 mMediaFocusControl.addFocusFollower(mPolicyCallback);
14494                 // can only ever be true if there is a focus listener
14495                 if (isFocusPolicy) {
14496                     mIsFocusPolicy = true;
14497                     mIsTestFocusPolicy = isTestFocusPolicy;
14498                     mMediaFocusControl.setFocusPolicy(mPolicyCallback, mIsTestFocusPolicy);
14499                 }
14500             }
14501             if (mIsVolumeController) {
14502                 setExtVolumeController(mPolicyCallback);
14503             }
14504             if (mProjection != null) {
14505                 mProjectionCallback = new UnregisterOnStopCallback();
14506                 try {
14507                     mProjection.registerCallback(mProjectionCallback);
14508                 } catch (RemoteException e) {
14509                     release();
14510                     throw new IllegalStateException("MediaProjection callback registration failed, "
14511                             + "could not link to " + projection + " binder death", e);
14512                 }
14513             }
14514 
14515             int status = connectMixes();
14516             if (status != AudioSystem.SUCCESS) {
14517                 release();
14518                 throw new IllegalStateException("Could not connect mix, error: " + status);
14519             }
14520         }
14521 
binderDied()14522         public void binderDied() {
14523             mDynPolicyLogger.enqueue((new EventLogger.StringEvent("AudioPolicy "
14524                     + mPolicyCallback.asBinder() + " died").printLog(TAG)));
14525 
14526             List<String> addresses = new ArrayList<>();
14527             for (AudioMix mix : mMixes) {
14528                 addresses.add(mix.getRegistration());
14529             }
14530             onPolicyClientDeath(addresses);
14531 
14532             release();
14533         }
14534 
getRegistrationId()14535         String getRegistrationId() {
14536             return getRegistration();
14537         }
14538 
release()14539         void release() {
14540             if (mIsFocusPolicy) {
14541                 mMediaFocusControl.unsetFocusPolicy(mPolicyCallback, mIsTestFocusPolicy);
14542             }
14543             if (mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) {
14544                 mMediaFocusControl.setDuckingInExtPolicyAvailable(false);
14545             }
14546             if (mHasFocusListener) {
14547                 mMediaFocusControl.removeFocusFollower(mPolicyCallback);
14548             }
14549             if (mProjectionCallback != null) {
14550                 try {
14551                     mProjection.unregisterCallback(mProjectionCallback);
14552                 } catch (RemoteException e) {
14553                     Log.e(TAG, "Fail to unregister Audiopolicy callback from MediaProjection");
14554                 }
14555             }
14556             if (mIsVolumeController) {
14557                 synchronized (mExtVolumeControllerLock) {
14558                     mExtVolumeController = null;
14559                 }
14560             }
14561             final long identity = Binder.clearCallingIdentity();
14562             try {
14563                 if (android.media.audiopolicy.Flags.audioMixOwnership()) {
14564                     synchronized (mMixes) {
14565                         removeMixes(new ArrayList(mMixes));
14566                     }
14567                 } else {
14568                     mAudioSystem.registerPolicyMixes(mMixes, false);
14569                 }
14570             } finally {
14571                 Binder.restoreCallingIdentity(identity);
14572             }
14573             synchronized (mAudioPolicies) {
14574                 mAudioPolicies.remove(mPolicyCallback.asBinder());
14575             }
14576             try {
14577                 mPolicyCallback.notifyUnregistration();
14578             } catch (RemoteException e) { }
14579         }
14580 
hasMixAffectingUsage(int usage, int excludedFlags)14581         boolean hasMixAffectingUsage(int usage, int excludedFlags) {
14582             for (AudioMix mix : mMixes) {
14583                 if (mix.isAffectingUsage(usage)
14584                         && ((mix.getRouteFlags() & excludedFlags) != excludedFlags)) {
14585                     return true;
14586                 }
14587             }
14588             return false;
14589         }
14590 
14591         // Verify all the devices in the array are served by mixes defined in this policy
hasMixRoutedToDevices(@onNull int[] deviceTypes, @NonNull String[] deviceAddresses)14592         boolean hasMixRoutedToDevices(@NonNull int[] deviceTypes,
14593                 @NonNull String[] deviceAddresses) {
14594             for (int i = 0; i < deviceTypes.length; i++) {
14595                 boolean hasDevice = false;
14596                 for (AudioMix mix : mMixes) {
14597                     // this will check both that the mix has ROUTE_FLAG_RENDER and the device
14598                     // is reached by this mix
14599                     if (mix.isRoutedToDevice(deviceTypes[i], deviceAddresses[i])) {
14600                         hasDevice = true;
14601                         break;
14602                     }
14603                 }
14604                 if (!hasDevice) {
14605                     return false;
14606                 }
14607             }
14608             return true;
14609         }
14610 
addMixes(@onNull ArrayList<AudioMix> mixes)14611         int addMixes(@NonNull ArrayList<AudioMix> mixes) {
14612             synchronized (mMixes) {
14613                 if (android.media.audiopolicy.Flags.audioMixOwnership()) {
14614                     for (AudioMix mix : mixes) {
14615                         setMixRegistration(mix);
14616                         mix.setVirtualDeviceId(mAttributionSource.getDeviceId());
14617                     }
14618 
14619                     int result = mAudioSystem.registerPolicyMixes(mixes, true);
14620                     if (result == AudioSystem.SUCCESS) {
14621                         this.add(mixes);
14622                     }
14623                     return result;
14624                 }
14625                 this.add(mixes);
14626                 return mAudioSystem.registerPolicyMixes(mixes, true);
14627             }
14628         }
14629 
removeMixes(@onNull ArrayList<AudioMix> mixes)14630         int removeMixes(@NonNull ArrayList<AudioMix> mixes) {
14631             synchronized (mMixes) {
14632                 this.remove(mixes);
14633                 return mAudioSystem.registerPolicyMixes(mixes, false);
14634             }
14635         }
14636 
connectMixes()14637         @AudioSystem.AudioSystemError int connectMixes() {
14638             final long identity = Binder.clearCallingIdentity();
14639             try {
14640                 for (AudioMix mix : mMixes) {
14641                     mix.setVirtualDeviceId(mAttributionSource.getDeviceId());
14642                 }
14643                 mAudioSystem.registerPolicyMixes(mMixes, false);
14644                 return mAudioSystem.registerPolicyMixes(mMixes, true);
14645             } finally {
14646                 Binder.restoreCallingIdentity(identity);
14647             }
14648 
14649         }
14650 
updateMixingRules( @onNull AudioMix[] mixesToUpdate, @NonNull AudioMixingRule[] updatedMixingRules)14651         @AudioSystem.AudioSystemError int updateMixingRules(
14652                                         @NonNull AudioMix[] mixesToUpdate,
14653                                         @NonNull AudioMixingRule[] updatedMixingRules) {
14654             Objects.requireNonNull(mixesToUpdate);
14655             Objects.requireNonNull(updatedMixingRules);
14656 
14657             for (AudioMix mix : mixesToUpdate) {
14658                 mix.setVirtualDeviceId(mAttributionSource.getDeviceId());
14659             }
14660             if (mixesToUpdate.length != updatedMixingRules.length) {
14661                 Log.e(TAG, "Provided list of audio mixes to update and corresponding mixing rules "
14662                         + "have mismatching length (mixesToUpdate.length = " + mixesToUpdate.length
14663                         + ", updatedMixingRules.length = " + updatedMixingRules.length +  ").");
14664                 return AudioSystem.BAD_VALUE;
14665             }
14666 
14667             synchronized (mMixes) {
14668                 try (SafeCloseable unused = ClearCallingIdentityContext.create()) {
14669                     int ret = mAudioSystem.updateMixingRules(mixesToUpdate, updatedMixingRules);
14670                     if (ret == AudioSystem.SUCCESS) {
14671                         for (int i = 0; i < mixesToUpdate.length; i++) {
14672                             AudioMix audioMixToUpdate = mixesToUpdate[i];
14673                             AudioMixingRule audioMixingRule = updatedMixingRules[i];
14674                             mMixes.stream().filter(audioMixToUpdate::equals).findAny().ifPresent(
14675                                     mix -> mix.setAudioMixingRule(audioMixingRule));
14676                         }
14677                     }
14678                     return ret;
14679                 }
14680             }
14681         }
14682 
setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses)14683         int setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses) {
14684             final Integer Uid = new Integer(uid);
14685             if (mUidDeviceAffinities.remove(Uid) != null) {
14686                 if (removeUidDeviceAffinitiesFromSystem(uid) != AudioSystem.SUCCESS) {
14687                     Log.e(TAG, "AudioSystem. removeUidDeviceAffinities(" + uid + ") failed, "
14688                             + " cannot call AudioSystem.setUidDeviceAffinities");
14689                     return AudioManager.ERROR;
14690                 }
14691             }
14692             AudioDeviceArray deviceArray = new AudioDeviceArray(types, addresses);
14693             if (setUidDeviceAffinitiesOnSystem(uid, deviceArray) == AudioSystem.SUCCESS) {
14694                 mUidDeviceAffinities.put(Uid, deviceArray);
14695                 return AudioManager.SUCCESS;
14696             }
14697             Log.e(TAG, "AudioSystem. setUidDeviceAffinities(" + uid + ") failed");
14698             return AudioManager.ERROR;
14699         }
14700 
removeUidDeviceAffinities(int uid)14701         int removeUidDeviceAffinities(int uid) {
14702             if (mUidDeviceAffinities.remove(new Integer(uid)) != null) {
14703                 if (removeUidDeviceAffinitiesFromSystem(uid) == AudioSystem.SUCCESS) {
14704                     return AudioManager.SUCCESS;
14705                 }
14706             }
14707             Log.e(TAG, "AudioSystem. removeUidDeviceAffinities failed");
14708             return AudioManager.ERROR;
14709         }
14710 
removeUidDeviceAffinitiesFromSystem(int uid)14711         @AudioSystem.AudioSystemError private int removeUidDeviceAffinitiesFromSystem(int uid) {
14712             final long identity = Binder.clearCallingIdentity();
14713             try {
14714                 return mAudioSystem.removeUidDeviceAffinities(uid);
14715             } finally {
14716                 Binder.restoreCallingIdentity(identity);
14717             }
14718         }
14719 
setUidDeviceAffinitiesOnSystem(int uid, AudioDeviceArray deviceArray)14720         @AudioSystem.AudioSystemError private int setUidDeviceAffinitiesOnSystem(int uid,
14721                 AudioDeviceArray deviceArray) {
14722             final long identity = Binder.clearCallingIdentity();
14723             try {
14724                 return mAudioSystem.setUidDeviceAffinities(uid, deviceArray.mDeviceTypes,
14725                         deviceArray.mDeviceAddresses);
14726             } finally {
14727                 Binder.restoreCallingIdentity(identity);
14728             }
14729         }
14730 
setUserIdDeviceAffinities(int userId, @NonNull int[] types, @NonNull String[] addresses)14731         int setUserIdDeviceAffinities(int userId,
14732                 @NonNull int[] types, @NonNull String[] addresses) {
14733             final Integer UserId = new Integer(userId);
14734             if (mUserIdDeviceAffinities.remove(UserId) != null) {
14735                 if (removeUserIdDeviceAffinitiesFromSystem(userId) != AudioSystem.SUCCESS) {
14736                     Log.e(TAG, "AudioSystem. removeUserIdDeviceAffinities("
14737                             + UserId + ") failed, "
14738                             + " cannot call AudioSystem.setUserIdDeviceAffinities");
14739                     return AudioManager.ERROR;
14740                 }
14741             }
14742             AudioDeviceArray audioDeviceArray = new AudioDeviceArray(types, addresses);
14743             if (setUserIdDeviceAffinitiesOnSystem(userId, audioDeviceArray)
14744                     == AudioSystem.SUCCESS) {
14745                 mUserIdDeviceAffinities.put(UserId, audioDeviceArray);
14746                 return AudioManager.SUCCESS;
14747             }
14748             Log.e(TAG, "AudioSystem.setUserIdDeviceAffinities(" + userId + ") failed");
14749             return AudioManager.ERROR;
14750         }
14751 
removeUserIdDeviceAffinities(int userId)14752         int removeUserIdDeviceAffinities(int userId) {
14753             if (mUserIdDeviceAffinities.remove(new Integer(userId)) != null) {
14754                 if (removeUserIdDeviceAffinitiesFromSystem(userId) == AudioSystem.SUCCESS) {
14755                     return AudioManager.SUCCESS;
14756                 }
14757             }
14758             Log.e(TAG, "AudioSystem.removeUserIdDeviceAffinities failed");
14759             return AudioManager.ERROR;
14760         }
14761 
removeUserIdDeviceAffinitiesFromSystem( @serIdInt int userId)14762         @AudioSystem.AudioSystemError private int removeUserIdDeviceAffinitiesFromSystem(
14763                 @UserIdInt int userId) {
14764             final long identity = Binder.clearCallingIdentity();
14765             try {
14766                 return mAudioSystem.removeUserIdDeviceAffinities(userId);
14767             } finally {
14768                 Binder.restoreCallingIdentity(identity);
14769             }
14770         }
14771 
setUserIdDeviceAffinitiesOnSystem( @serIdInt int userId, AudioDeviceArray deviceArray)14772         @AudioSystem.AudioSystemError private int setUserIdDeviceAffinitiesOnSystem(
14773                 @UserIdInt int userId, AudioDeviceArray deviceArray) {
14774             final long identity = Binder.clearCallingIdentity();
14775             try {
14776                 return mAudioSystem.setUserIdDeviceAffinities(userId, deviceArray.mDeviceTypes,
14777                         deviceArray.mDeviceAddresses);
14778             } finally {
14779                 Binder.restoreCallingIdentity(identity);
14780             }
14781         }
14782 
setupDeviceAffinities()14783         @AudioSystem.AudioSystemError int setupDeviceAffinities() {
14784             for (Map.Entry<Integer, AudioDeviceArray> uidEntry : mUidDeviceAffinities.entrySet()) {
14785                 int uidStatus = removeUidDeviceAffinitiesFromSystem(uidEntry.getKey());
14786                 if (uidStatus != AudioSystem.SUCCESS) {
14787                     Log.e(TAG,
14788                             "setupDeviceAffinities failed to remove device affinity for uid "
14789                                     + uidEntry.getKey());
14790                     return uidStatus;
14791                 }
14792                 uidStatus = setUidDeviceAffinitiesOnSystem(uidEntry.getKey(), uidEntry.getValue());
14793                 if (uidStatus != AudioSystem.SUCCESS) {
14794                     Log.e(TAG,
14795                             "setupDeviceAffinities failed to set device affinity for uid "
14796                                     + uidEntry.getKey());
14797                     return uidStatus;
14798                 }
14799             }
14800 
14801             for (Map.Entry<Integer, AudioDeviceArray> userIdEntry :
14802                     mUserIdDeviceAffinities.entrySet()) {
14803                 int userIdStatus = removeUserIdDeviceAffinitiesFromSystem(userIdEntry.getKey());
14804                 if (userIdStatus != AudioSystem.SUCCESS) {
14805                     Log.e(TAG,
14806                             "setupDeviceAffinities failed to remove device affinity for userId "
14807                                     + userIdEntry.getKey());
14808                     return userIdStatus;
14809                 }
14810                 userIdStatus = setUserIdDeviceAffinitiesOnSystem(userIdEntry.getKey(),
14811                                 userIdEntry.getValue());
14812                 if (userIdStatus != AudioSystem.SUCCESS) {
14813                     Log.e(TAG,
14814                             "setupDeviceAffinities failed to set device affinity for userId "
14815                                     + userIdEntry.getKey());
14816                     return userIdStatus;
14817                 }
14818             }
14819             return AudioSystem.SUCCESS;
14820         }
14821 
14822         /** @return human readable debug informations summarizing the state of the object. */
toLogFriendlyString()14823         public String toLogFriendlyString() {
14824             String textDump = super.toLogFriendlyString();
14825             textDump += " Uid Device Affinities:\n";
14826             String spacer = "     ";
14827             textDump += logFriendlyAttributeDeviceArrayMap("Uid",
14828                     mUidDeviceAffinities, spacer);
14829             textDump += " UserId Device Affinities:\n";
14830             textDump += logFriendlyAttributeDeviceArrayMap("UserId",
14831                     mUserIdDeviceAffinities, spacer);
14832             textDump += " Proxy:\n";
14833             textDump += "   is focus policy= " + mIsFocusPolicy + "\n";
14834             if (mIsFocusPolicy) {
14835                 textDump += "     focus duck behaviour= " + mFocusDuckBehavior + "\n";
14836                 textDump += "     is test focus policy= " + mIsTestFocusPolicy + "\n";
14837                 textDump += "     has focus listener= " + mHasFocusListener  + "\n";
14838             }
14839             textDump += "   media projection= " + mProjection + "\n";
14840             return textDump;
14841         }
14842 
logFriendlyAttributeDeviceArrayMap(String attribute, Map<Integer, AudioDeviceArray> map, String spacer)14843         private String logFriendlyAttributeDeviceArrayMap(String attribute,
14844                 Map<Integer, AudioDeviceArray> map, String spacer) {
14845             final StringBuilder stringBuilder = new StringBuilder();
14846             for (Map.Entry<Integer, AudioDeviceArray> mapEntry : map.entrySet()) {
14847                 stringBuilder.append(spacer).append(attribute).append(": ")
14848                         .append(mapEntry.getKey()).append("\n");
14849                 AudioDeviceArray deviceArray = mapEntry.getValue();
14850                 String deviceSpacer = spacer + "   ";
14851                 for (int i = 0; i < deviceArray.mDeviceTypes.length; i++) {
14852                     stringBuilder.append(deviceSpacer).append("Type: 0x")
14853                             .append(Integer.toHexString(deviceArray.mDeviceTypes[i]))
14854                             .append(" Address: ").append(deviceArray.mDeviceAddresses[i])
14855                                     .append("\n");
14856                 }
14857             }
14858             return stringBuilder.toString();
14859         }
14860     };
14861 
14862     //======================
14863     // Audio policy: focus
14864     //======================
14865     /**  */
dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb)14866     public int dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb) {
14867         if (afi == null) {
14868             throw new IllegalArgumentException("Illegal null AudioFocusInfo");
14869         }
14870         if (pcb == null) {
14871             throw new IllegalArgumentException("Illegal null AudioPolicy callback");
14872         }
14873         synchronized (mAudioPolicies) {
14874             if (!mAudioPolicies.containsKey(pcb.asBinder())) {
14875                 throw new IllegalStateException("Unregistered AudioPolicy for focus dispatch");
14876             }
14877             return mMediaFocusControl.dispatchFocusChange(afi, focusChange);
14878         }
14879     }
14880 
setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult, IAudioPolicyCallback pcb)14881     public void setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult,
14882             IAudioPolicyCallback pcb) {
14883         if (afi == null) {
14884             throw new IllegalArgumentException("Illegal null AudioFocusInfo");
14885         }
14886         if (pcb == null) {
14887             throw new IllegalArgumentException("Illegal null AudioPolicy callback");
14888         }
14889         synchronized (mAudioPolicies) {
14890             if (!mAudioPolicies.containsKey(pcb.asBinder())) {
14891                 throw new IllegalStateException("Unregistered AudioPolicy for external focus");
14892             }
14893             mMediaFocusControl.setFocusRequestResultFromExtPolicy(afi, requestResult);
14894         }
14895     }
14896 
14897     /**
14898      * see {@link AudioManager#dispatchAudioFocusChangeWithFade(AudioFocusInfo, int, AudioPolicy,
14899      * List, FadeManagerConfiguration)}
14900      */
14901     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
dispatchFocusChangeWithFade(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb, List<AudioFocusInfo> otherActiveAfis, FadeManagerConfiguration transientFadeMgrConfig)14902     public int dispatchFocusChangeWithFade(AudioFocusInfo afi, int focusChange,
14903             IAudioPolicyCallback pcb, List<AudioFocusInfo> otherActiveAfis,
14904             FadeManagerConfiguration transientFadeMgrConfig) {
14905         super.dispatchFocusChangeWithFade_enforcePermission();
14906         ensureFadeManagerConfigIsEnabled();
14907         Objects.requireNonNull(afi, "AudioFocusInfo cannot be null");
14908         Objects.requireNonNull(pcb, "AudioPolicy callback cannot be null");
14909         Objects.requireNonNull(otherActiveAfis,
14910                 "Other active AudioFocusInfo list cannot be null");
14911         if (transientFadeMgrConfig != null) {
14912             validateFadeManagerConfiguration(transientFadeMgrConfig);
14913         }
14914 
14915         synchronized (mAudioPolicies) {
14916             Preconditions.checkState(mAudioPolicies.containsKey(pcb.asBinder()),
14917                     "Unregistered AudioPolicy for focus dispatch with fade");
14918 
14919             // set the transient fade manager config to be used for handling this focus change
14920             if (transientFadeMgrConfig != null) {
14921                 mPlaybackMonitor.setTransientFadeManagerConfiguration(focusChange,
14922                         transientFadeMgrConfig);
14923             }
14924             int status = mMediaFocusControl.dispatchFocusChangeWithFade(afi, focusChange,
14925                     otherActiveAfis);
14926 
14927             if (transientFadeMgrConfig != null) {
14928                 mPlaybackMonitor.clearTransientFadeManagerConfiguration(focusChange);
14929             }
14930             return status;
14931         }
14932     }
14933 
14934 
14935     /**
14936      * @see AudioManager#shouldNotificationSoundPlay(AudioAttributes)
14937      */
14938     @android.annotation.EnforcePermission(QUERY_AUDIO_STATE)
shouldNotificationSoundPlay(@onNull final AudioAttributes aa)14939     public boolean shouldNotificationSoundPlay(@NonNull final AudioAttributes aa) {
14940         super.shouldNotificationSoundPlay_enforcePermission();
14941         Objects.requireNonNull(aa);
14942 
14943         // don't play notifications if the stream volume associated with the
14944         // AudioAttributes of the notification record is 0 (non-zero volume implies
14945         // not silenced by SILENT or VIBRATE ringer mode)
14946         final int stream = AudioAttributes.toLegacyStreamType(aa);
14947         final boolean mutingFromVolume = getStreamVolume(stream) == 0;
14948         if (mutingFromVolume) {
14949             Slog.i(TAG, "shouldNotificationSoundPlay false: muted stream:" + stream
14950                     + " attr:" + aa);
14951             return false;
14952         }
14953 
14954         // don't play notifications if there is a user of GAIN_TRANSIENT_EXCLUSIVE audio focus
14955         // and the focus owner is recording
14956         final int uid = mMediaFocusControl.getExclusiveFocusOwnerUid();
14957         if (uid == -1) { // return value is -1 if focus isn't GAIN_TRANSIENT_EXCLUSIVE
14958             return true;
14959         }
14960         // is the owner of GAIN_TRANSIENT_EXCLUSIVE focus also recording?
14961         final boolean mutingFromFocusAndRecording = mRecordMonitor.isRecordingActiveForUid(uid);
14962         if (mutingFromFocusAndRecording) {
14963             Slog.i(TAG, "shouldNotificationSoundPlay false: exclusive focus owner recording "
14964                         + " uid:" + uid + " attr:" + aa);
14965             return false;
14966         }
14967         return true;
14968     }
14969 
14970     /**
14971      * @see AudioManager#setEnableHardening(boolean)
14972      */
14973     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setEnableHardening(boolean shouldEnable)14974     public void setEnableHardening(boolean shouldEnable) {
14975         super.setEnableHardening_enforcePermission();
14976         mShouldEnableAllHardening.set(shouldEnable);
14977         mAudioPolicy.setEnableHardening(shouldEnable);
14978     }
14979 
14980     //======================
14981     // Audioserver state dispatch
14982     //======================
14983     private class AsdProxy implements IBinder.DeathRecipient {
14984         private final IAudioServerStateDispatcher mAsd;
14985 
AsdProxy(IAudioServerStateDispatcher asd)14986         AsdProxy(IAudioServerStateDispatcher asd) {
14987             mAsd = asd;
14988         }
14989 
binderDied()14990         public void binderDied() {
14991             synchronized (mAudioServerStateListeners) {
14992                 mAudioServerStateListeners.remove(mAsd.asBinder());
14993             }
14994         }
14995 
callback()14996         IAudioServerStateDispatcher callback() {
14997             return mAsd;
14998         }
14999     }
15000 
15001     private final HashMap<IBinder, AsdProxy> mAudioServerStateListeners =
15002             new HashMap<IBinder, AsdProxy>();
15003 
checkMonitorAudioServerStatePermission()15004     private void checkMonitorAudioServerStatePermission() {
15005         if (!(mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE)
15006                 == PackageManager.PERMISSION_GRANTED
15007                 || mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING)
15008                 == PackageManager.PERMISSION_GRANTED)) {
15009             throw new SecurityException("Not allowed to monitor audioserver state");
15010         }
15011     }
15012 
registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd)15013     public void registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd) {
15014         checkMonitorAudioServerStatePermission();
15015         synchronized (mAudioServerStateListeners) {
15016             if (mAudioServerStateListeners.containsKey(asd.asBinder())) {
15017                 Slog.w(TAG, "Cannot re-register audio server state dispatcher");
15018                 return;
15019             }
15020             AsdProxy asdp = new AsdProxy(asd);
15021             try {
15022                 asd.asBinder().linkToDeath(asdp, 0/*flags*/);
15023             } catch (RemoteException e) {
15024 
15025             }
15026             mAudioServerStateListeners.put(asd.asBinder(), asdp);
15027         }
15028     }
15029 
unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd)15030     public void unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd) {
15031         checkMonitorAudioServerStatePermission();
15032         synchronized (mAudioServerStateListeners) {
15033             AsdProxy asdp = mAudioServerStateListeners.remove(asd.asBinder());
15034             if (asdp == null) {
15035                 Slog.w(TAG, "Trying to unregister unknown audioserver state dispatcher for pid "
15036                         + Binder.getCallingPid() + " / uid " + Binder.getCallingUid());
15037                 return;
15038             } else {
15039                 asd.asBinder().unlinkToDeath(asdp, 0/*flags*/);
15040             }
15041         }
15042     }
15043 
isAudioServerRunning()15044     public boolean isAudioServerRunning() {
15045         checkMonitorAudioServerStatePermission();
15046         return (AudioSystem.checkAudioFlinger() == AudioSystem.AUDIO_STATUS_OK);
15047     }
15048 
15049     //======================
15050     // Audio HAL process dump
15051     //======================
15052 
15053     private static final String AUDIO_HAL_SERVICE_PREFIX = "android.hardware.audio";
15054 
getAudioAidlHalPids(HashSet<Integer> pids)15055     private void getAudioAidlHalPids(HashSet<Integer> pids) {
15056         try {
15057             ServiceDebugInfo[] infos = ServiceManager.getServiceDebugInfo();
15058             if (infos == null) return;
15059             for (ServiceDebugInfo info : infos) {
15060                 if (info.debugPid > 0 && info.name.startsWith(AUDIO_HAL_SERVICE_PREFIX)) {
15061                     pids.add(info.debugPid);
15062                 }
15063             }
15064         } catch (RuntimeException e) {
15065             // ignored, pid hashset does not change
15066         }
15067     }
15068 
getAudioHalHidlPids(HashSet<Integer> pids)15069     private void getAudioHalHidlPids(HashSet<Integer> pids) {
15070         try {
15071             IServiceManager serviceManager = IServiceManager.getService();
15072             ArrayList<IServiceManager.InstanceDebugInfo> dump =
15073                     serviceManager.debugDump();
15074             for (IServiceManager.InstanceDebugInfo info : dump) {
15075                 if (info.pid != IServiceManager.PidConstant.NO_PID
15076                         && info.interfaceName != null
15077                         && info.interfaceName.startsWith(AUDIO_HAL_SERVICE_PREFIX)) {
15078                     pids.add(info.pid);
15079                 }
15080             }
15081         } catch (RemoteException | RuntimeException e) {
15082             // ignored, pid hashset does not change
15083         }
15084     }
15085 
getAudioHalPids()15086     private Set<Integer> getAudioHalPids() {
15087         HashSet<Integer> pids = new HashSet<>();
15088         getAudioAidlHalPids(pids);
15089         getAudioHalHidlPids(pids);
15090         return pids;
15091     }
15092 
updateAudioHalPids()15093     private void updateAudioHalPids() {
15094         Set<Integer> pidsSet = getAudioHalPids();
15095         if (pidsSet.isEmpty()) {
15096             Slog.w(TAG, "Could not retrieve audio HAL service pids");
15097             return;
15098         }
15099         int[] pidsArray = pidsSet.stream().mapToInt(Integer::intValue).toArray();
15100         AudioSystem.setAudioHalPids(pidsArray);
15101     }
15102 
15103     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
15104     //======================
15105     // Multi Audio Focus
15106     //======================
setMultiAudioFocusEnabled(boolean enabled)15107     public void setMultiAudioFocusEnabled(boolean enabled) {
15108         super.setMultiAudioFocusEnabled_enforcePermission();
15109 
15110         if (mMediaFocusControl != null) {
15111             boolean mafEnabled = mMediaFocusControl.getMultiAudioFocusEnabled();
15112             if (mafEnabled != enabled) {
15113                 mMediaFocusControl.updateMultiAudioFocus(enabled);
15114                 if (!enabled) {
15115                     mDeviceBroker.postBroadcastBecomingNoisy();
15116                 }
15117             }
15118         }
15119     }
15120 
15121     /**
15122      * @hide
15123      * Sets an additional audio output device delay in milliseconds.
15124      *
15125      * The additional output delay is a request to the output device to
15126      * delay audio presentation (generally with respect to video presentation for better
15127      * synchronization).
15128      * It may not be supported by all output devices,
15129      * and typically increases the audio latency by the amount of additional
15130      * audio delay requested.
15131      *
15132      * If additional audio delay is supported by an audio output device,
15133      * it is expected to be supported for all output streams (and configurations)
15134      * opened on that device.
15135      *
15136      * @param deviceType
15137      * @param address
15138      * @param delayMillis delay in milliseconds desired.  This should be in range of {@code 0}
15139      *     to the value returned by {@link #getMaxAdditionalOutputDeviceDelay()}.
15140      * @return true if successful, false if the device does not support output device delay
15141      *     or the delay is not in range of {@link #getMaxAdditionalOutputDeviceDelay()}.
15142      */
15143     @Override
15144     //@RequiresPermission(MODIFY_AUDIO_ROUTING)
setAdditionalOutputDeviceDelay( @onNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis)15145     public boolean setAdditionalOutputDeviceDelay(
15146             @NonNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis) {
15147         Objects.requireNonNull(device, "device must not be null");
15148         enforceModifyAudioRoutingPermission();
15149 
15150         device = retrieveBluetoothAddress(device);
15151 
15152         final String getterKey = "additional_output_device_delay="
15153                 + device.getInternalType() + "," + device.getAddress(); // "getter" key as an id.
15154         final String setterKey = getterKey + "," + delayMillis;     // append the delay for setter
15155         return mRestorableParameters.setParameters(getterKey, setterKey)
15156                 == AudioSystem.AUDIO_STATUS_OK;
15157     }
15158 
15159     /**
15160      * @hide
15161      * Returns the current audio output device delay value of key in milliseconds.
15162      *
15163      * In aidl implementation, the param of getParameters is "key" and reply delay of all supported
15164      * devices which be composited as "key=device,address,delay|device,address,delay|...".
15165      * e.g.
15166      * param: additional_output_device_delay=
15167      * reply: additional_output_device_delay=2,,0|4,,0|8,,0|128,,0|256,,0|512,,0|1024,,0|8192,,0|
15168      * 16384,,0|262144,,0|262145,,0|524288,,0|67108864,,0|134217728,,0|536870912,,0|536870913,,0|
15169      * 536870914,,0
15170      *
15171      * In hidl implementation, the param of getParameters is "key=device,address" and reply a
15172      * specific device delay which be composited as "key=device,address,delay".
15173      * e.g.
15174      * param: additional_output_device_delay=2,
15175      * reply: additional_output_device_delay=2,,0
15176      *
15177      * @param key
15178      * @param deviceType
15179      * @param address
15180      * @return the delay value of key. This is a non-negative number.
15181      *     {@code 0} is returned if unsupported.
15182      */
getDelayByKeyDevice(@onNull String key, @NonNull AudioDeviceAttributes device)15183     private long getDelayByKeyDevice(@NonNull String key, @NonNull AudioDeviceAttributes device) {
15184         long delayMillis = 0;
15185 
15186         try {
15187             if (AudioHalVersionInfo.AUDIO_HAL_TYPE_AIDL == getHalVersion().getHalType()) {
15188                 final String reply = AudioSystem.getParameters(key);
15189                 final String keyDeviceAddressPrefix =
15190                     Integer.toUnsignedString(device.getInternalType()) + "," + device.getAddress() +
15191                     ",";
15192                 int start = reply.indexOf(keyDeviceAddressPrefix);
15193                 int end = -1;
15194                 if (start != -1) {
15195                     start += keyDeviceAddressPrefix.length();
15196                     end = reply.indexOf("|", start);
15197                     delayMillis = Long.parseLong(
15198                             end == -1 ? reply.substring(start) : reply.substring(start, end));
15199                 }
15200             } else {
15201                 final String reply = AudioSystem.getParameters(
15202                     key + "=" + device.getInternalType() + "," + device.getAddress());
15203                 if (reply.contains(key)) {
15204                     delayMillis = Long.parseLong(reply.substring(key.length() + 1));
15205                 }
15206             }
15207         } catch (NullPointerException e) {
15208             Log.w(TAG, "NullPointerException when getting delay for device " + device, e);
15209         }
15210 
15211         return delayMillis;
15212     }
15213 
15214     /**
15215      * @hide
15216      * Returns the current additional audio output device delay in milliseconds.
15217      *
15218      * @param deviceType
15219      * @param address
15220      * @return the additional output device delay. This is a non-negative number.
15221      *     {@code 0} is returned if unsupported.
15222      */
15223     @Override
15224     @IntRange(from = 0)
getAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)15225     public long getAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) {
15226         Objects.requireNonNull(device, "device must not be null");
15227 
15228         device = retrieveBluetoothAddress(device);
15229 
15230         final String key = "additional_output_device_delay";
15231 
15232         return getDelayByKeyDevice(key, device);
15233     }
15234 
15235     /**
15236      * @hide
15237      * Returns the maximum additional audio output device delay in milliseconds.
15238      *
15239      * @param deviceType
15240      * @param address
15241      * @return the maximum output device delay in milliseconds that can be set.
15242      *     This is a non-negative number
15243      *     representing the additional audio delay supported for the device.
15244      *     {@code 0} is returned if unsupported.
15245      */
15246     @Override
15247     @IntRange(from = 0)
getMaxAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)15248     public long getMaxAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) {
15249         Objects.requireNonNull(device, "device must not be null");
15250 
15251         device = retrieveBluetoothAddress(device);
15252 
15253         final String key = "max_additional_output_device_delay";
15254 
15255         return getDelayByKeyDevice(key, device);
15256     }
15257 
15258     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
15259     /** @see AudioManager#addAssistantServicesUids(int []) */
15260     @Override
addAssistantServicesUids(int [] assistantUids)15261     public void addAssistantServicesUids(int [] assistantUids) {
15262         super.addAssistantServicesUids_enforcePermission();
15263 
15264         Objects.requireNonNull(assistantUids);
15265 
15266         synchronized (mSettingsLock) {
15267             addAssistantServiceUidsLocked(assistantUids);
15268         }
15269     }
15270 
15271     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
15272     /** @see AudioManager#removeAssistantServicesUids(int []) */
15273     @Override
removeAssistantServicesUids(int [] assistantUids)15274     public void removeAssistantServicesUids(int [] assistantUids) {
15275         super.removeAssistantServicesUids_enforcePermission();
15276 
15277         Objects.requireNonNull(assistantUids);
15278         synchronized (mSettingsLock) {
15279             removeAssistantServiceUidsLocked(assistantUids);
15280         }
15281     }
15282 
15283     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
15284     /** @see AudioManager#getAssistantServicesUids() */
15285     @Override
getAssistantServicesUids()15286     public int[] getAssistantServicesUids() {
15287         super.getAssistantServicesUids_enforcePermission();
15288 
15289         int [] assistantUids;
15290         synchronized (mSettingsLock) {
15291             assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray();
15292         }
15293         return assistantUids;
15294     }
15295 
15296     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
15297     /** @see AudioManager#setActiveAssistantServiceUids(int []) */
15298     @Override
setActiveAssistantServiceUids(int [] activeAssistantUids)15299     public void setActiveAssistantServiceUids(int [] activeAssistantUids) {
15300         super.setActiveAssistantServiceUids_enforcePermission();
15301 
15302         Objects.requireNonNull(activeAssistantUids);
15303         synchronized (mSettingsLock) {
15304             mActiveAssistantServiceUids = activeAssistantUids;
15305         }
15306         updateActiveAssistantServiceUids();
15307     }
15308 
15309     @android.annotation.EnforcePermission(MODIFY_AUDIO_ROUTING)
15310     /** @see AudioManager#getActiveAssistantServiceUids() */
15311     @Override
getActiveAssistantServiceUids()15312     public int[] getActiveAssistantServiceUids() {
15313         super.getActiveAssistantServiceUids_enforcePermission();
15314 
15315         int [] activeAssistantUids;
15316         synchronized (mSettingsLock) {
15317             activeAssistantUids = mActiveAssistantServiceUids.clone();
15318         }
15319         return activeAssistantUids;
15320     }
15321 
15322     @Override
15323     /** @see AudioManager#permissionUpdateBarrier() */
permissionUpdateBarrier()15324     public void permissionUpdateBarrier() {
15325         if (!audioserverPermissions()) return;
15326         if (PropertyInvalidatedCache.separatePermissionNotificationsEnabled()) {
15327             mCacheWatcher.doCheck();
15328         } else {
15329             mAudioSystem.triggerSystemPropertyUpdate(mSysPropListenerNativeHandle);
15330         }
15331         List<Future> snapshot;
15332         synchronized (mScheduledPermissionTasks) {
15333             snapshot = List.copyOf(mScheduledPermissionTasks);
15334         }
15335         for (var x : snapshot) {
15336             try {
15337                 x.get();
15338             } catch (CancellationException e) {
15339                 // Task completed
15340             } catch (InterruptedException | ExecutionException e) {
15341                 Log.wtf(TAG, "Exception which should never occur", e);
15342             }
15343         }
15344     }
15345 
getDeviceIdentityAddresses(AudioDeviceAttributes device)15346     List<String> getDeviceIdentityAddresses(AudioDeviceAttributes device) {
15347         return mDeviceBroker.getDeviceIdentityAddresses(device);
15348     }
15349 
15350     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
getMusicFxHelper()15351     MusicFxHelper getMusicFxHelper() {
15352         return mMusicFxHelper;
15353     }
15354 
15355     //======================
15356     // misc
15357     //======================
15358     private final HashMap<IBinder, AudioPolicyProxy> mAudioPolicies =
15359             new HashMap<IBinder, AudioPolicyProxy>();
15360     @GuardedBy("mAudioPolicies")
15361     private int mAudioPolicyCounter = 0;
15362 
15363     //======================
15364     // Helper functions for full and fixed volume device
15365     //======================
isFixedVolumeDevice(int deviceType)15366     private boolean isFixedVolumeDevice(int deviceType) {
15367         if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX
15368                 && mRecordMonitor.isLegacyRemoteSubmixActive()) {
15369             return false;
15370         }
15371         return mFixedVolumeDevices.contains(deviceType);
15372     }
15373 
isFullVolumeDevice(int deviceType)15374     private boolean isFullVolumeDevice(int deviceType) {
15375         if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX
15376                 && mRecordMonitor.isLegacyRemoteSubmixActive()) {
15377             return false;
15378         }
15379         return mFullVolumeDevices.contains(deviceType);
15380     }
15381 
15382     /**
15383      * Returns the input device which uses absolute volume behavior, including its variants,
15384      * or {@code null} if there is no mapping for the device type
15385      */
15386     @Nullable
getAbsoluteVolumeDeviceInfo(int deviceType)15387     private AbsoluteVolumeDeviceInfo getAbsoluteVolumeDeviceInfo(int deviceType) {
15388         synchronized (mAbsoluteVolumeDeviceInfoMapLock) {
15389             return mAbsoluteVolumeDeviceInfoMap.get(deviceType);
15390         }
15391     }
15392 
15393     /**
15394      * Returns whether the input device uses absolute volume behavior, including its variants.
15395      * For included volume behaviors, see
15396      * {@link AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior}.
15397      * <p>This is distinct from Bluetooth A2DP absolute volume behavior
15398      * ({@link #isA2dpAbsoluteVolumeDevice}).
15399      */
isAbsoluteVolumeDevice(int deviceType)15400     private boolean isAbsoluteVolumeDevice(int deviceType) {
15401         synchronized (mAbsoluteVolumeDeviceInfoMapLock) {
15402             return mAbsoluteVolumeDeviceInfoMap.containsKey(deviceType);
15403         }
15404     }
15405 
15406     /**
15407      * Returns whether the input device is a Bluetooth A2dp device that uses absolute volume
15408      * behavior. This is distinct from the general implementation of absolute volume behavior
15409      * ({@link #isAbsoluteVolumeDevice}).
15410      */
isA2dpAbsoluteVolumeDevice(int deviceType)15411     private boolean isA2dpAbsoluteVolumeDevice(int deviceType) {
15412         return mAvrcpAbsVolSupported && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(deviceType);
15413     }
15414 
15415     //====================
15416     // Helper functions for {set,get}DeviceVolumeBehavior
15417     //====================
getSettingsNameForDeviceVolumeBehavior(int deviceType)15418     private static String getSettingsNameForDeviceVolumeBehavior(int deviceType) {
15419         return "AudioService_DeviceVolumeBehavior_" + AudioSystem.getOutputDeviceName(deviceType);
15420     }
15421 
persistDeviceVolumeBehavior(int deviceType, @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior)15422     private void persistDeviceVolumeBehavior(int deviceType,
15423             @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior) {
15424         if (DEBUG_VOL) {
15425             Log.d(TAG, "Persisting Volume Behavior for DeviceType: " + deviceType);
15426         }
15427         final long callingIdentity = Binder.clearCallingIdentity();
15428         try {
15429             mSettings.putSystemIntForUser(mContentResolver,
15430                     getSettingsNameForDeviceVolumeBehavior(deviceType),
15431                     deviceVolumeBehavior,
15432                     UserHandle.USER_CURRENT);
15433         } finally {
15434             Binder.restoreCallingIdentity(callingIdentity);
15435         }
15436     }
15437 
15438     @AudioDeviceVolumeManager.DeviceVolumeBehaviorState
retrieveStoredDeviceVolumeBehavior(int deviceType)15439     private int retrieveStoredDeviceVolumeBehavior(int deviceType) {
15440         return mSettings.getSystemIntForUser(mContentResolver,
15441                 getSettingsNameForDeviceVolumeBehavior(deviceType),
15442                 AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET,
15443                 UserHandle.USER_CURRENT);
15444     }
15445 
restoreDeviceVolumeBehavior()15446     private void restoreDeviceVolumeBehavior() {
15447         for (int deviceType : AudioSystem.DEVICE_OUT_ALL_SET) {
15448             if (DEBUG_VOL) {
15449                 Log.d(TAG, "Retrieving Volume Behavior for DeviceType: " + deviceType);
15450             }
15451             int deviceVolumeBehavior = retrieveStoredDeviceVolumeBehavior(deviceType);
15452             if (deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET) {
15453                 if (DEBUG_VOL) {
15454                     Log.d(TAG, "Skipping Setting Volume Behavior for DeviceType: " + deviceType);
15455                 }
15456                 continue;
15457             }
15458 
15459             setDeviceVolumeBehaviorInternal(new AudioDeviceAttributes(deviceType, ""),
15460                     deviceVolumeBehavior, "AudioService.restoreDeviceVolumeBehavior()");
15461         }
15462     }
15463 
15464     /**
15465      * @param audioSystemDeviceOut one of AudioSystem.DEVICE_OUT_*
15466      * @return whether {@code audioSystemDeviceOut} has previously been set to a specific volume
15467      * behavior
15468      */
hasDeviceVolumeBehavior( int audioSystemDeviceOut)15469     private boolean hasDeviceVolumeBehavior(
15470             int audioSystemDeviceOut) {
15471         return retrieveStoredDeviceVolumeBehavior(audioSystemDeviceOut)
15472                 != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET;
15473     }
15474 
addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut)15475     private boolean addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut) {
15476         if (DEBUG_VOL) {
15477             Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
15478                     + " to mFixedVolumeDevices");
15479         }
15480         return mFixedVolumeDevices.add(audioSystemDeviceOut);
15481     }
15482 
removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut)15483     private boolean removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut) {
15484         if (DEBUG_VOL) {
15485             Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
15486                     + " from mFixedVolumeDevices");
15487         }
15488         return mFixedVolumeDevices.remove(audioSystemDeviceOut);
15489     }
15490 
addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut)15491     private boolean addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut) {
15492         if (DEBUG_VOL) {
15493             Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
15494                     + " to mFullVolumeDevices");
15495         }
15496         return mFullVolumeDevices.add(audioSystemDeviceOut);
15497     }
15498 
removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut)15499     private boolean removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut) {
15500         if (DEBUG_VOL) {
15501             Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
15502                     + " from mFullVolumeDevices");
15503         }
15504         return mFullVolumeDevices.remove(audioSystemDeviceOut);
15505     }
15506 
addAudioSystemDeviceOutToAbsVolumeDevices(int audioSystemDeviceOut, AbsoluteVolumeDeviceInfo info)15507     private void addAudioSystemDeviceOutToAbsVolumeDevices(int audioSystemDeviceOut,
15508             AbsoluteVolumeDeviceInfo info) {
15509         if (info == null) {
15510             Log.e(TAG, "Cannot add null absolute volume info for audioSystemDeviceOut "
15511                     + audioSystemDeviceOut);
15512             return;
15513         }
15514         if (DEBUG_VOL) {
15515             Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
15516                     + " to mAbsoluteVolumeDeviceInfoMap with behavior "
15517                     + AudioDeviceVolumeManager.volumeBehaviorName(info.mDeviceVolumeBehavior)
15518             );
15519         }
15520         synchronized (mAbsoluteVolumeDeviceInfoMapLock) {
15521             mAbsoluteVolumeDeviceInfoMap.put(audioSystemDeviceOut, info);
15522         }
15523     }
15524 
removeAudioSystemDeviceOutFromAbsVolumeDevices( int audioSystemDeviceOut)15525     private AbsoluteVolumeDeviceInfo removeAudioSystemDeviceOutFromAbsVolumeDevices(
15526             int audioSystemDeviceOut) {
15527         if (DEBUG_VOL) {
15528             Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
15529                     + " from mAbsoluteVolumeDeviceInfoMap");
15530         }
15531 
15532         synchronized (mAbsoluteVolumeDeviceInfoMapLock) {
15533             return mAbsoluteVolumeDeviceInfoMap.remove(audioSystemDeviceOut);
15534         }
15535     }
15536 
getAudioPermissionsDelay()15537     private long getAudioPermissionsDelay() {
15538         return isAudioPermissionUpdatesAddtionallyDelayed()
15539                 ? SCHEDULED_PERMISSION_UPDATE_LONG_DELAY_MS
15540                 : SCHEDULED_PERMISSION_UPDATE_DELAY_MS;
15541     }
15542 
isAudioPermissionUpdatesAddtionallyDelayed()15543     private boolean isAudioPermissionUpdatesAddtionallyDelayed() {
15544         //  Additional delays on low core devices in order to optimize app launch latencies
15545         return deferWearPermissionUpdates()
15546             && mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
15547     }
15548 
15549     //====================
15550     // Helper functions for app ops
15551     //====================
15552     /**
15553      * Validates, and notes an app op for a given uid and package name.
15554      * Validation comes from exception catching: a security exception indicates the package
15555      * doesn't exist, an IAE indicates the uid and package don't match. The code only checks
15556      * if exception was thrown for robustness to code changes in op validation
15557      * @param op the app op to check
15558      * @param uid the uid of the caller
15559      * @param packageName the package to check
15560      * @return true if the origin of the call is valid (no uid / package mismatch) and the caller
15561      *      is allowed to perform the operation
15562      */
checkNoteAppOp(int op, int uid, String packageName, String attributionTag)15563     private boolean checkNoteAppOp(int op, int uid, String packageName, String attributionTag) {
15564         try {
15565             if (mAppOps.noteOp(op, uid, packageName, attributionTag, null)
15566                     != AppOpsManager.MODE_ALLOWED) {
15567                 return false;
15568             }
15569         } catch (Exception e) {
15570             Log.e(TAG, "Error noting op:" + op + " on uid:" + uid + " for package:"
15571                     + packageName, e);
15572             return false;
15573         }
15574         return true;
15575     }
15576 
getPackageNameForUid(int uid)15577     private String getPackageNameForUid(int uid) {
15578         final long token = Binder.clearCallingIdentity();
15579         try {
15580             final String[] names = AudioService.this.mContext.
15581                                         getPackageManager().getPackagesForUid(uid);
15582             if (names == null
15583                     || names.length == 0
15584                     || TextUtils.isEmpty(names[0])) {
15585                 return "[" + uid + "]";
15586             }
15587             return names[0];
15588         } finally {
15589             Binder.restoreCallingIdentity(token);
15590         }
15591     }
15592 
15593 
15594 }
15595