• 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.MODIFY_AUDIO_SETTINGS_PRIVILEGED;
20 import static android.Manifest.permission.REMOTE_AUDIO_PLAYBACK;
21 import static android.app.BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT;
22 import static android.media.AudioDeviceInfo.TYPE_BLE_HEADSET;
23 import static android.media.AudioDeviceInfo.TYPE_BLE_SPEAKER;
24 import static android.media.AudioDeviceInfo.TYPE_BLUETOOTH_A2DP;
25 import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_HEADPHONES;
26 import static android.media.AudioManager.AUDIO_DEVICE_CATEGORY_UNKNOWN;
27 import static android.media.AudioManager.DEVICE_OUT_BLE_HEADSET;
28 import static android.media.AudioManager.DEVICE_OUT_BLE_SPEAKER;
29 import static android.media.AudioManager.DEVICE_OUT_BLUETOOTH_A2DP;
30 import static android.media.AudioManager.RINGER_MODE_NORMAL;
31 import static android.media.AudioManager.RINGER_MODE_SILENT;
32 import static android.media.AudioManager.RINGER_MODE_VIBRATE;
33 import static android.media.AudioManager.STREAM_MUSIC;
34 import static android.media.AudioManager.STREAM_SYSTEM;
35 import static android.os.Process.FIRST_APPLICATION_UID;
36 import static android.os.Process.INVALID_UID;
37 import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE;
38 import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
39 import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE;
40 
41 import static com.android.server.audio.SoundDoseHelper.ACTION_CHECK_MUSIC_ACTIVE;
42 import static com.android.server.utils.EventLogger.Event.ALOGE;
43 import static com.android.server.utils.EventLogger.Event.ALOGI;
44 import static com.android.server.utils.EventLogger.Event.ALOGW;
45 
46 import android.Manifest;
47 import android.annotation.IntDef;
48 import android.annotation.IntRange;
49 import android.annotation.NonNull;
50 import android.annotation.Nullable;
51 import android.annotation.RequiresPermission;
52 import android.annotation.SuppressLint;
53 import android.annotation.UserIdInt;
54 import android.app.ActivityManager;
55 import android.app.ActivityManagerInternal;
56 import android.app.AppGlobals;
57 import android.app.AppOpsManager;
58 import android.app.BroadcastOptions;
59 import android.app.IUidObserver;
60 import android.app.NotificationManager;
61 import android.app.UidObserver;
62 import android.app.role.OnRoleHoldersChangedListener;
63 import android.app.role.RoleManager;
64 import android.bluetooth.BluetoothDevice;
65 import android.bluetooth.BluetoothHeadset;
66 import android.bluetooth.BluetoothProfile;
67 import android.content.BroadcastReceiver;
68 import android.content.ComponentName;
69 import android.content.ContentResolver;
70 import android.content.Context;
71 import android.content.Intent;
72 import android.content.IntentFilter;
73 import android.content.pm.ApplicationInfo;
74 import android.content.pm.PackageInfo;
75 import android.content.pm.PackageManager;
76 import android.content.pm.ResolveInfo;
77 import android.content.pm.UserInfo;
78 import android.content.res.Configuration;
79 import android.content.res.Resources;
80 import android.database.ContentObserver;
81 import android.hardware.SensorPrivacyManager;
82 import android.hardware.SensorPrivacyManagerInternal;
83 import android.hardware.hdmi.HdmiAudioSystemClient;
84 import android.hardware.hdmi.HdmiClient;
85 import android.hardware.hdmi.HdmiControlManager;
86 import android.hardware.hdmi.HdmiPlaybackClient;
87 import android.hardware.hdmi.HdmiTvClient;
88 import android.hardware.input.InputManager;
89 import android.hardware.usb.UsbManager;
90 import android.hidl.manager.V1_0.IServiceManager;
91 import android.media.AudioAttributes;
92 import android.media.AudioAttributes.AttributeSystemUsage;
93 import android.media.AudioDeviceAttributes;
94 import android.media.AudioDeviceInfo;
95 import android.media.AudioDeviceVolumeManager;
96 import android.media.AudioFocusInfo;
97 import android.media.AudioFocusRequest;
98 import android.media.AudioFormat;
99 import android.media.AudioHalVersionInfo;
100 import android.media.AudioManager;
101 import android.media.AudioManager.AudioDeviceCategory;
102 import android.media.AudioManagerInternal;
103 import android.media.AudioMixerAttributes;
104 import android.media.AudioPlaybackConfiguration;
105 import android.media.AudioRecordingConfiguration;
106 import android.media.AudioRoutesInfo;
107 import android.media.AudioSystem;
108 import android.media.BluetoothProfileConnectionInfo;
109 import android.media.IAudioDeviceVolumeDispatcher;
110 import android.media.IAudioFocusDispatcher;
111 import android.media.IAudioModeDispatcher;
112 import android.media.IAudioRoutesObserver;
113 import android.media.IAudioServerStateDispatcher;
114 import android.media.IAudioService;
115 import android.media.ICapturePresetDevicesRoleDispatcher;
116 import android.media.ICommunicationDeviceDispatcher;
117 import android.media.IDeviceVolumeBehaviorDispatcher;
118 import android.media.IDevicesForAttributesCallback;
119 import android.media.IMuteAwaitConnectionCallback;
120 import android.media.IPlaybackConfigDispatcher;
121 import android.media.IPreferredMixerAttributesDispatcher;
122 import android.media.IRecordingConfigDispatcher;
123 import android.media.IRingtonePlayer;
124 import android.media.ISpatializerCallback;
125 import android.media.ISpatializerHeadToSoundStagePoseCallback;
126 import android.media.ISpatializerHeadTrackerAvailableCallback;
127 import android.media.ISpatializerHeadTrackingModeCallback;
128 import android.media.ISpatializerOutputCallback;
129 import android.media.IStrategyNonDefaultDevicesDispatcher;
130 import android.media.IStrategyPreferredDevicesDispatcher;
131 import android.media.IStreamAliasingDispatcher;
132 import android.media.IVolumeController;
133 import android.media.MediaMetrics;
134 import android.media.MediaRecorder.AudioSource;
135 import android.media.PlayerBase;
136 import android.media.Spatializer;
137 import android.media.VolumeInfo;
138 import android.media.VolumePolicy;
139 import android.media.audiofx.AudioEffect;
140 import android.media.audiopolicy.AudioMix;
141 import android.media.audiopolicy.AudioPolicy;
142 import android.media.audiopolicy.AudioPolicyConfig;
143 import android.media.audiopolicy.AudioProductStrategy;
144 import android.media.audiopolicy.AudioVolumeGroup;
145 import android.media.audiopolicy.IAudioPolicyCallback;
146 import android.media.permission.ClearCallingIdentityContext;
147 import android.media.permission.SafeCloseable;
148 import android.media.projection.IMediaProjection;
149 import android.media.projection.IMediaProjectionCallback;
150 import android.media.projection.IMediaProjectionManager;
151 import android.net.Uri;
152 import android.os.Binder;
153 import android.os.Build;
154 import android.os.Bundle;
155 import android.os.Handler;
156 import android.os.HwBinder;
157 import android.os.IBinder;
158 import android.os.Looper;
159 import android.os.Message;
160 import android.os.PermissionEnforcer;
161 import android.os.PersistableBundle;
162 import android.os.PowerManager;
163 import android.os.Process;
164 import android.os.RemoteCallbackList;
165 import android.os.RemoteException;
166 import android.os.ResultReceiver;
167 import android.os.ServiceDebugInfo;
168 import android.os.ServiceManager;
169 import android.os.ShellCallback;
170 import android.os.SystemClock;
171 import android.os.SystemProperties;
172 import android.os.UserHandle;
173 import android.os.UserManager;
174 import android.os.VibrationAttributes;
175 import android.os.VibrationEffect;
176 import android.os.Vibrator;
177 import android.os.VibratorManager;
178 import android.provider.Settings;
179 import android.provider.Settings.System;
180 import android.service.notification.ZenModeConfig;
181 import android.telecom.TelecomManager;
182 import android.telephony.SubscriptionManager;
183 import android.text.TextUtils;
184 import android.util.AndroidRuntimeException;
185 import android.util.ArrayMap;
186 import android.util.ArraySet;
187 import android.util.IntArray;
188 import android.util.Log;
189 import android.util.PrintWriterPrinter;
190 import android.util.Slog;
191 import android.util.SparseArray;
192 import android.util.SparseIntArray;
193 import android.view.KeyEvent;
194 import android.view.accessibility.AccessibilityManager;
195 import android.widget.Toast;
196 
197 import com.android.internal.annotations.GuardedBy;
198 import com.android.internal.annotations.VisibleForTesting;
199 import com.android.internal.os.SomeArgs;
200 import com.android.internal.util.DumpUtils;
201 import com.android.internal.util.Preconditions;
202 import com.android.server.EventLogTags;
203 import com.android.server.LocalServices;
204 import com.android.server.SystemService;
205 import com.android.server.audio.AudioServiceEvents.DeviceVolumeEvent;
206 import com.android.server.audio.AudioServiceEvents.PhoneStateEvent;
207 import com.android.server.audio.AudioServiceEvents.VolChangedBroadcastEvent;
208 import com.android.server.audio.AudioServiceEvents.VolumeEvent;
209 import com.android.server.pm.UserManagerInternal;
210 import com.android.server.pm.UserManagerInternal.UserRestrictionsListener;
211 import com.android.server.pm.UserManagerService;
212 import com.android.server.utils.EventLogger;
213 import com.android.server.wm.ActivityTaskManagerInternal;
214 
215 import java.io.FileDescriptor;
216 import java.io.PrintWriter;
217 import java.lang.annotation.Retention;
218 import java.lang.annotation.RetentionPolicy;
219 import java.text.SimpleDateFormat;
220 import java.util.ArrayList;
221 import java.util.Arrays;
222 import java.util.Collection;
223 import java.util.Date;
224 import java.util.HashMap;
225 import java.util.HashSet;
226 import java.util.Iterator;
227 import java.util.LinkedHashMap;
228 import java.util.List;
229 import java.util.Map;
230 import java.util.NoSuchElementException;
231 import java.util.Objects;
232 import java.util.Set;
233 import java.util.TreeSet;
234 import java.util.UUID;
235 import java.util.concurrent.Executor;
236 import java.util.concurrent.atomic.AtomicBoolean;
237 import java.util.concurrent.atomic.AtomicInteger;
238 import java.util.function.BooleanSupplier;
239 import java.util.stream.Collectors;
240 
241 /**
242  * The implementation of the audio service for volume, audio focus, device management...
243  * <p>
244  * This implementation focuses on delivering a responsive UI. Most methods are
245  * asynchronous to external calls. For example, the task of setting a volume
246  * will update our internal state, but in a separate thread will set the system
247  * volume and later persist to the database. Similarly, setting the ringer mode
248  * will update the state and broadcast a change and in a separate thread later
249  * persist the ringer mode.
250  *
251  * @hide
252  */
253 public class AudioService extends IAudioService.Stub
254         implements AccessibilityManager.TouchExplorationStateChangeListener,
255             AccessibilityManager.AccessibilityServicesStateChangeListener,
256             AudioSystemAdapter.OnRoutingUpdatedListener,
257             AudioSystemAdapter.OnVolRangeInitRequestListener {
258 
259     private static final String TAG = "AS.AudioService";
260 
261     private final AudioSystemAdapter mAudioSystem;
262     private final SystemServerAdapter mSystemServer;
263     private final SettingsAdapter mSettings;
264     private final AudioPolicyFacade mAudioPolicy;
265 
266     /** Debug audio mode */
267     protected static final boolean DEBUG_MODE = false;
268 
269     /** Debug audio policy feature */
270     protected static final boolean DEBUG_AP = false;
271 
272     /** Debug volumes */
273     protected static final boolean DEBUG_VOL = false;
274 
275     /** debug calls to devices APIs */
276     protected static final boolean DEBUG_DEVICES = false;
277 
278     /** Debug communication route */
279     protected static final boolean DEBUG_COMM_RTE = false;
280 
281     /** Debug log sound fx (touchsounds...) in dumpsys */
282     protected static final boolean DEBUG_LOG_SOUND_FX = false;
283 
284     /** How long to delay before persisting a change in volume/ringer mode. */
285     private static final int PERSIST_DELAY = 500;
286 
287     /** How long to delay after a volume down event before unmuting a stream */
288     private static final int UNMUTE_STREAM_DELAY = 350;
289 
290     /**
291      * Delay before disconnecting a device that would cause BECOMING_NOISY intent to be sent,
292      * to give a chance to applications to pause.
293      */
294     @VisibleForTesting
295     public static final int BECOMING_NOISY_DELAY_MS = 1000;
296 
297     /**
298      * Only used in the result from {@link #checkForRingerModeChange(int, int, int)}
299      */
300     private static final int FLAG_ADJUST_VOLUME = 1;
301 
302     final Context mContext;
303     private final ContentResolver mContentResolver;
304     private final AppOpsManager mAppOps;
305 
306     // the platform type affects volume and silent mode behavior
307     private final int mPlatformType;
308 
309     // indicates whether the system maps all streams to a single stream.
310     private final boolean mIsSingleVolume;
311 
312     /**
313      * indicates whether STREAM_NOTIFICATION is aliased to STREAM_RING
314      *     not final due to test method, see {@link #setNotifAliasRingForTest(boolean)}.
315      */
316     private boolean mNotifAliasRing = false;
317 
318     /**
319      * Test method to temporarily override whether STREAM_NOTIFICATION is aliased to STREAM_RING,
320      * volumes will be updated in case of a change.
321      * @param alias if true, STREAM_NOTIFICATION is aliased to STREAM_RING
322      */
323     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setNotifAliasRingForTest(boolean alias)324     public void setNotifAliasRingForTest(boolean alias) {
325         super.setNotifAliasRingForTest_enforcePermission();
326         boolean update = (mNotifAliasRing != alias);
327         mNotifAliasRing = alias;
328         if (update) {
329             updateStreamVolumeAlias(true, "AudioServiceTest");
330         }
331     }
332 
isPlatformVoice()333     /*package*/ boolean isPlatformVoice() {
334         return mPlatformType == AudioSystem.PLATFORM_VOICE;
335     }
336 
isPlatformTelevision()337     /*package*/ boolean isPlatformTelevision() {
338         return mPlatformType == AudioSystem.PLATFORM_TELEVISION;
339     }
340 
isPlatformAutomotive()341     /*package*/ boolean isPlatformAutomotive() {
342         return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
343     }
344 
345     /** The controller for the volume UI. */
346     private final VolumeController mVolumeController = new VolumeController();
347 
348     // sendMsg() flags
349     /** If the msg is already queued, replace it with this one. */
350     private static final int SENDMSG_REPLACE = 0;
351     /** If the msg is already queued, ignore this one and leave the old. */
352     private static final int SENDMSG_NOOP = 1;
353     /** If the msg is already queued, queue this one and leave the old. */
354     private static final int SENDMSG_QUEUE = 2;
355 
356     // AudioHandler messages
357     /*package*/ static final int MSG_SET_DEVICE_VOLUME = 0;
358     private static final int MSG_PERSIST_VOLUME = 1;
359     private static final int MSG_PERSIST_VOLUME_GROUP = 2;
360     private static final int MSG_PERSIST_RINGER_MODE = 3;
361     private static final int MSG_AUDIO_SERVER_DIED = 4;
362     private static final int MSG_PLAY_SOUND_EFFECT = 5;
363     private static final int MSG_LOAD_SOUND_EFFECTS = 7;
364     private static final int MSG_SET_FORCE_USE = 8;
365     private static final int MSG_SET_ALL_VOLUMES = 10;
366     private static final int MSG_UNLOAD_SOUND_EFFECTS = 15;
367     private static final int MSG_SYSTEM_READY = 16;
368     private static final int MSG_UNMUTE_STREAM = 18;
369     private static final int MSG_DYN_POLICY_MIX_STATE_UPDATE = 19;
370     private static final int MSG_INDICATE_SYSTEM_READY = 20;
371     private static final int MSG_ACCESSORY_PLUG_MEDIA_UNMUTE = 21;
372     private static final int MSG_NOTIFY_VOL_EVENT = 22;
373     private static final int MSG_DISPATCH_AUDIO_SERVER_STATE = 23;
374     private static final int MSG_ENABLE_SURROUND_FORMATS = 24;
375     private static final int MSG_UPDATE_RINGER_MODE = 25;
376     private static final int MSG_SET_DEVICE_STREAM_VOLUME = 26;
377     private static final int MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS = 27;
378     private static final int MSG_HDMI_VOLUME_CHECK = 28;
379     private static final int MSG_PLAYBACK_CONFIG_CHANGE = 29;
380     private static final int MSG_BROADCAST_MICROPHONE_MUTE = 30;
381     private static final int MSG_CHECK_MODE_FOR_UID = 31;
382     private static final int MSG_STREAM_DEVICES_CHANGED = 32;
383     private static final int MSG_UPDATE_VOLUME_STATES_FOR_DEVICE = 33;
384     private static final int MSG_REINIT_VOLUMES = 34;
385     private static final int MSG_UPDATE_A11Y_SERVICE_UIDS = 35;
386     private static final int MSG_UPDATE_AUDIO_MODE = 36;
387     private static final int MSG_RECORDING_CONFIG_CHANGE = 37;
388     private static final int MSG_BT_DEV_CHANGED = 38;
389 
390     private static final int MSG_DISPATCH_AUDIO_MODE = 40;
391     private static final int MSG_ROUTING_UPDATED = 41;
392     private static final int MSG_INIT_HEADTRACKING_SENSORS = 42;
393     private static final int MSG_ADD_ASSISTANT_SERVICE_UID = 44;
394     private static final int MSG_REMOVE_ASSISTANT_SERVICE_UID = 45;
395     private static final int MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID = 46;
396     private static final int MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR = 47;
397     private static final int MSG_ROTATION_UPDATE = 48;
398     private static final int MSG_FOLD_UPDATE = 49;
399     private static final int MSG_RESET_SPATIALIZER = 50;
400     private static final int MSG_NO_LOG_FOR_PLAYER_I = 51;
401     private static final int MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES = 52;
402     private static final int MSG_LOWER_VOLUME_TO_RS1 = 53;
403     private static final int MSG_CONFIGURATION_CHANGED = 54;
404 
405     /** Messages handled by the {@link SoundDoseHelper}. */
406     /*package*/ static final int SAFE_MEDIA_VOLUME_MSG_START = 1000;
407 
408     // start of messages handled under wakelock
409     //   these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
410     //   and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
411     private static final int MSG_DISABLE_AUDIO_FOR_UID = 100;
412     private static final int MSG_INIT_STREAMS_VOLUMES = 101;
413     private static final int MSG_INIT_SPATIALIZER = 102;
414     private static final int MSG_INIT_ADI_DEVICE_STATES = 103;
415 
416     // end of messages handled under wakelock
417 
418     // retry delay in case of failure to indicate system ready to AudioFlinger
419     private static final int INDICATE_SYSTEM_READY_RETRY_DELAY_MS = 1000;
420 
421     // List of empty UIDs used to reset the active assistant list
422     private static final int[] NO_ACTIVE_ASSISTANT_SERVICE_UIDS = new int[0];
423 
424     // check playback or record activity every 6 seconds for UIDs owning mode IN_COMMUNICATION
425     private static final int CHECK_MODE_FOR_UID_PERIOD_MS = 6000;
426 
427     /** @see AudioSystemThread */
428     private AudioSystemThread mAudioSystemThread;
429     /** @see AudioHandler */
430     private AudioHandler mAudioHandler;
431     /** @see VolumeStreamState */
432     private VolumeStreamState[] mStreamStates;
433 
getVssVolumeForDevice(int stream, int device)434     /*package*/ int getVssVolumeForDevice(int stream, int device) {
435         return mStreamStates[stream].getIndex(device);
436     }
437 
getVssVolumeForStream(int stream)438     /*package*/ VolumeStreamState getVssVolumeForStream(int stream) {
439         return mStreamStates[stream];
440     }
441 
getMaxVssVolumeForStream(int stream)442     /*package*/ int getMaxVssVolumeForStream(int stream) {
443         return mStreamStates[stream].getMaxIndex();
444     }
445 
446     private SettingsObserver mSettingsObserver;
447 
448     private AtomicInteger mMode = new AtomicInteger(AudioSystem.MODE_NORMAL);
449 
450     // protects mRingerMode
451     private final Object mSettingsLock = new Object();
452 
453    /** Maximum volume index values for audio streams */
454     protected static int[] MAX_STREAM_VOLUME = new int[] {
455         5,  // STREAM_VOICE_CALL
456         7,  // STREAM_SYSTEM
457         7,  // STREAM_RING            // configured by config_audio_ring_vol_steps
458         15, // STREAM_MUSIC
459         7,  // STREAM_ALARM
460         7,  // STREAM_NOTIFICATION    // configured by config_audio_notif_vol_steps
461         15, // STREAM_BLUETOOTH_SCO
462         7,  // STREAM_SYSTEM_ENFORCED
463         15, // STREAM_DTMF
464         15, // STREAM_TTS
465         15, // STREAM_ACCESSIBILITY
466         15  // STREAM_ASSISTANT
467     };
468 
469     /** Minimum volume index values for audio streams */
470     protected static int[] MIN_STREAM_VOLUME = new int[] {
471         1,  // STREAM_VOICE_CALL
472         0,  // STREAM_SYSTEM
473         0,  // STREAM_RING
474         0,  // STREAM_MUSIC
475         1,  // STREAM_ALARM
476         0,  // STREAM_NOTIFICATION
477         0,  // STREAM_BLUETOOTH_SCO
478         0,  // STREAM_SYSTEM_ENFORCED
479         0,  // STREAM_DTMF
480         0,  // STREAM_TTS
481         1,  // STREAM_ACCESSIBILITY
482         0   // STREAM_ASSISTANT
483     };
484 
485     /* mStreamVolumeAlias[] indicates for each stream if it uses the volume settings
486      * of another stream: This avoids multiplying the volume settings for hidden
487      * stream types that follow other stream behavior for volume settings
488      * NOTE: do not create loops in aliases!
489      * Some streams alias to different streams according to device category (phone or tablet) or
490      * use case (in call vs off call...). See updateStreamVolumeAlias() for more details.
491      *  mStreamVolumeAlias contains STREAM_VOLUME_ALIAS_VOICE aliases for a voice capable device
492      *  (phone), STREAM_VOLUME_ALIAS_TELEVISION for a television or set-top box and
493      *  STREAM_VOLUME_ALIAS_DEFAULT for other devices (e.g. tablets).*/
494     private final int[] STREAM_VOLUME_ALIAS_VOICE = new int[] {
495         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
496         AudioSystem.STREAM_RING,            // STREAM_SYSTEM
497         AudioSystem.STREAM_RING,            // STREAM_RING
498         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
499         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
500         AudioSystem.STREAM_RING,            // STREAM_NOTIFICATION
501         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
502         AudioSystem.STREAM_RING,            // STREAM_SYSTEM_ENFORCED
503         AudioSystem.STREAM_RING,            // STREAM_DTMF
504         AudioSystem.STREAM_MUSIC,           // STREAM_TTS
505         AudioSystem.STREAM_MUSIC,           // STREAM_ACCESSIBILITY
506         AudioSystem.STREAM_MUSIC            // STREAM_ASSISTANT
507     };
508     private final int[] STREAM_VOLUME_ALIAS_TELEVISION = new int[] {
509         AudioSystem.STREAM_MUSIC,       // STREAM_VOICE_CALL
510         AudioSystem.STREAM_MUSIC,       // STREAM_SYSTEM
511         AudioSystem.STREAM_MUSIC,       // STREAM_RING
512         AudioSystem.STREAM_MUSIC,       // STREAM_MUSIC
513         AudioSystem.STREAM_MUSIC,       // STREAM_ALARM
514         AudioSystem.STREAM_MUSIC,       // STREAM_NOTIFICATION
515         AudioSystem.STREAM_BLUETOOTH_SCO,       // STREAM_BLUETOOTH_SCO
516         AudioSystem.STREAM_MUSIC,       // STREAM_SYSTEM_ENFORCED
517         AudioSystem.STREAM_MUSIC,       // STREAM_DTMF
518         AudioSystem.STREAM_MUSIC,       // STREAM_TTS
519         AudioSystem.STREAM_MUSIC,       // STREAM_ACCESSIBILITY
520         AudioSystem.STREAM_MUSIC        // STREAM_ASSISTANT
521     };
522     /**
523      * Using Volume groups configuration allows to control volume per attributes
524      * and group definition may differ from stream aliases.
525      * So, do not alias any stream on one another when using volume groups.
526      * TODO(b/181140246): volume group definition hosting alias definition.
527      */
528     private final int[] STREAM_VOLUME_ALIAS_NONE = new int[] {
529         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
530         AudioSystem.STREAM_SYSTEM,          // STREAM_SYSTEM
531         AudioSystem.STREAM_RING,            // STREAM_RING
532         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
533         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
534         AudioSystem.STREAM_NOTIFICATION,    // STREAM_NOTIFICATION
535         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
536         AudioSystem.STREAM_SYSTEM_ENFORCED, // STREAM_SYSTEM_ENFORCED
537         AudioSystem.STREAM_DTMF,            // STREAM_DTMF
538         AudioSystem.STREAM_TTS,             // STREAM_TTS
539         AudioSystem.STREAM_ACCESSIBILITY,   // STREAM_ACCESSIBILITY
540         AudioSystem.STREAM_ASSISTANT        // STREAM_ASSISTANT
541     };
542     private final int[] STREAM_VOLUME_ALIAS_DEFAULT = new int[] {
543         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
544         AudioSystem.STREAM_RING,            // STREAM_SYSTEM
545         AudioSystem.STREAM_RING,            // STREAM_RING
546         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
547         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
548         AudioSystem.STREAM_RING,            // STREAM_NOTIFICATION
549         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
550         AudioSystem.STREAM_RING,            // STREAM_SYSTEM_ENFORCED
551         AudioSystem.STREAM_RING,            // STREAM_DTMF
552         AudioSystem.STREAM_MUSIC,           // STREAM_TTS
553         AudioSystem.STREAM_MUSIC,           // STREAM_ACCESSIBILITY
554         AudioSystem.STREAM_MUSIC            // STREAM_ASSISTANT
555     };
556     protected static int[] mStreamVolumeAlias;
557     private static final int UNSET_INDEX = -1;
558 
559     /**
560      * Map AudioSystem.STREAM_* constants to app ops.  This should be used
561      * after mapping through mStreamVolumeAlias.
562      */
563     private static final int[] STREAM_VOLUME_OPS = new int[] {
564         AppOpsManager.OP_AUDIO_VOICE_VOLUME,            // STREAM_VOICE_CALL
565         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_SYSTEM
566         AppOpsManager.OP_AUDIO_RING_VOLUME,             // STREAM_RING
567         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_MUSIC
568         AppOpsManager.OP_AUDIO_ALARM_VOLUME,            // STREAM_ALARM
569         AppOpsManager.OP_AUDIO_NOTIFICATION_VOLUME,     // STREAM_NOTIFICATION
570         AppOpsManager.OP_AUDIO_BLUETOOTH_VOLUME,        // STREAM_BLUETOOTH_SCO
571         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_SYSTEM_ENFORCED
572         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_DTMF
573         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_TTS
574         AppOpsManager.OP_AUDIO_ACCESSIBILITY_VOLUME,    // STREAM_ACCESSIBILITY
575         AppOpsManager.OP_AUDIO_MEDIA_VOLUME             // STREAM_ASSISTANT
576     };
577 
578     private final boolean mUseFixedVolume;
579     private final boolean mUseVolumeGroupAliases;
580 
581     // If absolute volume is supported in AVRCP device
582     private volatile boolean mAvrcpAbsVolSupported = false;
583 
584     /**
585     * Default stream type used for volume control in the absence of playback
586     * e.g. user on homescreen, no app playing anything, presses hardware volume buttons, this
587     *    stream type is controlled.
588     */
589     protected static final int DEFAULT_VOL_STREAM_NO_PLAYBACK = AudioSystem.STREAM_MUSIC;
590 
591     private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() {
592         public void onError(int error) {
593             switch (error) {
594                 case AudioSystem.AUDIO_STATUS_SERVER_DIED:
595                     // check for null in case error callback is called during instance creation
596                     if (mRecordMonitor != null) {
597                         mRecordMonitor.onAudioServerDied();
598                     }
599                     // Notify the playback monitor that the audio server has died
600                     if (mPlaybackMonitor != null) {
601                         mPlaybackMonitor.onAudioServerDied();
602                     }
603                     sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED,
604                             SENDMSG_NOOP, 0, 0, null, 0);
605                     sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE,
606                             SENDMSG_QUEUE, 0, 0, null, 0);
607                     break;
608                 default:
609                     break;
610             }
611         }
612     };
613 
614     /**
615      * Current ringer mode from one of {@link AudioManager#RINGER_MODE_NORMAL},
616      * {@link AudioManager#RINGER_MODE_SILENT}, or
617      * {@link AudioManager#RINGER_MODE_VIBRATE}.
618      */
619     @GuardedBy("mSettingsLock")
620     private int mRingerMode;  // internal ringer mode, affects muting of underlying streams
621     @GuardedBy("mSettingsLock")
622     private int mRingerModeExternal = -1;  // reported ringer mode to outside clients (AudioManager)
623 
624     /** @see System#MODE_RINGER_STREAMS_AFFECTED */
625     private int mRingerModeAffectedStreams = 0;
626 
627     private int mZenModeAffectedStreams = 0;
628 
629     // Streams currently muted by ringer mode and dnd
630     protected static volatile int sRingerAndZenModeMutedStreams;
631 
632     /** Streams that can be muted. Do not resolve to aliases when checking.
633      * @see System#MUTE_STREAMS_AFFECTED */
634     private int mMuteAffectedStreams;
635 
636     @NonNull
637     private SoundEffectsHelper mSfxHelper;
638 
639     /**
640      * NOTE: setVibrateSetting(), getVibrateSetting(), shouldVibrate() are deprecated.
641      * mVibrateSetting is just maintained during deprecation period but vibration policy is
642      * now only controlled by mHasVibrator and mRingerMode
643      */
644     private int mVibrateSetting;
645 
646     // Is there a vibrator
647     private final boolean mHasVibrator;
648     // Used to play vibrations
649     private Vibrator mVibrator;
650     private static final VibrationAttributes TOUCH_VIBRATION_ATTRIBUTES =
651             VibrationAttributes.createForUsage(VibrationAttributes.USAGE_TOUCH);
652 
653     // Broadcast receiver for device connections intent broadcasts
654     private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver();
655 
656     private IMediaProjectionManager mProjectionService; // to validate projection token
657 
658     /** Interface for UserManagerService. */
659     private final UserManagerInternal mUserManagerInternal;
660     private final ActivityManagerInternal mActivityManagerInternal;
661     private final SensorPrivacyManagerInternal mSensorPrivacyManagerInternal;
662 
663     private final UserRestrictionsListener mUserRestrictionsListener =
664             new AudioServiceUserRestrictionsListener();
665 
666     // List of binder death handlers for setMode() client processes.
667     // The last process to have called setMode() is at the top of the list.
668     // package-private so it can be accessed in AudioDeviceBroker.getSetModeDeathHandlers
669     //TODO candidate to be moved to separate class that handles synchronization
670     @GuardedBy("mDeviceBroker.mSetModeLock")
671     /*package*/ final ArrayList<SetModeDeathHandler> mSetModeDeathHandlers =
672             new ArrayList<SetModeDeathHandler>();
673 
674     // true if boot sequence has been completed
675     private boolean mSystemReady;
676     // true if Intent.ACTION_USER_SWITCHED has ever been received
677     private boolean mUserSwitchedReceived;
678     // previous volume adjustment direction received by checkForRingerModeChange()
679     private int mPrevVolDirection = AudioManager.ADJUST_SAME;
680     // mVolumeControlStream is set by VolumePanel to temporarily force the stream type which volume
681     // is controlled by Vol keys.
682     private int mVolumeControlStream = -1;
683     // interpretation of whether the volume stream has been selected by the user by clicking on a
684     // volume slider to change which volume is controlled by the volume keys. Is false
685     // when mVolumeControlStream is -1.
686     private boolean mUserSelectedVolumeControlStream = false;
687     private final Object mForceControlStreamLock = new Object();
688     // VolumePanel is currently the only client of forceVolumeControlStream() and runs in system
689     // server process so in theory it is not necessary to monitor the client death.
690     // However it is good to be ready for future evolutions.
691     private ForceControlStreamClient mForceControlStreamClient = null;
692     // Used to play ringtones outside system_server
693     private volatile IRingtonePlayer mRingtonePlayer;
694 
695     // Devices for which the volume is fixed (volume is either max or muted)
696     Set<Integer> mFixedVolumeDevices = new HashSet<>(Arrays.asList(
697             AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET,
698             AudioSystem.DEVICE_OUT_AUX_LINE));
699     // Devices for which the volume is always max, no volume panel
700     Set<Integer> mFullVolumeDevices = new HashSet<>(Arrays.asList(
701             AudioSystem.DEVICE_OUT_HDMI_ARC,
702             AudioSystem.DEVICE_OUT_HDMI_EARC
703     ));
704 
705     // Devices where the framework sends a full scale audio signal, and controls the volume of
706     // the external audio system separately.
707     // For possible volume behaviors, see {@link AudioManager.AbsoluteDeviceVolumeBehavior}.
708     Map<Integer, AbsoluteVolumeDeviceInfo> mAbsoluteVolumeDeviceInfoMap = new ArrayMap<>();
709 
710     /**
711      * Stores information about a device using absolute volume behavior.
712      */
713     private static final class AbsoluteVolumeDeviceInfo {
714         private final AudioDeviceAttributes mDevice;
715         private final List<VolumeInfo> mVolumeInfos;
716         private final IAudioDeviceVolumeDispatcher mCallback;
717         private final boolean mHandlesVolumeAdjustment;
718         private @AudioManager.AbsoluteDeviceVolumeBehavior int mDeviceVolumeBehavior;
719 
AbsoluteVolumeDeviceInfo( AudioDeviceAttributes device, List<VolumeInfo> volumeInfos, IAudioDeviceVolumeDispatcher callback, boolean handlesVolumeAdjustment, @AudioManager.AbsoluteDeviceVolumeBehavior int behavior)720         private AbsoluteVolumeDeviceInfo(
721                 AudioDeviceAttributes device,
722                 List<VolumeInfo> volumeInfos,
723                 IAudioDeviceVolumeDispatcher callback,
724                 boolean handlesVolumeAdjustment,
725                 @AudioManager.AbsoluteDeviceVolumeBehavior int behavior) {
726             this.mDevice = device;
727             this.mVolumeInfos = volumeInfos;
728             this.mCallback = callback;
729             this.mHandlesVolumeAdjustment = handlesVolumeAdjustment;
730             this.mDeviceVolumeBehavior = behavior;
731         }
732 
733         /**
734          * Given a stream type, returns a matching VolumeInfo.
735          */
736         @Nullable
getMatchingVolumeInfoForStream(int streamType)737         private VolumeInfo getMatchingVolumeInfoForStream(int streamType) {
738             for (VolumeInfo volumeInfo : mVolumeInfos) {
739                 boolean streamTypeMatches = volumeInfo.hasStreamType()
740                         && volumeInfo.getStreamType() == streamType;
741                 boolean volumeGroupMatches = volumeInfo.hasVolumeGroup()
742                         && Arrays.stream(volumeInfo.getVolumeGroup().getLegacyStreamTypes())
743                         .anyMatch(s -> s == streamType);
744                 if (streamTypeMatches || volumeGroupMatches) {
745                     return volumeInfo;
746                 }
747             }
748             return null;
749         }
750     }
751 
752     // Devices for the which use the "absolute volume" concept (framework sends audio signal
753     // full scale, and volume control separately) and can be used for multiple use cases reflected
754     // by the audio mode (e.g. media playback in MODE_NORMAL, and phone calls in MODE_IN_CALL).
755     Set<Integer> mAbsVolumeMultiModeCaseDevices = new HashSet<>(
756             Arrays.asList(AudioSystem.DEVICE_OUT_HEARING_AID));
757 
758     private final boolean mMonitorRotation;
759 
760     private boolean mDockAudioMediaEnabled = true;
761 
762     /**
763      * RestorableParameters is a thread-safe class used to store a
764      * first-in first-out history of parameters for replay / restoration.
765      *
766      * The idealized implementation of restoration would have a list of setting methods and
767      * values to be called for restoration.  Explicitly managing such setters and
768      * values would be tedious - a simpler method is to store the values and the
769      * method implicitly by lambda capture (the values must be immutable or synchronization
770      * needs to be taken).
771      *
772      * We provide queueRestoreWithRemovalIfTrue() to allow
773      * the caller to provide a BooleanSupplier lambda, which conveniently packages
774      * the setter and its parameters needed for restoration.  If during restoration,
775      * the BooleanSupplier returns true, e.g. on error, it is removed from the mMap
776      * so as not to be called on a subsequent restore.
777      *
778      * We provide a setParameters() method as an example helper method.
779      */
780     private static class RestorableParameters {
781         /**
782          * Sets a parameter and queues for restoration if successful.
783          *
784          * @param id a string handle associated with this parameter.
785          * @param parameter the actual parameter string.
786          * @return the result of AudioSystem.setParameters
787          */
setParameters(@onNull String id, @NonNull String parameter)788         public int setParameters(@NonNull String id, @NonNull String parameter) {
789             Objects.requireNonNull(id, "id must not be null");
790             Objects.requireNonNull(parameter, "parameter must not be null");
791             synchronized (mMap) {
792                 final int status = AudioSystem.setParameters(parameter);
793                 if (status == AudioSystem.AUDIO_STATUS_OK) { // Java uses recursive mutexes.
794                     queueRestoreWithRemovalIfTrue(id, () -> { // remove me if set fails.
795                         return AudioSystem.setParameters(parameter) != AudioSystem.AUDIO_STATUS_OK;
796                     });
797                 }
798                 // Implementation detail: We do not mMap.remove(id); on failure.
799                 return status;
800             }
801         }
802 
803         /**
804          * Queues a restore method which is executed on restoreAll().
805          *
806          * If the supplier null, the id is removed from the restore map.
807          *
808          * Note: When the BooleanSupplier restore method is executed
809          * during restoreAll, if it returns true, it is removed from the
810          * restore map.
811          *
812          * @param id a unique tag associated with the restore method.
813          * @param supplier is a BooleanSupplier lambda.
814          */
queueRestoreWithRemovalIfTrue( @onNull String id, @Nullable BooleanSupplier supplier)815         public void queueRestoreWithRemovalIfTrue(
816                 @NonNull String id, @Nullable BooleanSupplier supplier) {
817             Objects.requireNonNull(id, "id must not be null");
818             synchronized (mMap) {
819                 if (supplier != null) {
820                     mMap.put(id, supplier);
821                 } else {
822                     mMap.remove(id);
823                 }
824             }
825         }
826 
827         /**
828          * Restore all parameters
829          *
830          * During restoration after audioserver death, any BooleanSupplier that returns
831          * true, for example on parameter restoration error, will be removed from mMap
832          * so as not to be executed on a subsequent restoreAll().
833          */
restoreAll()834         public void restoreAll() {
835             synchronized (mMap) {
836                 // Note: removing from values() also removes from the backing map.
837                 // TODO: Consider catching exceptions?
838                 mMap.values().removeIf(v -> {
839                     return v.getAsBoolean(); // this iterates the setters().
840                 });
841             }
842         }
843 
844         /**
845          * mMap is a LinkedHashMap<Key, Value> of parameters restored by restore().
846          * The Key is a unique id tag for identification.
847          * The Value is a lambda expression which returns true if the entry is to
848          *     be removed.
849          *
850          * 1) For memory limitation purposes, mMap keeps the latest MAX_ENTRIES
851          *    accessed in the map.
852          * 2) Parameters are restored in order of queuing, first in first out,
853          *    from earliest to latest.
854          */
855         @GuardedBy("mMap")
856         private Map</* @NonNull */ String, /* @NonNull */ BooleanSupplier> mMap =
857                 new LinkedHashMap<>() {
858             // TODO: do we need this memory limitation?
859             private static final int MAX_ENTRIES = 1000;  // limit our memory for now.
860             @Override
861             protected boolean removeEldestEntry(Map.Entry eldest) {
862                 if (size() <= MAX_ENTRIES) return false;
863                 Log.w(TAG, "Parameter map exceeds "
864                         + MAX_ENTRIES + " removing " + eldest.getKey()); // don't silently remove.
865                 return true;
866             }
867         };
868     }
869 
870     // We currently have one instance for mRestorableParameters used for
871     // setAdditionalOutputDeviceDelay().  Other methods requiring restoration could share this
872     // or use their own instance.
873     private RestorableParameters mRestorableParameters = new RestorableParameters();
874 
875     private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
876 
877     private PowerManager.WakeLock mAudioEventWakeLock;
878 
879     private final MediaFocusControl mMediaFocusControl;
880 
881     // Pre-scale for Bluetooth Absolute Volume
882     private float[] mPrescaleAbsoluteVolume = new float[] {
883         0.6f,    // Pre-scale for index 1
884         0.8f,    // Pre-scale for index 2
885         0.9f,   // Pre-scale for index 3
886     };
887 
888     private NotificationManager mNm;
889     private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate;
890     private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT;
891     private long mLoweredFromNormalToVibrateTime;
892 
893     // Array of Uids of valid assistant services to check if caller is one of them
894     @GuardedBy("mSettingsLock")
895     private final ArraySet<Integer> mAssistantUids = new ArraySet<>();
896     @GuardedBy("mSettingsLock")
897     private int mPrimaryAssistantUid = INVALID_UID;
898 
899     // Array of Uids of valid active assistant service to check if caller is one of them
900     @GuardedBy("mSettingsLock")
901     private int[] mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS;
902 
903     // Array of Uids of valid accessibility services to check if caller is one of them
904     private final Object mAccessibilityServiceUidsLock = new Object();
905     @GuardedBy("mAccessibilityServiceUidsLock")
906     private int[] mAccessibilityServiceUids;
907 
908     // Uid of the active input method service to check if caller is the one or not.
909     private int mInputMethodServiceUid = android.os.Process.INVALID_UID;
910     private final Object mInputMethodServiceUidLock = new Object();
911 
912     private int mEncodedSurroundMode;
913     private String mEnabledSurroundFormats;
914     private boolean mSurroundModeChanged;
915 
916     private boolean mSupportsMicPrivacyToggle;
917 
918     private boolean mMicMuteFromSwitch;
919     private boolean mMicMuteFromApi;
920     private boolean mMicMuteFromRestrictions;
921     private boolean mMicMuteFromPrivacyToggle;
922     // caches the value returned by AudioSystem.isMicrophoneMuted()
923     private boolean mMicMuteFromSystemCached;
924 
925     private boolean mNavigationRepeatSoundEffectsEnabled;
926     private boolean mHomeSoundEffectEnabled;
927 
928     private final SoundDoseHelper mSoundDoseHelper;
929 
930     private final Object mSupportedSystemUsagesLock = new Object();
931     @GuardedBy("mSupportedSystemUsagesLock")
932     private @AttributeSystemUsage int[] mSupportedSystemUsages =
933             new int[]{AudioAttributes.USAGE_CALL_ASSISTANT};
934 
935     // Defines the format for the connection "address" for ALSA devices
makeAlsaAddressString(int card, int device)936     public static String makeAlsaAddressString(int card, int device) {
937         return "card=" + card + ";device=" + device;
938     }
939 
940     public static final class Lifecycle extends SystemService {
941         private AudioService mService;
942 
Lifecycle(Context context)943         public Lifecycle(Context context) {
944             super(context);
945             mService = new AudioService(context,
946                               AudioSystemAdapter.getDefaultAdapter(),
947                               SystemServerAdapter.getDefaultAdapter(context),
948                               SettingsAdapter.getDefaultAdapter(),
949                               new DefaultAudioPolicyFacade(),
950                               null);
951 
952         }
953 
954         @Override
onStart()955         public void onStart() {
956             publishBinderService(Context.AUDIO_SERVICE, mService);
957         }
958 
959         @Override
onBootPhase(int phase)960         public void onBootPhase(int phase) {
961             if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
962                 mService.systemReady();
963             }
964         }
965     }
966 
967     final private IUidObserver mUidObserver = new UidObserver() {
968         @Override public void onUidGone(int uid, boolean disabled) {
969             // Once the uid is no longer running, no need to keep trying to disable its audio.
970             disableAudioForUid(false, uid);
971         }
972 
973         @Override public void onUidCachedChanged(int uid, boolean cached) {
974             disableAudioForUid(cached, uid);
975         }
976 
977         private void disableAudioForUid(boolean disable, int uid) {
978             queueMsgUnderWakeLock(mAudioHandler, MSG_DISABLE_AUDIO_FOR_UID,
979                     disable ? 1 : 0 /* arg1 */,  uid /* arg2 */,
980                     null /* obj */,  0 /* delay */);
981         }
982     };
983 
984     @GuardedBy("mSettingsLock")
985     private boolean mRttEnabled = false;
986 
987     ///////////////////////////////////////////////////////////////////////////
988     // Construction
989     ///////////////////////////////////////////////////////////////////////////
990 
991 
992     /**
993      * @param context
994      * @param audioSystem Adapter for {@link AudioSystem}
995      * @param systemServer Adapter for privilieged functionality for system server components
996      * @param settings Adapter for {@link Settings}
997      * @param looper Looper to use for the service's message handler. If this is null, an
998      *               {@link AudioSystemThread} is created as the messaging thread instead.
999      */
AudioService(Context context, AudioSystemAdapter audioSystem, SystemServerAdapter systemServer, SettingsAdapter settings, AudioPolicyFacade audioPolicy, @Nullable Looper looper)1000     public AudioService(Context context, AudioSystemAdapter audioSystem,
1001             SystemServerAdapter systemServer, SettingsAdapter settings,
1002             AudioPolicyFacade audioPolicy, @Nullable Looper looper) {
1003         this (context, audioSystem, systemServer, settings, audioPolicy, looper,
1004                 context.getSystemService(AppOpsManager.class),
1005                 PermissionEnforcer.fromContext(context));
1006     }
1007 
1008     /**
1009      * @param context
1010      * @param audioSystem Adapter for {@link AudioSystem}
1011      * @param systemServer Adapter for privilieged functionality for system server components
1012      * @param settings Adapter for {@link Settings}
1013      * @param looper Looper to use for the service's message handler. If this is null, an
1014      *               {@link AudioSystemThread} is created as the messaging thread instead.
1015      */
1016     @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
AudioService(Context context, AudioSystemAdapter audioSystem, SystemServerAdapter systemServer, SettingsAdapter settings, AudioPolicyFacade audioPolicy, @Nullable Looper looper, AppOpsManager appOps, @NonNull PermissionEnforcer enforcer)1017     public AudioService(Context context, AudioSystemAdapter audioSystem,
1018             SystemServerAdapter systemServer, SettingsAdapter settings,
1019             AudioPolicyFacade audioPolicy, @Nullable Looper looper, AppOpsManager appOps,
1020             @NonNull PermissionEnforcer enforcer) {
1021         super(enforcer);
1022         sLifecycleLogger.enqueue(new EventLogger.StringEvent("AudioService()"));
1023         mContext = context;
1024         mContentResolver = context.getContentResolver();
1025         mAppOps = appOps;
1026 
1027         mAudioSystem = audioSystem;
1028         mSystemServer = systemServer;
1029         mSettings = settings;
1030         mAudioPolicy = audioPolicy;
1031         mPlatformType = AudioSystem.getPlatformType(context);
1032 
1033         mDeviceBroker = new AudioDeviceBroker(mContext, this, mAudioSystem);
1034 
1035         mIsSingleVolume = AudioSystem.isSingleVolume(context);
1036 
1037         mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
1038         mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
1039         mSensorPrivacyManagerInternal =
1040                 LocalServices.getService(SensorPrivacyManagerInternal.class);
1041 
1042         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
1043         mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent");
1044 
1045         mSfxHelper = new SoundEffectsHelper(mContext, playerBase -> ignorePlayerLogs(playerBase));
1046 
1047         boolean binauralEnabledDefault = SystemProperties.getBoolean(
1048                 "ro.audio.spatializer_binaural_enabled_default", true);
1049         boolean transauralEnabledDefault = SystemProperties.getBoolean(
1050                 "ro.audio.spatializer_transaural_enabled_default", true);
1051         boolean headTrackingEnabledDefault = mContext.getResources().getBoolean(
1052                 com.android.internal.R.bool.config_spatial_audio_head_tracking_enabled_default);
1053 
1054         mSpatializerHelper = new SpatializerHelper(this, mAudioSystem, mDeviceBroker,
1055                 binauralEnabledDefault, transauralEnabledDefault, headTrackingEnabledDefault);
1056 
1057         mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
1058         mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator();
1059 
1060         mSupportsMicPrivacyToggle = context.getSystemService(SensorPrivacyManager.class)
1061                 .supportsSensorToggle(SensorPrivacyManager.Sensors.MICROPHONE);
1062 
1063         mUseVolumeGroupAliases = mContext.getResources().getBoolean(
1064                 com.android.internal.R.bool.config_handleVolumeAliasesUsingVolumeGroups);
1065 
1066         // Initialize volume
1067         // Priority 1 - Android Property
1068         // Priority 2 - Audio Policy Service
1069         // Priority 3 - Default Value
1070         if (AudioProductStrategy.getAudioProductStrategies().size() > 0) {
1071             int numStreamTypes = AudioSystem.getNumStreamTypes();
1072 
1073             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
1074                 AudioAttributes attr =
1075                         AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(
1076                                 streamType);
1077                 int maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr);
1078                 if (maxVolume != -1) {
1079                     MAX_STREAM_VOLUME[streamType] = maxVolume;
1080                 }
1081                 int minVolume = AudioSystem.getMinVolumeIndexForAttributes(attr);
1082                 if (minVolume != -1) {
1083                     MIN_STREAM_VOLUME[streamType] = minVolume;
1084                 }
1085             }
1086             if (mUseVolumeGroupAliases) {
1087                 // Set all default to uninitialized.
1088                 for (int stream = 0; stream < AudioSystem.DEFAULT_STREAM_VOLUME.length; stream++) {
1089                     AudioSystem.DEFAULT_STREAM_VOLUME[stream] = UNSET_INDEX;
1090                 }
1091             }
1092         }
1093 
1094         int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1);
1095         if (maxCallVolume != -1) {
1096             MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxCallVolume;
1097         }
1098 
1099         int defaultCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_default", -1);
1100         if (defaultCallVolume != -1 &&
1101                 defaultCallVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] &&
1102                 defaultCallVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]) {
1103             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = defaultCallVolume;
1104         } else {
1105             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] =
1106                     (MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] * 3) / 4;
1107         }
1108 
1109         int maxMusicVolume = SystemProperties.getInt("ro.config.media_vol_steps", -1);
1110         if (maxMusicVolume != -1) {
1111             MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxMusicVolume;
1112         }
1113 
1114         int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", -1);
1115         if (defaultMusicVolume != -1 &&
1116                 defaultMusicVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] &&
1117                 defaultMusicVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) {
1118             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = defaultMusicVolume;
1119         } else {
1120             if (isPlatformTelevision()) {
1121                 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] =
1122                         MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 4;
1123             } else {
1124                 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] =
1125                         MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 3;
1126             }
1127         }
1128 
1129         int maxAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_steps", -1);
1130         if (maxAlarmVolume != -1) {
1131             MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = maxAlarmVolume;
1132         }
1133 
1134         int defaultAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_default", -1);
1135         if (defaultAlarmVolume != -1 &&
1136                 defaultAlarmVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]) {
1137             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = defaultAlarmVolume;
1138         } else {
1139             // Default is 6 out of 7 (default maximum), so scale accordingly.
1140             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] =
1141                         6 * MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] / 7;
1142         }
1143 
1144         int maxSystemVolume = SystemProperties.getInt("ro.config.system_vol_steps", -1);
1145         if (maxSystemVolume != -1) {
1146             MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = maxSystemVolume;
1147         }
1148 
1149         int defaultSystemVolume = SystemProperties.getInt("ro.config.system_vol_default", -1);
1150         if (defaultSystemVolume != -1 &&
1151                 defaultSystemVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]) {
1152             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = defaultSystemVolume;
1153         } else {
1154             // Default is to use maximum.
1155             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] =
1156                         MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM];
1157         }
1158 
1159         int minAssistantVolume = SystemProperties.getInt("ro.config.assistant_vol_min", -1);
1160         if (minAssistantVolume != -1) {
1161             MIN_STREAM_VOLUME[AudioSystem.STREAM_ASSISTANT] = minAssistantVolume;
1162         }
1163 
1164         // Read following properties to configure max volume (number of steps) and default volume
1165         //   for STREAM_NOTIFICATION and STREAM_RING:
1166         //      config_audio_notif_vol_default
1167         //      config_audio_notif_vol_steps
1168         //      config_audio_ring_vol_default
1169         //      config_audio_ring_vol_steps
1170         int[] streams = { AudioSystem.STREAM_NOTIFICATION, AudioSystem.STREAM_RING };
1171         int[] stepsResId = { com.android.internal.R.integer.config_audio_notif_vol_steps,
1172                 com.android.internal.R.integer.config_audio_ring_vol_steps };
1173         int[] defaultResId = { com.android.internal.R.integer.config_audio_notif_vol_default,
1174                 com.android.internal.R.integer.config_audio_ring_vol_default };
1175         for (int s = 0; s < streams.length; s++) {
1176             try {
1177                 final int maxVol = mContext.getResources().getInteger(stepsResId[s]);
1178                 if (maxVol <= 0) {
1179                     throw new IllegalArgumentException("Invalid negative max volume for stream "
1180                             + streams[s]);
1181                 }
1182                 Log.i(TAG, "Stream " + streams[s] + ": using max vol of " + maxVol);
1183                 MAX_STREAM_VOLUME[streams[s]] = maxVol;
1184             } catch (Resources.NotFoundException e) {
1185                 Log.e(TAG, "Error querying max vol for stream type " + streams[s], e);
1186             }
1187             try {
1188                 final int defaultVol = mContext.getResources().getInteger(defaultResId[s]);
1189                 if (defaultVol > MAX_STREAM_VOLUME[streams[s]]) {
1190                     throw new IllegalArgumentException("Invalid default volume (" + defaultVol
1191                             + ") for stream " + streams[s] + ", greater than max volume of "
1192                             + MAX_STREAM_VOLUME[streams[s]]);
1193                 }
1194                 if (defaultVol < MIN_STREAM_VOLUME[streams[s]]) {
1195                     throw new IllegalArgumentException("Invalid default volume (" + defaultVol
1196                             + ") for stream " + streams[s] + ", lower than min volume of "
1197                             + MIN_STREAM_VOLUME[streams[s]]);
1198                 }
1199                 Log.i(TAG, "Stream " + streams[s] + ": using default vol of " + defaultVol);
1200                 AudioSystem.DEFAULT_STREAM_VOLUME[streams[s]] = defaultVol;
1201             } catch (Resources.NotFoundException e) {
1202                 Log.e(TAG, "Error querying default vol for stream type " + streams[s], e);
1203             }
1204         }
1205 
1206         if (looper == null) {
1207             createAudioSystemThread();
1208         } else {
1209             mAudioHandler = new AudioHandler(looper);
1210         }
1211 
1212         mSoundDoseHelper = new SoundDoseHelper(this, mContext, mAudioHandler, mSettings,
1213                 mVolumeController);
1214 
1215         AudioSystem.setErrorCallback(mAudioSystemCallback);
1216 
1217         updateAudioHalPids();
1218 
1219         mUseFixedVolume = mContext.getResources().getBoolean(
1220                 com.android.internal.R.bool.config_useFixedVolume);
1221 
1222         mRecordMonitor = new RecordingActivityMonitor(mContext);
1223         mRecordMonitor.registerRecordingCallback(mVoiceRecordingActivityMonitor, true);
1224 
1225         // must be called before readPersistedSettings() which needs a valid mStreamVolumeAlias[]
1226         // array initialized by updateStreamVolumeAlias()
1227         updateStreamVolumeAlias(false /*updateVolumes*/, TAG);
1228         readPersistedSettings();
1229         readUserRestrictions();
1230 
1231         mPlaybackMonitor =
1232                 new PlaybackActivityMonitor(context, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM],
1233                         device -> onMuteAwaitConnectionTimeout(device));
1234         mPlaybackMonitor.registerPlaybackCallback(mPlaybackActivityMonitor, true);
1235 
1236         mMediaFocusControl = new MediaFocusControl(mContext, mPlaybackMonitor);
1237 
1238         readAndSetLowRamDevice();
1239 
1240         mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported();
1241 
1242         if (mSystemServer.isPrivileged()) {
1243             LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal());
1244 
1245             mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
1246 
1247             mRecordMonitor.initMonitor();
1248         }
1249 
1250         mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false);
1251 
1252         mHasSpatializerEffect = SystemProperties.getBoolean("ro.audio.spatializer_enabled", false);
1253 
1254         // monitor routing updates coming from native
1255         mAudioSystem.setRoutingListener(this);
1256         // monitor requests for volume range initialization coming from native (typically when
1257         // errors are found by AudioPolicyManager
1258         mAudioSystem.setVolRangeInitReqListener(this);
1259 
1260         // done with service initialization, continue additional work in our Handler thread
1261         queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_STREAMS_VOLUMES,
1262                 0 /* arg1 */,  0 /* arg2 */, null /* obj */,  0 /* delay */);
1263         queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_ADI_DEVICE_STATES,
1264                 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */);
1265         queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_SPATIALIZER,
1266                 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */);
1267     }
1268 
initVolumeStreamStates()1269     private void initVolumeStreamStates() {
1270         int numStreamTypes = AudioSystem.getNumStreamTypes();
1271         synchronized (VolumeStreamState.class) {
1272             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
1273                 VolumeStreamState streamState = mStreamStates[streamType];
1274                 int groupId = getVolumeGroupForStreamType(streamType);
1275                 if (groupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP
1276                         && sVolumeGroupStates.indexOfKey(groupId) >= 0) {
1277                     streamState.setVolumeGroupState(sVolumeGroupStates.get(groupId));
1278                 }
1279             }
1280         }
1281     }
1282 
1283     /**
1284      * Called by handling of MSG_INIT_STREAMS_VOLUMES
1285      */
onInitStreamsAndVolumes()1286     private void onInitStreamsAndVolumes() {
1287         synchronized (mSettingsLock) {
1288             mCameraSoundForced = readCameraSoundForced();
1289             sendMsg(mAudioHandler,
1290                     MSG_SET_FORCE_USE,
1291                     SENDMSG_QUEUE,
1292                     AudioSystem.FOR_SYSTEM,
1293                     mCameraSoundForced
1294                             ? AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE,
1295                     new String("AudioService ctor"),
1296                     0);
1297         }
1298 
1299         createStreamStates();
1300 
1301         // must be called after createStreamStates() as it uses MUSIC volume as default if no
1302         // persistent data
1303         initVolumeGroupStates();
1304 
1305         mSoundDoseHelper.initSafeMediaVolumeIndex();
1306         // Link VGS on VSS
1307         initVolumeStreamStates();
1308 
1309         // Call setRingerModeInt() to apply correct mute
1310         // state on streams affected by ringer mode.
1311         sRingerAndZenModeMutedStreams = 0;
1312         sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent(
1313                 sRingerAndZenModeMutedStreams, "onInitStreamsAndVolumes"));
1314         setRingerModeInt(getRingerModeInternal(), false);
1315 
1316         final float[] preScale = new float[3];
1317         preScale[0] = mContext.getResources().getFraction(
1318                 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index1,
1319                 1, 1);
1320         preScale[1] = mContext.getResources().getFraction(
1321                 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index2,
1322                 1, 1);
1323         preScale[2] = mContext.getResources().getFraction(
1324                 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index3,
1325                 1, 1);
1326         for (int i = 0; i < preScale.length; i++) {
1327             if (0.0f <= preScale[i] && preScale[i] <= 1.0f) {
1328                 mPrescaleAbsoluteVolume[i] = preScale[i];
1329             }
1330         }
1331 
1332         initExternalEventReceivers();
1333 
1334         // check on volume initialization
1335         checkVolumeRangeInitialization("AudioService()");
1336 
1337     }
1338 
1339     private SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionChangedListener =
1340             new SubscriptionManager.OnSubscriptionsChangedListener() {
1341                 @Override
1342                 public void onSubscriptionsChanged() {
1343                     Log.i(TAG, "onSubscriptionsChanged()");
1344                     sendMsg(mAudioHandler, MSG_CONFIGURATION_CHANGED, SENDMSG_REPLACE,
1345                             0, 0, null, 0);
1346                 }
1347             };
1348 
1349     /**
1350      * Initialize intent receives and settings observers for this service.
1351      * Must be called after createStreamStates() as the handling of some events
1352      * may affect or need volumes, e.g. BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED
1353      * (for intent receiver), or Settings.Global.ZEN_MODE (for settings observer)
1354      */
initExternalEventReceivers()1355     private void initExternalEventReceivers() {
1356         mSettingsObserver = new SettingsObserver();
1357 
1358         // Register for device connection intent broadcasts.
1359         IntentFilter intentFilter =
1360                 new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
1361         intentFilter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED);
1362         intentFilter.addAction(Intent.ACTION_DOCK_EVENT);
1363         intentFilter.addAction(Intent.ACTION_SCREEN_ON);
1364         intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
1365         intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
1366         intentFilter.addAction(Intent.ACTION_USER_BACKGROUND);
1367         intentFilter.addAction(Intent.ACTION_USER_FOREGROUND);
1368         intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
1369         intentFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
1370 
1371         intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
1372         if (mMonitorRotation) {
1373             RotationHelper.init(mContext, mAudioHandler,
1374                     rotation -> onRotationUpdate(rotation),
1375                     foldState -> onFoldStateUpdate(foldState));
1376         }
1377 
1378         intentFilter.addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION);
1379         intentFilter.addAction(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION);
1380         intentFilter.addAction(ACTION_CHECK_MUSIC_ACTIVE);
1381         intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
1382 
1383         mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null,
1384                 Context.RECEIVER_EXPORTED);
1385 
1386         SubscriptionManager subscriptionManager = mContext.getSystemService(
1387                 SubscriptionManager.class);
1388         if (subscriptionManager == null) {
1389             Log.e(TAG, "initExternalEventReceivers cannot create SubscriptionManager!");
1390         } else {
1391             subscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionChangedListener);
1392         }
1393     }
1394 
systemReady()1395     public void systemReady() {
1396         sendMsg(mAudioHandler, MSG_SYSTEM_READY, SENDMSG_QUEUE,
1397                 0, 0, null, 0);
1398         if (false) {
1399             // This is turned off for now, because it is racy and thus causes apps to break.
1400             // Currently banning a uid means that if an app tries to start playing an audio
1401             // stream, that will be preventing, and unbanning it will not allow that stream
1402             // to resume.  However these changes in uid state are racy with what the app is doing,
1403             // so that after taking a process out of the cached state we can't guarantee that
1404             // we will unban the uid before the app actually tries to start playing audio.
1405             // (To do that, the activity manager would need to wait until it knows for sure
1406             // that the ban has been removed, before telling the app to do whatever it is
1407             // supposed to do that caused it to go out of the cached state.)
1408             try {
1409                 ActivityManager.getService().registerUidObserver(mUidObserver,
1410                         ActivityManager.UID_OBSERVER_CACHED | ActivityManager.UID_OBSERVER_GONE,
1411                         ActivityManager.PROCESS_STATE_UNKNOWN, null);
1412             } catch (RemoteException e) {
1413                 // ignored; both services live in system_server
1414             }
1415         }
1416     }
1417 
updateVibratorInfos()1418     private void updateVibratorInfos() {
1419         VibratorManager vibratorManager = mContext.getSystemService(VibratorManager.class);
1420         if (vibratorManager == null) {
1421             Slog.e(TAG, "Vibrator manager is not found");
1422             return;
1423         }
1424         int[] vibratorIds = vibratorManager.getVibratorIds();
1425         if (vibratorIds.length == 0) {
1426             Slog.d(TAG, "No vibrator found");
1427             return;
1428         }
1429         List<Vibrator> vibrators = new ArrayList<>(vibratorIds.length);
1430         for (int id : vibratorIds) {
1431             Vibrator vibrator = vibratorManager.getVibrator(id);
1432             if (vibrator != null) {
1433                 vibrators.add(vibrator);
1434             } else {
1435                 Slog.w(TAG, "Vibrator(" + id + ") is not found");
1436             }
1437         }
1438         if (vibrators.isEmpty()) {
1439             Slog.w(TAG, "Cannot find any available vibrator");
1440             return;
1441         }
1442         AudioSystem.setVibratorInfos(vibrators);
1443     }
1444 
onSystemReady()1445     public void onSystemReady() {
1446         mSystemReady = true;
1447         scheduleLoadSoundEffects();
1448 
1449         mDeviceBroker.onSystemReady();
1450 
1451         if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_HDMI_CEC)) {
1452             synchronized (mHdmiClientLock) {
1453                 mHdmiManager = mContext.getSystemService(HdmiControlManager.class);
1454                 if (mHdmiManager != null) {
1455                     mHdmiManager.addHdmiControlStatusChangeListener(
1456                             mHdmiControlStatusChangeListenerCallback);
1457                     mHdmiManager.addHdmiCecVolumeControlFeatureListener(mContext.getMainExecutor(),
1458                             mMyHdmiCecVolumeControlFeatureListener);
1459                 }
1460                 mHdmiTvClient = mHdmiManager.getTvClient();
1461                 if (mHdmiTvClient != null) {
1462                     mFixedVolumeDevices.removeAll(
1463                             AudioSystem.DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET);
1464                 }
1465                 mHdmiPlaybackClient = mHdmiManager.getPlaybackClient();
1466                 mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient();
1467             }
1468         }
1469 
1470         if (mSupportsMicPrivacyToggle) {
1471             mSensorPrivacyManagerInternal.addSensorPrivacyListenerForAllUsers(
1472                     SensorPrivacyManager.Sensors.MICROPHONE, (userId, enabled) -> {
1473                         if (userId == getCurrentUserId()) {
1474                             mMicMuteFromPrivacyToggle = enabled;
1475                             setMicrophoneMuteNoCallerCheck(getCurrentUserId());
1476                         }
1477                     });
1478         }
1479 
1480         mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
1481 
1482         mSoundDoseHelper.configureSafeMedia(/*forced=*/true, TAG);
1483 
1484         initA11yMonitoring();
1485 
1486         mRoleObserver = new RoleObserver();
1487         mRoleObserver.register();
1488 
1489         onIndicateSystemReady();
1490 
1491         mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted();
1492         setMicMuteFromSwitchInput();
1493 
1494         initMinStreamVolumeWithoutModifyAudioSettings();
1495 
1496         updateVibratorInfos();
1497 
1498         synchronized (mSupportedSystemUsagesLock) {
1499             AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages);
1500         }
1501     }
1502 
1503     //-----------------------------------------------------------------
1504     // routing monitoring from AudioSystemAdapter
1505     @Override
onRoutingUpdatedFromNative()1506     public void onRoutingUpdatedFromNative() {
1507         sendMsg(mAudioHandler,
1508                 MSG_ROUTING_UPDATED,
1509                 SENDMSG_REPLACE, 0, 0, null,
1510                 /*delay*/ 0);
1511     }
1512 
1513     /**
1514      * called when handling MSG_ROUTING_UPDATED
1515      */
onRoutingUpdatedFromAudioThread()1516     void onRoutingUpdatedFromAudioThread() {
1517         if (mHasSpatializerEffect) {
1518             mSpatializerHelper.onRoutingUpdated();
1519         }
1520         checkMuteAwaitConnection();
1521     }
1522 
1523     //-----------------------------------------------------------------
1524     // rotation/fold updates coming from RotationHelper
onRotationUpdate(Integer rotation)1525     void onRotationUpdate(Integer rotation) {
1526         mSpatializerHelper.setDisplayOrientation((float) (rotation * Math.PI / 180.));
1527         // use REPLACE as only the last rotation matters
1528         final String rotationParameter = "rotation=" + rotation;
1529         sendMsg(mAudioHandler, MSG_ROTATION_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0,
1530                 /*obj*/ rotationParameter, /*delay*/ 0);
1531     }
1532 
onFoldStateUpdate(Boolean foldState)1533     void onFoldStateUpdate(Boolean foldState) {
1534         mSpatializerHelper.setFoldState(foldState);
1535         // use REPLACE as only the last fold state matters
1536         final String foldStateParameter = "device_folded=" + (foldState ? "on" : "off");
1537         sendMsg(mAudioHandler, MSG_FOLD_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0,
1538                 /*obj*/ foldStateParameter, /*delay*/ 0);
1539     }
1540 
1541     //-----------------------------------------------------------------
1542     // Communicate to PlayackActivityMonitor whether to log or not
1543     // the sound FX activity (useful for removing touch sounds in the activity logs)
ignorePlayerLogs(@onNull PlayerBase playerToIgnore)1544     void ignorePlayerLogs(@NonNull PlayerBase playerToIgnore) {
1545         if (DEBUG_LOG_SOUND_FX) {
1546             return;
1547         }
1548         sendMsg(mAudioHandler, MSG_NO_LOG_FOR_PLAYER_I, SENDMSG_REPLACE,
1549                 /*arg1, piid of the player*/ playerToIgnore.getPlayerIId(),
1550                 /*arg2 ignored*/ 0, /*obj ignored*/ null, /*delay*/ 0);
1551     }
1552 
1553     //-----------------------------------------------------------------
1554     // monitoring requests for volume range initialization
1555     @Override // AudioSystemAdapter.OnVolRangeInitRequestListener
onVolumeRangeInitRequestFromNative()1556     public void onVolumeRangeInitRequestFromNative() {
1557         sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_REPLACE, 0, 0,
1558                 "onVolumeRangeInitRequestFromNative" /*obj: caller, for dumpsys*/, /*delay*/ 0);
1559     }
1560 
1561     //-----------------------------------------------------------------
1562     RoleObserver mRoleObserver;
1563 
1564     class RoleObserver implements OnRoleHoldersChangedListener {
1565         private RoleManager mRm;
1566         private final Executor mExecutor;
1567 
RoleObserver()1568         RoleObserver() {
1569             mExecutor = mContext.getMainExecutor();
1570         }
1571 
register()1572         public void register() {
1573             mRm = (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE);
1574             if (mRm != null) {
1575                 mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.ALL);
1576                 synchronized (mSettingsLock) {
1577                     updateAssistantUIdLocked(/* forceUpdate= */ true);
1578                 }
1579             }
1580         }
1581 
1582         @Override
onRoleHoldersChanged(@onNull String roleName, @NonNull UserHandle user)1583         public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
1584             if (RoleManager.ROLE_ASSISTANT.equals(roleName)) {
1585                 synchronized (mSettingsLock) {
1586                     updateAssistantUIdLocked(/* forceUpdate= */ false);
1587                 }
1588             }
1589         }
1590 
getAssistantRoleHolder()1591         public String getAssistantRoleHolder() {
1592             String assitantPackage = "";
1593             if (mRm != null) {
1594                 List<String> assistants = mRm.getRoleHolders(RoleManager.ROLE_ASSISTANT);
1595                 assitantPackage = assistants.size() == 0 ? "" : assistants.get(0);
1596             }
1597             return assitantPackage;
1598         }
1599     }
1600 
onIndicateSystemReady()1601     void onIndicateSystemReady() {
1602         if (AudioSystem.systemReady() == AudioSystem.SUCCESS) {
1603             return;
1604         }
1605         sendMsg(mAudioHandler,
1606                 MSG_INDICATE_SYSTEM_READY,
1607                 SENDMSG_REPLACE,
1608                 0,
1609                 0,
1610                 null,
1611                 INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
1612     }
1613 
onAudioServerDied()1614     public void onAudioServerDied() {
1615         if (!mSystemReady ||
1616                 (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) {
1617             Log.e(TAG, "Audioserver died.");
1618             sLifecycleLogger.enqueue(new EventLogger.StringEvent(
1619                     "onAudioServerDied() audioserver died"));
1620             sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, SENDMSG_NOOP, 0, 0,
1621                     null, 500);
1622             return;
1623         }
1624         Log.i(TAG, "Audioserver started.");
1625         sLifecycleLogger.enqueue(new EventLogger.StringEvent(
1626                 "onAudioServerDied() audioserver started"));
1627 
1628         updateAudioHalPids();
1629 
1630         // indicate to audio HAL that we start the reconfiguration phase after a media
1631         // server crash
1632         // Note that we only execute this when the media server
1633         // process restarts after a crash, not the first time it is started.
1634         AudioSystem.setParameters("restarting=true");
1635 
1636         readAndSetLowRamDevice();
1637 
1638         mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported();
1639 
1640         // Restore device connection states, BT state
1641         mDeviceBroker.onAudioServerDied();
1642 
1643         // Restore call state
1644         synchronized (mDeviceBroker.mSetModeLock) {
1645             onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(),
1646                     mContext.getPackageName(), true /*force*/);
1647         }
1648         final int forSys;
1649         synchronized (mSettingsLock) {
1650             forSys = mCameraSoundForced ?
1651                     AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE;
1652         }
1653 
1654         mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, forSys, "onAudioServerDied");
1655 
1656         // Restore stream volumes
1657         onReinitVolumes("after audioserver restart");
1658 
1659         // Restore audio volume groups
1660         restoreVolumeGroups();
1661 
1662         // Restore mono mode
1663         updateMasterMono(mContentResolver);
1664 
1665         // Restore audio balance
1666         updateMasterBalance(mContentResolver);
1667 
1668         // Restore ringer mode
1669         setRingerModeInt(getRingerModeInternal(), false);
1670 
1671         // Reset device rotation (if monitored for this device)
1672         if (mMonitorRotation) {
1673             RotationHelper.updateOrientation();
1674         }
1675 
1676         // Restore setParameters and other queued setters.
1677         mRestorableParameters.restoreAll();
1678 
1679         synchronized (mSettingsLock) {
1680             final int forDock = mDockAudioMediaEnabled ?
1681                     AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE;
1682             mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, forDock, "onAudioServerDied");
1683             sendEncodedSurroundMode(mContentResolver, "onAudioServerDied");
1684             sendEnabledSurroundFormats(mContentResolver, true);
1685             AudioSystem.setRttEnabled(mRttEnabled);
1686             resetAssistantServicesUidsLocked();
1687         }
1688 
1689         synchronized (mAccessibilityServiceUidsLock) {
1690             AudioSystem.setA11yServicesUids(mAccessibilityServiceUids);
1691         }
1692         synchronized (mInputMethodServiceUidLock) {
1693             mAudioSystem.setCurrentImeUid(mInputMethodServiceUid);
1694         }
1695         synchronized (mHdmiClientLock) {
1696             if (mHdmiManager != null && mHdmiTvClient != null) {
1697                 setHdmiSystemAudioSupported(mHdmiSystemAudioSupported);
1698             }
1699         }
1700 
1701         synchronized (mSupportedSystemUsagesLock) {
1702             AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages);
1703         }
1704 
1705         synchronized (mAudioPolicies) {
1706             ArrayList<AudioPolicyProxy> invalidProxies = new ArrayList<>();
1707             for (AudioPolicyProxy policy : mAudioPolicies.values()) {
1708                 final int status = policy.connectMixes();
1709                 if (status != AudioSystem.SUCCESS) {
1710                     // note that PERMISSION_DENIED may also indicate trouble getting to APService
1711                     Log.e(TAG, "onAudioServerDied: error "
1712                             + AudioSystem.audioSystemErrorToString(status)
1713                             + " when connecting mixes for policy " + policy.toLogFriendlyString());
1714                     invalidProxies.add(policy);
1715                 } else {
1716                     final int deviceAffinitiesStatus = policy.setupDeviceAffinities();
1717                     if (deviceAffinitiesStatus != AudioSystem.SUCCESS) {
1718                         Log.e(TAG, "onAudioServerDied: error "
1719                                 + AudioSystem.audioSystemErrorToString(deviceAffinitiesStatus)
1720                                 + " when connecting device affinities for policy "
1721                                 + policy.toLogFriendlyString());
1722                         invalidProxies.add(policy);
1723                     }
1724                 }
1725             }
1726             invalidProxies.forEach((policy) -> policy.release());
1727 
1728         }
1729 
1730         // Restore capture policies
1731         synchronized (mPlaybackMonitor) {
1732             HashMap<Integer, Integer> allowedCapturePolicies =
1733                     mPlaybackMonitor.getAllAllowedCapturePolicies();
1734             for (HashMap.Entry<Integer, Integer> entry : allowedCapturePolicies.entrySet()) {
1735                 int result = mAudioSystem.setAllowedCapturePolicy(
1736                         entry.getKey(),
1737                         AudioAttributes.capturePolicyToFlags(entry.getValue(), 0x0));
1738                 if (result != AudioSystem.AUDIO_STATUS_OK) {
1739                     Log.e(TAG, "Failed to restore capture policy, uid: "
1740                             + entry.getKey() + ", capture policy: " + entry.getValue()
1741                             + ", result: " + result);
1742                     // When restoring capture policy failed, set the capture policy as
1743                     // ALLOW_CAPTURE_BY_ALL, which will result in removing the cached
1744                     // capture policy in PlaybackActivityMonitor.
1745                     mPlaybackMonitor.setAllowedCapturePolicy(
1746                             entry.getKey(), AudioAttributes.ALLOW_CAPTURE_BY_ALL);
1747                 }
1748             }
1749         }
1750 
1751         mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect);
1752         mSoundDoseHelper.reset();
1753 
1754         // Restore rotation information.
1755         if (mMonitorRotation) {
1756             RotationHelper.forceUpdate();
1757         }
1758 
1759         onIndicateSystemReady();
1760         // indicate the end of reconfiguration phase to audio HAL
1761         AudioSystem.setParameters("restarting=false");
1762 
1763         sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE,
1764                 SENDMSG_QUEUE, 1, 0, null, 0);
1765 
1766         setMicrophoneMuteNoCallerCheck(getCurrentUserId()); // will also update the mic mute cache
1767         setMicMuteFromSwitchInput();
1768 
1769         // Restore vibrator info
1770         updateVibratorInfos();
1771     }
1772 
onRemoveAssistantServiceUids(int[] uids)1773     private void onRemoveAssistantServiceUids(int[] uids) {
1774         synchronized (mSettingsLock) {
1775             removeAssistantServiceUidsLocked(uids);
1776         }
1777     }
1778 
1779     @GuardedBy("mSettingsLock")
removeAssistantServiceUidsLocked(int[] uids)1780     private void removeAssistantServiceUidsLocked(int[] uids) {
1781         boolean changed = false;
1782         for (int index = 0; index < uids.length; index++) {
1783             if (!mAssistantUids.remove(uids[index])) {
1784                 Slog.e(TAG, TextUtils.formatSimple(
1785                         "Cannot remove assistant service, uid(%d) not present", uids[index]));
1786                 continue;
1787             }
1788             changed = true;
1789         }
1790         if (changed) {
1791             updateAssistantServicesUidsLocked();
1792         }
1793     }
1794 
onAddAssistantServiceUids(int[] uids)1795     private void onAddAssistantServiceUids(int[] uids) {
1796         synchronized (mSettingsLock) {
1797             addAssistantServiceUidsLocked(uids);
1798         }
1799     }
1800 
1801     @GuardedBy("mSettingsLock")
addAssistantServiceUidsLocked(int[] uids)1802     private void addAssistantServiceUidsLocked(int[] uids) {
1803         boolean changed = false;
1804         for (int index = 0; index < uids.length; index++) {
1805             if (uids[index] == INVALID_UID) {
1806                 continue;
1807             }
1808             if (!mAssistantUids.add(uids[index])) {
1809                 Slog.e(TAG, TextUtils.formatSimple(
1810                                 "Cannot add assistant service, uid(%d) already present",
1811                                 uids[index]));
1812                 continue;
1813             }
1814             changed = true;
1815         }
1816         if (changed) {
1817             updateAssistantServicesUidsLocked();
1818         }
1819     }
1820 
1821     @GuardedBy("mSettingsLock")
resetAssistantServicesUidsLocked()1822     private void resetAssistantServicesUidsLocked() {
1823         mAssistantUids.clear();
1824         updateAssistantUIdLocked(/* forceUpdate= */ true);
1825     }
1826 
1827     @GuardedBy("mSettingsLock")
updateAssistantServicesUidsLocked()1828     private void updateAssistantServicesUidsLocked() {
1829         int[] assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray();
1830         AudioSystem.setAssistantServicesUids(assistantUids);
1831     }
1832 
updateActiveAssistantServiceUids()1833     private void updateActiveAssistantServiceUids() {
1834         int [] activeAssistantServiceUids;
1835         synchronized (mSettingsLock) {
1836             activeAssistantServiceUids = mActiveAssistantServiceUids;
1837         }
1838         AudioSystem.setActiveAssistantServicesUids(activeAssistantServiceUids);
1839     }
1840 
onReinitVolumes(@onNull String caller)1841     private void onReinitVolumes(@NonNull String caller) {
1842         final int numStreamTypes = AudioSystem.getNumStreamTypes();
1843         // keep track of any error during stream volume initialization
1844         int status = AudioSystem.AUDIO_STATUS_OK;
1845         for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
1846             VolumeStreamState streamState = mStreamStates[streamType];
1847             final int res = AudioSystem.initStreamVolume(
1848                     streamType, streamState.mIndexMin / 10, streamState.mIndexMax / 10);
1849             if (res != AudioSystem.AUDIO_STATUS_OK) {
1850                 status = res;
1851                 Log.e(TAG, "Failed to initStreamVolume (" + res + ") for stream " + streamType);
1852                 // stream volume initialization failed, no need to try the others, it will be
1853                 // attempted again when MSG_REINIT_VOLUMES is handled
1854                 break;
1855             }
1856             streamState.applyAllVolumes();
1857         }
1858 
1859         // did it work? check based on status
1860         if (status != AudioSystem.AUDIO_STATUS_OK) {
1861             sLifecycleLogger.enqueue(new EventLogger.StringEvent(
1862                     caller + ": initStreamVolume failed with " + status + " will retry")
1863                     .printLog(ALOGE, TAG));
1864             sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0,
1865                     caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
1866             return;
1867         }
1868 
1869         // did it work? check based on min/max values of some basic streams
1870         if (!checkVolumeRangeInitialization(caller)) {
1871             return;
1872         }
1873 
1874         // success
1875         sLifecycleLogger.enqueue(new EventLogger.StringEvent(
1876                 caller + ": initStreamVolume succeeded").printLog(ALOGI, TAG));
1877     }
1878 
1879     /**
1880      * Check volume ranges were properly initialized
1881      * @return true if volume ranges were successfully initialized
1882      */
checkVolumeRangeInitialization(String caller)1883     private boolean checkVolumeRangeInitialization(String caller) {
1884         boolean success = true;
1885         final int[] basicStreams = { AudioSystem.STREAM_ALARM, AudioSystem.STREAM_RING,
1886                 AudioSystem.STREAM_MUSIC, AudioSystem.STREAM_VOICE_CALL,
1887                 AudioSystem.STREAM_ACCESSIBILITY };
1888         for (int streamType : basicStreams) {
1889             final AudioAttributes aa = new AudioAttributes.Builder()
1890                     .setInternalLegacyStreamType(streamType).build();
1891             if (AudioSystem.getMaxVolumeIndexForAttributes(aa) < 0
1892                     || AudioSystem.getMinVolumeIndexForAttributes(aa) < 0) {
1893                 success = false;
1894                 break;
1895             }
1896         }
1897         if (!success) {
1898             sLifecycleLogger.enqueue(new EventLogger.StringEvent(
1899                     caller + ": initStreamVolume succeeded but invalid mix/max levels, will retry")
1900                     .printLog(ALOGW, TAG));
1901             sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0,
1902                     caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
1903         }
1904         return success;
1905     }
1906 
onDispatchAudioServerStateChange(boolean state)1907     private void onDispatchAudioServerStateChange(boolean state) {
1908         synchronized (mAudioServerStateListeners) {
1909             for (AsdProxy asdp : mAudioServerStateListeners.values()) {
1910                 try {
1911                     asdp.callback().dispatchAudioServerStateChange(state);
1912                 } catch (RemoteException e) {
1913                     Log.w(TAG, "Could not call dispatchAudioServerStateChange()", e);
1914                 }
1915             }
1916         }
1917     }
1918 
createAudioSystemThread()1919     private void createAudioSystemThread() {
1920         mAudioSystemThread = new AudioSystemThread();
1921         mAudioSystemThread.start();
1922         waitForAudioHandlerCreation();
1923     }
1924 
1925     /** Waits for the volume handler to be created by the other thread. */
waitForAudioHandlerCreation()1926     private void waitForAudioHandlerCreation() {
1927         synchronized(this) {
1928             while (mAudioHandler == null) {
1929                 try {
1930                     // Wait for mAudioHandler to be set by the other thread
1931                     wait();
1932                 } catch (InterruptedException e) {
1933                     Log.e(TAG, "Interrupted while waiting on volume handler.");
1934                 }
1935             }
1936         }
1937     }
1938 
1939     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
1940     /**
1941      * @see AudioManager#setSupportedSystemUsages(int[])
1942      */
setSupportedSystemUsages(@onNull @ttributeSystemUsage int[] systemUsages)1943     public void setSupportedSystemUsages(@NonNull @AttributeSystemUsage int[] systemUsages) {
1944         super.setSupportedSystemUsages_enforcePermission();
1945 
1946         verifySystemUsages(systemUsages);
1947 
1948         synchronized (mSupportedSystemUsagesLock) {
1949             AudioSystem.setSupportedSystemUsages(systemUsages);
1950             mSupportedSystemUsages = systemUsages;
1951         }
1952     }
1953 
1954     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
1955     /**
1956      * @see AudioManager#getSupportedSystemUsages()
1957      */
getSupportedSystemUsages()1958     public @NonNull @AttributeSystemUsage int[] getSupportedSystemUsages() {
1959         super.getSupportedSystemUsages_enforcePermission();
1960 
1961         synchronized (mSupportedSystemUsagesLock) {
1962             return Arrays.copyOf(mSupportedSystemUsages, mSupportedSystemUsages.length);
1963         }
1964     }
1965 
verifySystemUsages(@onNull int[] systemUsages)1966     private void verifySystemUsages(@NonNull int[] systemUsages) {
1967         for (int i = 0; i < systemUsages.length; i++) {
1968             if (!AudioAttributes.isSystemUsage(systemUsages[i])) {
1969                 throw new IllegalArgumentException("Non-system usage provided: " + systemUsages[i]);
1970             }
1971         }
1972     }
1973 
1974     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
1975     /**
1976      * @return the {@link android.media.audiopolicy.AudioProductStrategy} discovered from the
1977      * platform configuration file.
1978      */
1979     @NonNull
getAudioProductStrategies()1980     public List<AudioProductStrategy> getAudioProductStrategies() {
1981         // verify permissions
1982         super.getAudioProductStrategies_enforcePermission();
1983 
1984         return AudioProductStrategy.getAudioProductStrategies();
1985     }
1986 
1987     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
1988     /**
1989      * @return the List of {@link android.media.audiopolicy.AudioVolumeGroup} discovered from the
1990      * platform configuration file.
1991      */
1992     @NonNull
getAudioVolumeGroups()1993     public List<AudioVolumeGroup> getAudioVolumeGroups() {
1994         // verify permissions
1995         super.getAudioVolumeGroups_enforcePermission();
1996 
1997         return AudioVolumeGroup.getAudioVolumeGroups();
1998     }
1999 
checkAllAliasStreamVolumes()2000     private void checkAllAliasStreamVolumes() {
2001         synchronized (mSettingsLock) {
2002             synchronized (VolumeStreamState.class) {
2003                 int numStreamTypes = AudioSystem.getNumStreamTypes();
2004                 for (int streamType = 0; streamType < numStreamTypes; streamType++) {
2005                     mStreamStates[streamType]
2006                             .setAllIndexes(mStreamStates[mStreamVolumeAlias[streamType]], TAG);
2007                     // apply stream volume
2008                     if (!mStreamStates[streamType].mIsMuted) {
2009                         mStreamStates[streamType].applyAllVolumes();
2010                     }
2011                 }
2012             }
2013         }
2014     }
2015 
2016 
2017     /**
2018      * Called from AudioDeviceBroker when DEVICE_OUT_HDMI is connected or disconnected.
2019      */
postCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)2020     /*package*/ void postCheckVolumeCecOnHdmiConnection(
2021             @AudioService.ConnectionState  int state, String caller) {
2022         sendMsg(mAudioHandler, MSG_HDMI_VOLUME_CHECK, SENDMSG_REPLACE,
2023                 state /*arg1*/, 0 /*arg2 ignored*/, caller /*obj*/, 0 /*delay*/);
2024     }
2025 
onCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)2026     private void onCheckVolumeCecOnHdmiConnection(
2027             @AudioService.ConnectionState int state, String caller) {
2028         if (state == AudioService.CONNECTION_STATE_CONNECTED) {
2029             // DEVICE_OUT_HDMI is now connected
2030             if (mSoundDoseHelper.safeDevicesContains(AudioSystem.DEVICE_OUT_HDMI)) {
2031                 mSoundDoseHelper.scheduleMusicActiveCheck();
2032             }
2033 
2034             if (isPlatformTelevision()) {
2035                 synchronized (mHdmiClientLock) {
2036                     if (mHdmiManager != null && mHdmiPlaybackClient != null) {
2037                         updateHdmiCecSinkLocked(
2038                                 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI));
2039                     }
2040                 }
2041             }
2042             sendEnabledSurroundFormats(mContentResolver, true);
2043         } else {
2044             // DEVICE_OUT_HDMI disconnected
2045             if (isPlatformTelevision()) {
2046                 synchronized (mHdmiClientLock) {
2047                     if (mHdmiManager != null) {
2048                         updateHdmiCecSinkLocked(
2049                                 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI));
2050                     }
2051                 }
2052             }
2053         }
2054     }
2055 
2056     /**
2057      * Asynchronously update volume states for the given device.
2058      *
2059      * @param device a single audio device, ensure that this is not a devices bitmask
2060      * @param caller caller of this method
2061      */
postUpdateVolumeStatesForAudioDevice(int device, String caller)2062     private void postUpdateVolumeStatesForAudioDevice(int device, String caller) {
2063         sendMsg(mAudioHandler,
2064                 MSG_UPDATE_VOLUME_STATES_FOR_DEVICE,
2065                 SENDMSG_QUEUE, device /*arg1*/, 0 /*arg2*/, caller /*obj*/,
2066                 0 /*delay*/);
2067     }
2068 
2069     /**
2070      * Update volume states for the given device.
2071      *
2072      * This will initialize the volume index if no volume index is available.
2073      * If the device is the currently routed device, fixed/full volume policies will be applied.
2074      *
2075      * @param device a single audio device, ensure that this is not a devices bitmask
2076      * @param caller caller of this method
2077      */
onUpdateVolumeStatesForAudioDevice(int device, String caller)2078     private void onUpdateVolumeStatesForAudioDevice(int device, String caller) {
2079         final int numStreamTypes = AudioSystem.getNumStreamTypes();
2080         synchronized (mSettingsLock) {
2081             synchronized (VolumeStreamState.class) {
2082                 for (int streamType = 0; streamType < numStreamTypes; streamType++) {
2083                     updateVolumeStates(device, streamType, caller);
2084                 }
2085             }
2086         }
2087     }
2088 
2089     /**
2090      * Update volume states for the given device and given stream.
2091      *
2092      * This will initialize the volume index if no volume index is available.
2093      * If the device is the currently routed device, fixed/full volume policies will be applied.
2094      *
2095      * @param device a single audio device, ensure that this is not a devices bitmask
2096      * @param streamType streamType to be updated
2097      * @param caller caller of this method
2098      */
updateVolumeStates(int device, int streamType, String caller)2099     private void updateVolumeStates(int device, int streamType, String caller) {
2100         // Handle device volume aliasing of SPEAKER_SAFE.
2101         if (device == AudioSystem.DEVICE_OUT_SPEAKER_SAFE) {
2102             device = AudioSystem.DEVICE_OUT_SPEAKER;
2103         }
2104         if (!mStreamStates[streamType].hasIndexForDevice(device)) {
2105             // set the default value, if device is affected by a full/fix/abs volume rule, it
2106             // will taken into account in checkFixedVolumeDevices()
2107             mStreamStates[streamType].setIndex(
2108                     mStreamStates[mStreamVolumeAlias[streamType]]
2109                             .getIndex(AudioSystem.DEVICE_OUT_DEFAULT),
2110                     device, caller, true /*hasModifyAudioSettings*/);
2111         }
2112 
2113         // Check if device to be updated is routed for the given audio stream
2114         // This may include devices such as SPEAKER_SAFE.
2115         List<AudioDeviceAttributes> devicesForAttributes = getDevicesForAttributesInt(
2116                 new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build(),
2117                 true /* forVolume */);
2118         for (AudioDeviceAttributes deviceAttributes : devicesForAttributes) {
2119             if (deviceAttributes.getType() == AudioDeviceInfo.convertInternalDeviceToDeviceType(
2120                     device)) {
2121                 mStreamStates[streamType].checkFixedVolumeDevices();
2122 
2123                 // Unmute streams if required and device is full volume
2124                 if (isStreamMute(streamType) && mFullVolumeDevices.contains(device)) {
2125                     mStreamStates[streamType].mute(false, "updateVolumeStates(" + caller);
2126                 }
2127             }
2128         }
2129     }
2130 
checkAllFixedVolumeDevices()2131     private void checkAllFixedVolumeDevices()
2132     {
2133         int numStreamTypes = AudioSystem.getNumStreamTypes();
2134         for (int streamType = 0; streamType < numStreamTypes; streamType++) {
2135             mStreamStates[streamType].checkFixedVolumeDevices();
2136         }
2137     }
2138 
checkAllFixedVolumeDevices(int streamType)2139     private void checkAllFixedVolumeDevices(int streamType) {
2140         mStreamStates[streamType].checkFixedVolumeDevices();
2141     }
2142 
checkMuteAffectedStreams()2143     private void checkMuteAffectedStreams() {
2144         // any stream with a min level > 0 is not muteable by definition
2145         // STREAM_VOICE_CALL and STREAM_BLUETOOTH_SCO can be muted by applications
2146         // that has the the MODIFY_PHONE_STATE permission.
2147         for (int i = 0; i < mStreamStates.length; i++) {
2148             final VolumeStreamState vss = mStreamStates[i];
2149             if (vss.mIndexMin > 0 &&
2150                 (vss.mStreamType != AudioSystem.STREAM_VOICE_CALL &&
2151                 vss.mStreamType != AudioSystem.STREAM_BLUETOOTH_SCO)) {
2152                 mMuteAffectedStreams &= ~(1 << vss.mStreamType);
2153             }
2154         }
2155     }
2156 
createStreamStates()2157     private void createStreamStates() {
2158         int numStreamTypes = AudioSystem.getNumStreamTypes();
2159         VolumeStreamState[] streams = mStreamStates = new VolumeStreamState[numStreamTypes];
2160 
2161         for (int i = 0; i < numStreamTypes; i++) {
2162             streams[i] =
2163                     new VolumeStreamState(System.VOLUME_SETTINGS_INT[mStreamVolumeAlias[i]], i);
2164         }
2165 
2166         checkAllFixedVolumeDevices();
2167         checkAllAliasStreamVolumes();
2168         checkMuteAffectedStreams();
2169         updateDefaultVolumes();
2170     }
2171 
2172     /**
2173      * Update default indexes from aliased streams. Must be called after mStreamStates is created
2174      * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for default
2175      * index. Need to make default index configurable and independent of streams.
2176      * Fallback on music stream for default initialization to take benefit of property based default
2177      * initialization.
2178      * For other volume groups not linked to any streams, default music stream index is considered.
2179      */
updateDefaultVolumes()2180     private void updateDefaultVolumes() {
2181         for (int stream = 0; stream < mStreamStates.length; stream++) {
2182             int streamVolumeAlias = mStreamVolumeAlias[stream];
2183             if (mUseVolumeGroupAliases) {
2184                 if (AudioSystem.DEFAULT_STREAM_VOLUME[stream] != UNSET_INDEX) {
2185                     // Already initialized through default property based mecanism.
2186                     continue;
2187                 }
2188                 streamVolumeAlias = AudioSystem.STREAM_MUSIC;
2189                 int defaultAliasVolume = getUiDefaultRescaledIndex(streamVolumeAlias, stream);
2190                 if ((defaultAliasVolume >= MIN_STREAM_VOLUME[stream])
2191                         && (defaultAliasVolume <= MAX_STREAM_VOLUME[stream])) {
2192                     AudioSystem.DEFAULT_STREAM_VOLUME[stream] = defaultAliasVolume;
2193                     continue;
2194                 }
2195             }
2196             if (stream != streamVolumeAlias) {
2197                 AudioSystem.DEFAULT_STREAM_VOLUME[stream] =
2198                         getUiDefaultRescaledIndex(streamVolumeAlias, stream);
2199             }
2200         }
2201     }
2202 
getUiDefaultRescaledIndex(int srcStream, int dstStream)2203     private int getUiDefaultRescaledIndex(int srcStream, int dstStream) {
2204         return (rescaleIndex(AudioSystem.DEFAULT_STREAM_VOLUME[srcStream] * 10,
2205                 srcStream, dstStream) + 5) / 10;
2206     }
2207 
dumpStreamStates(PrintWriter pw)2208     private void dumpStreamStates(PrintWriter pw) {
2209         pw.println("\nStream volumes (device: index)");
2210         int numStreamTypes = AudioSystem.getNumStreamTypes();
2211         for (int i = 0; i < numStreamTypes; i++) {
2212             StringBuilder alias = new StringBuilder();
2213             if (mStreamVolumeAlias[i] != i) {
2214                 alias.append(" (aliased to: ")
2215                         .append(AudioSystem.STREAM_NAMES[mStreamVolumeAlias[i]])
2216                         .append(")");
2217             }
2218             pw.println("- " + AudioSystem.STREAM_NAMES[i] + alias + ":");
2219             mStreamStates[i].dump(pw);
2220             pw.println("");
2221         }
2222         pw.print("\n- mute affected streams = 0x");
2223         pw.println(Integer.toHexString(mMuteAffectedStreams));
2224     }
2225 
updateStreamVolumeAlias(boolean updateVolumes, String caller)2226     private void updateStreamVolumeAlias(boolean updateVolumes, String caller) {
2227         int dtmfStreamAlias;
2228         final int a11yStreamAlias = sIndependentA11yVolume ?
2229                 AudioSystem.STREAM_ACCESSIBILITY : AudioSystem.STREAM_MUSIC;
2230         final int assistantStreamAlias = mContext.getResources().getBoolean(
2231                 com.android.internal.R.bool.config_useAssistantVolume) ?
2232                 AudioSystem.STREAM_ASSISTANT : AudioSystem.STREAM_MUSIC;
2233 
2234         if (mIsSingleVolume) {
2235             mStreamVolumeAlias = STREAM_VOLUME_ALIAS_TELEVISION.clone();
2236             dtmfStreamAlias = AudioSystem.STREAM_MUSIC;
2237         } else if (mUseVolumeGroupAliases) {
2238             mStreamVolumeAlias = STREAM_VOLUME_ALIAS_NONE.clone();
2239             dtmfStreamAlias = AudioSystem.STREAM_DTMF;
2240         } else {
2241             switch (mPlatformType) {
2242                 case AudioSystem.PLATFORM_VOICE:
2243                     mStreamVolumeAlias = STREAM_VOLUME_ALIAS_VOICE.clone();
2244                     dtmfStreamAlias = AudioSystem.STREAM_RING;
2245                     break;
2246                 default:
2247                     mStreamVolumeAlias = STREAM_VOLUME_ALIAS_DEFAULT.clone();
2248                     dtmfStreamAlias = AudioSystem.STREAM_MUSIC;
2249             }
2250             if (!mNotifAliasRing) {
2251                 mStreamVolumeAlias[AudioSystem.STREAM_NOTIFICATION] =
2252                         AudioSystem.STREAM_NOTIFICATION;
2253             }
2254         }
2255 
2256         if (mIsSingleVolume) {
2257             mRingerModeAffectedStreams = 0;
2258         } else {
2259             if (isInCommunication()) {
2260                 dtmfStreamAlias = AudioSystem.STREAM_VOICE_CALL;
2261                 mRingerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF);
2262             } else {
2263                 mRingerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF);
2264             }
2265         }
2266 
2267         mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias;
2268         mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY] = a11yStreamAlias;
2269         mStreamVolumeAlias[AudioSystem.STREAM_ASSISTANT] = assistantStreamAlias;
2270 
2271         if (updateVolumes && mStreamStates != null) {
2272             updateDefaultVolumes();
2273 
2274             synchronized (mSettingsLock) {
2275                 synchronized (VolumeStreamState.class) {
2276                     mStreamStates[AudioSystem.STREAM_DTMF]
2277                             .setAllIndexes(mStreamStates[dtmfStreamAlias], caller);
2278                     mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setSettingName(
2279                             System.VOLUME_SETTINGS_INT[a11yStreamAlias]);
2280                     mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setAllIndexes(
2281                             mStreamStates[a11yStreamAlias], caller);
2282                 }
2283             }
2284             if (sIndependentA11yVolume) {
2285                 // restore the a11y values from the settings
2286                 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].readSettings();
2287             }
2288 
2289             // apply stream mute states according to new value of mRingerModeAffectedStreams
2290             setRingerModeInt(getRingerModeInternal(), false);
2291             sendMsg(mAudioHandler,
2292                     MSG_SET_ALL_VOLUMES,
2293                     SENDMSG_QUEUE,
2294                     0,
2295                     0,
2296                     mStreamStates[AudioSystem.STREAM_DTMF], 0);
2297             sendMsg(mAudioHandler,
2298                     MSG_SET_ALL_VOLUMES,
2299                     SENDMSG_QUEUE,
2300                     0,
2301                     0,
2302                     mStreamStates[AudioSystem.STREAM_ACCESSIBILITY], 0);
2303         }
2304         dispatchStreamAliasingUpdate();
2305     }
2306 
readDockAudioSettings(ContentResolver cr)2307     private void readDockAudioSettings(ContentResolver cr)
2308     {
2309         mDockAudioMediaEnabled = mSettings.getGlobalInt(
2310                                         cr, Settings.Global.DOCK_AUDIO_MEDIA_ENABLED, 0) == 1;
2311 
2312         sendMsg(mAudioHandler,
2313                 MSG_SET_FORCE_USE,
2314                 SENDMSG_QUEUE,
2315                 AudioSystem.FOR_DOCK,
2316                 mDockAudioMediaEnabled ?
2317                         AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE,
2318                 new String("readDockAudioSettings"),
2319                 0);
2320 
2321     }
2322 
2323 
updateMasterMono(ContentResolver cr)2324     private void updateMasterMono(ContentResolver cr)
2325     {
2326         final boolean masterMono = mSettings.getSystemIntForUser(
2327                 cr, System.MASTER_MONO, 0 /* default */, UserHandle.USER_CURRENT) == 1;
2328         if (DEBUG_VOL) {
2329             Log.d(TAG, String.format("Master mono %b", masterMono));
2330         }
2331         AudioSystem.setMasterMono(masterMono);
2332     }
2333 
updateMasterBalance(ContentResolver cr)2334     private void updateMasterBalance(ContentResolver cr) {
2335         final float masterBalance = System.getFloatForUser(
2336                 cr, System.MASTER_BALANCE, 0.f /* default */, UserHandle.USER_CURRENT);
2337         if (DEBUG_VOL) {
2338             Log.d(TAG, String.format("Master balance %f", masterBalance));
2339         }
2340         if (AudioSystem.setMasterBalance(masterBalance) != 0) {
2341             Log.e(TAG, String.format("setMasterBalance failed for %f", masterBalance));
2342         }
2343     }
2344 
sendEncodedSurroundMode(ContentResolver cr, String eventSource)2345     private void sendEncodedSurroundMode(ContentResolver cr, String eventSource)
2346     {
2347         final int encodedSurroundMode = mSettings.getGlobalInt(
2348                 cr, Settings.Global.ENCODED_SURROUND_OUTPUT,
2349                 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
2350         sendEncodedSurroundMode(encodedSurroundMode, eventSource);
2351     }
2352 
sendEncodedSurroundMode(int encodedSurroundMode, String eventSource)2353     private void sendEncodedSurroundMode(int encodedSurroundMode, String eventSource)
2354     {
2355         // initialize to guaranteed bad value
2356         int forceSetting = AudioSystem.NUM_FORCE_CONFIG;
2357         switch (encodedSurroundMode) {
2358             case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO:
2359                 forceSetting = AudioSystem.FORCE_NONE;
2360                 break;
2361             case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER:
2362                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_NEVER;
2363                 break;
2364             case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS:
2365                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_ALWAYS;
2366                 break;
2367             case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL:
2368                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_MANUAL;
2369                 break;
2370             default:
2371                 Log.e(TAG, "updateSurroundSoundSettings: illegal value "
2372                         + encodedSurroundMode);
2373                 break;
2374         }
2375         if (forceSetting != AudioSystem.NUM_FORCE_CONFIG) {
2376             mDeviceBroker.setForceUse_Async(AudioSystem.FOR_ENCODED_SURROUND, forceSetting,
2377                     eventSource);
2378         }
2379     }
2380 
2381     @Override // Binder call
onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)2382     public void onShellCommand(FileDescriptor in, FileDescriptor out,
2383             FileDescriptor err, String[] args, ShellCallback callback,
2384             ResultReceiver resultReceiver) {
2385         if (mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_AUDIO_POLICY)
2386                 != PackageManager.PERMISSION_GRANTED) {
2387             throw new SecurityException("Missing MANAGE_AUDIO_POLICY permission");
2388         }
2389         new AudioManagerShellCommand(AudioService.this).exec(this, in, out, err,
2390                 args, callback, resultReceiver);
2391     }
2392 
2393     /** @see AudioManager#getSurroundFormats() */
2394     @Override
getSurroundFormats()2395     public Map<Integer, Boolean> getSurroundFormats() {
2396         Map<Integer, Boolean> surroundFormats = new HashMap<>();
2397         int status = AudioSystem.getSurroundFormats(surroundFormats);
2398         if (status != AudioManager.SUCCESS) {
2399             // fail and bail!
2400             Log.e(TAG, "getSurroundFormats failed:" + status);
2401             return new HashMap<>(); // Always return a map.
2402         }
2403         return surroundFormats;
2404     }
2405 
2406     /** @see AudioManager#getReportedSurroundFormats() */
2407     @Override
getReportedSurroundFormats()2408     public List<Integer> getReportedSurroundFormats() {
2409         ArrayList<Integer> reportedSurroundFormats = new ArrayList<>();
2410         int status = AudioSystem.getReportedSurroundFormats(reportedSurroundFormats);
2411         if (status != AudioManager.SUCCESS) {
2412             // fail and bail!
2413             Log.e(TAG, "getReportedSurroundFormats failed:" + status);
2414             return new ArrayList<>(); // Always return a list.
2415         }
2416         return reportedSurroundFormats;
2417     }
2418 
2419     /** @see AudioManager#isSurroundFormatEnabled(int) */
2420     @Override
isSurroundFormatEnabled(int audioFormat)2421     public boolean isSurroundFormatEnabled(int audioFormat) {
2422         if (!isSurroundFormat(audioFormat)) {
2423             Log.w(TAG, "audioFormat to enable is not a surround format.");
2424             return false;
2425         }
2426 
2427         final long token = Binder.clearCallingIdentity();
2428         try {
2429             synchronized (mSettingsLock) {
2430                 HashSet<Integer> enabledFormats = getEnabledFormats();
2431                 return enabledFormats.contains(audioFormat);
2432             }
2433         } finally {
2434             Binder.restoreCallingIdentity(token);
2435         }
2436     }
2437 
2438     /** @see AudioManager#setSurroundFormatEnabled(int, boolean) */
2439     @Override
setSurroundFormatEnabled(int audioFormat, boolean enabled)2440     public boolean setSurroundFormatEnabled(int audioFormat, boolean enabled) {
2441         if (!isSurroundFormat(audioFormat)) {
2442             Log.w(TAG, "audioFormat to enable is not a surround format.");
2443             return false;
2444         }
2445         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS)
2446                 != PackageManager.PERMISSION_GRANTED) {
2447             throw new SecurityException("Missing WRITE_SETTINGS permission");
2448         }
2449 
2450         HashSet<Integer> enabledFormats = getEnabledFormats();
2451         if (enabled) {
2452             enabledFormats.add(audioFormat);
2453         } else {
2454             enabledFormats.remove(audioFormat);
2455         }
2456         final long token = Binder.clearCallingIdentity();
2457         try {
2458             synchronized (mSettingsLock) {
2459                 mSettings.putGlobalString(mContentResolver,
2460                         Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
2461                         TextUtils.join(",", enabledFormats));
2462             }
2463         } finally {
2464             Binder.restoreCallingIdentity(token);
2465         }
2466         return true;
2467     }
2468 
2469     /** @see AudioManager#setEncodedSurroundMode(int) */
2470     @Override
setEncodedSurroundMode(@udioManager.EncodedSurroundOutputMode int mode)2471     public boolean setEncodedSurroundMode(@AudioManager.EncodedSurroundOutputMode int mode) {
2472         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS)
2473                 != PackageManager.PERMISSION_GRANTED) {
2474             throw new SecurityException("Missing WRITE_SETTINGS permission");
2475         }
2476 
2477         final long token = Binder.clearCallingIdentity();
2478         try {
2479             synchronized (mSettingsLock) {
2480                 mSettings.putGlobalInt(mContentResolver,
2481                         Settings.Global.ENCODED_SURROUND_OUTPUT,
2482                         toEncodedSurroundSetting(mode));
2483             }
2484         } finally {
2485             Binder.restoreCallingIdentity(token);
2486         }
2487         return true;
2488     }
2489 
2490     /** @see AudioManager#getEncodedSurroundMode() */
2491     @Override
getEncodedSurroundMode(int targetSdkVersion)2492     public int getEncodedSurroundMode(int targetSdkVersion) {
2493         final long token = Binder.clearCallingIdentity();
2494         try {
2495             synchronized (mSettingsLock) {
2496                 int encodedSurroundSetting = mSettings.getGlobalInt(mContentResolver,
2497                         Settings.Global.ENCODED_SURROUND_OUTPUT,
2498                         AudioManager.ENCODED_SURROUND_OUTPUT_AUTO);
2499                 return toEncodedSurroundOutputMode(encodedSurroundSetting, targetSdkVersion);
2500             }
2501         } finally {
2502             Binder.restoreCallingIdentity(token);
2503         }
2504     }
2505 
2506     /** @return the formats that are enabled in global settings */
getEnabledFormats()2507     private HashSet<Integer> getEnabledFormats() {
2508         HashSet<Integer> formats = new HashSet<>();
2509         String enabledFormats = mSettings.getGlobalString(mContentResolver,
2510                 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
2511         if (enabledFormats != null) {
2512             try {
2513                 Arrays.stream(TextUtils.split(enabledFormats, ","))
2514                         .mapToInt(Integer::parseInt)
2515                         .forEach(formats::add);
2516             } catch (NumberFormatException e) {
2517                 Log.w(TAG, "ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS misformatted.", e);
2518             }
2519         }
2520         return formats;
2521     }
2522 
2523     @SuppressWarnings("AndroidFrameworkCompatChange")
2524     @AudioManager.EncodedSurroundOutputMode
toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion)2525     private int toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion) {
2526         if (targetSdkVersion <= Build.VERSION_CODES.S
2527                 && encodedSurroundSetting > Settings.Global.ENCODED_SURROUND_SC_MAX) {
2528             return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN;
2529         }
2530         switch (encodedSurroundSetting) {
2531             case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO:
2532                 return AudioManager.ENCODED_SURROUND_OUTPUT_AUTO;
2533             case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER:
2534                 return AudioManager.ENCODED_SURROUND_OUTPUT_NEVER;
2535             case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS:
2536                 return AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS;
2537             case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL:
2538                 return AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL;
2539             default:
2540                 return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN;
2541         }
2542     }
2543 
toEncodedSurroundSetting( @udioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode)2544     private int toEncodedSurroundSetting(
2545             @AudioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode) {
2546         switch (encodedSurroundOutputMode) {
2547             case AudioManager.ENCODED_SURROUND_OUTPUT_NEVER:
2548                 return Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER;
2549             case AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS:
2550                 return Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS;
2551             case AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL:
2552                 return Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL;
2553             default:
2554                 return Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO;
2555         }
2556     }
2557 
isSurroundFormat(int audioFormat)2558     private boolean isSurroundFormat(int audioFormat) {
2559         for (int sf : AudioFormat.SURROUND_SOUND_ENCODING) {
2560             if (sf == audioFormat) {
2561                 return true;
2562             }
2563         }
2564         return false;
2565     }
2566 
sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate)2567     private void sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate) {
2568         if (mEncodedSurroundMode != Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL) {
2569             // Manually enable surround formats only when the setting is in manual mode.
2570             return;
2571         }
2572         String enabledSurroundFormats = mSettings.getGlobalString(
2573                 cr, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
2574         if (enabledSurroundFormats == null) {
2575             // Never allow enabledSurroundFormats as a null, which could happen when
2576             // ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS is not appear in settings DB.
2577             enabledSurroundFormats = "";
2578         }
2579         if (!forceUpdate && TextUtils.equals(enabledSurroundFormats, mEnabledSurroundFormats)) {
2580             // Update enabled surround formats to AudioPolicyManager only when forceUpdate
2581             // is true or enabled surround formats changed.
2582             return;
2583         }
2584 
2585         mEnabledSurroundFormats = enabledSurroundFormats;
2586         String[] surroundFormats = TextUtils.split(enabledSurroundFormats, ",");
2587         ArrayList<Integer> formats = new ArrayList<>();
2588         for (String format : surroundFormats) {
2589             try {
2590                 int audioFormat = Integer.valueOf(format);
2591                 if (isSurroundFormat(audioFormat) && !formats.contains(audioFormat)) {
2592                     formats.add(audioFormat);
2593                 }
2594             } catch (Exception e) {
2595                 Log.e(TAG, "Invalid enabled surround format:" + format);
2596             }
2597         }
2598         // Set filtered surround formats to settings DB in case
2599         // there are invalid surround formats in original settings.
2600         mSettings.putGlobalString(mContext.getContentResolver(),
2601                 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
2602                 TextUtils.join(",", formats));
2603         sendMsg(mAudioHandler, MSG_ENABLE_SURROUND_FORMATS, SENDMSG_QUEUE, 0, 0, formats, 0);
2604     }
2605 
onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats)2606     private void onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats) {
2607         // Set surround format enabled accordingly.
2608         for (int surroundFormat : AudioFormat.SURROUND_SOUND_ENCODING) {
2609             boolean enabled = enabledSurroundFormats.contains(surroundFormat);
2610             int ret = AudioSystem.setSurroundFormatEnabled(surroundFormat, enabled);
2611             Log.i(TAG, "enable surround format:" + surroundFormat + " " + enabled + " " + ret);
2612         }
2613     }
2614 
2615     @GuardedBy("mSettingsLock")
updateAssistantUIdLocked(boolean forceUpdate)2616     private void updateAssistantUIdLocked(boolean forceUpdate) {
2617         int assistantUid = INVALID_UID;
2618         // Consider assistants in the following order of priority:
2619         // 1) apk in assistant role
2620         // 2) voice interaction service
2621         // 3) assistant service
2622 
2623         String packageName = "";
2624         if (mRoleObserver != null) {
2625             packageName = mRoleObserver.getAssistantRoleHolder();
2626         }
2627         if (TextUtils.isEmpty(packageName)) {
2628             String assistantName = mSettings.getSecureStringForUser(
2629                             mContentResolver,
2630                             Settings.Secure.VOICE_INTERACTION_SERVICE, UserHandle.USER_CURRENT);
2631             if (TextUtils.isEmpty(assistantName)) {
2632                 assistantName = mSettings.getSecureStringForUser(
2633                         mContentResolver,
2634                         Settings.Secure.ASSISTANT, UserHandle.USER_CURRENT);
2635             }
2636             if (!TextUtils.isEmpty(assistantName)) {
2637                 ComponentName componentName = ComponentName.unflattenFromString(assistantName);
2638                 if (componentName == null) {
2639                     Slog.w(TAG, "Invalid service name for "
2640                             + Settings.Secure.VOICE_INTERACTION_SERVICE + ": " + assistantName);
2641                     return;
2642                 }
2643                 packageName = componentName.getPackageName();
2644             }
2645         }
2646         if (!TextUtils.isEmpty(packageName)) {
2647             PackageManager pm = mContext.getPackageManager();
2648 
2649             if (pm.checkPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD, packageName)
2650                     == PackageManager.PERMISSION_GRANTED) {
2651                 try {
2652                     assistantUid = pm.getPackageUidAsUser(packageName, getCurrentUserId());
2653                 } catch (PackageManager.NameNotFoundException e) {
2654                     Log.e(TAG,
2655                             "updateAssistantUId() could not find UID for package: " + packageName);
2656                 }
2657             }
2658         }
2659         if ((mPrimaryAssistantUid != assistantUid) || forceUpdate) {
2660             mAssistantUids.remove(mPrimaryAssistantUid);
2661             mPrimaryAssistantUid = assistantUid;
2662             addAssistantServiceUidsLocked(new int[]{mPrimaryAssistantUid});
2663         }
2664     }
2665 
readPersistedSettings()2666     private void readPersistedSettings() {
2667         if (!mSystemServer.isPrivileged()) {
2668             return;
2669         }
2670         final ContentResolver cr = mContentResolver;
2671 
2672         int ringerModeFromSettings =
2673                 mSettings.getGlobalInt(
2674                         cr, Settings.Global.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
2675         int ringerMode = ringerModeFromSettings;
2676         // validity check in case the settings are restored from a device with incompatible
2677         // ringer modes
2678         if (!isValidRingerMode(ringerMode)) {
2679             ringerMode = AudioManager.RINGER_MODE_NORMAL;
2680         }
2681         if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) {
2682             ringerMode = AudioManager.RINGER_MODE_SILENT;
2683         }
2684         if (ringerMode != ringerModeFromSettings) {
2685             mSettings.putGlobalInt(cr, Settings.Global.MODE_RINGER, ringerMode);
2686         }
2687         if (mUseFixedVolume || mIsSingleVolume) {
2688             ringerMode = AudioManager.RINGER_MODE_NORMAL;
2689         }
2690         synchronized(mSettingsLock) {
2691             mRingerMode = ringerMode;
2692             if (mRingerModeExternal == -1) {
2693                 mRingerModeExternal = mRingerMode;
2694             }
2695 
2696             // System.VIBRATE_ON is not used any more but defaults for mVibrateSetting
2697             // are still needed while setVibrateSetting() and getVibrateSetting() are being
2698             // deprecated.
2699             mVibrateSetting = AudioSystem.getValueForVibrateSetting(0,
2700                                             AudioManager.VIBRATE_TYPE_NOTIFICATION,
2701                                             mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT
2702                                                             : AudioManager.VIBRATE_SETTING_OFF);
2703             mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting,
2704                                             AudioManager.VIBRATE_TYPE_RINGER,
2705                                             mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT
2706                                                             : AudioManager.VIBRATE_SETTING_OFF);
2707 
2708             updateRingerAndZenModeAffectedStreams();
2709             readDockAudioSettings(cr);
2710             sendEncodedSurroundMode(cr, "readPersistedSettings");
2711             sendEnabledSurroundFormats(cr, true);
2712             updateAssistantUIdLocked(/* forceUpdate= */ true);
2713             resetActiveAssistantUidsLocked();
2714             AudioSystem.setRttEnabled(mRttEnabled);
2715         }
2716 
2717         mMuteAffectedStreams = mSettings.getSystemIntForUser(cr,
2718                 System.MUTE_STREAMS_AFFECTED, AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED,
2719                 UserHandle.USER_CURRENT);
2720 
2721         updateMasterMono(cr);
2722 
2723         updateMasterBalance(cr);
2724 
2725         // Each stream will read its own persisted settings
2726 
2727         // Broadcast the sticky intents
2728         broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, mRingerModeExternal);
2729         broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, mRingerMode);
2730 
2731         // Broadcast vibrate settings
2732         broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
2733         broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION);
2734 
2735         // Load settings for the volume controller
2736         mVolumeController.loadSettings(cr);
2737     }
2738 
2739     @GuardedBy("mSettingsLock")
resetActiveAssistantUidsLocked()2740     private void resetActiveAssistantUidsLocked() {
2741         mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS;
2742         updateActiveAssistantServiceUids();
2743     }
2744 
readUserRestrictions()2745     private void readUserRestrictions() {
2746         if (!mSystemServer.isPrivileged()) {
2747             return;
2748         }
2749         final int currentUser = getCurrentUserId();
2750 
2751         // Check the current user restriction.
2752         boolean masterMute =
2753                 mUserManagerInternal.getUserRestriction(currentUser,
2754                         UserManager.DISALLOW_UNMUTE_DEVICE)
2755                         || mUserManagerInternal.getUserRestriction(currentUser,
2756                         UserManager.DISALLOW_ADJUST_VOLUME);
2757         if (mUseFixedVolume) {
2758             masterMute = false;
2759             AudioSystem.setMasterVolume(1.0f);
2760         }
2761         if (DEBUG_VOL) {
2762             Log.d(TAG, String.format("Master mute %s, user=%d", masterMute, currentUser));
2763         }
2764         AudioSystem.setMasterMute(masterMute);
2765         broadcastMasterMuteStatus(masterMute);
2766 
2767         mMicMuteFromRestrictions = mUserManagerInternal.getUserRestriction(
2768                 currentUser, UserManager.DISALLOW_UNMUTE_MICROPHONE);
2769         if (DEBUG_VOL) {
2770             Log.d(TAG, String.format("Mic mute %b, user=%d", mMicMuteFromRestrictions,
2771                     currentUser));
2772         }
2773         setMicrophoneMuteNoCallerCheck(currentUser);
2774     }
2775 
getIndexRange(int streamType)2776     private int getIndexRange(int streamType) {
2777         return (mStreamStates[streamType].getMaxIndex() - mStreamStates[streamType].getMinIndex());
2778     }
2779 
rescaleIndex(VolumeInfo volumeInfo, int dstStream)2780     private int rescaleIndex(VolumeInfo volumeInfo, int dstStream) {
2781         if (volumeInfo.getVolumeIndex() == VolumeInfo.INDEX_NOT_SET
2782                 || volumeInfo.getMinVolumeIndex() == VolumeInfo.INDEX_NOT_SET
2783                 || volumeInfo.getMaxVolumeIndex() == VolumeInfo.INDEX_NOT_SET) {
2784             Log.e(TAG, "rescaleIndex: volumeInfo has invalid index or range");
2785             return mStreamStates[dstStream].getMinIndex();
2786         }
2787         return rescaleIndex(volumeInfo.getVolumeIndex(),
2788                 volumeInfo.getMinVolumeIndex(), volumeInfo.getMaxVolumeIndex(),
2789                 mStreamStates[dstStream].getMinIndex(), mStreamStates[dstStream].getMaxIndex());
2790     }
2791 
rescaleIndex(int index, int srcStream, VolumeInfo dstVolumeInfo)2792     private int rescaleIndex(int index, int srcStream, VolumeInfo dstVolumeInfo) {
2793         int dstMin = dstVolumeInfo.getMinVolumeIndex();
2794         int dstMax = dstVolumeInfo.getMaxVolumeIndex();
2795         // Don't rescale index if the VolumeInfo is missing a min or max index
2796         if (dstMin == VolumeInfo.INDEX_NOT_SET || dstMax == VolumeInfo.INDEX_NOT_SET) {
2797             return index;
2798         }
2799         return rescaleIndex(index,
2800                 mStreamStates[srcStream].getMinIndex(), mStreamStates[srcStream].getMaxIndex(),
2801                 dstMin, dstMax);
2802     }
2803 
rescaleIndex(int index, int srcStream, int dstStream)2804     private int rescaleIndex(int index, int srcStream, int dstStream) {
2805         return rescaleIndex(index,
2806                 mStreamStates[srcStream].getMinIndex(), mStreamStates[srcStream].getMaxIndex(),
2807                 mStreamStates[dstStream].getMinIndex(), mStreamStates[dstStream].getMaxIndex());
2808     }
2809 
rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax)2810     private int rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax) {
2811         int srcRange = srcMax - srcMin;
2812         int dstRange = dstMax - dstMin;
2813         if (srcRange == 0) {
2814             Log.e(TAG, "rescaleIndex : index range should not be zero");
2815             return dstMin;
2816         }
2817         return dstMin + ((index - srcMin) * dstRange + srcRange / 2) / srcRange;
2818     }
2819 
rescaleStep(int step, int srcStream, int dstStream)2820     private int rescaleStep(int step, int srcStream, int dstStream) {
2821         int srcRange = getIndexRange(srcStream);
2822         int dstRange = getIndexRange(dstStream);
2823         if (srcRange == 0) {
2824             Log.e(TAG, "rescaleStep : index range should not be zero");
2825             return 0;
2826         }
2827 
2828         return ((step * dstRange + srcRange / 2) / srcRange);
2829     }
2830 
2831     ///////////////////////////////////////////////////////////////////////////
2832     // IPC methods
2833     ///////////////////////////////////////////////////////////////////////////
2834     /**
2835      * @see AudioManager#setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes)
2836      * @see AudioManager#setPreferredDevicesForStrategy(AudioProductStrategy,
2837      *                                                  List<AudioDeviceAttributes>)
2838      */
2839     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices)2840     public int setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices) {
2841         super.setPreferredDevicesForStrategy_enforcePermission();
2842         if (devices == null) {
2843             return AudioSystem.ERROR;
2844         }
2845         final String logString = String.format(
2846                 "setPreferredDeviceForStrategy u/pid:%d/%d strat:%d dev:%s",
2847                 Binder.getCallingUid(), Binder.getCallingPid(), strategy,
2848                 devices.stream().map(e -> e.toString()).collect(Collectors.joining(",")));
2849         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
2850         if (devices.stream().anyMatch(device ->
2851                 device.getRole() == AudioDeviceAttributes.ROLE_INPUT)) {
2852             Log.e(TAG, "Unsupported input routing in " + logString);
2853             return AudioSystem.ERROR;
2854         }
2855 
2856         final int status = mDeviceBroker.setPreferredDevicesForStrategySync(strategy, devices);
2857         if (status != AudioSystem.SUCCESS) {
2858             Log.e(TAG, String.format("Error %d in %s)", status, logString));
2859         }
2860 
2861         return status;
2862     }
2863 
2864     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
2865     /** @see AudioManager#removePreferredDeviceForStrategy(AudioProductStrategy) */
removePreferredDevicesForStrategy(int strategy)2866     public int removePreferredDevicesForStrategy(int strategy) {
2867         super.removePreferredDevicesForStrategy_enforcePermission();
2868 
2869         final String logString =
2870                 String.format("removePreferredDeviceForStrategy strat:%d", strategy);
2871         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
2872 
2873         final int status = mDeviceBroker.removePreferredDevicesForStrategySync(strategy);
2874         if (status != AudioSystem.SUCCESS) {
2875             Log.e(TAG, String.format("Error %d in %s)", status, logString));
2876         }
2877         return status;
2878     }
2879 
2880     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
2881     /**
2882      * @see AudioManager#getPreferredDeviceForStrategy(AudioProductStrategy)
2883      * @see AudioManager#getPreferredDevicesForStrategy(AudioProductStrategy)
2884      */
getPreferredDevicesForStrategy(int strategy)2885     public List<AudioDeviceAttributes> getPreferredDevicesForStrategy(int strategy) {
2886         super.getPreferredDevicesForStrategy_enforcePermission();
2887 
2888         List<AudioDeviceAttributes> devices = new ArrayList<>();
2889         int status = AudioSystem.SUCCESS;
2890         final long identity = Binder.clearCallingIdentity();
2891         try {
2892             status = AudioSystem.getDevicesForRoleAndStrategy(
2893                     strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
2894         } finally {
2895             Binder.restoreCallingIdentity(identity);
2896         }
2897         if (status != AudioSystem.SUCCESS) {
2898             Log.e(TAG, String.format("Error %d in getPreferredDeviceForStrategy(%d)",
2899                     status, strategy));
2900             return new ArrayList<AudioDeviceAttributes>();
2901         } else {
2902             return devices;
2903         }
2904     }
2905 
2906     /**
2907      * @see AudioManager#setDeviceAsNonDefaultForStrategy(AudioProductStrategy,
2908      *                                                    AudioDeviceAttributes)
2909      * @see AudioManager#setDeviceAsNonDefaultForStrategy(AudioProductStrategy,
2910      *                                                     List<AudioDeviceAttributes>)
2911      */
2912     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
setDeviceAsNonDefaultForStrategy(int strategy, @NonNull AudioDeviceAttributes device)2913     public int setDeviceAsNonDefaultForStrategy(int strategy,
2914                                                 @NonNull AudioDeviceAttributes device) {
2915         super.setDeviceAsNonDefaultForStrategy_enforcePermission();
2916         Objects.requireNonNull(device);
2917         final String logString = String.format(
2918                 "setDeviceAsNonDefaultForStrategy u/pid:%d/%d strat:%d dev:%s",
2919                 Binder.getCallingUid(), Binder.getCallingPid(), strategy, device.toString());
2920         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
2921         if (device.getRole() == AudioDeviceAttributes.ROLE_INPUT) {
2922             Log.e(TAG, "Unsupported input routing in " + logString);
2923             return AudioSystem.ERROR;
2924         }
2925 
2926         final int status = mDeviceBroker.setDeviceAsNonDefaultForStrategySync(strategy, device);
2927         if (status != AudioSystem.SUCCESS) {
2928             Log.e(TAG, String.format("Error %d in %s)", status, logString));
2929         }
2930 
2931         return status;
2932     }
2933 
2934     /**
2935      * @see AudioManager#removeDeviceAsNonDefaultForStrategy(AudioProductStrategy,
2936      *                                                       AudioDeviceAttributes)
2937      */
2938     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
removeDeviceAsNonDefaultForStrategy(int strategy, AudioDeviceAttributes device)2939     public int removeDeviceAsNonDefaultForStrategy(int strategy,
2940                                                    AudioDeviceAttributes device) {
2941         super.removeDeviceAsNonDefaultForStrategy_enforcePermission();
2942         Objects.requireNonNull(device);
2943         final String logString = String.format(
2944                 "removeDeviceAsNonDefaultForStrategy strat:%d dev:%s", strategy, device.toString());
2945         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
2946         if (device.getRole() == AudioDeviceAttributes.ROLE_INPUT) {
2947             Log.e(TAG, "Unsupported input routing in " + logString);
2948             return AudioSystem.ERROR;
2949         }
2950 
2951         final int status = mDeviceBroker.removeDeviceAsNonDefaultForStrategySync(strategy, device);
2952         if (status != AudioSystem.SUCCESS) {
2953             Log.e(TAG, String.format("Error %d in %s)", status, logString));
2954         }
2955         return status;
2956     }
2957 
2958     /**
2959      * @see AudioManager#getNonDefaultDevicesForStrategy(AudioProductStrategy)
2960      */
2961     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
getNonDefaultDevicesForStrategy(int strategy)2962     public List<AudioDeviceAttributes> getNonDefaultDevicesForStrategy(int strategy) {
2963         super.getNonDefaultDevicesForStrategy_enforcePermission();
2964         List<AudioDeviceAttributes> devices = new ArrayList<>();
2965         int status = AudioSystem.ERROR;
2966 
2967         try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
2968             status = AudioSystem.getDevicesForRoleAndStrategy(
2969                     strategy, AudioSystem.DEVICE_ROLE_DISABLED, devices);
2970         }
2971 
2972         if (status != AudioSystem.SUCCESS) {
2973             Log.e(TAG, String.format("Error %d in getNonDefaultDeviceForStrategy(%d)",
2974                     status, strategy));
2975             return new ArrayList<AudioDeviceAttributes>();
2976         } else {
2977             return devices;
2978         }
2979     }
2980 
2981     /** @see AudioManager#addOnPreferredDevicesForStrategyChangedListener(
2982      *               Executor, AudioManager.OnPreferredDevicesForStrategyChangedListener)
2983      */
registerStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)2984     public void registerStrategyPreferredDevicesDispatcher(
2985             @Nullable IStrategyPreferredDevicesDispatcher dispatcher) {
2986         if (dispatcher == null) {
2987             return;
2988         }
2989         enforceModifyAudioRoutingPermission();
2990         mDeviceBroker.registerStrategyPreferredDevicesDispatcher(dispatcher);
2991     }
2992 
2993     /** @see AudioManager#removeOnPreferredDevicesForStrategyChangedListener(
2994      *               AudioManager.OnPreferredDevicesForStrategyChangedListener)
2995      */
unregisterStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)2996     public void unregisterStrategyPreferredDevicesDispatcher(
2997             @Nullable IStrategyPreferredDevicesDispatcher dispatcher) {
2998         if (dispatcher == null) {
2999             return;
3000         }
3001         enforceModifyAudioRoutingPermission();
3002         mDeviceBroker.unregisterStrategyPreferredDevicesDispatcher(dispatcher);
3003     }
3004 
3005     /** @see AudioManager#addOnNonDefaultDevicesForStrategyChangedListener(
3006      *               Executor, AudioManager.OnNonDefaultDevicesForStrategyChangedListener)
3007      */
registerStrategyNonDefaultDevicesDispatcher( @ullable IStrategyNonDefaultDevicesDispatcher dispatcher)3008     public void registerStrategyNonDefaultDevicesDispatcher(
3009             @Nullable IStrategyNonDefaultDevicesDispatcher dispatcher) {
3010         if (dispatcher == null) {
3011             return;
3012         }
3013         enforceModifyAudioRoutingPermission();
3014         mDeviceBroker.registerStrategyNonDefaultDevicesDispatcher(dispatcher);
3015     }
3016 
3017     /** @see AudioManager#removeOnNonDefaultDevicesForStrategyChangedListener(
3018      *               AudioManager.OnNonDefaultDevicesForStrategyChangedListener)
3019      */
unregisterStrategyNonDefaultDevicesDispatcher( @ullable IStrategyNonDefaultDevicesDispatcher dispatcher)3020     public void unregisterStrategyNonDefaultDevicesDispatcher(
3021             @Nullable IStrategyNonDefaultDevicesDispatcher dispatcher) {
3022         if (dispatcher == null) {
3023             return;
3024         }
3025         enforceModifyAudioRoutingPermission();
3026         mDeviceBroker.unregisterStrategyNonDefaultDevicesDispatcher(dispatcher);
3027     }
3028 
3029     /**
3030      * @see AudioManager#setPreferredDeviceForCapturePreset(int, AudioDeviceAttributes)
3031      */
setPreferredDevicesForCapturePreset( int capturePreset, List<AudioDeviceAttributes> devices)3032     public int setPreferredDevicesForCapturePreset(
3033             int capturePreset, List<AudioDeviceAttributes> devices) {
3034         if (devices == null) {
3035             return AudioSystem.ERROR;
3036         }
3037         enforceModifyAudioRoutingPermission();
3038         final String logString = String.format(
3039                 "setPreferredDevicesForCapturePreset u/pid:%d/%d source:%d dev:%s",
3040                 Binder.getCallingUid(), Binder.getCallingPid(), capturePreset,
3041                 devices.stream().map(e -> e.toString()).collect(Collectors.joining(",")));
3042         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
3043         if (devices.stream().anyMatch(device ->
3044                 device.getRole() == AudioDeviceAttributes.ROLE_OUTPUT)) {
3045             Log.e(TAG, "Unsupported output routing in " + logString);
3046             return AudioSystem.ERROR;
3047         }
3048 
3049         final int status = mDeviceBroker.setPreferredDevicesForCapturePresetSync(
3050                 capturePreset, devices);
3051         if (status != AudioSystem.SUCCESS) {
3052             Log.e(TAG, String.format("Error %d in %s)", status, logString));
3053         }
3054 
3055         return status;
3056     }
3057 
3058     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
3059     /** @see AudioManager#clearPreferredDevicesForCapturePreset(int) */
clearPreferredDevicesForCapturePreset(int capturePreset)3060     public int clearPreferredDevicesForCapturePreset(int capturePreset) {
3061         super.clearPreferredDevicesForCapturePreset_enforcePermission();
3062 
3063         final String logString = String.format(
3064                 "removePreferredDeviceForCapturePreset source:%d", capturePreset);
3065         sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
3066 
3067         final int status = mDeviceBroker.clearPreferredDevicesForCapturePresetSync(capturePreset);
3068         if (status != AudioSystem.SUCCESS) {
3069             Log.e(TAG, String.format("Error %d in %s", status, logString));
3070         }
3071         return status;
3072     }
3073 
3074     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
3075     /**
3076      * @see AudioManager#getPreferredDevicesForCapturePreset(int)
3077      */
getPreferredDevicesForCapturePreset(int capturePreset)3078     public List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int capturePreset) {
3079         super.getPreferredDevicesForCapturePreset_enforcePermission();
3080 
3081         List<AudioDeviceAttributes> devices = new ArrayList<>();
3082         int status = AudioSystem.SUCCESS;
3083         final long identity = Binder.clearCallingIdentity();
3084         try {
3085             status = AudioSystem.getDevicesForRoleAndCapturePreset(
3086                     capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
3087         } finally {
3088             Binder.restoreCallingIdentity(identity);
3089         }
3090         if (status != AudioSystem.SUCCESS) {
3091             Log.e(TAG, String.format("Error %d in getPreferredDeviceForCapturePreset(%d)",
3092                     status, capturePreset));
3093             return new ArrayList<AudioDeviceAttributes>();
3094         } else {
3095             return devices;
3096         }
3097     }
3098 
3099     /**
3100      * @see AudioManager#addOnPreferredDevicesForCapturePresetChangedListener(
3101      *              Executor, OnPreferredDevicesForCapturePresetChangedListener)
3102      */
registerCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)3103     public void registerCapturePresetDevicesRoleDispatcher(
3104             @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) {
3105         if (dispatcher == null) {
3106             return;
3107         }
3108         enforceModifyAudioRoutingPermission();
3109         mDeviceBroker.registerCapturePresetDevicesRoleDispatcher(dispatcher);
3110     }
3111 
3112     /**
3113      * @see AudioManager#removeOnPreferredDevicesForCapturePresetChangedListener(
3114      *              AudioManager.OnPreferredDevicesForCapturePresetChangedListener)
3115      */
unregisterCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)3116     public void unregisterCapturePresetDevicesRoleDispatcher(
3117             @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) {
3118         if (dispatcher == null) {
3119             return;
3120         }
3121         enforceModifyAudioRoutingPermission();
3122         mDeviceBroker.unregisterCapturePresetDevicesRoleDispatcher(dispatcher);
3123     }
3124 
3125     /** @see AudioManager#getDevicesForAttributes(AudioAttributes) */
getDevicesForAttributes( @onNull AudioAttributes attributes)3126     public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes(
3127             @NonNull AudioAttributes attributes) {
3128         enforceQueryStateOrModifyRoutingPermission();
3129         return getDevicesForAttributesInt(attributes, false /* forVolume */);
3130     }
3131 
3132     /** @see AudioManager#getAudioDevicesForAttributes(AudioAttributes)
3133      * This method is similar with AudioService#getDevicesForAttributes,
3134      * only it doesn't enforce permissions because it is used by an unprivileged public API
3135      * instead of the system API.
3136      */
getDevicesForAttributesUnprotected( @onNull AudioAttributes attributes)3137     public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesUnprotected(
3138             @NonNull AudioAttributes attributes) {
3139         return getDevicesForAttributesInt(attributes, false /* forVolume */);
3140     }
3141 
3142     /**
3143      * @see AudioManager#isMusicActive()
3144      * @param remotely true if query is for remote playback (cast), false for local playback.
3145      */
isMusicActive(boolean remotely)3146     public boolean isMusicActive(boolean remotely) {
3147         // no permission required
3148         final long token = Binder.clearCallingIdentity();
3149         try {
3150             if (remotely) {
3151                 return AudioSystem.isStreamActiveRemotely(AudioSystem.STREAM_MUSIC, 0);
3152             } else {
3153                 return AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0);
3154             }
3155         } finally {
3156             Binder.restoreCallingIdentity(token);
3157         }
3158     }
3159 
getDevicesForAttributesInt( @onNull AudioAttributes attributes, boolean forVolume)3160     protected @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesInt(
3161             @NonNull AudioAttributes attributes, boolean forVolume) {
3162         Objects.requireNonNull(attributes);
3163         return mAudioSystem.getDevicesForAttributes(attributes, forVolume);
3164     }
3165 
3166     /**
3167      * @see AudioManager#addOnDevicesForAttributesChangedListener(
3168      *      AudioAttributes, Executor, OnDevicesForAttributesChangedListener)
3169      */
addOnDevicesForAttributesChangedListener(AudioAttributes attributes, IDevicesForAttributesCallback callback)3170     public void addOnDevicesForAttributesChangedListener(AudioAttributes attributes,
3171             IDevicesForAttributesCallback callback) {
3172         mAudioSystem.addOnDevicesForAttributesChangedListener(
3173                 attributes, false /* forVolume */, callback);
3174     }
3175 
3176     /**
3177      * @see AudioManager#removeOnDevicesForAttributesChangedListener(
3178      *      OnDevicesForAttributesChangedListener)
3179      */
removeOnDevicesForAttributesChangedListener( IDevicesForAttributesCallback callback)3180     public void removeOnDevicesForAttributesChangedListener(
3181             IDevicesForAttributesCallback callback) {
3182         mAudioSystem.removeOnDevicesForAttributesChangedListener(callback);
3183     }
3184 
3185     // pre-condition: event.getKeyCode() is one of KeyEvent.KEYCODE_VOLUME_UP,
3186     //                                   KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_MUTE
handleVolumeKey(@onNull KeyEvent event, boolean isOnTv, @NonNull String callingPackage, @NonNull String caller)3187     public void handleVolumeKey(@NonNull KeyEvent event, boolean isOnTv,
3188             @NonNull String callingPackage, @NonNull String caller) {
3189         int keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_NORMAL;
3190         if (isOnTv) {
3191             if (event.getAction() == KeyEvent.ACTION_DOWN) {
3192                 keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_START;
3193             } else { // may catch more than ACTION_UP, but will end vol adjustement
3194                 // the vol key is either released (ACTION_UP), or multiple keys are pressed
3195                 // (ACTION_MULTIPLE) and we don't know what to do for volume control on CEC, end
3196                 // the repeated volume adjustement
3197                 keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_END;
3198             }
3199         } else if (event.getAction() != KeyEvent.ACTION_DOWN) {
3200             return;
3201         }
3202 
3203         int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND
3204                 | AudioManager.FLAG_FROM_KEY;
3205 
3206         switch (event.getKeyCode()) {
3207             case KeyEvent.KEYCODE_VOLUME_UP:
3208                     adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE,
3209                             AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller,
3210                             Binder.getCallingUid(), Binder.getCallingPid(), true, keyEventMode);
3211                 break;
3212             case KeyEvent.KEYCODE_VOLUME_DOWN:
3213                     adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER,
3214                             AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller,
3215                             Binder.getCallingUid(), Binder.getCallingPid(), true, keyEventMode);
3216                 break;
3217             case KeyEvent.KEYCODE_VOLUME_MUTE:
3218                 if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
3219                     adjustSuggestedStreamVolume(AudioManager.ADJUST_TOGGLE_MUTE,
3220                             AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller,
3221                             Binder.getCallingUid(), Binder.getCallingPid(),
3222                             true, AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
3223                 }
3224                 break;
3225             default:
3226                 Log.e(TAG, "Invalid key code " + event.getKeyCode() + " sent by " + callingPackage);
3227                 return; // not needed but added if code gets added below this switch statement
3228         }
3229     }
3230 
setNavigationRepeatSoundEffectsEnabled(boolean enabled)3231     public void setNavigationRepeatSoundEffectsEnabled(boolean enabled) {
3232         mNavigationRepeatSoundEffectsEnabled = enabled;
3233     }
3234 
3235     /**
3236      * @return true if the fast scroll sound effects are enabled
3237      */
areNavigationRepeatSoundEffectsEnabled()3238     public boolean areNavigationRepeatSoundEffectsEnabled() {
3239         return mNavigationRepeatSoundEffectsEnabled;
3240     }
3241 
setHomeSoundEffectEnabled(boolean enabled)3242     public void setHomeSoundEffectEnabled(boolean enabled) {
3243         mHomeSoundEffectEnabled = enabled;
3244     }
3245 
3246     /**
3247      * @return true if the home sound effect is enabled
3248      */
isHomeSoundEffectEnabled()3249     public boolean isHomeSoundEffectEnabled() {
3250         return mHomeSoundEffectEnabled;
3251     }
3252 
3253     /** 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)3254     private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
3255             String callingPackage, String caller, int uid, int pid, boolean hasModifyAudioSettings,
3256             int keyEventMode) {
3257         if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream=" + suggestedStreamType
3258                 + ", flags=" + flags + ", caller=" + caller
3259                 + ", volControlStream=" + mVolumeControlStream
3260                 + ", userSelect=" + mUserSelectedVolumeControlStream);
3261         if (direction != AudioManager.ADJUST_SAME) {
3262             sVolumeLogger.enqueue(
3263                     new VolumeEvent(VolumeEvent.VOL_ADJUST_SUGG_VOL, suggestedStreamType,
3264                             direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage)
3265                             .append("/").append(caller).append(" uid:").append(uid).toString()));
3266         }
3267 
3268         boolean hasExternalVolumeController = notifyExternalVolumeController(direction);
3269 
3270         new MediaMetrics.Item(mMetricsId + "adjustSuggestedStreamVolume")
3271                 .setUid(Binder.getCallingUid())
3272                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage)
3273                 .set(MediaMetrics.Property.CLIENT_NAME, caller)
3274                 .set(MediaMetrics.Property.DIRECTION, direction > 0
3275                         ? MediaMetrics.Value.UP : MediaMetrics.Value.DOWN)
3276                 .set(MediaMetrics.Property.EXTERNAL, hasExternalVolumeController
3277                         ? MediaMetrics.Value.YES : MediaMetrics.Value.NO)
3278                 .set(MediaMetrics.Property.FLAGS, flags)
3279                 .record();
3280 
3281         if (hasExternalVolumeController) {
3282             return;
3283         }
3284 
3285         final int streamType;
3286         synchronized (mForceControlStreamLock) {
3287             // Request lock in case mVolumeControlStream is changed by other thread.
3288             if (mUserSelectedVolumeControlStream) { // implies mVolumeControlStream != -1
3289                 streamType = mVolumeControlStream;
3290             } else {
3291                 // TODO discard activity on a muted stream?
3292                 final int maybeActiveStreamType = getActiveStreamType(suggestedStreamType);
3293                 final boolean activeForReal;
3294                 if (maybeActiveStreamType == AudioSystem.STREAM_RING
3295                         || maybeActiveStreamType == AudioSystem.STREAM_NOTIFICATION) {
3296                     activeForReal = wasStreamActiveRecently(maybeActiveStreamType, 0);
3297                 } else {
3298                     activeForReal = mAudioSystem.isStreamActive(maybeActiveStreamType, 0);
3299                 }
3300                 if (activeForReal || mVolumeControlStream == -1) {
3301                     streamType = maybeActiveStreamType;
3302                 } else {
3303                     streamType = mVolumeControlStream;
3304                 }
3305             }
3306         }
3307 
3308         final boolean isMute = isMuteAdjust(direction);
3309 
3310         ensureValidStreamType(streamType);
3311         final int resolvedStream = mStreamVolumeAlias[streamType];
3312 
3313         // Play sounds on STREAM_RING only.
3314         if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 &&
3315                 resolvedStream != AudioSystem.STREAM_RING) {
3316             flags &= ~AudioManager.FLAG_PLAY_SOUND;
3317         }
3318 
3319         // For notifications/ring, show the ui before making any adjustments
3320         // Don't suppress mute/unmute requests
3321         // Don't suppress adjustments for single volume device
3322         if (mVolumeController.suppressAdjustment(resolvedStream, flags, isMute)
3323                 && !mIsSingleVolume) {
3324             direction = 0;
3325             flags &= ~AudioManager.FLAG_PLAY_SOUND;
3326             flags &= ~AudioManager.FLAG_VIBRATE;
3327             if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment");
3328         }
3329 
3330         adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid, pid,
3331                 null, hasModifyAudioSettings, keyEventMode);
3332     }
3333 
notifyExternalVolumeController(int direction)3334     private boolean notifyExternalVolumeController(int direction) {
3335         final IAudioPolicyCallback externalVolumeController;
3336         synchronized (mExtVolumeControllerLock) {
3337             externalVolumeController = mExtVolumeController;
3338         }
3339         if (externalVolumeController == null) {
3340             return false;
3341         }
3342 
3343         sendMsg(mAudioHandler, MSG_NOTIFY_VOL_EVENT, SENDMSG_QUEUE,
3344                 direction, 0 /*ignored*/,
3345                 externalVolumeController, 0 /*delay*/);
3346         return true;
3347     }
3348 
3349     /** Retain API for unsupported app usage */
adjustStreamVolume(int streamType, int direction, int flags, String callingPackage)3350     public void adjustStreamVolume(int streamType, int direction, int flags,
3351             String callingPackage) {
3352         adjustStreamVolumeWithAttribution(streamType, direction, flags, callingPackage, null);
3353     }
3354 
3355     /** @see AudioManager#adjustStreamVolume(int, int, int)
3356      * Part of service interface, check permissions here */
adjustStreamVolumeWithAttribution(int streamType, int direction, int flags, String callingPackage, String attributionTag)3357     public void adjustStreamVolumeWithAttribution(int streamType, int direction, int flags,
3358             String callingPackage, String attributionTag) {
3359         if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {
3360             Log.w(TAG, "Trying to call adjustStreamVolume() for a11y without"
3361                     + "CHANGE_ACCESSIBILITY_VOLUME / callingPackage=" + callingPackage);
3362             return;
3363         }
3364 
3365         final VolumeEvent evt = new VolumeEvent(VolumeEvent.VOL_ADJUST_STREAM_VOL, streamType,
3366                 direction/*val1*/, flags/*val2*/, callingPackage);
3367         sVolumeLogger.enqueue(evt);
3368         // also logging mute/unmute calls to the dedicated logger
3369         if (isMuteAdjust(direction)) {
3370             sMuteLogger.enqueue(evt);
3371         }
3372         adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage,
3373                 Binder.getCallingUid(), Binder.getCallingPid(), attributionTag,
3374                 callingHasAudioSettingsPermission(), AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
3375     }
3376 
adjustStreamVolume(int streamType, int direction, int flags, String callingPackage, String caller, int uid, int pid, String attributionTag, boolean hasModifyAudioSettings, int keyEventMode)3377     protected void adjustStreamVolume(int streamType, int direction, int flags,
3378             String callingPackage, String caller, int uid, int pid, String attributionTag,
3379             boolean hasModifyAudioSettings, int keyEventMode) {
3380         if (mUseFixedVolume) {
3381             return;
3382         }
3383         if (DEBUG_VOL) Log.d(TAG, "adjustStreamVolume() stream=" + streamType + ", dir=" + direction
3384                 + ", flags=" + flags + ", caller=" + caller);
3385 
3386         ensureValidDirection(direction);
3387         ensureValidStreamType(streamType);
3388 
3389         boolean isMuteAdjust = isMuteAdjust(direction);
3390 
3391         if (isMuteAdjust && !isStreamAffectedByMute(streamType)) {
3392             return;
3393         }
3394 
3395         // If adjust is mute and the stream is STREAM_VOICE_CALL or STREAM_BLUETOOTH_SCO, make sure
3396         // that the calling app have the MODIFY_PHONE_STATE permission.
3397         if (isMuteAdjust &&
3398             (streamType == AudioSystem.STREAM_VOICE_CALL ||
3399                 streamType == AudioSystem.STREAM_BLUETOOTH_SCO) &&
3400                 mContext.checkPermission(android.Manifest.permission.MODIFY_PHONE_STATE, pid, uid)
3401                     != PackageManager.PERMISSION_GRANTED) {
3402             Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: adjustStreamVolume from pid="
3403                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
3404             return;
3405         }
3406 
3407         // If the stream is STREAM_ASSISTANT,
3408         // make sure that the calling app have the MODIFY_AUDIO_ROUTING permission.
3409         if (streamType == AudioSystem.STREAM_ASSISTANT &&
3410                 mContext.checkPermission(
3411                 android.Manifest.permission.MODIFY_AUDIO_ROUTING, pid, uid)
3412                     != PackageManager.PERMISSION_GRANTED) {
3413             Log.w(TAG, "MODIFY_AUDIO_ROUTING Permission Denial: adjustStreamVolume from pid="
3414                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
3415             return;
3416         }
3417 
3418         // use stream type alias here so that streams with same alias have the same behavior,
3419         // including with regard to silent mode control (e.g the use of STREAM_RING below and in
3420         // checkForRingerModeChange() in place of STREAM_RING or STREAM_NOTIFICATION)
3421         int streamTypeAlias = mStreamVolumeAlias[streamType];
3422 
3423         VolumeStreamState streamState = mStreamStates[streamTypeAlias];
3424 
3425         final int device = getDeviceForStream(streamTypeAlias);
3426 
3427         int aliasIndex = streamState.getIndex(device);
3428         boolean adjustVolume = true;
3429         int step;
3430 
3431         // skip a2dp absolute volume control request when the device
3432         // is neither an a2dp device nor BLE device
3433         if ((!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
3434                 && !AudioSystem.DEVICE_OUT_ALL_BLE_SET.contains(device))
3435                 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) {
3436             return;
3437         }
3438 
3439         // If we are being called by the system (e.g. hardware keys) check for current user
3440         // so we handle user restrictions correctly.
3441         if (uid == android.os.Process.SYSTEM_UID) {
3442             uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid));
3443         }
3444         // validate calling package and app op
3445         if (!checkNoteAppOp(
3446                 STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage, attributionTag)) {
3447             return;
3448         }
3449 
3450         mSoundDoseHelper.invalidatPendingVolumeCommand();
3451 
3452         flags &= ~AudioManager.FLAG_FIXED_VOLUME;
3453         if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) {
3454             flags |= AudioManager.FLAG_FIXED_VOLUME;
3455 
3456             // Always toggle between max safe volume and 0 for fixed volume devices where safe
3457             // volume is enforced, and max and 0 for the others.
3458             // This is simulated by stepping by the full allowed volume range
3459             step = mSoundDoseHelper.getSafeMediaVolumeIndex(device);
3460             if (step < 0) {
3461                 step = streamState.getMaxIndex();
3462             }
3463             if (aliasIndex != 0) {
3464                 aliasIndex = step;
3465             }
3466         } else {
3467             // convert one UI step (+/-1) into a number of internal units on the stream alias
3468             step = rescaleStep(10, streamType, streamTypeAlias);
3469         }
3470 
3471         // If either the client forces allowing ringer modes for this adjustment,
3472         // or stream is used for UI sonification
3473         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
3474                 (isUiSoundsStreamType(streamTypeAlias))) {
3475             int ringerMode = getRingerModeInternal();
3476             // do not vibrate if already in vibrate mode
3477             if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
3478                 flags &= ~AudioManager.FLAG_VIBRATE;
3479             }
3480             // Check if the ringer mode handles this adjustment. If it does we don't
3481             // need to adjust the volume further.
3482             final int result = checkForRingerModeChange(aliasIndex, direction, step,
3483                     streamState.mIsMuted, callingPackage, flags);
3484             adjustVolume = (result & FLAG_ADJUST_VOLUME) != 0;
3485             // If suppressing a volume adjustment in silent mode, display the UI hint
3486             if ((result & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) {
3487                 flags |= AudioManager.FLAG_SHOW_SILENT_HINT;
3488             }
3489             // If suppressing a volume down adjustment in vibrate mode, display the UI hint
3490             if ((result & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) {
3491                 flags |= AudioManager.FLAG_SHOW_VIBRATE_HINT;
3492             }
3493         } else if (isStreamMutedByRingerOrZenMode(streamTypeAlias) && streamState.mIsMuted) {
3494             // if the stream is currently muted streams by ringer/zen mode
3495             // then it cannot be unmuted (without FLAG_ALLOW_RINGER_MODES) with an unmute or raise
3496             if (direction == AudioManager.ADJUST_TOGGLE_MUTE
3497                     || direction == AudioManager.ADJUST_UNMUTE
3498                     || direction == AudioManager.ADJUST_RAISE) {
3499                 adjustVolume = false;
3500             }
3501         }
3502 
3503         // If the ringer mode or zen is muting the stream, do not change stream unless
3504         // it'll cause us to exit dnd
3505         if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) {
3506             adjustVolume = false;
3507         }
3508         int oldIndex = mStreamStates[streamType].getIndex(device);
3509 
3510         // Check if the volume adjustment should be handled by an absolute volume controller instead
3511         if (isAbsoluteVolumeDevice(device)
3512                 && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) {
3513             AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device);
3514             if (info.mHandlesVolumeAdjustment) {
3515                 dispatchAbsoluteVolumeAdjusted(streamType, info, oldIndex, direction,
3516                         keyEventMode);
3517                 return;
3518             }
3519         }
3520 
3521         if (adjustVolume && (direction != AudioManager.ADJUST_SAME)
3522                 && (keyEventMode != AudioDeviceVolumeManager.ADJUST_MODE_END)) {
3523             mAudioHandler.removeMessages(MSG_UNMUTE_STREAM);
3524 
3525             if (isMuteAdjust && !mFullVolumeDevices.contains(device)) {
3526                 boolean state;
3527                 if (direction == AudioManager.ADJUST_TOGGLE_MUTE) {
3528                     state = !streamState.mIsMuted;
3529                 } else {
3530                     state = direction == AudioManager.ADJUST_MUTE;
3531                 }
3532                 muteAliasStreams(streamTypeAlias, state);
3533             } else if ((direction == AudioManager.ADJUST_RAISE)
3534                     && mSoundDoseHelper.raiseVolumeDisplaySafeMediaVolume(streamTypeAlias,
3535                             aliasIndex + step, device, flags)) {
3536                 Log.e(TAG, "adjustStreamVolume() safe volume index = " + oldIndex);
3537             } else if (!isFullVolumeDevice(device)
3538                     && (streamState.adjustIndex(direction * step, device, caller,
3539                             hasModifyAudioSettings)
3540                             || streamState.mIsMuted)) {
3541                 // Post message to set system volume (it in turn will post a
3542                 // message to persist).
3543                 if (streamState.mIsMuted) {
3544                     // Unmute the stream if it was previously muted
3545                     if (direction == AudioManager.ADJUST_RAISE) {
3546                         // unmute immediately for volume up
3547                         muteAliasStreams(streamTypeAlias, false);
3548                     } else if (direction == AudioManager.ADJUST_LOWER) {
3549                         if (mIsSingleVolume) {
3550                             sendMsg(mAudioHandler, MSG_UNMUTE_STREAM, SENDMSG_QUEUE,
3551                                     streamTypeAlias, flags, null, UNMUTE_STREAM_DELAY);
3552                         }
3553                     }
3554                 }
3555                 sendMsg(mAudioHandler,
3556                         MSG_SET_DEVICE_VOLUME,
3557                         SENDMSG_QUEUE,
3558                         device,
3559                         0,
3560                         streamState,
3561                         0);
3562             }
3563 
3564             int newIndex = mStreamStates[streamType].getIndex(device);
3565 
3566             // Check if volume update should be send to AVRCP
3567             if (streamTypeAlias == AudioSystem.STREAM_MUSIC
3568                     && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
3569                     && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
3570                 if (DEBUG_VOL) {
3571                     Log.d(TAG, "adjustSreamVolume: postSetAvrcpAbsoluteVolumeIndex index="
3572                             + newIndex + "stream=" + streamType);
3573                 }
3574                 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(newIndex / 10);
3575             } else if (isAbsoluteVolumeDevice(device)
3576                     && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) {
3577                 AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device);
3578                 dispatchAbsoluteVolumeChanged(streamType, info, newIndex);
3579             }
3580 
3581             if (AudioSystem.isLeAudioDeviceType(device)
3582                     && streamType == getBluetoothContextualVolumeStream()
3583                     && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
3584                 if (DEBUG_VOL) {
3585                     Log.d(TAG, "adjustSreamVolume postSetLeAudioVolumeIndex index="
3586                             + newIndex + " stream=" + streamType);
3587                 }
3588                 mDeviceBroker.postSetLeAudioVolumeIndex(newIndex,
3589                     mStreamStates[streamType].getMaxIndex(), streamType);
3590             }
3591 
3592             // Check if volume update should be send to Hearing Aid
3593             if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
3594                 // only modify the hearing aid attenuation when the stream to modify matches
3595                 // the one expected by the hearing aid
3596                 if (streamType == getBluetoothContextualVolumeStream()) {
3597                     if (DEBUG_VOL) {
3598                         Log.d(TAG, "adjustSreamVolume postSetHearingAidVolumeIndex index="
3599                                 + newIndex + " stream=" + streamType);
3600                     }
3601                     mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType);
3602                 }
3603             }
3604         }
3605 
3606         final int newIndex = mStreamStates[streamType].getIndex(device);
3607 
3608         if (adjustVolume) {
3609             synchronized (mHdmiClientLock) {
3610                 if (mHdmiManager != null) {
3611                     // At most one of mHdmiPlaybackClient and mHdmiTvClient should be non-null
3612                     HdmiClient fullVolumeHdmiClient = mHdmiPlaybackClient;
3613                     if (mHdmiTvClient != null) {
3614                         fullVolumeHdmiClient = mHdmiTvClient;
3615                     }
3616 
3617                     if (fullVolumeHdmiClient != null
3618                             && mHdmiCecVolumeControlEnabled
3619                             && streamTypeAlias == AudioSystem.STREAM_MUSIC
3620                             // vol change on a full volume device
3621                             && isFullVolumeDevice(device)) {
3622                         int keyCode = KeyEvent.KEYCODE_UNKNOWN;
3623                         switch (direction) {
3624                             case AudioManager.ADJUST_RAISE:
3625                                 keyCode = KeyEvent.KEYCODE_VOLUME_UP;
3626                                 break;
3627                             case AudioManager.ADJUST_LOWER:
3628                                 keyCode = KeyEvent.KEYCODE_VOLUME_DOWN;
3629                                 break;
3630                             case AudioManager.ADJUST_TOGGLE_MUTE:
3631                             case AudioManager.ADJUST_MUTE:
3632                             case AudioManager.ADJUST_UNMUTE:
3633                                 // Many CEC devices only support toggle mute. Therefore, we send the
3634                                 // same keycode for all three mute options.
3635                                 keyCode = KeyEvent.KEYCODE_VOLUME_MUTE;
3636                                 break;
3637                             default:
3638                                 break;
3639                         }
3640                         if (keyCode != KeyEvent.KEYCODE_UNKNOWN) {
3641                             final long ident = Binder.clearCallingIdentity();
3642                             try {
3643                                 switch (keyEventMode) {
3644                                     case AudioDeviceVolumeManager.ADJUST_MODE_NORMAL:
3645                                         fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, true);
3646                                         fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, false);
3647                                         break;
3648                                     case AudioDeviceVolumeManager.ADJUST_MODE_START:
3649                                         fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, true);
3650                                         break;
3651                                     case AudioDeviceVolumeManager.ADJUST_MODE_END:
3652                                         fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, false);
3653                                         break;
3654                                     default:
3655                                         Log.e(TAG, "Invalid keyEventMode " + keyEventMode);
3656                                 }
3657                             } finally {
3658                                 Binder.restoreCallingIdentity(ident);
3659                             }
3660                         }
3661                     }
3662 
3663                     if (streamTypeAlias == AudioSystem.STREAM_MUSIC
3664                             && (oldIndex != newIndex || isMuteAdjust)) {
3665                         maybeSendSystemAudioStatusCommand(isMuteAdjust);
3666                     }
3667                 }
3668             }
3669         }
3670         sendVolumeUpdate(streamType, oldIndex, newIndex, flags, device);
3671     }
3672 
3673     /**
3674      * Loops on aliasted stream, update the mute cache attribute of each
3675      * {@see AudioService#VolumeStreamState}, and then apply the change.
3676      * It prevents to unnecessary {@see AudioSystem#setStreamVolume} done for each stream
3677      * and aliases before mute change changed and after.
3678      */
muteAliasStreams(int streamAlias, boolean state)3679     private void muteAliasStreams(int streamAlias, boolean state) {
3680         // Locking mSettingsLock to avoid inversion when calling doMute -> updateVolumeGroupIndex
3681         synchronized (mSettingsLock) {
3682             synchronized (VolumeStreamState.class) {
3683                 List<Integer> streamsToMute = new ArrayList<>();
3684                 for (int stream = 0; stream < mStreamStates.length; stream++) {
3685                     VolumeStreamState vss = mStreamStates[stream];
3686                     if (streamAlias == mStreamVolumeAlias[stream] && vss.isMutable()) {
3687                         if (!(mCameraSoundForced
3688                                 && (vss.getStreamType()
3689                                 == AudioSystem.STREAM_SYSTEM_ENFORCED))) {
3690                             boolean changed = vss.mute(state, /* apply= */ false,
3691                                     "muteAliasStreams");
3692                             if (changed) {
3693                                 streamsToMute.add(stream);
3694                             }
3695                         }
3696                     }
3697                 }
3698                 streamsToMute.forEach(streamToMute -> {
3699                     mStreamStates[streamToMute].doMute();
3700                     broadcastMuteSetting(streamToMute, state);
3701                 });
3702             }
3703         }
3704     }
3705 
broadcastMuteSetting(int streamType, boolean isMuted)3706     private void broadcastMuteSetting(int streamType, boolean isMuted) {
3707         // Stream mute changed, fire the intent.
3708         Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION);
3709         intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, streamType);
3710         intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, isMuted);
3711         sendBroadcastToAll(intent, null /* options */);
3712     }
3713 
3714     // Called after a delay when volume down is pressed while muted
onUnmuteStream(int stream, int flags)3715     private void onUnmuteStream(int stream, int flags) {
3716         boolean wasMuted;
3717         // Locking mSettingsLock to avoid inversion when calling vss.mute -> vss.doMute ->
3718         // vss.updateVolumeGroupIndex
3719         synchronized (mSettingsLock) {
3720             synchronized (VolumeStreamState.class) {
3721                 final VolumeStreamState streamState = mStreamStates[stream];
3722                 // if unmuting causes a change, it was muted
3723                 wasMuted = streamState.mute(false, "onUnmuteStream");
3724 
3725                 final int device = getDeviceForStream(stream);
3726                 final int index = streamState.getIndex(device);
3727                 sendVolumeUpdate(stream, index, index, flags, device);
3728             }
3729             if (stream == AudioSystem.STREAM_MUSIC && wasMuted) {
3730                 synchronized (mHdmiClientLock) {
3731                     maybeSendSystemAudioStatusCommand(true);
3732                 }
3733             }
3734         }
3735     }
3736 
3737     @GuardedBy("mHdmiClientLock")
maybeSendSystemAudioStatusCommand(boolean isMuteAdjust)3738     private void maybeSendSystemAudioStatusCommand(boolean isMuteAdjust) {
3739         if (mHdmiAudioSystemClient == null
3740                 || !mHdmiSystemAudioSupported
3741                 || !mHdmiCecVolumeControlEnabled) {
3742             return;
3743         }
3744 
3745         final long identity = Binder.clearCallingIdentity();
3746         try {
3747             mHdmiAudioSystemClient.sendReportAudioStatusCecCommand(
3748                     isMuteAdjust, getStreamVolume(AudioSystem.STREAM_MUSIC),
3749                     getStreamMaxVolume(AudioSystem.STREAM_MUSIC),
3750                     isStreamMute(AudioSystem.STREAM_MUSIC));
3751         } finally {
3752             Binder.restoreCallingIdentity(identity);
3753         }
3754     }
3755 
getNewRingerMode(int stream, int index, int flags)3756     private int getNewRingerMode(int stream, int index, int flags) {
3757         // setRingerMode does nothing if the device is single volume,so the value would be unchanged
3758         if (mIsSingleVolume) {
3759             return getRingerModeExternal();
3760         }
3761 
3762         // setting volume on ui sounds stream type also controls silent mode
3763         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
3764                 (stream == getUiSoundsStreamType())) {
3765             int newRingerMode;
3766             if (index == 0) {
3767                 newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE
3768                         : mVolumePolicy.volumeDownToEnterSilent ? AudioManager.RINGER_MODE_SILENT
3769                                 : AudioManager.RINGER_MODE_NORMAL;
3770             } else {
3771                 newRingerMode = AudioManager.RINGER_MODE_NORMAL;
3772             }
3773             return newRingerMode;
3774         }
3775         return getRingerModeExternal();
3776     }
3777 
isAndroidNPlus(String caller)3778     private boolean isAndroidNPlus(String caller) {
3779         try {
3780             final ApplicationInfo applicationInfo =
3781                     mContext.getPackageManager().getApplicationInfoAsUser(
3782                             caller, 0, UserHandle.getUserId(Binder.getCallingUid()));
3783             if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N) {
3784                 return true;
3785             }
3786             return false;
3787         } catch (PackageManager.NameNotFoundException e) {
3788             return true;
3789         }
3790     }
3791 
wouldToggleZenMode(int newMode)3792     private boolean wouldToggleZenMode(int newMode) {
3793         if (getRingerModeExternal() == AudioManager.RINGER_MODE_SILENT
3794                 && newMode != AudioManager.RINGER_MODE_SILENT) {
3795             return true;
3796         } else if (getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT
3797                 && newMode == AudioManager.RINGER_MODE_SILENT) {
3798             return true;
3799         }
3800         return false;
3801     }
3802 
3803     /**
3804      * Update stream volume, ringer mode and mute status after a volume index change
3805      * @param streamType
3806      * @param index
3807      * @param flags
3808      * @param device the device for which the volume is changed
3809      * @param caller
3810      * @param hasModifyAudioSettings
3811      * @param canChangeMute true if the origin of this event is one where the mute state should be
3812      *                      updated following the change in volume index
3813      */
onSetStreamVolume(int streamType, int index, int flags, int device, String caller, boolean hasModifyAudioSettings, boolean canChangeMute)3814     /*package*/ void onSetStreamVolume(int streamType, int index, int flags, int device,
3815             String caller, boolean hasModifyAudioSettings, boolean canChangeMute) {
3816         final int stream = mStreamVolumeAlias[streamType];
3817         // setting volume on ui sounds stream type also controls silent mode
3818         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
3819                 (stream == getUiSoundsStreamType())) {
3820             setRingerMode(getNewRingerMode(stream, index, flags),
3821                     TAG + ".onSetStreamVolume", false /*external*/);
3822         }
3823         setStreamVolumeInt(stream, index, device, false, caller, hasModifyAudioSettings);
3824         // setting non-zero volume for a muted stream unmutes the stream and vice versa
3825         // except for BT SCO stream where only explicit mute is allowed to comply to BT requirements
3826         if ((streamType != AudioSystem.STREAM_BLUETOOTH_SCO) && canChangeMute) {
3827             // As adjustStreamVolume with muteAdjust flags mute/unmutes stream and aliased streams.
3828             muteAliasStreams(stream, index == 0);
3829         }
3830     }
3831 
enforceModifyAudioRoutingPermission()3832     private void enforceModifyAudioRoutingPermission() {
3833         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
3834                 != PackageManager.PERMISSION_GRANTED) {
3835             throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission");
3836         }
3837     }
3838 
enforceAccessUltrasoundPermission()3839     private void enforceAccessUltrasoundPermission() {
3840         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.ACCESS_ULTRASOUND)
3841                 != PackageManager.PERMISSION_GRANTED) {
3842             throw new SecurityException("Missing ACCESS_ULTRASOUND permission");
3843         }
3844     }
3845 
enforceQueryStatePermission()3846     private void enforceQueryStatePermission() {
3847         if (mContext.checkCallingOrSelfPermission(Manifest.permission.QUERY_AUDIO_STATE)
3848                 != PackageManager.PERMISSION_GRANTED) {
3849             throw new SecurityException("Missing QUERY_AUDIO_STATE permissions");
3850         }
3851     }
3852 
enforceQueryStateOrModifyRoutingPermission()3853     private void enforceQueryStateOrModifyRoutingPermission() {
3854         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
3855                 != PackageManager.PERMISSION_GRANTED
3856                 && mContext.checkCallingOrSelfPermission(Manifest.permission.QUERY_AUDIO_STATE)
3857                 != PackageManager.PERMISSION_GRANTED) {
3858             throw new SecurityException(
3859                     "Missing MODIFY_AUDIO_ROUTING or QUERY_AUDIO_STATE permissions");
3860         }
3861     }
3862 
enforceCallAudioInterceptionPermission()3863     private void enforceCallAudioInterceptionPermission() {
3864         if (mContext.checkCallingOrSelfPermission(
3865                 android.Manifest.permission.CALL_AUDIO_INTERCEPTION)
3866                 != PackageManager.PERMISSION_GRANTED) {
3867             throw new SecurityException("Missing CALL_AUDIO_INTERCEPTION permission");
3868         }
3869     }
3870 
3871 
3872     @Override
3873     @android.annotation.EnforcePermission(anyOf = {
3874             MODIFY_AUDIO_SETTINGS_PRIVILEGED,
3875             android.Manifest.permission.MODIFY_AUDIO_ROUTING
3876     })
3877     /** @see AudioManager#setVolumeGroupVolumeIndex(int, int, int) */
setVolumeGroupVolumeIndex(int groupId, int index, int flags, String callingPackage, String attributionTag)3878     public void setVolumeGroupVolumeIndex(int groupId, int index, int flags,
3879             String callingPackage, String attributionTag) {
3880         super.setVolumeGroupVolumeIndex_enforcePermission();
3881         if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
3882             Log.e(TAG, ": no volume group found for id " + groupId);
3883             return;
3884         }
3885         VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
3886 
3887         sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_GROUP_VOL, vgs.name(),
3888                 index, flags, callingPackage + ", user " + getCurrentUserId()));
3889 
3890         vgs.setVolumeIndex(index, flags);
3891 
3892         // For legacy reason, propagate to all streams associated to this volume group
3893         for (int groupedStream : vgs.getLegacyStreamTypes()) {
3894             try {
3895                 ensureValidStreamType(groupedStream);
3896             } catch (IllegalArgumentException e) {
3897                 Log.d(TAG, "volume group " + groupId + " has internal streams (" + groupedStream
3898                         + "), do not change associated stream volume");
3899                 continue;
3900             }
3901             setStreamVolume(groupedStream, index, flags, /*device*/ null,
3902                     callingPackage, callingPackage,
3903                     attributionTag, Binder.getCallingUid(), true /*hasModifyAudioSettings*/);
3904         }
3905     }
3906 
3907     @Nullable
getAudioVolumeGroupById(int volumeGroupId)3908     private AudioVolumeGroup getAudioVolumeGroupById(int volumeGroupId) {
3909         for (AudioVolumeGroup avg : AudioVolumeGroup.getAudioVolumeGroups()) {
3910             if (avg.getId() == volumeGroupId) {
3911                 return avg;
3912             }
3913         }
3914 
3915         Log.e(TAG, ": invalid volume group id: " + volumeGroupId + " requested");
3916         return null;
3917     }
3918 
3919     @Override
3920     @android.annotation.EnforcePermission(anyOf = {
3921             MODIFY_AUDIO_SETTINGS_PRIVILEGED,
3922             android.Manifest.permission.MODIFY_AUDIO_ROUTING
3923     })
3924     /** @see AudioManager#getVolumeGroupVolumeIndex(int) */
getVolumeGroupVolumeIndex(int groupId)3925     public int getVolumeGroupVolumeIndex(int groupId) {
3926         super.getVolumeGroupVolumeIndex_enforcePermission();
3927         synchronized (VolumeStreamState.class) {
3928             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
3929                 throw new IllegalArgumentException("No volume group for id " + groupId);
3930             }
3931             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
3932             // Return 0 when muted, not min index since for e.g. Voice Call, it has a non zero
3933             // min but it mutable on permission condition.
3934             return vgs.isMuted() ? 0 : vgs.getVolumeIndex();
3935         }
3936     }
3937 
3938     /** @see AudioManager#getVolumeGroupMaxVolumeIndex(int) */
3939     @android.annotation.EnforcePermission(anyOf = {
3940             MODIFY_AUDIO_SETTINGS_PRIVILEGED,
3941             android.Manifest.permission.MODIFY_AUDIO_ROUTING
3942     })
getVolumeGroupMaxVolumeIndex(int groupId)3943     public int getVolumeGroupMaxVolumeIndex(int groupId) {
3944         super.getVolumeGroupMaxVolumeIndex_enforcePermission();
3945         synchronized (VolumeStreamState.class) {
3946             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
3947                 throw new IllegalArgumentException("No volume group for id " + groupId);
3948             }
3949             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
3950             return vgs.getMaxIndex();
3951         }
3952     }
3953 
3954     /** @see AudioManager#getVolumeGroupMinVolumeIndex(int) */
3955     @android.annotation.EnforcePermission(anyOf = {
3956             MODIFY_AUDIO_SETTINGS_PRIVILEGED,
3957             android.Manifest.permission.MODIFY_AUDIO_ROUTING
3958     })
getVolumeGroupMinVolumeIndex(int groupId)3959     public int getVolumeGroupMinVolumeIndex(int groupId) {
3960         super.getVolumeGroupMinVolumeIndex_enforcePermission();
3961         synchronized (VolumeStreamState.class) {
3962             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
3963                 throw new IllegalArgumentException("No volume group for id " + groupId);
3964             }
3965             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
3966             return vgs.getMinIndex();
3967         }
3968     }
3969 
3970     @Override
3971     @android.annotation.EnforcePermission(anyOf = {
3972             android.Manifest.permission.MODIFY_AUDIO_ROUTING,
3973             android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED
3974     })
3975     /** @see AudioDeviceVolumeManager#setDeviceVolume(VolumeInfo, AudioDeviceAttributes)
3976      * Part of service interface, check permissions and parameters here
3977      * Note calling package is for logging purposes only, not to be trusted
3978      */
setDeviceVolume(@onNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage)3979     public void setDeviceVolume(@NonNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada,
3980             @NonNull String callingPackage) {
3981         super.setDeviceVolume_enforcePermission();
3982         Objects.requireNonNull(vi);
3983         Objects.requireNonNull(ada);
3984         Objects.requireNonNull(callingPackage);
3985 
3986         if (!vi.hasStreamType()) {
3987             Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception());
3988             return;
3989         }
3990 
3991         int index = vi.getVolumeIndex();
3992         if (index == VolumeInfo.INDEX_NOT_SET && !vi.hasMuteCommand()) {
3993             throw new IllegalArgumentException(
3994                     "changing device volume requires a volume index or mute command");
3995         }
3996 
3997         // force a cache clear to force reevaluating stream type to audio device selection
3998         // that can interfere with the sending of the VOLUME_CHANGED_ACTION intent
3999         mAudioSystem.clearRoutingCache();
4000 
4001         // log the current device that will be used when evaluating the sending of the
4002         // VOLUME_CHANGED_ACTION intent to see if the current device is the one being modified
4003         final int currDev = getDeviceForStream(vi.getStreamType());
4004 
4005         final boolean skipping = (currDev == ada.getInternalType());
4006 
4007         AudioService.sVolumeLogger.enqueue(new DeviceVolumeEvent(vi.getStreamType(), index, ada,
4008                 currDev, callingPackage, skipping));
4009 
4010         if (skipping) {
4011             // setDeviceVolume was called on a device currently being used
4012             return;
4013         }
4014 
4015         // TODO handle unmuting of current audio device
4016         // if a stream is not muted but the VolumeInfo is for muting, set the volume index
4017         // for the device to min volume
4018         if (vi.hasMuteCommand() && vi.isMuted() && !isStreamMute(vi.getStreamType())) {
4019             setStreamVolumeWithAttributionInt(vi.getStreamType(),
4020                     mStreamStates[vi.getStreamType()].getMinIndex(),
4021                     /*flags*/ 0,
4022                     ada, callingPackage, null);
4023             return;
4024         }
4025 
4026         AudioService.sVolumeLogger.enqueueAndLog("setDeviceVolume" + " from:" + callingPackage
4027                 + " " + vi + " " + ada, EventLogger.Event.ALOGI, TAG);
4028 
4029         if (vi.getMinVolumeIndex() == VolumeInfo.INDEX_NOT_SET
4030                 || vi.getMaxVolumeIndex() == VolumeInfo.INDEX_NOT_SET) {
4031             // assume index meant to be in stream type range, validate
4032             if ((index * 10) < mStreamStates[vi.getStreamType()].getMinIndex()
4033                     || (index * 10) > mStreamStates[vi.getStreamType()].getMaxIndex()) {
4034                 throw new IllegalArgumentException("invalid volume index " + index
4035                         + " not between min/max for stream " + vi.getStreamType());
4036             }
4037         } else {
4038             // check if index needs to be rescaled
4039             final int min = (mStreamStates[vi.getStreamType()].getMinIndex() + 5) / 10;
4040             final int max = (mStreamStates[vi.getStreamType()].getMaxIndex() + 5) / 10;
4041             if (vi.getMinVolumeIndex() != min || vi.getMaxVolumeIndex() != max) {
4042                 index = rescaleIndex(index,
4043                         /*srcMin*/ vi.getMinVolumeIndex(), /*srcMax*/ vi.getMaxVolumeIndex(),
4044                         /*dstMin*/ min, /*dstMax*/ max);
4045             }
4046         }
4047         setStreamVolumeWithAttributionInt(vi.getStreamType(), index, /*flags*/ 0,
4048                 ada, callingPackage, null);
4049     }
4050 
4051     /** Retain API for unsupported app usage */
setStreamVolume(int streamType, int index, int flags, String callingPackage)4052     public void setStreamVolume(int streamType, int index, int flags, String callingPackage) {
4053         setStreamVolumeWithAttribution(streamType, index, flags,
4054                 callingPackage, /*attributionTag*/ null);
4055     }
4056 
4057     /** @see AudioManager#adjustVolumeGroupVolume(int, int, int) */
adjustVolumeGroupVolume(int groupId, int direction, int flags, String callingPackage)4058     public void adjustVolumeGroupVolume(int groupId, int direction, int flags,
4059                                         String callingPackage) {
4060         ensureValidDirection(direction);
4061         if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
4062             Log.e(TAG, ": no volume group found for id " + groupId);
4063             return;
4064         }
4065         VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
4066         // For compatibility reason, use stream API if group linked to a valid stream
4067         boolean fallbackOnStream = false;
4068         for (int stream : vgs.getLegacyStreamTypes()) {
4069             try {
4070                 ensureValidStreamType(stream);
4071             } catch (IllegalArgumentException e) {
4072                 Log.d(TAG, "volume group " + groupId + " has internal streams (" + stream
4073                         + "), do not change associated stream volume");
4074                 continue;
4075             }
4076             // Note: Group and Stream does not share same convention, 0 is mute for stream,
4077             // min index is acting as mute for Groups
4078             if (vgs.isVssMuteBijective(stream)) {
4079                 adjustStreamVolume(stream, direction, flags, callingPackage);
4080                 if (isMuteAdjust(direction)) {
4081                     // will be propagated to all aliased streams
4082                     return;
4083                 }
4084                 fallbackOnStream = true;
4085             }
4086         }
4087         if (fallbackOnStream) {
4088             // Handled by at least one stream, will be propagated to group, bailing out.
4089             return;
4090         }
4091         sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_ADJUST_GROUP_VOL, vgs.name(),
4092                 direction, flags, callingPackage));
4093         vgs.adjustVolume(direction, flags);
4094     }
4095 
4096     /** @see AudioManager#getLastAudibleVolumeForVolumeGroup(int) */
4097     @android.annotation.EnforcePermission(android.Manifest.permission.QUERY_AUDIO_STATE)
getLastAudibleVolumeForVolumeGroup(int groupId)4098     public int getLastAudibleVolumeForVolumeGroup(int groupId) {
4099         super.getLastAudibleVolumeForVolumeGroup_enforcePermission();
4100         synchronized (VolumeStreamState.class) {
4101             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
4102                 Log.e(TAG, ": no volume group found for id " + groupId);
4103                 return 0;
4104             }
4105             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
4106             return vgs.getVolumeIndex();
4107         }
4108     }
4109 
4110     /** @see AudioManager#isVolumeGroupMuted(int) */
isVolumeGroupMuted(int groupId)4111     public boolean isVolumeGroupMuted(int groupId) {
4112         synchronized (VolumeStreamState.class) {
4113             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
4114                 Log.e(TAG, ": no volume group found for id " + groupId);
4115                 return false;
4116             }
4117             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
4118             return vgs.isMuted();
4119         }
4120     }
4121 
4122     /** @see AudioManager#setStreamVolume(int, int, int)
4123      * Part of service interface, check permissions here */
setStreamVolumeWithAttribution(int streamType, int index, int flags, String callingPackage, String attributionTag)4124     public void setStreamVolumeWithAttribution(int streamType, int index, int flags,
4125             String callingPackage, String attributionTag) {
4126         setStreamVolumeWithAttributionInt(streamType, index, flags, /*device*/ null,
4127                 callingPackage, attributionTag);
4128     }
4129 
4130     /**
4131      * Internal method for a stream type volume change. Can be used to change the volume on a
4132      * given device only
4133      * @param streamType the stream type whose volume is to be changed
4134      * @param index the volume index
4135      * @param flags options for volume handling
4136      * @param device null when controlling volume for the current routing, otherwise the device
4137      *               for which volume is being changed
4138      * @param callingPackage client side-provided package name of caller, not to be trusted
4139      * @param attributionTag client side-provided attribution name, not to be trusted
4140      */
setStreamVolumeWithAttributionInt(int streamType, int index, int flags, @Nullable AudioDeviceAttributes device, String callingPackage, String attributionTag)4141     protected void setStreamVolumeWithAttributionInt(int streamType, int index, int flags,
4142             @Nullable AudioDeviceAttributes device,
4143             String callingPackage, String attributionTag) {
4144         if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {
4145             Log.w(TAG, "Trying to call setStreamVolume() for a11y without"
4146                     + " CHANGE_ACCESSIBILITY_VOLUME  callingPackage=" + callingPackage);
4147             return;
4148         }
4149         if ((streamType == AudioManager.STREAM_VOICE_CALL) && (index == 0)
4150                 && (mContext.checkCallingOrSelfPermission(
4151                     android.Manifest.permission.MODIFY_PHONE_STATE)
4152                     != PackageManager.PERMISSION_GRANTED)) {
4153             Log.w(TAG, "Trying to call setStreamVolume() for STREAM_VOICE_CALL and index 0 without"
4154                     + " MODIFY_PHONE_STATE  callingPackage=" + callingPackage);
4155             return;
4156         }
4157         if ((streamType == AudioManager.STREAM_ASSISTANT)
4158             && (mContext.checkCallingOrSelfPermission(
4159                     android.Manifest.permission.MODIFY_AUDIO_ROUTING)
4160                     != PackageManager.PERMISSION_GRANTED)) {
4161             Log.w(TAG, "Trying to call setStreamVolume() for STREAM_ASSISTANT without"
4162                     + " MODIFY_AUDIO_ROUTING  callingPackage=" + callingPackage);
4163             return;
4164         }
4165 
4166         if (device == null) {
4167             // call was already logged in setDeviceVolume()
4168             sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType,
4169                     index/*val1*/, flags/*val2*/, callingPackage));
4170         }
4171         setStreamVolume(streamType, index, flags, device,
4172                 callingPackage, callingPackage, attributionTag,
4173                 Binder.getCallingUid(), callingOrSelfHasAudioSettingsPermission());
4174     }
4175 
4176     @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_ULTRASOUND)
4177     /** @see AudioManager#isUltrasoundSupported() */
isUltrasoundSupported()4178     public boolean isUltrasoundSupported() {
4179         super.isUltrasoundSupported_enforcePermission();
4180 
4181         return AudioSystem.isUltrasoundSupported();
4182     }
4183 
4184     /** @see AudioManager#isHotwordStreamSupported() */
4185     @android.annotation.EnforcePermission(android.Manifest.permission.CAPTURE_AUDIO_HOTWORD)
isHotwordStreamSupported(boolean lookbackAudio)4186     public boolean isHotwordStreamSupported(boolean lookbackAudio) {
4187         super.isHotwordStreamSupported_enforcePermission();
4188         try {
4189             return mAudioPolicy.isHotwordStreamSupported(lookbackAudio);
4190         } catch (IllegalStateException e) {
4191             // Suppress connection failure to APM, since the method is purely informative
4192             Log.e(TAG, "Suppressing exception calling into AudioPolicy", e);
4193             return false;
4194         }
4195     }
4196 
4197 
canChangeAccessibilityVolume()4198     private boolean canChangeAccessibilityVolume() {
4199         synchronized (mAccessibilityServiceUidsLock) {
4200             if (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
4201                     android.Manifest.permission.CHANGE_ACCESSIBILITY_VOLUME)) {
4202                 return true;
4203             }
4204             if (mAccessibilityServiceUids != null) {
4205                 int callingUid = Binder.getCallingUid();
4206                 for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
4207                     if (mAccessibilityServiceUids[i] == callingUid) {
4208                         return true;
4209                     }
4210                 }
4211             }
4212             return false;
4213         }
4214     }
4215 
getBluetoothContextualVolumeStream()4216     /*package*/ int getBluetoothContextualVolumeStream() {
4217         return getBluetoothContextualVolumeStream(mMode.get());
4218     }
4219 
getBluetoothContextualVolumeStream(int mode)4220     private int getBluetoothContextualVolumeStream(int mode) {
4221         switch (mode) {
4222             case AudioSystem.MODE_IN_COMMUNICATION:
4223             case AudioSystem.MODE_IN_CALL:
4224                 return AudioSystem.STREAM_VOICE_CALL;
4225             case AudioSystem.MODE_NORMAL:
4226             default:
4227                 // other conditions will influence the stream type choice, read on...
4228                 break;
4229         }
4230         if (mVoicePlaybackActive.get()) {
4231             return AudioSystem.STREAM_VOICE_CALL;
4232         }
4233         return AudioSystem.STREAM_MUSIC;
4234     }
4235 
4236     private AtomicBoolean mVoicePlaybackActive = new AtomicBoolean(false);
4237     private AtomicBoolean mMediaPlaybackActive = new AtomicBoolean(false);
4238 
4239     private final IPlaybackConfigDispatcher mPlaybackActivityMonitor =
4240             new IPlaybackConfigDispatcher.Stub() {
4241         @Override
4242         public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs,
4243                                                  boolean flush) {
4244             sendMsg(mAudioHandler, MSG_PLAYBACK_CONFIG_CHANGE, SENDMSG_REPLACE,
4245                     0 /*arg1 ignored*/, 0 /*arg2 ignored*/,
4246                     configs /*obj*/, 0 /*delay*/);
4247         }
4248     };
4249 
onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs)4250     private void onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) {
4251         boolean voiceActive = false;
4252         boolean mediaActive = false;
4253         for (AudioPlaybackConfiguration config : configs) {
4254             final int usage = config.getAudioAttributes().getUsage();
4255             if (!config.isActive()) {
4256                 continue;
4257             }
4258             if (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION
4259                     || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING) {
4260                 voiceActive = true;
4261             }
4262             if (usage == AudioAttributes.USAGE_MEDIA || usage == AudioAttributes.USAGE_GAME) {
4263                 mediaActive = true;
4264             }
4265         }
4266         if (mVoicePlaybackActive.getAndSet(voiceActive) != voiceActive) {
4267             updateHearingAidVolumeOnVoiceActivityUpdate();
4268         }
4269         if (mMediaPlaybackActive.getAndSet(mediaActive) != mediaActive && mediaActive) {
4270             mSoundDoseHelper.scheduleMusicActiveCheck();
4271         }
4272         // Update playback active state for all apps in audio mode stack.
4273         // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE
4274         // and request an audio mode update immediately. Upon any other change, queue the message
4275         // and request an audio mode update after a grace period.
4276         updateAudioModeHandlers(
4277                 configs /* playbackConfigs */, null /* recordConfigs */);
4278         mDeviceBroker.updateCommunicationRouteClientsActivity(
4279                 configs /* playbackConfigs */, null /* recordConfigs */);
4280     }
4281 
updateAudioModeHandlers(List<AudioPlaybackConfiguration> playbackConfigs, List<AudioRecordingConfiguration> recordConfigs)4282     void updateAudioModeHandlers(List<AudioPlaybackConfiguration> playbackConfigs,
4283                                  List<AudioRecordingConfiguration> recordConfigs) {
4284         synchronized (mDeviceBroker.mSetModeLock) {
4285             boolean updateAudioMode = false;
4286             int existingMsgPolicy = SENDMSG_QUEUE;
4287             int delay = CHECK_MODE_FOR_UID_PERIOD_MS;
4288             for (SetModeDeathHandler h : mSetModeDeathHandlers) {
4289                 boolean wasActive = h.isActive();
4290                 if (playbackConfigs != null) {
4291                     h.setPlaybackActive(false);
4292                     for (AudioPlaybackConfiguration config : playbackConfigs) {
4293                         final int usage = config.getAudioAttributes().getUsage();
4294                         if (config.getClientUid() == h.getUid()
4295                                 && (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION
4296                                 || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING)
4297                                 && config.isActive()) {
4298                             h.setPlaybackActive(true);
4299                             break;
4300                         }
4301                     }
4302                 }
4303                 if (recordConfigs != null) {
4304                     h.setRecordingActive(false);
4305                     for (AudioRecordingConfiguration config : recordConfigs) {
4306                         if (config.getClientUid() == h.getUid() && !config.isClientSilenced()
4307                                 && config.getAudioSource() == AudioSource.VOICE_COMMUNICATION) {
4308                             h.setRecordingActive(true);
4309                             break;
4310                         }
4311                     }
4312                 }
4313                 if (wasActive != h.isActive()) {
4314                     updateAudioMode = true;
4315                     if (h.isActive() && h == getAudioModeOwnerHandler()) {
4316                         existingMsgPolicy = SENDMSG_REPLACE;
4317                         delay = 0;
4318                     }
4319                 }
4320             }
4321             if (updateAudioMode) {
4322                 sendMsg(mAudioHandler,
4323                         MSG_UPDATE_AUDIO_MODE,
4324                         existingMsgPolicy,
4325                         AudioSystem.MODE_CURRENT,
4326                         android.os.Process.myPid(),
4327                         mContext.getPackageName(),
4328                         delay);
4329             }
4330         }
4331     }
4332 
4333     private final IRecordingConfigDispatcher mVoiceRecordingActivityMonitor =
4334             new IRecordingConfigDispatcher.Stub() {
4335         @Override
4336         public void dispatchRecordingConfigChange(List<AudioRecordingConfiguration> configs) {
4337             sendMsg(mAudioHandler, MSG_RECORDING_CONFIG_CHANGE, SENDMSG_REPLACE,
4338                     0 /*arg1 ignored*/, 0 /*arg2 ignored*/,
4339                     configs /*obj*/, 0 /*delay*/);
4340         }
4341     };
4342 
onRecordingConfigChange(List<AudioRecordingConfiguration> configs)4343     private void onRecordingConfigChange(List<AudioRecordingConfiguration> configs) {
4344         // Update recording active state for all apps in audio mode stack.
4345         // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE
4346         // and request an audio mode update immediately. Upon any other change, queue the message
4347         // and request an audio mode update after a grace period.
4348         updateAudioModeHandlers(
4349                 null /* playbackConfigs */, configs /* recordConfigs */);
4350         mDeviceBroker.updateCommunicationRouteClientsActivity(
4351                 null /* playbackConfigs */, configs /* recordConfigs */);
4352     }
4353 
dumpAudioMode(PrintWriter pw)4354     private void dumpAudioMode(PrintWriter pw) {
4355         pw.println("\nAudio mode: ");
4356         pw.println("- Requested mode = " + AudioSystem.modeToString(getMode()));
4357         pw.println("- Actual mode = " + AudioSystem.modeToString(mMode.get()));
4358         pw.println("- Mode owner: ");
4359         SetModeDeathHandler hdlr = getAudioModeOwnerHandler();
4360         if (hdlr != null) {
4361             hdlr.dump(pw, -1);
4362         } else {
4363             pw.println("   None");
4364         }
4365         pw.println("- Mode owner stack: ");
4366         if (mSetModeDeathHandlers.isEmpty()) {
4367             pw.println("   Empty");
4368         } else {
4369             for (int i = 0; i < mSetModeDeathHandlers.size(); i++) {
4370                 mSetModeDeathHandlers.get(i).dump(pw, i);
4371             }
4372         }
4373     }
4374 
updateHearingAidVolumeOnVoiceActivityUpdate()4375     private void updateHearingAidVolumeOnVoiceActivityUpdate() {
4376         final int streamType = getBluetoothContextualVolumeStream();
4377         final int index = getStreamVolume(streamType);
4378         sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_HEARING_AID,
4379                 mVoicePlaybackActive.get(), streamType, index));
4380         mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
4381 
4382     }
4383 
4384     /**
4385      * Manage an audio mode change for audio devices that use an "absolute volume" model,
4386      * i.e. the framework sends the full scale signal, and the actual volume for the use case
4387      * is communicated separately.
4388      */
updateAbsVolumeMultiModeDevices(int oldMode, int newMode)4389     void updateAbsVolumeMultiModeDevices(int oldMode, int newMode) {
4390         if (oldMode == newMode) {
4391             return;
4392         }
4393         switch (newMode) {
4394             case AudioSystem.MODE_IN_COMMUNICATION:
4395             case AudioSystem.MODE_IN_CALL:
4396             case AudioSystem.MODE_NORMAL:
4397             case AudioSystem.MODE_CALL_SCREENING:
4398             case AudioSystem.MODE_CALL_REDIRECT:
4399             case AudioSystem.MODE_COMMUNICATION_REDIRECT:
4400                 break;
4401             default:
4402                 // no-op is enough for all other values
4403                 return;
4404         }
4405 
4406         int streamType = getBluetoothContextualVolumeStream(newMode);
4407 
4408         final Set<Integer> deviceTypes = getDeviceSetForStreamDirect(streamType);
4409         final Set<Integer> absVolumeMultiModeCaseDevices = AudioSystem.intersectionAudioDeviceTypes(
4410                 mAbsVolumeMultiModeCaseDevices, deviceTypes);
4411         if (absVolumeMultiModeCaseDevices.isEmpty()) {
4412             return;
4413         }
4414 
4415         // handling of specific interfaces goes here:
4416         if (AudioSystem.isSingleAudioDeviceType(
4417                 absVolumeMultiModeCaseDevices, AudioSystem.DEVICE_OUT_HEARING_AID)) {
4418             final int index = getStreamVolume(streamType);
4419             sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_MODE_CHANGE_HEARING_AID,
4420                     newMode, streamType, index));
4421             mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
4422         }
4423     }
4424 
setLeAudioVolumeOnModeUpdate(int mode, int device, int streamType, int index, int maxIndex)4425     private void setLeAudioVolumeOnModeUpdate(int mode, int device, int streamType, int index,
4426             int maxIndex) {
4427         switch (mode) {
4428             case AudioSystem.MODE_IN_COMMUNICATION:
4429             case AudioSystem.MODE_IN_CALL:
4430             case AudioSystem.MODE_NORMAL:
4431             case AudioSystem.MODE_CALL_SCREENING:
4432             case AudioSystem.MODE_CALL_REDIRECT:
4433             case AudioSystem.MODE_COMMUNICATION_REDIRECT:
4434                 break;
4435             default:
4436                 // no-op is enough for all other values
4437                 return;
4438         }
4439 
4440         // In some cases (like the outgoing or rejected call) the value of 'device' is not
4441         // DEVICE_OUT_BLE_* even when BLE is connected. Changing the volume level in such case
4442         // may cuase the other devices volume level leaking into the LeAudio device settings.
4443         if (!AudioSystem.isLeAudioDeviceType(device)) {
4444             Log.w(TAG, "setLeAudioVolumeOnModeUpdate ignoring invalid device="
4445                     + device + ", mode=" + mode + ", index=" + index + " maxIndex=" + maxIndex
4446                     + " streamType=" + streamType);
4447             return;
4448         }
4449 
4450         if (DEBUG_VOL) {
4451             Log.d(TAG, "setLeAudioVolumeOnModeUpdate postSetLeAudioVolumeIndex device="
4452                     + device + ", mode=" + mode + ", index=" + index + " maxIndex=" + maxIndex
4453                     + " streamType=" + streamType);
4454         }
4455         mDeviceBroker.postSetLeAudioVolumeIndex(index, maxIndex, streamType);
4456         mDeviceBroker.postApplyVolumeOnDevice(streamType, device, "setLeAudioVolumeOnModeUpdate");
4457     }
4458 
setStreamVolume(int streamType, int index, int flags, @Nullable AudioDeviceAttributes ada, String callingPackage, String caller, String attributionTag, int uid, boolean hasModifyAudioSettings)4459     private void setStreamVolume(int streamType, int index, int flags,
4460             @Nullable AudioDeviceAttributes ada,
4461             String callingPackage, String caller, String attributionTag, int uid,
4462             boolean hasModifyAudioSettings) {
4463         if (DEBUG_VOL) {
4464             Log.d(TAG, "setStreamVolume(stream=" + streamType+", index=" + index
4465                     + ", dev=" + ada
4466                     + ", calling=" + callingPackage + ")");
4467         }
4468         if (mUseFixedVolume) {
4469             return;
4470         }
4471 
4472         ensureValidStreamType(streamType);
4473         int streamTypeAlias = mStreamVolumeAlias[streamType];
4474         VolumeStreamState streamState = mStreamStates[streamTypeAlias];
4475 
4476         final int device = (ada == null)
4477                 ? getDeviceForStream(streamType)
4478                 : ada.getInternalType();
4479         int oldIndex;
4480 
4481         // skip a2dp absolute volume control request when the device
4482         // is neither an a2dp device nor BLE device
4483         if ((!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
4484                 && !AudioSystem.DEVICE_OUT_ALL_BLE_SET.contains(device))
4485                 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) {
4486             return;
4487         }
4488         // If we are being called by the system (e.g. hardware keys) check for current user
4489         // so we handle user restrictions correctly.
4490         if (uid == android.os.Process.SYSTEM_UID) {
4491             uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid));
4492         }
4493         if (!checkNoteAppOp(
4494                 STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage, attributionTag)) {
4495             return;
4496         }
4497 
4498         if (isAndroidNPlus(callingPackage)
4499                 && wouldToggleZenMode(getNewRingerMode(streamTypeAlias, index, flags))
4500                 && !mNm.isNotificationPolicyAccessGrantedForPackage(callingPackage)) {
4501             throw new SecurityException("Not allowed to change Do Not Disturb state");
4502         }
4503 
4504         if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) {
4505             return;
4506         }
4507 
4508         mSoundDoseHelper.invalidatPendingVolumeCommand();
4509 
4510         oldIndex = streamState.getIndex(device);
4511 
4512         index = rescaleIndex(index * 10, streamType, streamTypeAlias);
4513 
4514         if (streamTypeAlias == AudioSystem.STREAM_MUSIC
4515                 && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
4516                 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
4517             if (DEBUG_VOL) {
4518                 Log.d(TAG, "setStreamVolume postSetAvrcpAbsoluteVolumeIndex index=" + index
4519                         + "stream=" + streamType);
4520             }
4521             mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index / 10);
4522         } else if (isAbsoluteVolumeDevice(device)
4523                 && ((flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0)) {
4524             AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device);
4525 
4526             dispatchAbsoluteVolumeChanged(streamType, info, index);
4527         }
4528 
4529         if (AudioSystem.isLeAudioDeviceType(device)
4530                 && streamType == getBluetoothContextualVolumeStream()
4531                 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
4532             if (DEBUG_VOL) {
4533                 Log.d(TAG, "adjustSreamVolume postSetLeAudioVolumeIndex index="
4534                         + index + " stream=" + streamType);
4535             }
4536             mDeviceBroker.postSetLeAudioVolumeIndex(index, mStreamStates[streamType].getMaxIndex(),
4537                     streamType);
4538         }
4539 
4540         if (device == AudioSystem.DEVICE_OUT_HEARING_AID
4541                 && streamType == getBluetoothContextualVolumeStream()) {
4542             Log.i(TAG, "setStreamVolume postSetHearingAidVolumeIndex index=" + index
4543                     + " stream=" + streamType);
4544             mDeviceBroker.postSetHearingAidVolumeIndex(index, streamType);
4545         }
4546 
4547         flags &= ~AudioManager.FLAG_FIXED_VOLUME;
4548         if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) {
4549             flags |= AudioManager.FLAG_FIXED_VOLUME;
4550 
4551             // volume is either 0 or max allowed for fixed volume devices
4552             if (index != 0) {
4553                 index = mSoundDoseHelper.getSafeMediaVolumeIndex(device);
4554                 if (index < 0) {
4555                     index = streamState.getMaxIndex();
4556                 }
4557             }
4558         }
4559 
4560         if (!mSoundDoseHelper.willDisplayWarningAfterCheckVolume(streamType, index, device,
4561                 flags)) {
4562             onSetStreamVolume(streamType, index, flags, device, caller, hasModifyAudioSettings,
4563                     // ada is non-null when called from setDeviceVolume,
4564                     // which shouldn't update the mute state
4565                     ada == null /*canChangeMute*/);
4566             index = mStreamStates[streamType].getIndex(device);
4567         }
4568 
4569         synchronized (mHdmiClientLock) {
4570             if (streamTypeAlias == AudioSystem.STREAM_MUSIC
4571                     && (oldIndex != index)) {
4572                 maybeSendSystemAudioStatusCommand(false);
4573             }
4574         }
4575         if (ada == null) {
4576             // only non-null when coming here from setDeviceVolume
4577             // TODO change test to check early if device is current device or not
4578             sendVolumeUpdate(streamType, oldIndex, index, flags, device);
4579         }
4580     }
4581 
dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, int index)4582     private void dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo,
4583             int index) {
4584         VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType);
4585         if (volumeInfo != null) {
4586             try {
4587                 deviceInfo.mCallback.dispatchDeviceVolumeChanged(deviceInfo.mDevice,
4588                         new VolumeInfo.Builder(volumeInfo)
4589                                 .setVolumeIndex(rescaleIndex(index, streamType, volumeInfo))
4590                                 .build());
4591             } catch (RemoteException e) {
4592                 Log.w(TAG, "Couldn't dispatch absolute volume behavior volume change");
4593             }
4594         }
4595     }
4596 
dispatchAbsoluteVolumeAdjusted(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, int index, int direction, int mode)4597     private void dispatchAbsoluteVolumeAdjusted(int streamType,
4598             AbsoluteVolumeDeviceInfo deviceInfo, int index, int direction, int mode) {
4599         VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType);
4600         if (volumeInfo != null) {
4601             try {
4602                 deviceInfo.mCallback.dispatchDeviceVolumeAdjusted(deviceInfo.mDevice,
4603                         new VolumeInfo.Builder(volumeInfo)
4604                                 .setVolumeIndex(rescaleIndex(index, streamType, volumeInfo))
4605                                 .build(),
4606                         direction,
4607                         mode);
4608             } catch (RemoteException e) {
4609                 Log.w(TAG, "Couldn't dispatch absolute volume behavior volume adjustment");
4610             }
4611         }
4612     }
4613 
4614     // No ringer or zen muted stream volumes can be changed unless it'll exit dnd
volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags)4615     private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) {
4616         switch (mNm.getZenMode()) {
4617             case Settings.Global.ZEN_MODE_OFF:
4618                 return true;
4619             case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
4620             case Settings.Global.ZEN_MODE_ALARMS:
4621             case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
4622                 return !isStreamMutedByRingerOrZenMode(streamTypeAlias)
4623                         || isUiSoundsStreamType(streamTypeAlias)
4624                         || (flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0;
4625         }
4626 
4627         return true;
4628     }
4629 
4630     /** @see AudioManager#forceVolumeControlStream(int) */
forceVolumeControlStream(int streamType, IBinder cb)4631     public void forceVolumeControlStream(int streamType, IBinder cb) {
4632         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
4633                 != PackageManager.PERMISSION_GRANTED) {
4634             return;
4635         }
4636         if (DEBUG_VOL) { Log.d(TAG, String.format("forceVolumeControlStream(%d)", streamType)); }
4637         synchronized(mForceControlStreamLock) {
4638             if (mVolumeControlStream != -1 && streamType != -1) {
4639                 mUserSelectedVolumeControlStream = true;
4640             }
4641             mVolumeControlStream = streamType;
4642             if (mVolumeControlStream == -1) {
4643                 if (mForceControlStreamClient != null) {
4644                     mForceControlStreamClient.release();
4645                     mForceControlStreamClient = null;
4646                 }
4647                 mUserSelectedVolumeControlStream = false;
4648             } else {
4649                 if (null == mForceControlStreamClient) {
4650                     mForceControlStreamClient = new ForceControlStreamClient(cb);
4651                 } else {
4652                     if (mForceControlStreamClient.getBinder() == cb) {
4653                         Log.d(TAG, "forceVolumeControlStream cb:" + cb + " is already linked.");
4654                     } else {
4655                         mForceControlStreamClient.release();
4656                         mForceControlStreamClient = new ForceControlStreamClient(cb);
4657                     }
4658                 }
4659             }
4660         }
4661     }
4662 
4663     private class ForceControlStreamClient implements IBinder.DeathRecipient {
4664         private IBinder mCb; // To be notified of client's death
4665 
ForceControlStreamClient(IBinder cb)4666         ForceControlStreamClient(IBinder cb) {
4667             if (cb != null) {
4668                 try {
4669                     cb.linkToDeath(this, 0);
4670                 } catch (RemoteException e) {
4671                     // Client has died!
4672                     Log.w(TAG, "ForceControlStreamClient() could not link to "+cb+" binder death");
4673                     cb = null;
4674                 }
4675             }
4676             mCb = cb;
4677         }
4678 
binderDied()4679         public void binderDied() {
4680             synchronized(mForceControlStreamLock) {
4681                 Log.w(TAG, "SCO client died");
4682                 if (mForceControlStreamClient != this) {
4683                     Log.w(TAG, "unregistered control stream client died");
4684                 } else {
4685                     mForceControlStreamClient = null;
4686                     mVolumeControlStream = -1;
4687                     mUserSelectedVolumeControlStream = false;
4688                 }
4689             }
4690         }
4691 
release()4692         public void release() {
4693             if (mCb != null) {
4694                 mCb.unlinkToDeath(this, 0);
4695                 mCb = null;
4696             }
4697         }
4698 
getBinder()4699         public IBinder getBinder() {
4700             return mCb;
4701         }
4702     }
4703 
sendBroadcastToAll(Intent intent, Bundle options)4704     private void sendBroadcastToAll(Intent intent, Bundle options) {
4705         if (!mSystemServer.isPrivileged()) {
4706             return;
4707         }
4708         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
4709         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
4710         final long ident = Binder.clearCallingIdentity();
4711         try {
4712             mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
4713                     null /* receiverPermission */, options);
4714         } finally {
4715             Binder.restoreCallingIdentity(ident);
4716         }
4717     }
4718 
sendStickyBroadcastToAll(Intent intent)4719     private void sendStickyBroadcastToAll(Intent intent) {
4720         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
4721         final long ident = Binder.clearCallingIdentity();
4722         try {
4723             mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
4724         } finally {
4725             Binder.restoreCallingIdentity(ident);
4726         }
4727     }
4728 
getCurrentUserId()4729     private int getCurrentUserId() {
4730         final long ident = Binder.clearCallingIdentity();
4731         try {
4732             UserInfo currentUser = ActivityManager.getService().getCurrentUser();
4733             return currentUser.id;
4734         } catch (RemoteException e) {
4735             // Activity manager not running, nothing we can do assume user 0.
4736         } finally {
4737             Binder.restoreCallingIdentity(ident);
4738         }
4739         return UserHandle.USER_SYSTEM;
4740     }
4741 
4742     // UI update and Broadcast Intent
sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device)4743     protected void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device)
4744     {
4745         streamType = mStreamVolumeAlias[streamType];
4746 
4747         if (streamType == AudioSystem.STREAM_MUSIC && isFullVolumeDevice(device)) {
4748             flags &= ~AudioManager.FLAG_SHOW_UI;
4749         }
4750         mVolumeController.postVolumeChanged(streamType, flags);
4751     }
4752 
4753     // Don't show volume UI when:
4754     //  - Hdmi-CEC system audio mode is on and we are a TV panel
updateFlagsForTvPlatform(int flags)4755     private int updateFlagsForTvPlatform(int flags) {
4756         synchronized (mHdmiClientLock) {
4757             if (mHdmiTvClient != null && mHdmiSystemAudioSupported
4758                     && mHdmiCecVolumeControlEnabled) {
4759                 flags &= ~AudioManager.FLAG_SHOW_UI;
4760             }
4761         }
4762         return flags;
4763     }
4764     // UI update and Broadcast Intent
sendMasterMuteUpdate(boolean muted, int flags)4765     private void sendMasterMuteUpdate(boolean muted, int flags) {
4766         mVolumeController.postMasterMuteChanged(updateFlagsForTvPlatform(flags));
4767         broadcastMasterMuteStatus(muted);
4768     }
4769 
broadcastMasterMuteStatus(boolean muted)4770     private void broadcastMasterMuteStatus(boolean muted) {
4771         Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION);
4772         intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, muted);
4773         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
4774                 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
4775         sendStickyBroadcastToAll(intent);
4776     }
4777 
4778     /**
4779      * Sets the stream state's index, and posts a message to set system volume.
4780      * This will not call out to the UI. Assumes a valid stream type.
4781      *
4782      * @param streamType Type of the stream
4783      * @param index Desired volume index of the stream
4784      * @param device the device whose volume must be changed
4785      * @param force If true, set the volume even if the desired volume is same
4786      * @param caller
4787      * @param hasModifyAudioSettings true if the caller is granted MODIFY_AUDIO_SETTINGS or
4788      *                              MODIFY_AUDIO_ROUTING permission
4789      * as the current volume.
4790      */
setStreamVolumeInt(int streamType, int index, int device, boolean force, String caller, boolean hasModifyAudioSettings)4791     private void setStreamVolumeInt(int streamType,
4792                                     int index,
4793                                     int device,
4794                                     boolean force,
4795                                     String caller, boolean hasModifyAudioSettings) {
4796         if (isFullVolumeDevice(device)) {
4797             return;
4798         }
4799         VolumeStreamState streamState = mStreamStates[streamType];
4800 
4801         if (streamState.setIndex(index, device, caller, hasModifyAudioSettings) || force) {
4802             // Post message to set system volume (it in turn will post a message
4803             // to persist).
4804             sendMsg(mAudioHandler,
4805                     MSG_SET_DEVICE_VOLUME,
4806                     SENDMSG_QUEUE,
4807                     device,
4808                     0,
4809                     streamState,
4810                     0);
4811         }
4812     }
4813 
4814     /** get stream mute state. */
isStreamMute(int streamType)4815     public boolean isStreamMute(int streamType) {
4816         if (streamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
4817             streamType = getActiveStreamType(streamType);
4818         }
4819         synchronized (VolumeStreamState.class) {
4820             ensureValidStreamType(streamType);
4821             return mStreamStates[streamType].mIsMuted;
4822         }
4823     }
4824 
4825     private class RmtSbmxFullVolDeathHandler implements IBinder.DeathRecipient {
4826         private IBinder mICallback; // To be notified of client's death
4827 
RmtSbmxFullVolDeathHandler(IBinder cb)4828         RmtSbmxFullVolDeathHandler(IBinder cb) {
4829             mICallback = cb;
4830             try {
4831                 cb.linkToDeath(this, 0/*flags*/);
4832             } catch (RemoteException e) {
4833                 Log.e(TAG, "can't link to death", e);
4834             }
4835         }
4836 
isHandlerFor(IBinder cb)4837         boolean isHandlerFor(IBinder cb) {
4838             return mICallback.equals(cb);
4839         }
4840 
forget()4841         void forget() {
4842             try {
4843                 mICallback.unlinkToDeath(this, 0/*flags*/);
4844             } catch (NoSuchElementException e) {
4845                 Log.e(TAG, "error unlinking to death", e);
4846             }
4847         }
4848 
binderDied()4849         public void binderDied() {
4850             Log.w(TAG, "Recorder with remote submix at full volume died " + mICallback);
4851             forceRemoteSubmixFullVolume(false, mICallback);
4852         }
4853     }
4854 
4855     /**
4856      * call must be synchronized on mRmtSbmxFullVolDeathHandlers
4857      * @return true if there is a registered death handler, false otherwise */
discardRmtSbmxFullVolDeathHandlerFor(IBinder cb)4858     private boolean discardRmtSbmxFullVolDeathHandlerFor(IBinder cb) {
4859         Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator();
4860         while (it.hasNext()) {
4861             final RmtSbmxFullVolDeathHandler handler = it.next();
4862             if (handler.isHandlerFor(cb)) {
4863                 handler.forget();
4864                 mRmtSbmxFullVolDeathHandlers.remove(handler);
4865                 return true;
4866             }
4867         }
4868         return false;
4869     }
4870 
4871     /** call synchronized on mRmtSbmxFullVolDeathHandlers */
hasRmtSbmxFullVolDeathHandlerFor(IBinder cb)4872     private boolean hasRmtSbmxFullVolDeathHandlerFor(IBinder cb) {
4873         Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator();
4874         while (it.hasNext()) {
4875             if (it.next().isHandlerFor(cb)) {
4876                 return true;
4877             }
4878         }
4879         return false;
4880     }
4881 
4882     private int mRmtSbmxFullVolRefCount = 0;
4883     private final ArrayList<RmtSbmxFullVolDeathHandler> mRmtSbmxFullVolDeathHandlers =
4884             new ArrayList<RmtSbmxFullVolDeathHandler>();
4885 
forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb)4886     public void forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb) {
4887         if (cb == null) {
4888             return;
4889         }
4890         if ((PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
4891                         android.Manifest.permission.CAPTURE_AUDIO_OUTPUT))) {
4892             Log.w(TAG, "Trying to call forceRemoteSubmixFullVolume() without CAPTURE_AUDIO_OUTPUT");
4893             return;
4894         }
4895         synchronized(mRmtSbmxFullVolDeathHandlers) {
4896             boolean applyRequired = false;
4897             if (startForcing) {
4898                 if (!hasRmtSbmxFullVolDeathHandlerFor(cb)) {
4899                     mRmtSbmxFullVolDeathHandlers.add(new RmtSbmxFullVolDeathHandler(cb));
4900                     if (mRmtSbmxFullVolRefCount == 0) {
4901                         mFullVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
4902                         mFixedVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
4903                         applyRequired = true;
4904                     }
4905                     mRmtSbmxFullVolRefCount++;
4906                 }
4907             } else {
4908                 if (discardRmtSbmxFullVolDeathHandlerFor(cb) && (mRmtSbmxFullVolRefCount > 0)) {
4909                     mRmtSbmxFullVolRefCount--;
4910                     if (mRmtSbmxFullVolRefCount == 0) {
4911                         mFullVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
4912                         mFixedVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
4913                         applyRequired = true;
4914                     }
4915                 }
4916             }
4917             if (applyRequired) {
4918                 // Assumes only STREAM_MUSIC going through DEVICE_OUT_REMOTE_SUBMIX
4919                 checkAllFixedVolumeDevices(AudioSystem.STREAM_MUSIC);
4920                 mStreamStates[AudioSystem.STREAM_MUSIC].applyAllVolumes();
4921             }
4922         }
4923     }
4924 
setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, int userId, int pid, String attributionTag)4925     private void setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid,
4926             int userId, int pid, String attributionTag) {
4927         // If we are being called by the system check for user we are going to change
4928         // so we handle user restrictions correctly.
4929         if (uid == android.os.Process.SYSTEM_UID) {
4930             uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4931         }
4932         // If OP_AUDIO_MASTER_VOLUME is set, disallow unmuting.
4933         if (!mute && !checkNoteAppOp(
4934                 AppOpsManager.OP_AUDIO_MASTER_VOLUME, uid, callingPackage, attributionTag)) {
4935             return;
4936         }
4937         if (userId != UserHandle.getCallingUserId() &&
4938                 mContext.checkPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4939                         pid, uid)
4940                 != PackageManager.PERMISSION_GRANTED) {
4941             return;
4942         }
4943         setMasterMuteInternalNoCallerCheck(mute, flags, userId);
4944     }
4945 
setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId)4946     private void setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId) {
4947         if (DEBUG_VOL) {
4948             Log.d(TAG, String.format("Master mute %s, %d, user=%d", mute, flags, userId));
4949         }
4950         if (!isPlatformAutomotive() && mUseFixedVolume) {
4951             // If using fixed volume, we don't mute.
4952             // TODO: remove the isPlatformAutomotive check here.
4953             // The isPlatformAutomotive check is added for safety but may not be necessary.
4954             return;
4955         }
4956         // For automotive,
4957         // - the car service is always running as system user
4958         // - foreground users are non-system users
4959         // Car service is in charge of dispatching the key event include global mute to Android.
4960         // Therefore, the getCurrentUser() is always different to the foreground user.
4961         if ((isPlatformAutomotive() && userId == UserHandle.USER_SYSTEM)
4962                 || (getCurrentUserId() == userId)) {
4963             if (mute != AudioSystem.getMasterMute()) {
4964                 AudioSystem.setMasterMute(mute);
4965                 sendMasterMuteUpdate(mute, flags);
4966             }
4967         }
4968     }
4969 
4970     /** get global mute state. */
isMasterMute()4971     public boolean isMasterMute() {
4972         return AudioSystem.getMasterMute();
4973     }
4974 
4975     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
4976     /** @see AudioManager#setMasterMute(boolean, int) */
setMasterMute(boolean mute, int flags, String callingPackage, int userId, String attributionTag)4977     public void setMasterMute(boolean mute, int flags, String callingPackage, int userId,
4978             String attributionTag) {
4979         super.setMasterMute_enforcePermission();
4980 
4981         setMasterMuteInternal(mute, flags, callingPackage,
4982                 Binder.getCallingUid(), userId, Binder.getCallingPid(), attributionTag);
4983     }
4984 
4985     /** @see AudioManager#getStreamVolume(int) */
getStreamVolume(int streamType)4986     public int getStreamVolume(int streamType) {
4987         ensureValidStreamType(streamType);
4988         int device = getDeviceForStream(streamType);
4989         synchronized (VolumeStreamState.class) {
4990             int index = mStreamStates[streamType].getIndex(device);
4991 
4992             // by convention getStreamVolume() returns 0 when a stream is muted.
4993             if (mStreamStates[streamType].mIsMuted) {
4994                 index = 0;
4995             }
4996             if (index != 0 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
4997                     isFixedVolumeDevice(device)) {
4998                 index = mStreamStates[streamType].getMaxIndex();
4999             }
5000             return (index + 5) / 10;
5001         }
5002     }
5003 
5004     @Override
5005     @android.annotation.EnforcePermission(anyOf = {
5006             android.Manifest.permission.MODIFY_AUDIO_ROUTING,
5007             android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED
5008     })
5009     /**
5010      * @see AudioDeviceVolumeManager#getDeviceVolume(VolumeInfo, AudioDeviceAttributes)
5011      */
getDeviceVolume(@onNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage)5012     public @NonNull VolumeInfo getDeviceVolume(@NonNull VolumeInfo vi,
5013             @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage) {
5014         super.getDeviceVolume_enforcePermission();
5015         Objects.requireNonNull(vi);
5016         Objects.requireNonNull(ada);
5017         Objects.requireNonNull(callingPackage);
5018         if (!vi.hasStreamType()) {
5019             Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception());
5020             return getDefaultVolumeInfo();
5021         }
5022 
5023         int streamType = vi.getStreamType();
5024         final VolumeInfo.Builder vib = new VolumeInfo.Builder(vi);
5025         vib.setMinVolumeIndex((mStreamStates[streamType].mIndexMin + 5) / 10);
5026         vib.setMaxVolumeIndex((mStreamStates[streamType].mIndexMax + 5) / 10);
5027         synchronized (VolumeStreamState.class) {
5028             final int index;
5029             if (isFixedVolumeDevice(ada.getInternalType())) {
5030                 index = (mStreamStates[streamType].mIndexMax + 5) / 10;
5031             } else {
5032                 index = (mStreamStates[streamType].getIndex(ada.getInternalType()) + 5) / 10;
5033             }
5034             vib.setVolumeIndex(index);
5035             // only set as a mute command if stream muted
5036             if (mStreamStates[streamType].mIsMuted) {
5037                 vib.setMuted(true);
5038             }
5039             return vib.build();
5040         }
5041     }
5042 
5043     /** @see AudioManager#getStreamMaxVolume(int) */
getStreamMaxVolume(int streamType)5044     public int getStreamMaxVolume(int streamType) {
5045         ensureValidStreamType(streamType);
5046         return (mStreamStates[streamType].getMaxIndex() + 5) / 10;
5047     }
5048 
5049     /** @see AudioManager#getStreamMinVolumeInt(int)
5050      * Part of service interface, check permissions here */
getStreamMinVolume(int streamType)5051     public int getStreamMinVolume(int streamType) {
5052         ensureValidStreamType(streamType);
5053         final boolean isPrivileged =
5054                 Binder.getCallingUid() == Process.SYSTEM_UID
5055                  || callingHasAudioSettingsPermission()
5056                  || (mContext.checkCallingPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)
5057                         == PackageManager.PERMISSION_GRANTED);
5058         return (mStreamStates[streamType].getMinIndex(isPrivileged) + 5) / 10;
5059     }
5060 
5061     @android.annotation.EnforcePermission(android.Manifest.permission.QUERY_AUDIO_STATE)
5062     /** Get last audible volume before stream was muted. */
getLastAudibleStreamVolume(int streamType)5063     public int getLastAudibleStreamVolume(int streamType) {
5064         super.getLastAudibleStreamVolume_enforcePermission();
5065 
5066         ensureValidStreamType(streamType);
5067         int device = getDeviceForStream(streamType);
5068         return (mStreamStates[streamType].getIndex(device) + 5) / 10;
5069     }
5070 
5071     /**
5072      * Default VolumeInfo returned by {@link VolumeInfo#getDefaultVolumeInfo()}
5073      * Lazily initialized in {@link #getDefaultVolumeInfo()}
5074      */
5075     static VolumeInfo sDefaultVolumeInfo;
5076 
5077     /** @see VolumeInfo#getDefaultVolumeInfo() */
getDefaultVolumeInfo()5078     public VolumeInfo getDefaultVolumeInfo() {
5079         if (sDefaultVolumeInfo == null) {
5080             sDefaultVolumeInfo = new VolumeInfo.Builder(AudioSystem.STREAM_MUSIC)
5081                     .setMinVolumeIndex(getStreamMinVolume(AudioSystem.STREAM_MUSIC))
5082                     .setMaxVolumeIndex(getStreamMaxVolume(AudioSystem.STREAM_MUSIC))
5083                     .build();
5084         }
5085         return sDefaultVolumeInfo;
5086     }
5087 
5088     /**
5089      * list of callback dispatchers for stream aliasing updates
5090      */
5091     final RemoteCallbackList<IStreamAliasingDispatcher> mStreamAliasingDispatchers =
5092             new RemoteCallbackList<IStreamAliasingDispatcher>();
5093 
5094     /**
5095      * Register/unregister a callback for stream aliasing updates
5096      * @param isad the callback dispatcher
5097      * @param register whether this for a registration or unregistration
5098      * @see AudioManager#addOnStreamAliasingChangedListener(Executor, Runnable)
5099      * @see AudioManager#removeOnStreamAliasingChangedListener(Runnable)
5100      */
5101     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
registerStreamAliasingDispatcher(IStreamAliasingDispatcher isad, boolean register)5102     public void registerStreamAliasingDispatcher(IStreamAliasingDispatcher isad, boolean register) {
5103         super.registerStreamAliasingDispatcher_enforcePermission();
5104         Objects.requireNonNull(isad);
5105 
5106         if (register) {
5107             mStreamAliasingDispatchers.register(isad);
5108         } else {
5109             mStreamAliasingDispatchers.unregister(isad);
5110         }
5111     }
5112 
dispatchStreamAliasingUpdate()5113     protected void dispatchStreamAliasingUpdate() {
5114         final int nbDispatchers = mStreamAliasingDispatchers.beginBroadcast();
5115         for (int i = 0; i < nbDispatchers; i++) {
5116             try {
5117                 mStreamAliasingDispatchers.getBroadcastItem(i).dispatchStreamAliasingChanged();
5118             } catch (RemoteException e) {
5119                 Log.e(TAG, "Error on stream alias update dispatch", e);
5120             }
5121         }
5122         mStreamAliasingDispatchers.finishBroadcast();
5123     }
5124 
5125     /**
5126      * @see AudioManager#getIndependentStreamTypes()
5127      * @return the list of non-aliased stream types
5128      */
5129     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
getIndependentStreamTypes()5130     public ArrayList<Integer> getIndependentStreamTypes() {
5131         super.getIndependentStreamTypes_enforcePermission();
5132 
5133         if (mUseVolumeGroupAliases) {
5134             return new ArrayList<>(Arrays.stream(AudioManager.getPublicStreamTypes())
5135                     .boxed().toList());
5136         }
5137         ArrayList<Integer> res = new ArrayList(1);
5138         for (int stream : mStreamVolumeAlias) {
5139             if (!res.contains(stream)) {
5140                 res.add(stream);
5141             }
5142         }
5143         return res;
5144     }
5145 
5146     /**
5147      * @see AudioManager#getStreamTypeAlias(int)
5148      * @param sourceStreamType the stream type for which the alias is queried
5149      * @return the stream alias
5150      */
5151     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
5152     public @AudioManager.PublicStreamTypes
getStreamTypeAlias(@udioManager.PublicStreamTypes int sourceStreamType)5153     int getStreamTypeAlias(@AudioManager.PublicStreamTypes int sourceStreamType) {
5154         super.getStreamTypeAlias_enforcePermission();
5155         // verify parameters
5156         ensureValidStreamType(sourceStreamType);
5157 
5158         return mStreamVolumeAlias[sourceStreamType];
5159     }
5160 
5161     /**
5162      * @see AudioManager#isVolumeControlUsingVolumeGroups()
5163      * @return true when volume control is performed through volume groups, false if it uses
5164      *     stream types.
5165      */
5166     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
isVolumeControlUsingVolumeGroups()5167     public boolean isVolumeControlUsingVolumeGroups() {
5168         super.isVolumeControlUsingVolumeGroups_enforcePermission();
5169 
5170         return mUseVolumeGroupAliases;
5171     }
5172 
5173     /** @see AudioManager#getUiSoundsStreamType()
5174      * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for
5175      * UI Sounds identification.
5176      * Fallback on Voice configuration to ensure correct behavior of DnD feature.
5177      */
getUiSoundsStreamType()5178     public int getUiSoundsStreamType() {
5179         return mUseVolumeGroupAliases ? STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM]
5180                 : mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM];
5181     }
5182 
5183     /**
5184      * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for
5185      * UI Sounds identification.
5186      * Fallback on Voice configuration to ensure correct behavior of DnD feature.
5187      */
isUiSoundsStreamType(int aliasStreamType)5188     private boolean isUiSoundsStreamType(int aliasStreamType) {
5189         return mUseVolumeGroupAliases
5190                 ? STREAM_VOLUME_ALIAS_VOICE[aliasStreamType]
5191                         == STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM]
5192                 : aliasStreamType == mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM];
5193     }
5194 
5195     /** @see AudioManager#setMicrophoneMute(boolean) */
5196     @Override
setMicrophoneMute(boolean on, String callingPackage, int userId, String attributionTag)5197     public void setMicrophoneMute(boolean on, String callingPackage, int userId,
5198             String attributionTag) {
5199         // If we are being called by the system check for user we are going to change
5200         // so we handle user restrictions correctly.
5201         int uid = Binder.getCallingUid();
5202         if (uid == android.os.Process.SYSTEM_UID) {
5203             uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
5204         }
5205         MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
5206                 .setUid(uid)
5207                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage)
5208                 .set(MediaMetrics.Property.EVENT, "setMicrophoneMute")
5209                 .set(MediaMetrics.Property.REQUEST, on
5210                         ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE);
5211 
5212         // If OP_MUTE_MICROPHONE is set, disallow unmuting.
5213         if (!on && !checkNoteAppOp(
5214                 AppOpsManager.OP_MUTE_MICROPHONE, uid, callingPackage, attributionTag)) {
5215             mmi.set(MediaMetrics.Property.EARLY_RETURN, "disallow unmuting").record();
5216             return;
5217         }
5218         if (!checkAudioSettingsPermission("setMicrophoneMute()")) {
5219             mmi.set(MediaMetrics.Property.EARLY_RETURN, "!checkAudioSettingsPermission").record();
5220             return;
5221         }
5222         if (userId != UserHandle.getCallingUserId() &&
5223                 mContext.checkCallingOrSelfPermission(
5224                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
5225                 != PackageManager.PERMISSION_GRANTED) {
5226             mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission").record();
5227             return;
5228         }
5229         mMicMuteFromApi = on;
5230         mmi.record(); // record now, the no caller check will set the mute state.
5231         setMicrophoneMuteNoCallerCheck(userId);
5232     }
5233 
5234     /** @see AudioManager#setMicrophoneMuteFromSwitch(boolean) */
setMicrophoneMuteFromSwitch(boolean on)5235     public void setMicrophoneMuteFromSwitch(boolean on) {
5236         int userId = Binder.getCallingUid();
5237         if (userId != android.os.Process.SYSTEM_UID) {
5238             Log.e(TAG, "setMicrophoneMuteFromSwitch() called from non system user!");
5239             return;
5240         }
5241         mMicMuteFromSwitch = on;
5242         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
5243                 .setUid(userId)
5244                 .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteFromSwitch")
5245                 .set(MediaMetrics.Property.REQUEST, on
5246                         ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE)
5247                 .record();
5248         setMicrophoneMuteNoCallerCheck(userId);
5249     }
5250 
setMicMuteFromSwitchInput()5251     private void setMicMuteFromSwitchInput() {
5252         InputManager im = mContext.getSystemService(InputManager.class);
5253         final int isMicMuted = im.isMicMuted();
5254         if (isMicMuted != InputManager.SWITCH_STATE_UNKNOWN) {
5255             setMicrophoneMuteFromSwitch(im.isMicMuted() != InputManager.SWITCH_STATE_OFF);
5256         }
5257     }
5258 
5259     /**
5260      * Returns the microphone mute state as seen from the native audio system
5261      * @return true if microphone is reported as muted by primary HAL
5262      */
isMicrophoneMuted()5263     public boolean isMicrophoneMuted() {
5264         return mMicMuteFromSystemCached
5265                 && (!mMicMuteFromPrivacyToggle
5266                         || mMicMuteFromApi || mMicMuteFromRestrictions || mMicMuteFromSwitch);
5267     }
5268 
isMicrophoneSupposedToBeMuted()5269     private boolean isMicrophoneSupposedToBeMuted() {
5270         return mMicMuteFromSwitch || mMicMuteFromRestrictions || mMicMuteFromApi
5271                 || mMicMuteFromPrivacyToggle;
5272     }
5273 
setMicrophoneMuteNoCallerCheck(int userId)5274     private void setMicrophoneMuteNoCallerCheck(int userId) {
5275         final boolean muted = isMicrophoneSupposedToBeMuted();
5276         if (DEBUG_VOL) {
5277             Log.d(TAG, String.format("Mic mute %b, user=%d", muted, userId));
5278         }
5279         // only mute for the current user
5280         if (getCurrentUserId() == userId || userId == android.os.Process.SYSTEM_UID) {
5281             final boolean currentMute = mAudioSystem.isMicrophoneMuted();
5282             final long identity = Binder.clearCallingIdentity();
5283             try {
5284                 final int ret = mAudioSystem.muteMicrophone(muted);
5285 
5286                 // update cache with the real state independently from what was set
5287                 mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted();
5288                 if (ret != AudioSystem.AUDIO_STATUS_OK) {
5289                     Log.e(TAG, "Error changing mic mute state to " + muted + " current:"
5290                             + mMicMuteFromSystemCached);
5291                 }
5292 
5293                 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
5294                         .setUid(userId)
5295                         .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteNoCallerCheck")
5296                         .set(MediaMetrics.Property.MUTE, mMicMuteFromSystemCached
5297                                 ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
5298                         .set(MediaMetrics.Property.REQUEST, muted
5299                                 ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE)
5300                         .set(MediaMetrics.Property.STATUS, ret)
5301                         .record();
5302 
5303                 // send the intent even if there was a failure to change the actual mute state:
5304                 // the AudioManager.setMicrophoneMute API doesn't have a return value to
5305                 // indicate if the call failed to successfully change the mute state, and receiving
5306                 // the intent may be the only time an application can resynchronize its mic mute
5307                 // state with the actual system mic mute state
5308                 if (muted != currentMute) {
5309                     sendMsg(mAudioHandler, MSG_BROADCAST_MICROPHONE_MUTE,
5310                                 SENDMSG_NOOP, 0, 0, null, 0);
5311                 }
5312             } finally {
5313                 Binder.restoreCallingIdentity(identity);
5314             }
5315         }
5316     }
5317 
5318     @Override
getRingerModeExternal()5319     public int getRingerModeExternal() {
5320         synchronized(mSettingsLock) {
5321             return mRingerModeExternal;
5322         }
5323     }
5324 
5325     @Override
getRingerModeInternal()5326     public int getRingerModeInternal() {
5327         synchronized(mSettingsLock) {
5328             return mRingerMode;
5329         }
5330     }
5331 
ensureValidRingerMode(int ringerMode)5332     private void ensureValidRingerMode(int ringerMode) {
5333         if (!isValidRingerMode(ringerMode)) {
5334             throw new IllegalArgumentException("Bad ringer mode " + ringerMode);
5335         }
5336     }
5337 
5338     /** @see AudioManager#isValidRingerMode(int) */
isValidRingerMode(int ringerMode)5339     public boolean isValidRingerMode(int ringerMode) {
5340         return ringerMode >= 0 && ringerMode <= AudioManager.RINGER_MODE_MAX;
5341     }
5342 
setRingerModeExternal(int ringerMode, String caller)5343     public void setRingerModeExternal(int ringerMode, String caller) {
5344         if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode)
5345                 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)) {
5346             throw new SecurityException("Not allowed to change Do Not Disturb state");
5347         }
5348 
5349         setRingerMode(ringerMode, caller, true /*external*/);
5350     }
5351 
setRingerModeInternal(int ringerMode, String caller)5352     public void setRingerModeInternal(int ringerMode, String caller) {
5353         enforceVolumeController("setRingerModeInternal");
5354         setRingerMode(ringerMode, caller, false /*external*/);
5355     }
5356 
silenceRingerModeInternal(String reason)5357     public void silenceRingerModeInternal(String reason) {
5358         VibrationEffect effect = null;
5359         int ringerMode = AudioManager.RINGER_MODE_SILENT;
5360         int toastText = 0;
5361 
5362         int silenceRingerSetting = Settings.Secure.VOLUME_HUSH_OFF;
5363         if (mContext.getResources()
5364                 .getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled)) {
5365             silenceRingerSetting = mSettings.getSecureIntForUser(mContentResolver,
5366                     Settings.Secure.VOLUME_HUSH_GESTURE, VOLUME_HUSH_OFF,
5367                     UserHandle.USER_CURRENT);
5368         }
5369 
5370         switch(silenceRingerSetting) {
5371             case VOLUME_HUSH_MUTE:
5372                 effect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK);
5373                 ringerMode = AudioManager.RINGER_MODE_SILENT;
5374                 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_silent;
5375                 break;
5376             case VOLUME_HUSH_VIBRATE:
5377                 effect = VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK);
5378                 ringerMode = AudioManager.RINGER_MODE_VIBRATE;
5379                 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_vibrate;
5380                 break;
5381         }
5382         maybeVibrate(effect, reason);
5383         setRingerModeInternal(ringerMode, reason);
5384         Toast.makeText(mContext, toastText, Toast.LENGTH_SHORT).show();
5385     }
5386 
maybeVibrate(VibrationEffect effect, String reason)5387     private boolean maybeVibrate(VibrationEffect effect, String reason) {
5388         if (!mHasVibrator) {
5389             return false;
5390         }
5391         if (effect == null) {
5392             return false;
5393         }
5394         mVibrator.vibrate(Binder.getCallingUid(), mContext.getOpPackageName(), effect,
5395                 reason, TOUCH_VIBRATION_ATTRIBUTES);
5396         return true;
5397     }
5398 
setRingerMode(int ringerMode, String caller, boolean external)5399     private void setRingerMode(int ringerMode, String caller, boolean external) {
5400         if (mUseFixedVolume || mIsSingleVolume || mUseVolumeGroupAliases) {
5401             return;
5402         }
5403         if (caller == null || caller.length() == 0) {
5404             throw new IllegalArgumentException("Bad caller: " + caller);
5405         }
5406         ensureValidRingerMode(ringerMode);
5407         if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) {
5408             ringerMode = AudioManager.RINGER_MODE_SILENT;
5409         }
5410         final long identity = Binder.clearCallingIdentity();
5411         try {
5412             synchronized (mSettingsLock) {
5413                 final int ringerModeInternal = getRingerModeInternal();
5414                 final int ringerModeExternal = getRingerModeExternal();
5415                 if (external) {
5416                     setRingerModeExt(ringerMode);
5417                     if (mRingerModeDelegate != null) {
5418                         ringerMode = mRingerModeDelegate.onSetRingerModeExternal(ringerModeExternal,
5419                                 ringerMode, caller, ringerModeInternal, mVolumePolicy);
5420                     }
5421                     if (ringerMode != ringerModeInternal) {
5422                         setRingerModeInt(ringerMode, true /*persist*/);
5423                     }
5424                 } else /*internal*/ {
5425                     if (ringerMode != ringerModeInternal) {
5426                         setRingerModeInt(ringerMode, true /*persist*/);
5427                     }
5428                     if (mRingerModeDelegate != null) {
5429                         ringerMode = mRingerModeDelegate.onSetRingerModeInternal(ringerModeInternal,
5430                                 ringerMode, caller, ringerModeExternal, mVolumePolicy);
5431                     }
5432                     setRingerModeExt(ringerMode);
5433                 }
5434             }
5435         } finally {
5436             Binder.restoreCallingIdentity(identity);
5437         }
5438     }
5439 
setRingerModeExt(int ringerMode)5440     private void setRingerModeExt(int ringerMode) {
5441         synchronized(mSettingsLock) {
5442             if (ringerMode == mRingerModeExternal) return;
5443             mRingerModeExternal = ringerMode;
5444         }
5445         // Send sticky broadcast
5446         broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, ringerMode);
5447     }
5448 
5449     @GuardedBy("mSettingsLock")
muteRingerModeStreams()5450     private void muteRingerModeStreams() {
5451         // Mute stream if not previously muted by ringer mode and (ringer mode
5452         // is not RINGER_MODE_NORMAL OR stream is zen muted) and stream is affected by ringer mode.
5453         // Unmute stream if previously muted by ringer/zen mode and ringer mode
5454         // is RINGER_MODE_NORMAL or stream is not affected by ringer mode.
5455         int numStreamTypes = AudioSystem.getNumStreamTypes();
5456 
5457         if (mNm == null) {
5458             mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
5459         }
5460 
5461         final int ringerMode = mRingerMode; // Read ringer mode as reading primitives is atomic
5462         final boolean ringerModeMute = ringerMode == AudioManager.RINGER_MODE_VIBRATE
5463                 || ringerMode == AudioManager.RINGER_MODE_SILENT;
5464         final boolean shouldRingSco = ringerMode == AudioManager.RINGER_MODE_VIBRATE
5465                 && mDeviceBroker.isBluetoothScoActive();
5466         // Ask audio policy engine to force use Bluetooth SCO channel if needed
5467         final String eventSource = "muteRingerModeStreams() from u/pid:" + Binder.getCallingUid()
5468                 + "/" + Binder.getCallingPid();
5469         sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, AudioSystem.FOR_VIBRATE_RINGING,
5470                 shouldRingSco ? AudioSystem.FORCE_BT_SCO : AudioSystem.FORCE_NONE, eventSource, 0);
5471 
5472         for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
5473             final boolean isMuted = isStreamMutedByRingerOrZenMode(streamType);
5474             final boolean muteAllowedBySco =
5475                     !(shouldRingSco && streamType == AudioSystem.STREAM_RING);
5476             final boolean shouldZenMute = shouldZenMuteStream(streamType);
5477             final boolean shouldMute = shouldZenMute || (ringerModeMute
5478                     && isStreamAffectedByRingerMode(streamType) && muteAllowedBySco);
5479             if (isMuted == shouldMute) continue;
5480             if (!shouldMute) {
5481                 // unmute
5482                 // ring and notifications volume should never be 0 when not silenced
5483                 if (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING
5484                         || mStreamVolumeAlias[streamType] == AudioSystem.STREAM_NOTIFICATION) {
5485                     synchronized (VolumeStreamState.class) {
5486                         final VolumeStreamState vss = mStreamStates[streamType];
5487                         for (int i = 0; i < vss.mIndexMap.size(); i++) {
5488                             int device = vss.mIndexMap.keyAt(i);
5489                             int value = vss.mIndexMap.valueAt(i);
5490                             if (value == 0) {
5491                                 vss.setIndex(10, device, TAG, true /*hasModifyAudioSettings*/);
5492                             }
5493                         }
5494                         // Persist volume for stream ring when it is changed here
5495                       final int device = getDeviceForStream(streamType);
5496                       sendMsg(mAudioHandler,
5497                               MSG_PERSIST_VOLUME,
5498                               SENDMSG_QUEUE,
5499                               device,
5500                               0,
5501                               mStreamStates[streamType],
5502                               PERSIST_DELAY);
5503                     }
5504                 }
5505                 sRingerAndZenModeMutedStreams &= ~(1 << streamType);
5506                 sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent(
5507                         sRingerAndZenModeMutedStreams, "muteRingerModeStreams"));
5508                 mStreamStates[streamType].mute(false, "muteRingerModeStreams");
5509             } else {
5510                 // mute
5511                 sRingerAndZenModeMutedStreams |= (1 << streamType);
5512                 sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent(
5513                         sRingerAndZenModeMutedStreams, "muteRingerModeStreams"));
5514                 mStreamStates[streamType].mute(true, "muteRingerModeStreams");
5515             }
5516         }
5517     }
5518 
isAlarm(int streamType)5519     private boolean isAlarm(int streamType) {
5520         return streamType == AudioSystem.STREAM_ALARM;
5521     }
5522 
isNotificationOrRinger(int streamType)5523     private boolean isNotificationOrRinger(int streamType) {
5524         return streamType == AudioSystem.STREAM_NOTIFICATION
5525                 || streamType == AudioSystem.STREAM_RING;
5526     }
5527 
isMedia(int streamType)5528     private boolean isMedia(int streamType) {
5529         return streamType == AudioSystem.STREAM_MUSIC;
5530     }
5531 
5532 
isSystem(int streamType)5533     private boolean isSystem(int streamType) {
5534         return streamType == AudioSystem.STREAM_SYSTEM;
5535     }
5536 
setRingerModeInt(int ringerMode, boolean persist)5537     private void setRingerModeInt(int ringerMode, boolean persist) {
5538         final boolean change;
5539         synchronized(mSettingsLock) {
5540             change = mRingerMode != ringerMode;
5541             mRingerMode = ringerMode;
5542             muteRingerModeStreams();
5543         }
5544 
5545         // Post a persist ringer mode msg
5546         if (persist) {
5547             sendMsg(mAudioHandler, MSG_PERSIST_RINGER_MODE,
5548                     SENDMSG_REPLACE, 0, 0, null, PERSIST_DELAY);
5549         }
5550         if (change) {
5551             // Send sticky broadcast
5552             broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, ringerMode);
5553         }
5554     }
5555 
postUpdateRingerModeServiceInt()5556     /*package*/ void postUpdateRingerModeServiceInt() {
5557         sendMsg(mAudioHandler, MSG_UPDATE_RINGER_MODE, SENDMSG_QUEUE, 0, 0, null, 0);
5558     }
5559 
onUpdateRingerModeServiceInt()5560     private void onUpdateRingerModeServiceInt() {
5561         setRingerModeInt(getRingerModeInternal(), false);
5562     }
5563 
5564     /** @see AudioManager#shouldVibrate(int) */
shouldVibrate(int vibrateType)5565     public boolean shouldVibrate(int vibrateType) {
5566         if (!mHasVibrator) return false;
5567 
5568         switch (getVibrateSetting(vibrateType)) {
5569 
5570             case AudioManager.VIBRATE_SETTING_ON:
5571                 return getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT;
5572 
5573             case AudioManager.VIBRATE_SETTING_ONLY_SILENT:
5574                 return getRingerModeExternal() == AudioManager.RINGER_MODE_VIBRATE;
5575 
5576             case AudioManager.VIBRATE_SETTING_OFF:
5577                 // return false, even for incoming calls
5578                 return false;
5579 
5580             default:
5581                 return false;
5582         }
5583     }
5584 
5585     /** @see AudioManager#getVibrateSetting(int) */
getVibrateSetting(int vibrateType)5586     public int getVibrateSetting(int vibrateType) {
5587         if (!mHasVibrator) return AudioManager.VIBRATE_SETTING_OFF;
5588         return (mVibrateSetting >> (vibrateType * 2)) & 3;
5589     }
5590 
5591     /** @see AudioManager#setVibrateSetting(int, int) */
setVibrateSetting(int vibrateType, int vibrateSetting)5592     public void setVibrateSetting(int vibrateType, int vibrateSetting) {
5593 
5594         if (!mHasVibrator) return;
5595 
5596         mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, vibrateType,
5597                 vibrateSetting);
5598 
5599         // Broadcast change
5600         broadcastVibrateSetting(vibrateType);
5601 
5602     }
5603 
5604     private class SetModeDeathHandler implements IBinder.DeathRecipient {
5605         private final IBinder mCb; // To be notified of client's death
5606         private final int mPid;
5607         private final int mUid;
5608         private final boolean mIsPrivileged;
5609         private final String mPackage;
5610         private int mMode;
5611         private long mUpdateTime;
5612         private boolean mPlaybackActive = false;
5613         private boolean mRecordingActive = false;
5614 
SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged, String caller, int mode)5615         SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged,
5616                             String caller, int mode) {
5617             mMode = mode;
5618             mCb = cb;
5619             mPid = pid;
5620             mUid = uid;
5621             mPackage = caller;
5622             mIsPrivileged = isPrivileged;
5623             mUpdateTime = java.lang.System.currentTimeMillis();
5624         }
5625 
binderDied()5626         public void binderDied() {
5627             synchronized (mDeviceBroker.mSetModeLock) {
5628                 Log.w(TAG, "SetModeDeathHandler client died");
5629                 int index = mSetModeDeathHandlers.indexOf(this);
5630                 if (index < 0) {
5631                     Log.w(TAG, "unregistered SetModeDeathHandler client died");
5632                 } else {
5633                     SetModeDeathHandler h = mSetModeDeathHandlers.get(index);
5634                     mSetModeDeathHandlers.remove(index);
5635                     sendMsg(mAudioHandler,
5636                             MSG_UPDATE_AUDIO_MODE,
5637                             SENDMSG_QUEUE,
5638                             AudioSystem.MODE_CURRENT,
5639                             android.os.Process.myPid(),
5640                             mContext.getPackageName(),
5641                             0);
5642                 }
5643             }
5644         }
5645 
getPid()5646         public int getPid() {
5647             return mPid;
5648         }
5649 
setMode(int mode)5650         public void setMode(int mode) {
5651             mMode = mode;
5652             mUpdateTime = java.lang.System.currentTimeMillis();
5653         }
5654 
getMode()5655         public int getMode() {
5656             return mMode;
5657         }
5658 
getBinder()5659         public IBinder getBinder() {
5660             return mCb;
5661         }
5662 
getUid()5663         public int getUid() {
5664             return mUid;
5665         }
5666 
getPackage()5667         public String getPackage() {
5668             return mPackage;
5669         }
5670 
isPrivileged()5671         public boolean isPrivileged() {
5672             return mIsPrivileged;
5673         }
5674 
getUpdateTime()5675         public long getUpdateTime() {
5676             return mUpdateTime;
5677         }
5678 
setPlaybackActive(boolean active)5679         public void setPlaybackActive(boolean active) {
5680             mPlaybackActive = active;
5681         }
5682 
setRecordingActive(boolean active)5683         public void setRecordingActive(boolean active) {
5684             mRecordingActive = active;
5685         }
5686 
5687         /**
5688          * An app is considered active if:
5689          * - It is privileged (has MODIFY_PHONE_STATE permission)
5690          *  or
5691          * - It requests mode MODE_IN_COMMUNICATION, and it is either playing
5692          * or recording for VOICE_COMMUNICATION.
5693          *   or
5694          * - It requests a mode different from MODE_IN_COMMUNICATION or MODE_NORMAL
5695          * Note: only privileged apps can request MODE_IN_CALL, MODE_CALL_REDIRECT
5696          * or MODE_COMMUNICATION_REDIRECT.
5697          */
isActive()5698         public boolean isActive() {
5699             return mIsPrivileged
5700                     || ((mMode == AudioSystem.MODE_IN_COMMUNICATION)
5701                         && (mRecordingActive || mPlaybackActive))
5702                     || mMode == AudioSystem.MODE_RINGTONE
5703                     || mMode == AudioSystem.MODE_CALL_SCREENING;
5704         }
5705 
dump(PrintWriter pw, int index)5706         public void dump(PrintWriter pw, int index) {
5707             SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm:ss:SSS");
5708 
5709             if (index >= 0) {
5710                 pw.println("  Requester # " + (index + 1) + ":");
5711             }
5712             pw.println("  - Mode: " + AudioSystem.modeToString(mMode));
5713             pw.println("  - Binder: " + mCb);
5714             pw.println("  - Pid: " + mPid);
5715             pw.println("  - Uid: " + mUid);
5716             pw.println("  - Package: " + mPackage);
5717             pw.println("  - Privileged: " + mIsPrivileged);
5718             pw.println("  - Active: " + isActive());
5719             pw.println("    Playback active: " + mPlaybackActive);
5720             pw.println("    Recording active: " + mRecordingActive);
5721             pw.println("  - update time: " + format.format(new Date(mUpdateTime)));
5722         }
5723     }
5724 
5725     @GuardedBy("mDeviceBroker.mSetModeLock")
getAudioModeOwnerHandler()5726     private SetModeDeathHandler getAudioModeOwnerHandler() {
5727         // The Audio mode owner is:
5728         // 1) the most recent privileged app in the stack
5729         // 2) the most recent active app in the tack
5730         SetModeDeathHandler modeOwner = null;
5731         SetModeDeathHandler privilegedModeOwner = null;
5732         for (SetModeDeathHandler h : mSetModeDeathHandlers) {
5733             if (h.isActive()) {
5734                 // privileged apps are always active
5735                 if (h.isPrivileged()) {
5736                     if (privilegedModeOwner == null
5737                             || h.getUpdateTime() > privilegedModeOwner.getUpdateTime()) {
5738                         privilegedModeOwner = h;
5739                     }
5740                 } else {
5741                     if (modeOwner == null
5742                             || h.getUpdateTime() > modeOwner.getUpdateTime()) {
5743                         modeOwner = h;
5744                     }
5745                 }
5746             }
5747         }
5748         return privilegedModeOwner != null ? privilegedModeOwner :  modeOwner;
5749     }
5750 
5751     /**
5752      * Return information on the current audio mode owner
5753      * @return 0 if nobody owns the mode
5754      */
5755     @GuardedBy("mDeviceBroker.mSetModeLock")
getAudioModeOwner()5756     /*package*/ AudioDeviceBroker.AudioModeInfo getAudioModeOwner() {
5757         SetModeDeathHandler hdlr = getAudioModeOwnerHandler();
5758         if (hdlr != null) {
5759             return new AudioDeviceBroker.AudioModeInfo(
5760                     hdlr.getMode(), hdlr.getPid(), hdlr.getUid());
5761         }
5762         return new AudioDeviceBroker.AudioModeInfo(AudioSystem.MODE_NORMAL, 0 , 0);
5763     }
5764 
5765     /**
5766      * Return the uid of the current audio mode owner
5767      * @return 0 if nobody owns the mode
5768      */
5769     @GuardedBy("mDeviceBroker.mSetModeLock")
getModeOwnerUid()5770     /*package*/ int getModeOwnerUid() {
5771         SetModeDeathHandler hdlr = getAudioModeOwnerHandler();
5772         if (hdlr != null) {
5773             return hdlr.getUid();
5774         }
5775         return 0;
5776     }
5777 
5778     /** @see AudioManager#setMode(int) */
setMode(int mode, IBinder cb, String callingPackage)5779     public void setMode(int mode, IBinder cb, String callingPackage) {
5780         int pid = Binder.getCallingPid();
5781         int uid = Binder.getCallingUid();
5782         if (DEBUG_MODE) {
5783             Log.v(TAG, "setMode(mode=" + mode + ", pid=" + pid
5784                     + ", uid=" + uid + ", caller=" + callingPackage + ")");
5785         }
5786         if (!checkAudioSettingsPermission("setMode()")) {
5787             return;
5788         }
5789         if (cb == null) {
5790             Log.e(TAG, "setMode() called with null binder");
5791             return;
5792         }
5793         if (mode < AudioSystem.MODE_CURRENT || mode >= AudioSystem.NUM_MODES) {
5794             Log.w(TAG, "setMode() invalid mode: " + mode);
5795             return;
5796         }
5797 
5798         if (mode == AudioSystem.MODE_CURRENT) {
5799             mode = getMode();
5800         }
5801 
5802         if (mode == AudioSystem.MODE_CALL_SCREENING && !mIsCallScreeningModeSupported) {
5803             Log.w(TAG, "setMode(MODE_CALL_SCREENING) not permitted "
5804                     + "when call screening is not supported");
5805             return;
5806         }
5807 
5808         final boolean hasModifyPhoneStatePermission = mContext.checkCallingOrSelfPermission(
5809                 android.Manifest.permission.MODIFY_PHONE_STATE)
5810                 == PackageManager.PERMISSION_GRANTED;
5811         if ((mode == AudioSystem.MODE_IN_CALL
5812                 || mode == AudioSystem.MODE_CALL_REDIRECT
5813                 || mode == AudioSystem.MODE_COMMUNICATION_REDIRECT)
5814                 && !hasModifyPhoneStatePermission) {
5815             Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setMode("
5816                     + AudioSystem.modeToString(mode) + ") from pid=" + pid
5817                     + ", uid=" + Binder.getCallingUid());
5818             return;
5819         }
5820 
5821         SetModeDeathHandler currentModeHandler = null;
5822         synchronized (mDeviceBroker.mSetModeLock) {
5823             for (SetModeDeathHandler h : mSetModeDeathHandlers) {
5824                 if (h.getPid() == pid) {
5825                     currentModeHandler = h;
5826                     break;
5827                 }
5828             }
5829 
5830             if (mode == AudioSystem.MODE_NORMAL) {
5831                 if (currentModeHandler != null) {
5832                     if (!currentModeHandler.isPrivileged()
5833                             && currentModeHandler.getMode() == AudioSystem.MODE_IN_COMMUNICATION) {
5834                         mAudioHandler.removeEqualMessages(
5835                                 MSG_CHECK_MODE_FOR_UID, currentModeHandler);
5836                     }
5837                     mSetModeDeathHandlers.remove(currentModeHandler);
5838                     if (DEBUG_MODE) {
5839                         Log.v(TAG, "setMode(" + mode + ") removing hldr for pid: " + pid);
5840                     }
5841                     try {
5842                         currentModeHandler.getBinder().unlinkToDeath(currentModeHandler, 0);
5843                     } catch (NoSuchElementException e) {
5844                         Log.w(TAG, "setMode link does not exist ...");
5845                     }
5846                 }
5847             } else {
5848                 if (currentModeHandler != null) {
5849                     currentModeHandler.setMode(mode);
5850                     if (DEBUG_MODE) {
5851                         Log.v(TAG, "setMode(" + mode + ") updating hldr for pid: " + pid);
5852                     }
5853                 } else {
5854                     currentModeHandler = new SetModeDeathHandler(cb, pid, uid,
5855                             hasModifyPhoneStatePermission, callingPackage, mode);
5856                     // Register for client death notification
5857                     try {
5858                         cb.linkToDeath(currentModeHandler, 0);
5859                     } catch (RemoteException e) {
5860                         // Client has died!
5861                         Log.w(TAG, "setMode() could not link to " + cb + " binder death");
5862                         return;
5863                     }
5864                     mSetModeDeathHandlers.add(currentModeHandler);
5865                     if (DEBUG_MODE) {
5866                         Log.v(TAG, "setMode(" + mode + ") adding handler for pid=" + pid);
5867                     }
5868                 }
5869                 if (mode == AudioSystem.MODE_IN_COMMUNICATION) {
5870                     // Force active state when entering/updating the stack to avoid glitches when
5871                     // an app starts playing/recording after settng the audio mode,
5872                     // and send a reminder to check activity after a grace period.
5873                     if (!currentModeHandler.isPrivileged()) {
5874                         currentModeHandler.setPlaybackActive(true);
5875                         currentModeHandler.setRecordingActive(true);
5876                         sendMsg(mAudioHandler,
5877                                 MSG_CHECK_MODE_FOR_UID,
5878                                 SENDMSG_QUEUE,
5879                                 0,
5880                                 0,
5881                                 currentModeHandler,
5882                                 CHECK_MODE_FOR_UID_PERIOD_MS);
5883                     }
5884                 }
5885             }
5886 
5887             sendMsg(mAudioHandler,
5888                     MSG_UPDATE_AUDIO_MODE,
5889                     SENDMSG_REPLACE,
5890                     mode,
5891                     pid,
5892                     callingPackage,
5893                     0);
5894         }
5895     }
5896 
5897     @GuardedBy("mDeviceBroker.mSetModeLock")
onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage, boolean force)5898     void onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage,
5899                            boolean force) {
5900         if (requestedMode == AudioSystem.MODE_CURRENT) {
5901             requestedMode = getMode();
5902         }
5903         int mode = AudioSystem.MODE_NORMAL;
5904         int uid = 0;
5905         int pid = 0;
5906         SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler();
5907         if (currentModeHandler != null) {
5908             mode = currentModeHandler.getMode();
5909             uid = currentModeHandler.getUid();
5910             pid = currentModeHandler.getPid();
5911         }
5912         if (DEBUG_MODE) {
5913             Log.v(TAG, "onUpdateAudioMode() new mode: " + mode + ", current mode: "
5914                     + mMode.get() + " requested mode: " + requestedMode);
5915         }
5916         if (mode != mMode.get() || force) {
5917             int status = AudioSystem.SUCCESS;
5918             final long identity = Binder.clearCallingIdentity();
5919             try {
5920                 status = mAudioSystem.setPhoneState(mode, uid);
5921             } finally {
5922                 Binder.restoreCallingIdentity(identity);
5923             }
5924             if (status == AudioSystem.AUDIO_STATUS_OK) {
5925                 if (DEBUG_MODE) {
5926                     Log.v(TAG, "onUpdateAudioMode: mode successfully set to " + mode);
5927                 }
5928                 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_MODE, SENDMSG_REPLACE, mode, 0,
5929                         /*obj*/ null, /*delay*/ 0);
5930                 int previousMode = mMode.getAndSet(mode);
5931                 // Note: newModeOwnerPid is always 0 when actualMode is MODE_NORMAL
5932                 mModeLogger.enqueue(new PhoneStateEvent(requesterPackage, requesterPid,
5933                         requestedMode, pid, mode));
5934 
5935                 final int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
5936                 final int device = getDeviceForStream(streamType);
5937                 final int streamAlias = mStreamVolumeAlias[streamType];
5938 
5939                 if (DEBUG_MODE) {
5940                     Log.v(TAG, "onUpdateAudioMode: streamType=" + streamType
5941                             + ", streamAlias=" + streamAlias);
5942                 }
5943 
5944                 final int index = mStreamStates[streamAlias].getIndex(device);
5945                 final int maxIndex = mStreamStates[streamAlias].getMaxIndex();
5946                 setStreamVolumeInt(streamAlias, index, device, true,
5947                         requesterPackage, true /*hasModifyAudioSettings*/);
5948 
5949                 updateStreamVolumeAlias(true /*updateVolumes*/, requesterPackage);
5950 
5951                 // change of mode may require volume to be re-applied on some devices
5952                 updateAbsVolumeMultiModeDevices(previousMode, mode);
5953 
5954                 setLeAudioVolumeOnModeUpdate(mode, device, streamAlias, index, maxIndex);
5955 
5956                 // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all SCO
5957                 // connections not started by the application changing the mode when pid changes
5958                 mDeviceBroker.postSetModeOwner(mode, pid, uid);
5959             } else {
5960                 Log.w(TAG, "onUpdateAudioMode: failed to set audio mode to: " + mode);
5961             }
5962         }
5963     }
5964 
5965     /** @see AudioManager#getMode() */
getMode()5966     public int getMode() {
5967         synchronized (mDeviceBroker.mSetModeLock) {
5968             SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler();
5969             if (currentModeHandler != null) {
5970                 return currentModeHandler.getMode();
5971             }
5972             return AudioSystem.MODE_NORMAL;
5973         }
5974     }
5975 
5976     /** cached value read from audiopolicy manager after initialization. */
5977     private boolean mIsCallScreeningModeSupported = false;
5978 
5979     /** @see AudioManager#isCallScreeningModeSupported() */
isCallScreeningModeSupported()5980     public boolean isCallScreeningModeSupported() {
5981         return mIsCallScreeningModeSupported;
5982     }
5983 
dispatchMode(int mode)5984     protected void dispatchMode(int mode) {
5985         final int nbDispatchers = mModeDispatchers.beginBroadcast();
5986         for (int i = 0; i < nbDispatchers; i++) {
5987             try {
5988                 mModeDispatchers.getBroadcastItem(i).dispatchAudioModeChanged(mode);
5989             } catch (RemoteException e) {
5990             }
5991         }
5992         mModeDispatchers.finishBroadcast();
5993     }
5994 
5995     final RemoteCallbackList<IAudioModeDispatcher> mModeDispatchers =
5996             new RemoteCallbackList<IAudioModeDispatcher>();
5997 
5998     /**
5999      * @see {@link AudioManager#addOnModeChangedListener(Executor, AudioManager.OnModeChangedListener)}
6000      * @param dispatcher
6001      */
registerModeDispatcher( @onNull IAudioModeDispatcher dispatcher)6002     public void registerModeDispatcher(
6003             @NonNull IAudioModeDispatcher dispatcher) {
6004         mModeDispatchers.register(dispatcher);
6005     }
6006 
6007     /**
6008      * @see {@link AudioManager#removeOnModeChangedListener(AudioManager.OnModeChangedListener)}
6009      * @param dispatcher
6010      */
unregisterModeDispatcher( @onNull IAudioModeDispatcher dispatcher)6011     public void unregisterModeDispatcher(
6012             @NonNull IAudioModeDispatcher dispatcher) {
6013         mModeDispatchers.unregister(dispatcher);
6014     }
6015 
6016     @android.annotation.EnforcePermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION)
6017     /** @see AudioManager#isPstnCallAudioInterceptable() */
isPstnCallAudioInterceptable()6018     public boolean isPstnCallAudioInterceptable() {
6019 
6020         super.isPstnCallAudioInterceptable_enforcePermission();
6021 
6022         boolean uplinkDeviceFound = false;
6023         boolean downlinkDeviceFound = false;
6024         AudioDeviceInfo[] devices = AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_ALL);
6025         for (AudioDeviceInfo device : devices) {
6026             if (device.getInternalType() == AudioSystem.DEVICE_OUT_TELEPHONY_TX) {
6027                 uplinkDeviceFound = true;
6028             } else if (device.getInternalType() == AudioSystem.DEVICE_IN_TELEPHONY_RX) {
6029                 downlinkDeviceFound = true;
6030             }
6031             if (uplinkDeviceFound && downlinkDeviceFound) {
6032                 return true;
6033             }
6034         }
6035         return false;
6036     }
6037 
6038     /** @see AudioManager#setRttEnabled() */
6039     @Override
setRttEnabled(boolean rttEnabled)6040     public void setRttEnabled(boolean rttEnabled) {
6041         if (mContext.checkCallingOrSelfPermission(
6042                 android.Manifest.permission.MODIFY_PHONE_STATE)
6043                 != PackageManager.PERMISSION_GRANTED) {
6044             Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setRttEnabled from pid="
6045                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
6046             return;
6047         }
6048         synchronized (mSettingsLock) {
6049             mRttEnabled = rttEnabled;
6050             final long identity = Binder.clearCallingIdentity();
6051             try {
6052                 AudioSystem.setRttEnabled(rttEnabled);
6053             } finally {
6054                 Binder.restoreCallingIdentity(identity);
6055             }
6056         }
6057     }
6058 
6059     /** @see AudioManager#adjustSuggestedStreamVolumeForUid(int, int, int, String, int, int, int) */
6060     @Override
adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6061     public void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags,
6062             @NonNull String packageName, int uid, int pid, UserHandle userHandle,
6063             int targetSdkVersion) {
6064         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
6065             throw new SecurityException("Should only be called from system process");
6066         }
6067 
6068         // direction and stream type swap here because the public
6069         // adjustSuggested has a different order than the other methods.
6070         adjustSuggestedStreamVolume(direction, streamType, flags, packageName, packageName,
6071                 uid, pid, hasAudioSettingsPermission(uid, pid),
6072                 AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
6073     }
6074 
6075     /** @see AudioManager#adjustStreamVolumeForUid(int, int, int, String, int, int, int) */
6076     @Override
adjustStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6077     public void adjustStreamVolumeForUid(int streamType, int direction, int flags,
6078             @NonNull String packageName, int uid, int pid, UserHandle userHandle,
6079             int targetSdkVersion) {
6080         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
6081             throw new SecurityException("Should only be called from system process");
6082         }
6083 
6084         if (direction != AudioManager.ADJUST_SAME) {
6085             sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_ADJUST_VOL_UID, streamType,
6086                     direction/*val1*/, flags/*val2*/,
6087                     new StringBuilder(packageName).append(" uid:").append(uid)
6088                     .toString()));
6089         }
6090 
6091         adjustStreamVolume(streamType, direction, flags, packageName, packageName, uid, pid,
6092                 null, hasAudioSettingsPermission(uid, pid),
6093                 AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
6094     }
6095 
6096     /** @see AudioManager#setStreamVolumeForUid(int, int, int, String, int, int, int) */
6097     @Override
setStreamVolumeForUid(int streamType, int index, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)6098     public void setStreamVolumeForUid(int streamType, int index, int flags,
6099             @NonNull String packageName, int uid, int pid, UserHandle userHandle,
6100             int targetSdkVersion) {
6101         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
6102             throw new SecurityException("Should only be called from system process");
6103         }
6104 
6105         setStreamVolume(streamType, index, flags, /*device*/ null,
6106                 packageName, packageName, null, uid,
6107                 hasAudioSettingsPermission(uid, pid));
6108     }
6109 
6110     //==========================================================================================
6111     // Sound Effects
6112     //==========================================================================================
6113     private static final class LoadSoundEffectReply
6114             implements SoundEffectsHelper.OnEffectsLoadCompleteHandler {
6115         private static final int SOUND_EFFECTS_LOADING = 1;
6116         private static final int SOUND_EFFECTS_LOADED = 0;
6117         private static final int SOUND_EFFECTS_ERROR = -1;
6118         private static final int SOUND_EFFECTS_LOAD_TIMEOUT_MS = 5000;
6119 
6120         private int mStatus = SOUND_EFFECTS_LOADING;
6121 
6122         @Override
run(boolean success)6123         public synchronized void run(boolean success) {
6124             mStatus = success ? SOUND_EFFECTS_LOADED : SOUND_EFFECTS_ERROR;
6125             notify();
6126         }
6127 
waitForLoaded(int attempts)6128         public synchronized boolean waitForLoaded(int attempts) {
6129             while ((mStatus == SOUND_EFFECTS_LOADING) && (attempts-- > 0)) {
6130                 try {
6131                     wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS);
6132                 } catch (InterruptedException e) {
6133                     Log.w(TAG, "Interrupted while waiting sound pool loaded.");
6134                 }
6135             }
6136             return mStatus == SOUND_EFFECTS_LOADED;
6137         }
6138     }
6139 
6140     /** @see AudioManager#playSoundEffect(int, int) */
playSoundEffect(int effectType, int userId)6141     public void playSoundEffect(int effectType, int userId) {
6142         if (querySoundEffectsEnabled(userId)) {
6143             playSoundEffectVolume(effectType, -1.0f);
6144         }
6145     }
6146 
6147     /**
6148      * Settings has an in memory cache, so this is fast.
6149      */
querySoundEffectsEnabled(int user)6150     private boolean querySoundEffectsEnabled(int user) {
6151         return mSettings.getSystemIntForUser(getContentResolver(),
6152                 Settings.System.SOUND_EFFECTS_ENABLED, 0, user) != 0;
6153     }
6154 
6155     /** @see AudioManager#playSoundEffect(int, float) */
playSoundEffectVolume(int effectType, float volume)6156     public void playSoundEffectVolume(int effectType, float volume) {
6157         // do not try to play the sound effect if the system stream is muted
6158         if (isStreamMute(STREAM_SYSTEM)) {
6159             return;
6160         }
6161 
6162         if (effectType >= AudioManager.NUM_SOUND_EFFECTS || effectType < 0) {
6163             Log.w(TAG, "AudioService effectType value " + effectType + " out of range");
6164             return;
6165         }
6166 
6167         sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SENDMSG_QUEUE,
6168                 effectType, (int) (volume * 1000), null, 0);
6169     }
6170 
6171     /**
6172      * Loads samples into the soundpool.
6173      * This method must be called at first when sound effects are enabled
6174      */
loadSoundEffects()6175     public boolean loadSoundEffects() {
6176         LoadSoundEffectReply reply = new LoadSoundEffectReply();
6177         sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, reply, 0);
6178         return reply.waitForLoaded(3 /*attempts*/);
6179     }
6180 
6181     /**
6182      * Schedule loading samples into the soundpool.
6183      * This method can be overridden to schedule loading at a later time.
6184      */
scheduleLoadSoundEffects()6185     protected void scheduleLoadSoundEffects() {
6186         sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0);
6187     }
6188 
6189     /**
6190      *  Unloads samples from the sound pool.
6191      *  This method can be called to free some memory when
6192      *  sound effects are disabled.
6193      */
unloadSoundEffects()6194     public void unloadSoundEffects() {
6195         sendMsg(mAudioHandler, MSG_UNLOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0);
6196     }
6197 
6198     /** @see AudioManager#reloadAudioSettings() */
reloadAudioSettings()6199     public void reloadAudioSettings() {
6200         readAudioSettings(false /*userSwitch*/);
6201     }
6202 
readAudioSettings(boolean userSwitch)6203     private void readAudioSettings(boolean userSwitch) {
6204         // restore ringer mode, ringer mode affected streams, mute affected streams and vibrate settings
6205         readPersistedSettings();
6206         readUserRestrictions();
6207 
6208         // restore volume settings
6209         int numStreamTypes = AudioSystem.getNumStreamTypes();
6210         for (int streamType = 0; streamType < numStreamTypes; streamType++) {
6211             VolumeStreamState streamState = mStreamStates[streamType];
6212 
6213             if (userSwitch && mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) {
6214                 continue;
6215             }
6216 
6217             streamState.readSettings();
6218             synchronized (VolumeStreamState.class) {
6219                 // unmute stream that was muted but is not affect by mute anymore
6220                 if (streamState.mIsMuted && ((!isStreamAffectedByMute(streamType) &&
6221                         !isStreamMutedByRingerOrZenMode(streamType)) || mUseFixedVolume)) {
6222                     streamState.mIsMuted = false;
6223                 }
6224             }
6225         }
6226 
6227         readVolumeGroupsSettings(userSwitch);
6228 
6229         // apply new ringer mode before checking volume for alias streams so that streams
6230         // muted by ringer mode have the correct volume
6231         setRingerModeInt(getRingerModeInternal(), false);
6232 
6233         checkAllFixedVolumeDevices();
6234         checkAllAliasStreamVolumes();
6235         checkMuteAffectedStreams();
6236 
6237         mSoundDoseHelper.restoreMusicActiveMs();
6238         mSoundDoseHelper.enforceSafeMediaVolumeIfActive(TAG);
6239 
6240         if (DEBUG_VOL) {
6241             Log.d(TAG, "Restoring device volume behavior");
6242         }
6243         restoreDeviceVolumeBehavior();
6244     }
6245 
6246     /** @see AudioManager#getAvailableCommunicationDevices(int) */
getAvailableCommunicationDeviceIds()6247     public int[] getAvailableCommunicationDeviceIds() {
6248         List<AudioDeviceInfo> commDevices = AudioDeviceBroker.getAvailableCommunicationDevices();
6249         return commDevices.stream().mapToInt(AudioDeviceInfo::getId).toArray();
6250     }
6251 
6252     /**
6253      * @see AudioManager#setCommunicationDevice(int)
6254      * @see AudioManager#clearCommunicationDevice()
6255      */
setCommunicationDevice(IBinder cb, int portId)6256     public boolean setCommunicationDevice(IBinder cb, int portId) {
6257         final int uid = Binder.getCallingUid();
6258         final int pid = Binder.getCallingPid();
6259 
6260         AudioDeviceInfo device = null;
6261         if (portId != 0) {
6262             device = AudioManager.getDeviceForPortId(portId, AudioManager.GET_DEVICES_OUTPUTS);
6263             if (device == null) {
6264                 Log.w(TAG, "setCommunicationDevice: invalid portID " + portId);
6265                 return false;
6266             }
6267             if (!AudioDeviceBroker.isValidCommunicationDevice(device)) {
6268                 if (!device.isSink()) {
6269                     throw new IllegalArgumentException("device must have sink role");
6270                 } else {
6271                     throw new IllegalArgumentException("invalid device type: " + device.getType());
6272                 }
6273             }
6274         }
6275         final String eventSource = new StringBuilder()
6276                 .append(device == null ? "clearCommunicationDevice(" : "setCommunicationDevice(")
6277                 .append(") from u/pid:").append(uid).append("/")
6278                 .append(pid).toString();
6279 
6280         int deviceType = AudioSystem.DEVICE_OUT_DEFAULT;
6281         String deviceAddress = null;
6282         if (device != null) {
6283             deviceType = device.getPort().type();
6284             deviceAddress = device.getAddress();
6285         } else {
6286             AudioDeviceInfo curDevice = mDeviceBroker.getCommunicationDevice();
6287             if (curDevice != null) {
6288                 deviceType = curDevice.getPort().type();
6289                 deviceAddress = curDevice.getAddress();
6290             }
6291         }
6292         // do not log metrics if clearing communication device while no communication device
6293         // was selected
6294         if (deviceType != AudioSystem.DEVICE_OUT_DEFAULT) {
6295             new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
6296                     + MediaMetrics.SEPARATOR + "setCommunicationDevice")
6297                     .set(MediaMetrics.Property.DEVICE,
6298                             AudioSystem.getDeviceName(deviceType))
6299                     .set(MediaMetrics.Property.ADDRESS, deviceAddress)
6300                     .set(MediaMetrics.Property.STATE, device != null
6301                             ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED)
6302                     .record();
6303         }
6304         final boolean isPrivileged = mContext.checkCallingOrSelfPermission(
6305                 android.Manifest.permission.MODIFY_PHONE_STATE)
6306                 == PackageManager.PERMISSION_GRANTED;
6307         final long ident = Binder.clearCallingIdentity();
6308         try {
6309             return mDeviceBroker.setCommunicationDevice(cb, uid, device, isPrivileged, eventSource);
6310         } finally {
6311             Binder.restoreCallingIdentity(ident);
6312         }
6313     }
6314 
6315     /** @see AudioManager#getCommunicationDevice() */
getCommunicationDevice()6316     public int getCommunicationDevice() {
6317         int deviceId = 0;
6318         final long ident = Binder.clearCallingIdentity();
6319         try {
6320             AudioDeviceInfo device = mDeviceBroker.getCommunicationDevice();
6321             deviceId = device != null ? device.getId() : 0;
6322         } finally {
6323             Binder.restoreCallingIdentity(ident);
6324         }
6325         return deviceId;
6326     }
6327 
6328     /** @see AudioManager#addOnCommunicationDeviceChangedListener(
6329      *               Executor, AudioManager.OnCommunicationDeviceChangedListener)
6330      */
registerCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)6331     public void registerCommunicationDeviceDispatcher(
6332             @Nullable ICommunicationDeviceDispatcher dispatcher) {
6333         if (dispatcher == null) {
6334             return;
6335         }
6336         mDeviceBroker.registerCommunicationDeviceDispatcher(dispatcher);
6337     }
6338 
6339     /** @see AudioManager#removeOnCommunicationDeviceChangedListener(
6340      *               AudioManager.OnCommunicationDeviceChangedListener)
6341      */
unregisterCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)6342     public void unregisterCommunicationDeviceDispatcher(
6343             @Nullable ICommunicationDeviceDispatcher dispatcher) {
6344         if (dispatcher == null) {
6345             return;
6346         }
6347         mDeviceBroker.unregisterCommunicationDeviceDispatcher(dispatcher);
6348     }
6349 
6350     /** @see AudioManager#setSpeakerphoneOn(boolean) */
setSpeakerphoneOn(IBinder cb, boolean on)6351     public void setSpeakerphoneOn(IBinder cb, boolean on) {
6352         if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) {
6353             return;
6354         }
6355         final boolean isPrivileged = mContext.checkCallingOrSelfPermission(
6356                 android.Manifest.permission.MODIFY_PHONE_STATE)
6357                 == PackageManager.PERMISSION_GRANTED;
6358 
6359         // for logging only
6360         final int uid = Binder.getCallingUid();
6361         final int pid = Binder.getCallingPid();
6362 
6363         final String eventSource = new StringBuilder("setSpeakerphoneOn(").append(on)
6364                 .append(") from u/pid:").append(uid).append("/")
6365                 .append(pid).toString();
6366         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
6367                 + MediaMetrics.SEPARATOR + "setSpeakerphoneOn")
6368                 .setUid(uid)
6369                 .setPid(pid)
6370                 .set(MediaMetrics.Property.STATE, on
6371                         ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
6372                 .record();
6373 
6374         final long ident = Binder.clearCallingIdentity();
6375         try {
6376             mDeviceBroker.setSpeakerphoneOn(cb, uid, on, isPrivileged, eventSource);
6377         } finally {
6378             Binder.restoreCallingIdentity(ident);
6379         }
6380     }
6381 
6382     /** @see AudioManager#isSpeakerphoneOn() */
isSpeakerphoneOn()6383     public boolean isSpeakerphoneOn() {
6384         return mDeviceBroker.isSpeakerphoneOn();
6385     }
6386 
6387 
6388     /** BT SCO audio state seen by apps using the deprecated API setBluetoothScoOn().
6389      * @see isBluetoothScoOn() */
6390     private boolean mBtScoOnByApp;
6391 
6392     /** @see AudioManager#setBluetoothScoOn(boolean) */
setBluetoothScoOn(boolean on)6393     public void setBluetoothScoOn(boolean on) {
6394         if (!checkAudioSettingsPermission("setBluetoothScoOn()")) {
6395             return;
6396         }
6397 
6398         // Only enable calls from system components
6399         if (UserHandle.getCallingAppId() >= FIRST_APPLICATION_UID) {
6400             mBtScoOnByApp = on;
6401             return;
6402         }
6403 
6404         // for logging only
6405         final int uid = Binder.getCallingUid();
6406         final int pid = Binder.getCallingPid();
6407         final String eventSource = new StringBuilder("setBluetoothScoOn(").append(on)
6408                 .append(") from u/pid:").append(uid).append("/").append(pid).toString();
6409 
6410         //bt sco
6411         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
6412                 + MediaMetrics.SEPARATOR + "setBluetoothScoOn")
6413                 .setUid(uid)
6414                 .setPid(pid)
6415                 .set(MediaMetrics.Property.STATE, on
6416                         ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
6417                 .record();
6418 
6419         mDeviceBroker.setBluetoothScoOn(on, eventSource);
6420     }
6421 
6422     /** @see AudioManager#setA2dpSuspended(boolean) */
6423     @android.annotation.EnforcePermission(android.Manifest.permission.BLUETOOTH_STACK)
setA2dpSuspended(boolean enable)6424     public void setA2dpSuspended(boolean enable) {
6425         super.setA2dpSuspended_enforcePermission();
6426         final String eventSource = new StringBuilder("setA2dpSuspended(").append(enable)
6427                 .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
6428                 .append(Binder.getCallingPid()).toString();
6429         mDeviceBroker.setA2dpSuspended(enable, false /*internal*/, eventSource);
6430     }
6431 
6432     /** @see AudioManager#setA2dpSuspended(boolean) */
6433     @android.annotation.EnforcePermission(android.Manifest.permission.BLUETOOTH_STACK)
setLeAudioSuspended(boolean enable)6434     public void setLeAudioSuspended(boolean enable) {
6435         super.setLeAudioSuspended_enforcePermission();
6436         final String eventSource = new StringBuilder("setLeAudioSuspended(").append(enable)
6437                 .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
6438                 .append(Binder.getCallingPid()).toString();
6439         mDeviceBroker.setLeAudioSuspended(enable, false /*internal*/, eventSource);
6440     }
6441 
6442     /** @see AudioManager#isBluetoothScoOn()
6443      * Note that it doesn't report internal state, but state seen by apps (which may have
6444      * called setBluetoothScoOn() */
isBluetoothScoOn()6445     public boolean isBluetoothScoOn() {
6446         return mBtScoOnByApp || mDeviceBroker.isBluetoothScoOn();
6447     }
6448 
6449     // TODO investigate internal users due to deprecation of SDK API
6450     /** @see AudioManager#setBluetoothA2dpOn(boolean) */
setBluetoothA2dpOn(boolean on)6451     public void setBluetoothA2dpOn(boolean on) {
6452         if (!checkAudioSettingsPermission("setBluetoothA2dpOn()")) {
6453             return;
6454         }
6455 
6456         // for logging only
6457         final int uid = Binder.getCallingUid();
6458         final int pid = Binder.getCallingPid();
6459         final String eventSource = new StringBuilder("setBluetoothA2dpOn(").append(on)
6460                 .append(") from u/pid:").append(uid).append("/")
6461                 .append(pid).toString();
6462 
6463         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
6464                 + MediaMetrics.SEPARATOR + "setBluetoothA2dpOn")
6465                 .setUid(uid)
6466                 .setPid(pid)
6467                 .set(MediaMetrics.Property.STATE, on
6468                         ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
6469                 .record();
6470 
6471         mDeviceBroker.setBluetoothA2dpOn_Async(on, eventSource);
6472     }
6473 
6474     /** @see AudioManager#isBluetoothA2dpOn() */
isBluetoothA2dpOn()6475     public boolean isBluetoothA2dpOn() {
6476         return mDeviceBroker.isBluetoothA2dpOn();
6477     }
6478 
6479     /** @see AudioManager#startBluetoothSco() */
startBluetoothSco(IBinder cb, int targetSdkVersion)6480     public void startBluetoothSco(IBinder cb, int targetSdkVersion) {
6481         if (!checkAudioSettingsPermission("startBluetoothSco()")) {
6482             return;
6483         }
6484 
6485         final int uid = Binder.getCallingUid();
6486         final int pid = Binder.getCallingPid();
6487         final int scoAudioMode =
6488                 (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ?
6489                         BtHelper.SCO_MODE_VIRTUAL_CALL : BtHelper.SCO_MODE_UNDEFINED;
6490         final String eventSource = new StringBuilder("startBluetoothSco()")
6491                 .append(") from u/pid:").append(uid).append("/")
6492                 .append(pid).toString();
6493 
6494         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
6495                 .setUid(uid)
6496                 .setPid(pid)
6497                 .set(MediaMetrics.Property.EVENT, "startBluetoothSco")
6498                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
6499                         BtHelper.scoAudioModeToString(scoAudioMode))
6500                 .record();
6501         startBluetoothScoInt(cb, uid, scoAudioMode, eventSource);
6502 
6503     }
6504 
6505     /** @see AudioManager#startBluetoothScoVirtualCall() */
startBluetoothScoVirtualCall(IBinder cb)6506     public void startBluetoothScoVirtualCall(IBinder cb) {
6507         if (!checkAudioSettingsPermission("startBluetoothScoVirtualCall()")) {
6508             return;
6509         }
6510 
6511         final int uid = Binder.getCallingUid();
6512         final int pid = Binder.getCallingPid();
6513         final String eventSource = new StringBuilder("startBluetoothScoVirtualCall()")
6514                 .append(") from u/pid:").append(uid).append("/")
6515                 .append(pid).toString();
6516 
6517         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
6518                 .setUid(uid)
6519                 .setPid(pid)
6520                 .set(MediaMetrics.Property.EVENT, "startBluetoothScoVirtualCall")
6521                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
6522                         BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_VIRTUAL_CALL))
6523                 .record();
6524         startBluetoothScoInt(cb, uid, BtHelper.SCO_MODE_VIRTUAL_CALL, eventSource);
6525     }
6526 
startBluetoothScoInt(IBinder cb, int uid, int scoAudioMode, @NonNull String eventSource)6527     void startBluetoothScoInt(IBinder cb, int uid, int scoAudioMode, @NonNull String eventSource) {
6528         MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
6529                 .set(MediaMetrics.Property.EVENT, "startBluetoothScoInt")
6530                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
6531                         BtHelper.scoAudioModeToString(scoAudioMode));
6532 
6533         if (!checkAudioSettingsPermission("startBluetoothSco()") ||
6534                 !mSystemReady) {
6535             mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission or systemReady").record();
6536             return;
6537         }
6538         final boolean isPrivileged = mContext.checkCallingOrSelfPermission(
6539                 android.Manifest.permission.MODIFY_PHONE_STATE)
6540                 == PackageManager.PERMISSION_GRANTED;
6541         final long ident = Binder.clearCallingIdentity();
6542         try {
6543             mDeviceBroker.startBluetoothScoForClient(
6544                     cb, uid, scoAudioMode, isPrivileged, eventSource);
6545         } finally {
6546             Binder.restoreCallingIdentity(ident);
6547         }
6548         mmi.record();
6549     }
6550 
6551     /** @see AudioManager#stopBluetoothSco() */
stopBluetoothSco(IBinder cb)6552     public void stopBluetoothSco(IBinder cb){
6553         if (!checkAudioSettingsPermission("stopBluetoothSco()") ||
6554                 !mSystemReady) {
6555             return;
6556         }
6557         final int uid = Binder.getCallingUid();
6558         final int pid = Binder.getCallingPid();
6559         final String eventSource =  new StringBuilder("stopBluetoothSco()")
6560                 .append(") from u/pid:").append(uid).append("/")
6561                 .append(pid).toString();
6562         final boolean isPrivileged = mContext.checkCallingOrSelfPermission(
6563                 android.Manifest.permission.MODIFY_PHONE_STATE)
6564                 == PackageManager.PERMISSION_GRANTED;
6565         final long ident = Binder.clearCallingIdentity();
6566         try {
6567             mDeviceBroker.stopBluetoothScoForClient(cb, uid, isPrivileged, eventSource);
6568         } finally {
6569             Binder.restoreCallingIdentity(ident);
6570         }
6571         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
6572                 .setUid(uid)
6573                 .setPid(pid)
6574                 .set(MediaMetrics.Property.EVENT, "stopBluetoothSco")
6575                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
6576                         BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_UNDEFINED))
6577                 .record();
6578     }
6579 
6580 
getContentResolver()6581     /*package*/ ContentResolver getContentResolver() {
6582         return mContentResolver;
6583     }
6584 
getSettings()6585     /*package*/ SettingsAdapter getSettings() {
6586         return mSettings;
6587     }
6588 
6589     ///////////////////////////////////////////////////////////////////////////
6590     // Internal methods
6591     ///////////////////////////////////////////////////////////////////////////
6592 
6593     /**
6594      * Checks if the adjustment should change ringer mode instead of just
6595      * adjusting volume. If so, this will set the proper ringer mode and volume
6596      * indices on the stream states.
6597      */
checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted, String caller, int flags)6598     private int checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted,
6599             String caller, int flags) {
6600         int result = FLAG_ADJUST_VOLUME;
6601         if (isPlatformTelevision() || mIsSingleVolume) {
6602             return result;
6603         }
6604 
6605         int ringerMode = getRingerModeInternal();
6606 
6607         switch (ringerMode) {
6608         case RINGER_MODE_NORMAL:
6609             if (direction == AudioManager.ADJUST_LOWER) {
6610                 if (mHasVibrator) {
6611                     // "step" is the delta in internal index units corresponding to a
6612                     // change of 1 in UI index units.
6613                     // Because of rounding when rescaling from one stream index range to its alias
6614                     // index range, we cannot simply test oldIndex == step:
6615                     //   (step <= oldIndex < 2 * step) is equivalent to: (old UI index == 1)
6616                     if (step <= oldIndex && oldIndex < 2 * step) {
6617                         ringerMode = RINGER_MODE_VIBRATE;
6618                         mLoweredFromNormalToVibrateTime = SystemClock.uptimeMillis();
6619                     }
6620                 } else {
6621                     if (oldIndex == step && mVolumePolicy.volumeDownToEnterSilent) {
6622                         ringerMode = RINGER_MODE_SILENT;
6623                     }
6624                 }
6625             } else if (mIsSingleVolume && (direction == AudioManager.ADJUST_TOGGLE_MUTE
6626                     || direction == AudioManager.ADJUST_MUTE)) {
6627                 if (mHasVibrator) {
6628                     ringerMode = RINGER_MODE_VIBRATE;
6629                 } else {
6630                     ringerMode = RINGER_MODE_SILENT;
6631                 }
6632                 // Setting the ringer mode will toggle mute
6633                 result &= ~FLAG_ADJUST_VOLUME;
6634             }
6635             break;
6636         case RINGER_MODE_VIBRATE:
6637             if (!mHasVibrator) {
6638                 Log.e(TAG, "checkForRingerModeChange() current ringer mode is vibrate" +
6639                         "but no vibrator is present");
6640                 break;
6641             }
6642             if ((direction == AudioManager.ADJUST_LOWER)) {
6643                 // This is the case we were muted with the volume turned up
6644                 if (mIsSingleVolume && oldIndex >= 2 * step && isMuted) {
6645                     ringerMode = RINGER_MODE_NORMAL;
6646                 } else if (mPrevVolDirection != AudioManager.ADJUST_LOWER) {
6647                     if (mVolumePolicy.volumeDownToEnterSilent) {
6648                         final long diff = SystemClock.uptimeMillis()
6649                                 - mLoweredFromNormalToVibrateTime;
6650                         if (diff > mVolumePolicy.vibrateToSilentDebounce
6651                                 && mRingerModeDelegate.canVolumeDownEnterSilent()) {
6652                             ringerMode = RINGER_MODE_SILENT;
6653                         }
6654                     } else {
6655                         result |= AudioManager.FLAG_SHOW_VIBRATE_HINT;
6656                     }
6657                 }
6658             } else if (direction == AudioManager.ADJUST_RAISE
6659                     || direction == AudioManager.ADJUST_TOGGLE_MUTE
6660                     || direction == AudioManager.ADJUST_UNMUTE) {
6661                 ringerMode = RINGER_MODE_NORMAL;
6662             }
6663             result &= ~FLAG_ADJUST_VOLUME;
6664             break;
6665         case RINGER_MODE_SILENT:
6666             if (mIsSingleVolume && direction == AudioManager.ADJUST_LOWER && oldIndex >= 2 * step && isMuted) {
6667                 // This is the case we were muted with the volume turned up
6668                 ringerMode = RINGER_MODE_NORMAL;
6669             } else if (direction == AudioManager.ADJUST_RAISE
6670                     || direction == AudioManager.ADJUST_TOGGLE_MUTE
6671                     || direction == AudioManager.ADJUST_UNMUTE) {
6672                 if (!mVolumePolicy.volumeUpToExitSilent) {
6673                     result |= AudioManager.FLAG_SHOW_SILENT_HINT;
6674                 } else {
6675                   if (mHasVibrator && direction == AudioManager.ADJUST_RAISE) {
6676                       ringerMode = RINGER_MODE_VIBRATE;
6677                   } else {
6678                       // If we don't have a vibrator or they were toggling mute
6679                       // go straight back to normal.
6680                       ringerMode = RINGER_MODE_NORMAL;
6681                   }
6682                 }
6683             }
6684             result &= ~FLAG_ADJUST_VOLUME;
6685             break;
6686         default:
6687             Log.e(TAG, "checkForRingerModeChange() wrong ringer mode: "+ringerMode);
6688             break;
6689         }
6690 
6691         if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode)
6692                 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)
6693                 && (flags & AudioManager.FLAG_FROM_KEY) == 0) {
6694             throw new SecurityException("Not allowed to change Do Not Disturb state");
6695         }
6696 
6697         setRingerMode(ringerMode, TAG + ".checkForRingerModeChange", false /*external*/);
6698 
6699         mPrevVolDirection = direction;
6700 
6701         return result;
6702     }
6703 
6704     @Override
isStreamAffectedByRingerMode(int streamType)6705     public boolean isStreamAffectedByRingerMode(int streamType) {
6706         return (mRingerModeAffectedStreams & (1 << streamType)) != 0;
6707     }
6708 
shouldZenMuteStream(int streamType)6709     private boolean shouldZenMuteStream(int streamType) {
6710         if (mNm.getZenMode() != Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
6711             return false;
6712         }
6713 
6714         NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy();
6715         final boolean muteAlarms = (zenPolicy.priorityCategories
6716                 & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0;
6717         final boolean muteMedia = (zenPolicy.priorityCategories
6718                 & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0;
6719         final boolean muteSystem = (zenPolicy.priorityCategories
6720                 & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0;
6721         final boolean muteNotificationAndRing = ZenModeConfig
6722                 .areAllPriorityOnlyRingerSoundsMuted(zenPolicy);
6723         return muteAlarms && isAlarm(streamType)
6724                 || muteMedia && isMedia(streamType)
6725                 || muteSystem && isSystem(streamType)
6726                 || muteNotificationAndRing && isNotificationOrRinger(streamType);
6727     }
6728 
isStreamMutedByRingerOrZenMode(int streamType)6729     private boolean isStreamMutedByRingerOrZenMode(int streamType) {
6730         return (sRingerAndZenModeMutedStreams & (1 << streamType)) != 0;
6731     }
6732 
6733     /**
6734      * Notifications, ringer and system sounds are controlled by the ringer:
6735      * {@link ZenModeHelper.RingerModeDelegate#getRingerModeAffectedStreams(int)} but can
6736      * also be muted by DND based on the DND mode:
6737      * DND total silence: media and alarms streams can be muted by DND
6738      * DND alarms only: no streams additionally controlled by DND
6739      * DND priority only: alarms, media, system, ringer and notification streams can be muted by
6740      * DND.  The current applied zenPolicy determines which streams will be muted by DND.
6741      * @return true if changed, else false
6742      */
updateZenModeAffectedStreams()6743     private boolean updateZenModeAffectedStreams() {
6744         if (!mSystemReady) {
6745             return false;
6746         }
6747 
6748         int zenModeAffectedStreams = 0;
6749         final int zenMode = mNm.getZenMode();
6750 
6751         if (zenMode == Settings.Global.ZEN_MODE_NO_INTERRUPTIONS) {
6752             zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM;
6753             zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC;
6754         } else if (zenMode == Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
6755             NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy();
6756             if ((zenPolicy.priorityCategories
6757                     & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0) {
6758                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM;
6759             }
6760 
6761             if ((zenPolicy.priorityCategories
6762                     & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0) {
6763                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC;
6764             }
6765 
6766             // even if zen isn't muting the system stream, the ringer mode can still mute
6767             // the system stream
6768             if ((zenPolicy.priorityCategories
6769                     & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0) {
6770                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM;
6771             }
6772 
6773             if (ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(zenPolicy)) {
6774                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION;
6775                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING;
6776             }
6777         }
6778 
6779         if (mZenModeAffectedStreams != zenModeAffectedStreams) {
6780             mZenModeAffectedStreams = zenModeAffectedStreams;
6781             return true;
6782         }
6783 
6784         return false;
6785     }
6786 
6787     @GuardedBy("mSettingsLock")
updateRingerAndZenModeAffectedStreams()6788     private boolean updateRingerAndZenModeAffectedStreams() {
6789         boolean updatedZenModeAffectedStreams = updateZenModeAffectedStreams();
6790         int ringerModeAffectedStreams = mSettings.getSystemIntForUser(mContentResolver,
6791                 Settings.System.MODE_RINGER_STREAMS_AFFECTED,
6792                 ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
6793                  (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)),
6794                  UserHandle.USER_CURRENT);
6795 
6796         if (mIsSingleVolume) {
6797             ringerModeAffectedStreams = 0;
6798         } else if (mRingerModeDelegate != null) {
6799             ringerModeAffectedStreams = mRingerModeDelegate
6800                     .getRingerModeAffectedStreams(ringerModeAffectedStreams);
6801         }
6802         if (mCameraSoundForced) {
6803             ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
6804         } else {
6805             ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
6806         }
6807         if (mStreamVolumeAlias[AudioSystem.STREAM_DTMF] == AudioSystem.STREAM_RING) {
6808             ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF);
6809         } else {
6810             ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF);
6811         }
6812 
6813         if (ringerModeAffectedStreams != mRingerModeAffectedStreams) {
6814             mSettings.putSystemIntForUser(mContentResolver,
6815                     Settings.System.MODE_RINGER_STREAMS_AFFECTED,
6816                     ringerModeAffectedStreams,
6817                     UserHandle.USER_CURRENT);
6818             mRingerModeAffectedStreams = ringerModeAffectedStreams;
6819             return true;
6820         }
6821         return updatedZenModeAffectedStreams;
6822     }
6823 
6824     @Override
isStreamAffectedByMute(int streamType)6825     public boolean isStreamAffectedByMute(int streamType) {
6826         return (mMuteAffectedStreams & (1 << streamType)) != 0;
6827     }
6828 
ensureValidDirection(int direction)6829     private void ensureValidDirection(int direction) {
6830         switch (direction) {
6831             case AudioManager.ADJUST_LOWER:
6832             case AudioManager.ADJUST_RAISE:
6833             case AudioManager.ADJUST_SAME:
6834             case AudioManager.ADJUST_MUTE:
6835             case AudioManager.ADJUST_UNMUTE:
6836             case AudioManager.ADJUST_TOGGLE_MUTE:
6837                 break;
6838             default:
6839                 throw new IllegalArgumentException("Bad direction " + direction);
6840         }
6841     }
6842 
ensureValidStreamType(int streamType)6843     private void ensureValidStreamType(int streamType) {
6844         if (streamType < 0 || streamType >= mStreamStates.length) {
6845             throw new IllegalArgumentException("Bad stream type " + streamType);
6846         }
6847     }
6848 
isMuteAdjust(int adjust)6849     private boolean isMuteAdjust(int adjust) {
6850         return adjust == AudioManager.ADJUST_MUTE || adjust == AudioManager.ADJUST_UNMUTE
6851                 || adjust == AudioManager.ADJUST_TOGGLE_MUTE;
6852     }
6853 
6854     /** only public for mocking/spying, do not call outside of AudioService */
6855     @VisibleForTesting
isInCommunication()6856     public boolean isInCommunication() {
6857         boolean IsInCall = false;
6858 
6859         TelecomManager telecomManager =
6860                 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
6861 
6862         final long ident = Binder.clearCallingIdentity();
6863         try {
6864             IsInCall = telecomManager.isInCall();
6865         } finally {
6866             Binder.restoreCallingIdentity(ident);
6867         }
6868 
6869         int mode = mMode.get();
6870         return (IsInCall
6871                 || mode == AudioManager.MODE_IN_COMMUNICATION
6872                 || mode == AudioManager.MODE_IN_CALL);
6873     }
6874 
6875     /**
6876      * For code clarity for getActiveStreamType(int)
6877      * @param delay_ms max time since last stream activity to consider
6878      * @return true if stream is active in streams handled by AudioFlinger now or
6879      *     in the last "delay_ms" ms.
6880      */
wasStreamActiveRecently(int stream, int delay_ms)6881     private boolean wasStreamActiveRecently(int stream, int delay_ms) {
6882         return mAudioSystem.isStreamActive(stream, delay_ms)
6883                 || mAudioSystem.isStreamActiveRemotely(stream, delay_ms);
6884     }
6885 
getActiveStreamType(int suggestedStreamType)6886     private int getActiveStreamType(int suggestedStreamType) {
6887         if (mIsSingleVolume
6888                 && suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
6889             return AudioSystem.STREAM_MUSIC;
6890         }
6891 
6892         switch (mPlatformType) {
6893         case AudioSystem.PLATFORM_VOICE:
6894             if (isInCommunication()) {
6895                 if (mDeviceBroker.isBluetoothScoActive()) {
6896                     // Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO...");
6897                     return AudioSystem.STREAM_BLUETOOTH_SCO;
6898                 } else {
6899                     // Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL...");
6900                     return AudioSystem.STREAM_VOICE_CALL;
6901                 }
6902             } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
6903                 if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
6904                     if (DEBUG_VOL)
6905                         Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active");
6906                     return AudioSystem.STREAM_RING;
6907                 } else if (wasStreamActiveRecently(
6908                         AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
6909                         if (DEBUG_VOL) {
6910                             Log.v(
6911                                     TAG,
6912                                     "getActiveStreamType: Forcing STREAM_NOTIFICATION stream"
6913                                             + " active");
6914                         }
6915                         return AudioSystem.STREAM_NOTIFICATION;
6916                 } else {
6917                     if (DEBUG_VOL) {
6918                         Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK("
6919                                 + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default");
6920                     }
6921                     return DEFAULT_VOL_STREAM_NO_PLAYBACK;
6922                 }
6923             } else if (
6924                     wasStreamActiveRecently(AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
6925                 if (DEBUG_VOL)
6926                     Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION stream active");
6927                 return AudioSystem.STREAM_NOTIFICATION;
6928             } else if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
6929                 if (DEBUG_VOL)
6930                     Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active");
6931                 return AudioSystem.STREAM_RING;
6932             }
6933         default:
6934             if (isInCommunication()) {
6935                 if (mDeviceBroker.isBluetoothScoActive()) {
6936                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO");
6937                     return AudioSystem.STREAM_BLUETOOTH_SCO;
6938                 } else {
6939                     if (DEBUG_VOL)  Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL");
6940                     return AudioSystem.STREAM_VOICE_CALL;
6941                 }
6942             } else if (mAudioSystem.isStreamActive(
6943                     AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
6944                 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION");
6945                 return AudioSystem.STREAM_NOTIFICATION;
6946             } else if (mAudioSystem.isStreamActive(
6947                     AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
6948                 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING");
6949                 return AudioSystem.STREAM_RING;
6950             } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
6951                 if (mAudioSystem.isStreamActive(
6952                         AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
6953                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION");
6954                     return AudioSystem.STREAM_NOTIFICATION;
6955                 }
6956                 if (mAudioSystem.isStreamActive(
6957                         AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
6958                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING");
6959                     return AudioSystem.STREAM_RING;
6960                 }
6961                 if (DEBUG_VOL) {
6962                     Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK("
6963                             + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default");
6964                 }
6965                 return DEFAULT_VOL_STREAM_NO_PLAYBACK;
6966             }
6967             break;
6968         }
6969         if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Returning suggested type "
6970                 + suggestedStreamType);
6971         return suggestedStreamType;
6972     }
6973 
broadcastRingerMode(String action, int ringerMode)6974     private void broadcastRingerMode(String action, int ringerMode) {
6975         if (!mSystemServer.isPrivileged()) {
6976             return;
6977         }
6978         // Send sticky broadcast
6979         Intent broadcast = new Intent(action);
6980         broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, ringerMode);
6981         broadcast.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
6982                 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
6983         sendStickyBroadcastToAll(broadcast);
6984     }
6985 
broadcastVibrateSetting(int vibrateType)6986     private void broadcastVibrateSetting(int vibrateType) {
6987         if (!mSystemServer.isPrivileged()) {
6988             return;
6989         }
6990         // Send broadcast
6991         if (mActivityManagerInternal.isSystemReady()) {
6992             Intent broadcast = new Intent(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
6993             broadcast.putExtra(AudioManager.EXTRA_VIBRATE_TYPE, vibrateType);
6994             broadcast.putExtra(AudioManager.EXTRA_VIBRATE_SETTING, getVibrateSetting(vibrateType));
6995             sendBroadcastToAll(broadcast, null /* options */);
6996         }
6997     }
6998 
6999     // Message helper methods
7000     /**
7001      * Queue a message on the given handler's message queue, after acquiring the service wake lock.
7002      * Note that the wake lock needs to be released after the message has been handled.
7003      */
queueMsgUnderWakeLock(Handler handler, int msg, int arg1, int arg2, Object obj, int delay)7004     private void queueMsgUnderWakeLock(Handler handler, int msg,
7005             int arg1, int arg2, Object obj, int delay) {
7006         final long ident = Binder.clearCallingIdentity();
7007         try {
7008             // Always acquire the wake lock as AudioService because it is released by the
7009             // message handler.
7010             mAudioEventWakeLock.acquire();
7011         } finally {
7012             Binder.restoreCallingIdentity(ident);
7013         }
7014         sendMsg(handler, msg, SENDMSG_QUEUE, arg1, arg2, obj, delay);
7015     }
7016 
sendMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, int delay)7017     private static void sendMsg(Handler handler, int msg,
7018             int existingMsgPolicy, int arg1, int arg2, Object obj, int delay) {
7019         if (existingMsgPolicy == SENDMSG_REPLACE) {
7020             handler.removeMessages(msg);
7021         } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) {
7022             return;
7023         }
7024 
7025         final long time = SystemClock.uptimeMillis() + delay;
7026         handler.sendMessageAtTime(handler.obtainMessage(msg, arg1, arg2, obj), time);
7027     }
7028 
sendBundleMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, Bundle bundle, int delay)7029     private static void sendBundleMsg(Handler handler, int msg,
7030             int existingMsgPolicy, int arg1, int arg2, Object obj, Bundle bundle, int delay) {
7031         if (existingMsgPolicy == SENDMSG_REPLACE) {
7032             handler.removeMessages(msg);
7033         } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) {
7034             return;
7035         }
7036 
7037         final long time = SystemClock.uptimeMillis() + delay;
7038         Message message = handler.obtainMessage(msg, arg1, arg2, obj);
7039         message.setData(bundle);
7040         handler.sendMessageAtTime(message, time);
7041     }
7042 
checkAudioSettingsPermission(String method)7043     boolean checkAudioSettingsPermission(String method) {
7044         if (callingOrSelfHasAudioSettingsPermission()) {
7045             return true;
7046         }
7047         String msg = "Audio Settings Permission Denial: " + method + " from pid="
7048                 + Binder.getCallingPid()
7049                 + ", uid=" + Binder.getCallingUid();
7050         Log.w(TAG, msg);
7051         return false;
7052     }
7053 
callingOrSelfHasAudioSettingsPermission()7054     private boolean callingOrSelfHasAudioSettingsPermission() {
7055         return mContext.checkCallingOrSelfPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS)
7056                 == PackageManager.PERMISSION_GRANTED;
7057     }
7058 
callingHasAudioSettingsPermission()7059     private boolean callingHasAudioSettingsPermission() {
7060         return mContext.checkCallingPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS)
7061                 == PackageManager.PERMISSION_GRANTED;
7062     }
7063 
hasAudioSettingsPermission(int uid, int pid)7064     private boolean hasAudioSettingsPermission(int uid, int pid) {
7065         return mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid)
7066                 == PackageManager.PERMISSION_GRANTED;
7067     }
7068 
7069     /**
7070      * Minimum attenuation that can be set for alarms over speaker by an application that
7071      * doesn't have the MODIFY_AUDIO_SETTINGS permission.
7072      */
7073     protected static final float MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB = -36.0f;
7074 
7075     /**
7076      * Configures the VolumeStreamState instances for minimum stream index that can be accessed
7077      * without MODIFY_AUDIO_SETTINGS permission.
7078      * Can only be done successfully once audio policy has finished reading its configuration files
7079      * for the volume curves. If not, getStreamVolumeDB will return NaN, and the min value will
7080      * remain at the stream min index value.
7081      */
initMinStreamVolumeWithoutModifyAudioSettings()7082     protected void initMinStreamVolumeWithoutModifyAudioSettings() {
7083         int idx;
7084         int deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER_SAFE;
7085         if (Float.isNaN(AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM,
7086                 MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM], deviceForAlarm))) {
7087             deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER;
7088         }
7089         for (idx = MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM];
7090                 idx >= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]; idx--) {
7091             if (AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM, idx, deviceForAlarm)
7092                     < MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB) {
7093                 break;
7094             }
7095         }
7096         final int safeIndex = idx <= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]
7097                 ? MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]
7098                 : Math.min(idx + 1, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]);
7099         // update the VolumeStreamState for STREAM_ALARM and its aliases
7100         for (int stream : mStreamVolumeAlias) {
7101             if (mStreamVolumeAlias[stream] == AudioSystem.STREAM_ALARM) {
7102                 mStreamStates[stream].updateNoPermMinIndex(safeIndex);
7103             }
7104         }
7105     }
7106 
7107     /**
7108      * Returns device associated with the stream volume.
7109      *
7110      * Only public for mocking/spying, do not call outside of AudioService.
7111      * Device volume aliasing means DEVICE_OUT_SPEAKER may be returned for
7112      * DEVICE_OUT_SPEAKER_SAFE.
7113      */
7114     @VisibleForTesting
getDeviceForStream(int stream)7115     public int getDeviceForStream(int stream) {
7116         return selectOneAudioDevice(getDeviceSetForStream(stream));
7117     }
7118 
7119     /*
7120      * Must match native apm_extract_one_audio_device() used in getDeviceForVolume()
7121      * or the wrong device volume may be adjusted.
7122      */
selectOneAudioDevice(Set<Integer> deviceSet)7123     private int selectOneAudioDevice(Set<Integer> deviceSet) {
7124         if (deviceSet.isEmpty()) {
7125             return AudioSystem.DEVICE_NONE;
7126         } else if (deviceSet.size() == 1) {
7127             return deviceSet.iterator().next();
7128         } else {
7129             // Multiple device selection is either:
7130             //  - dock + one other device: give priority to dock in this case.
7131             //  - speaker + one other device: give priority to speaker in this case.
7132             //  - one A2DP device + another device: happens with duplicated output. In this case
7133             // retain the device on the A2DP output as the other must not correspond to an active
7134             // selection if not the speaker.
7135             //  - HDMI-CEC system audio mode only output: give priority to available item in order.
7136 
7137             if (deviceSet.contains(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET)) {
7138                 return AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET;
7139             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPEAKER)) {
7140                 return AudioSystem.DEVICE_OUT_SPEAKER;
7141             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPEAKER_SAFE)) {
7142                 // Note: DEVICE_OUT_SPEAKER_SAFE not present in getDeviceSetForStreamDirect
7143                 return AudioSystem.DEVICE_OUT_SPEAKER_SAFE;
7144             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_HDMI_ARC)) {
7145                 return AudioSystem.DEVICE_OUT_HDMI_ARC;
7146             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_HDMI_EARC)) {
7147                 return AudioSystem.DEVICE_OUT_HDMI_EARC;
7148             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_AUX_LINE)) {
7149                 return AudioSystem.DEVICE_OUT_AUX_LINE;
7150             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPDIF)) {
7151                 return AudioSystem.DEVICE_OUT_SPDIF;
7152             } else {
7153                 // At this point, deviceSet should contain exactly one A2DP device;
7154                 // regardless, return the first A2DP device in numeric order.
7155                 // If there is no A2DP device, this falls through to log an error.
7156                 for (int deviceType : deviceSet) {
7157                     if (AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(deviceType)) {
7158                         return deviceType;
7159                     }
7160                 }
7161             }
7162         }
7163         Log.w(TAG, "selectOneAudioDevice returning DEVICE_NONE from invalid device combination "
7164                 + AudioSystem.deviceSetToString(deviceSet));
7165         return AudioSystem.DEVICE_NONE;
7166     }
7167 
7168     /**
7169      * @see AudioManager#getDevicesForStream(int)
7170      * @deprecated on {@link android.os.Build.VERSION_CODES#T} as new devices
7171      *              will have multi-bit device types since S.
7172      *              Use {@link #getDevicesForAttributes()} instead.
7173      */
7174     @Override
7175     @Deprecated
getDeviceMaskForStream(int streamType)7176     public int getDeviceMaskForStream(int streamType) {
7177         ensureValidStreamType(streamType);
7178         // no permission required
7179         final long token = Binder.clearCallingIdentity();
7180         try {
7181             return AudioSystem.getDeviceMaskFromSet(
7182                     getDeviceSetForStreamDirect(streamType));
7183         } finally {
7184             Binder.restoreCallingIdentity(token);
7185         }
7186     }
7187 
7188     /**
7189      * Returns the devices associated with a stream type.
7190      *
7191      * SPEAKER_SAFE will alias to SPEAKER.
7192      */
7193     @NonNull
getDeviceSetForStreamDirect(int stream)7194     private Set<Integer> getDeviceSetForStreamDirect(int stream) {
7195         final AudioAttributes attr =
7196                 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream);
7197         Set<Integer> deviceSet =
7198                 AudioSystem.generateAudioDeviceTypesSet(
7199                         getDevicesForAttributesInt(attr, true /* forVolume */));
7200         return deviceSet;
7201     }
7202 
7203     /**
7204      * Returns a reference to the list of devices for the stream, do not modify.
7205      *
7206      * The device returned may be aliased to the actual device whose volume curve
7207      * will be used.  For example DEVICE_OUT_SPEAKER_SAFE aliases to DEVICE_OUT_SPEAKER.
7208      */
7209     @NonNull
getDeviceSetForStream(int stream)7210     public Set<Integer> getDeviceSetForStream(int stream) {
7211         ensureValidStreamType(stream);
7212         synchronized (VolumeStreamState.class) {
7213             return mStreamStates[stream].observeDevicesForStream_syncVSS(true);
7214         }
7215     }
7216 
onObserveDevicesForAllStreams(int skipStream)7217     private void onObserveDevicesForAllStreams(int skipStream) {
7218         synchronized (mSettingsLock) {
7219             synchronized (VolumeStreamState.class) {
7220                 for (int stream = 0; stream < mStreamStates.length; stream++) {
7221                     if (stream != skipStream) {
7222                         Set<Integer> deviceSet =
7223                                 mStreamStates[stream].observeDevicesForStream_syncVSS(
7224                                         false /*checkOthers*/);
7225                         for (Integer device : deviceSet) {
7226                             // Update volume states for devices routed for the stream
7227                             updateVolumeStates(device, stream,
7228                                     "AudioService#onObserveDevicesForAllStreams");
7229                         }
7230                     }
7231                 }
7232             }
7233         }
7234     }
7235 
7236     /** only public for mocking/spying, do not call outside of AudioService */
7237     @VisibleForTesting
postObserveDevicesForAllStreams()7238     public void postObserveDevicesForAllStreams() {
7239         postObserveDevicesForAllStreams(-1);
7240     }
7241 
7242     /** only public for mocking/spying, do not call outside of AudioService */
7243     @VisibleForTesting
postObserveDevicesForAllStreams(int skipStream)7244     public void postObserveDevicesForAllStreams(int skipStream) {
7245         sendMsg(mAudioHandler,
7246                 MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS,
7247                 SENDMSG_QUEUE, skipStream /*arg1*/, 0 /*arg2*/, null /*obj*/,
7248                 0 /*delay*/);
7249     }
7250 
7251     /**
7252      * @see AudioDeviceVolumeManager#setDeviceAbsoluteMultiVolumeBehavior
7253      *
7254      * @param register Whether the listener is to be registered or unregistered. If false, the
7255      *                 device adopts variable volume behavior.
7256      */
7257     @RequiresPermission(anyOf = { android.Manifest.permission.MODIFY_AUDIO_ROUTING,
7258             android.Manifest.permission.BLUETOOTH_PRIVILEGED })
registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register, IAudioDeviceVolumeDispatcher cb, String packageName, AudioDeviceAttributes device, List<VolumeInfo> volumes, boolean handlesVolumeAdjustment, @AudioManager.AbsoluteDeviceVolumeBehavior int deviceVolumeBehavior)7259     public void registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register,
7260             IAudioDeviceVolumeDispatcher cb, String packageName,
7261             AudioDeviceAttributes device, List<VolumeInfo> volumes,
7262             boolean handlesVolumeAdjustment,
7263             @AudioManager.AbsoluteDeviceVolumeBehavior int deviceVolumeBehavior) {
7264         // verify permissions
7265         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
7266                 != PackageManager.PERMISSION_GRANTED
7267                 && mContext.checkCallingOrSelfPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
7268                 != PackageManager.PERMISSION_GRANTED) {
7269             throw new SecurityException(
7270                     "Missing MODIFY_AUDIO_ROUTING or BLUETOOTH_PRIVILEGED permissions");
7271         }
7272         // verify arguments
7273         Objects.requireNonNull(device);
7274         Objects.requireNonNull(volumes);
7275 
7276         int deviceOut = device.getInternalType();
7277         if (register) {
7278             AbsoluteVolumeDeviceInfo info = new AbsoluteVolumeDeviceInfo(
7279                     device, volumes, cb, handlesVolumeAdjustment, deviceVolumeBehavior);
7280             AbsoluteVolumeDeviceInfo oldInfo = mAbsoluteVolumeDeviceInfoMap.get(deviceOut);
7281             boolean volumeBehaviorChanged = (oldInfo == null)
7282                     || (oldInfo.mDeviceVolumeBehavior != deviceVolumeBehavior);
7283             if (volumeBehaviorChanged) {
7284                 removeAudioSystemDeviceOutFromFullVolumeDevices(deviceOut);
7285                 removeAudioSystemDeviceOutFromFixedVolumeDevices(deviceOut);
7286                 addAudioSystemDeviceOutToAbsVolumeDevices(deviceOut, info);
7287 
7288                 dispatchDeviceVolumeBehavior(device, deviceVolumeBehavior);
7289             }
7290             // Update stream volumes to the given device, if specified in a VolumeInfo.
7291             // Mute state is not updated because it is stream-wide - the only way to mute a
7292             // stream's output to a particular device is to set the volume index to zero.
7293             for (VolumeInfo volumeInfo : volumes) {
7294                 if (volumeInfo.getVolumeIndex() != VolumeInfo.INDEX_NOT_SET
7295                         && volumeInfo.getMinVolumeIndex() != VolumeInfo.INDEX_NOT_SET
7296                         && volumeInfo.getMaxVolumeIndex() != VolumeInfo.INDEX_NOT_SET) {
7297                     if (volumeInfo.hasStreamType()) {
7298                         setStreamVolumeInt(volumeInfo.getStreamType(),
7299                                 rescaleIndex(volumeInfo, volumeInfo.getStreamType()),
7300                                 deviceOut, false /*force*/, packageName,
7301                                 true /*hasModifyAudioSettings*/);
7302                     } else {
7303                         for (int streamType : volumeInfo.getVolumeGroup().getLegacyStreamTypes()) {
7304                             setStreamVolumeInt(streamType, rescaleIndex(volumeInfo, streamType),
7305                                     deviceOut, false /*force*/, packageName,
7306                                     true /*hasModifyAudioSettings*/);
7307                         }
7308                     }
7309                 }
7310             }
7311         } else {
7312             boolean wasAbsVol = removeAudioSystemDeviceOutFromAbsVolumeDevices(deviceOut) != null;
7313             if (wasAbsVol) {
7314                 dispatchDeviceVolumeBehavior(device, AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE);
7315             }
7316         }
7317     }
7318 
7319     /**
7320      * @see AudioManager#setDeviceVolumeBehavior(AudioDeviceAttributes, int)
7321      * @param device the audio device to be affected
7322      * @param deviceVolumeBehavior one of the device behaviors
7323      */
7324     @android.annotation.EnforcePermission(anyOf = {
7325             android.Manifest.permission.MODIFY_AUDIO_ROUTING,
7326             android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED
7327     })
setDeviceVolumeBehavior(@onNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName)7328     public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
7329             @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName) {
7330         // verify permissions
7331         super.setDeviceVolumeBehavior_enforcePermission();
7332         // verify arguments
7333         Objects.requireNonNull(device);
7334         AudioManager.enforceValidVolumeBehavior(deviceVolumeBehavior);
7335 
7336         sVolumeLogger.enqueue(new EventLogger.StringEvent("setDeviceVolumeBehavior: dev:"
7337                 + AudioSystem.getOutputDeviceName(device.getInternalType()) + " addr:"
7338                 + device.getAddress() + " behavior:"
7339                 + AudioDeviceVolumeManager.volumeBehaviorName(deviceVolumeBehavior)
7340                 + " pack:" + pkgName).printLog(TAG));
7341         if (pkgName == null) {
7342             pkgName = "";
7343         }
7344         if (device.getType() == TYPE_BLUETOOTH_A2DP) {
7345             avrcpSupportsAbsoluteVolume(device.getAddress(),
7346                     deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
7347             return;
7348         }
7349 
7350         setDeviceVolumeBehaviorInternal(device, deviceVolumeBehavior, pkgName);
7351         persistDeviceVolumeBehavior(device.getInternalType(), deviceVolumeBehavior);
7352     }
7353 
setDeviceVolumeBehaviorInternal(@onNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller)7354     private void setDeviceVolumeBehaviorInternal(@NonNull AudioDeviceAttributes device,
7355             @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller) {
7356         int audioSystemDeviceOut = device.getInternalType();
7357         boolean volumeBehaviorChanged = false;
7358         // update device masks based on volume behavior
7359         switch (deviceVolumeBehavior) {
7360             case AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE:
7361                 volumeBehaviorChanged |=
7362                         removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut)
7363                         | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut)
7364                         | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut)
7365                                 != null);
7366                 break;
7367             case AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED:
7368                 volumeBehaviorChanged |=
7369                         removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut)
7370                         | addAudioSystemDeviceOutToFixedVolumeDevices(audioSystemDeviceOut)
7371                         | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut)
7372                                 != null);
7373                 break;
7374             case AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL:
7375                 volumeBehaviorChanged |=
7376                         addAudioSystemDeviceOutToFullVolumeDevices(audioSystemDeviceOut)
7377                         | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut)
7378                         | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut)
7379                                 != null);
7380                 break;
7381             case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE:
7382             case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY:
7383             case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE:
7384                 throw new IllegalArgumentException("Absolute volume unsupported for now");
7385         }
7386 
7387         if (volumeBehaviorChanged) {
7388             sendMsg(mAudioHandler, MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR, SENDMSG_QUEUE,
7389                     deviceVolumeBehavior, 0, device, /*delay*/ 0);
7390         }
7391 
7392         // log event and caller
7393         sDeviceLogger.enqueue(new EventLogger.StringEvent(
7394                 "Volume behavior " + deviceVolumeBehavior + " for dev=0x"
7395                       + Integer.toHexString(audioSystemDeviceOut) + " from:" + caller));
7396         // make sure we have a volume entry for this device, and that volume is updated according
7397         // to volume behavior
7398         postUpdateVolumeStatesForAudioDevice(audioSystemDeviceOut,
7399                 "setDeviceVolumeBehavior:" + caller);
7400     }
7401 
7402     /**
7403      * @see AudioManager#getDeviceVolumeBehavior(AudioDeviceAttributes)
7404      * @param device the audio output device type
7405      * @return the volume behavior for the device
7406      */
7407     @android.annotation.EnforcePermission(anyOf = {
7408             android.Manifest.permission.MODIFY_AUDIO_ROUTING,
7409             android.Manifest.permission.QUERY_AUDIO_STATE,
7410             android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED
7411     })
7412     public @AudioManager.DeviceVolumeBehavior
getDeviceVolumeBehavior(@onNull AudioDeviceAttributes device)7413     int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
7414         // verify permissions
7415         super.getDeviceVolumeBehavior_enforcePermission();
7416         // verify parameters
7417         Objects.requireNonNull(device);
7418 
7419         return getDeviceVolumeBehaviorInt(device);
7420     }
7421 
7422     private @AudioManager.DeviceVolumeBehavior
getDeviceVolumeBehaviorInt(@onNull AudioDeviceAttributes device)7423             int getDeviceVolumeBehaviorInt(@NonNull AudioDeviceAttributes device) {
7424         // Get the internal type set by the AudioDeviceAttributes constructor which is always more
7425         // exact (avoids double conversions) than a conversion from SDK type via
7426         // AudioDeviceInfo.convertDeviceTypeToInternalDevice()
7427         final int audioSystemDeviceOut = device.getInternalType();
7428 
7429         // setDeviceVolumeBehavior has not been explicitly called for the device type. Deduce the
7430         // current volume behavior.
7431         if (mFullVolumeDevices.contains(audioSystemDeviceOut)) {
7432             return AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL;
7433         }
7434         if (mFixedVolumeDevices.contains(audioSystemDeviceOut)) {
7435             return AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED;
7436         }
7437         if (mAbsVolumeMultiModeCaseDevices.contains(audioSystemDeviceOut)) {
7438             return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE;
7439         }
7440         if (mAbsoluteVolumeDeviceInfoMap.containsKey(audioSystemDeviceOut)) {
7441             return mAbsoluteVolumeDeviceInfoMap.get(audioSystemDeviceOut).mDeviceVolumeBehavior;
7442         }
7443 
7444         if (isA2dpAbsoluteVolumeDevice(audioSystemDeviceOut)
7445                 || AudioSystem.isLeAudioDeviceType(audioSystemDeviceOut)) {
7446             return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE;
7447         }
7448         return AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE;
7449     }
7450 
7451     /**
7452      * @see AudioManager#isVolumeFixed()
7453      * Note there are no permission checks on this operation, as this is part of API 21
7454      * @return true if the current device's volume behavior for media is
7455      *         DEVICE_VOLUME_BEHAVIOR_FIXED
7456      */
isVolumeFixed()7457     public boolean isVolumeFixed() {
7458         if (mUseFixedVolume) {
7459             return true;
7460         }
7461         final AudioAttributes attributes = new AudioAttributes.Builder()
7462                 .setUsage(AudioAttributes.USAGE_MEDIA)
7463                 .build();
7464         // calling getDevice*Int to bypass permission check
7465         final List<AudioDeviceAttributes> devices =
7466                 getDevicesForAttributesInt(attributes, true /* forVolume */);
7467         for (AudioDeviceAttributes device : devices) {
7468             if (getDeviceVolumeBehaviorInt(device) == AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED) {
7469                 return true;
7470             }
7471         }
7472         return false;
7473     }
7474 
7475     /*package*/ static final int CONNECTION_STATE_DISCONNECTED = 0;
7476     /*package*/ static final int CONNECTION_STATE_CONNECTED = 1;
7477     /**
7478      * The states that can be used with AudioService.setWiredDeviceConnectionState()
7479      * Attention: those values differ from those in BluetoothProfile, follow annotations to
7480      * distinguish between @ConnectionState and @BtProfileConnectionState
7481      */
7482     @IntDef({
7483             CONNECTION_STATE_DISCONNECTED,
7484             CONNECTION_STATE_CONNECTED,
7485     })
7486     @Retention(RetentionPolicy.SOURCE)
7487     public @interface ConnectionState {}
7488 
7489     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
7490     /**
7491      * see AudioManager.setWiredDeviceConnectionState()
7492      */
setWiredDeviceConnectionState(AudioDeviceAttributes attributes, @ConnectionState int state, String caller)7493     public void setWiredDeviceConnectionState(AudioDeviceAttributes attributes,
7494             @ConnectionState int state, String caller) {
7495         super.setWiredDeviceConnectionState_enforcePermission();
7496 
7497         if (state != CONNECTION_STATE_CONNECTED
7498                 && state != CONNECTION_STATE_DISCONNECTED) {
7499             throw new IllegalArgumentException("Invalid state " + state);
7500         }
7501         new MediaMetrics.Item(mMetricsId + "setWiredDeviceConnectionState")
7502                 .set(MediaMetrics.Property.ADDRESS, attributes.getAddress())
7503                 .set(MediaMetrics.Property.CLIENT_NAME, caller)
7504                 .set(MediaMetrics.Property.DEVICE,
7505                         AudioSystem.getDeviceName(attributes.getInternalType()))
7506                 .set(MediaMetrics.Property.NAME, attributes.getName())
7507                 .set(MediaMetrics.Property.STATE,
7508                         state == CONNECTION_STATE_CONNECTED ? "connected" : "disconnected")
7509                 .record();
7510         mDeviceBroker.setWiredDeviceConnectionState(attributes, state, caller);
7511         // The Dynamic Soundbar mode feature introduces dynamic presence for an HDMI Audio System
7512         // Client. For example, the device can start with the Audio System Client unavailable.
7513         // When the feature is activated the client becomes available, therefore Audio Service
7514         // requests a new HDMI Audio System Client instance when the ARC status is changed.
7515         if (attributes.getInternalType() == AudioSystem.DEVICE_IN_HDMI_ARC) {
7516             updateHdmiAudioSystemClient();
7517         }
7518     }
7519 
7520     /**
7521      * Replace the current HDMI Audio System Client.
7522      * See {@link #setWiredDeviceConnectionState(AudioDeviceAttributes, int, String)}.
7523      */
updateHdmiAudioSystemClient()7524     private void updateHdmiAudioSystemClient() {
7525         Slog.d(TAG, "Hdmi Audio System Client is updated");
7526         synchronized (mHdmiClientLock) {
7527             mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient();
7528         }
7529     }
7530 
7531     /** @see AudioManager#setTestDeviceConnectionState(AudioDeviceAttributes, boolean) */
setTestDeviceConnectionState(@onNull AudioDeviceAttributes device, boolean connected)7532     public void setTestDeviceConnectionState(@NonNull AudioDeviceAttributes device,
7533             boolean connected) {
7534         Objects.requireNonNull(device);
7535         enforceModifyAudioRoutingPermission();
7536         mDeviceBroker.setTestDeviceConnectionState(device,
7537                 connected ? CONNECTION_STATE_CONNECTED : CONNECTION_STATE_DISCONNECTED);
7538         // simulate a routing update from native
7539         sendMsg(mAudioHandler,
7540                 MSG_ROUTING_UPDATED,
7541                 SENDMSG_REPLACE, 0, 0, null,
7542                 /*delay*/ 0);
7543     }
7544 
7545     /**
7546      * @hide
7547      * The states that can be used with AudioService.setBluetoothHearingAidDeviceConnectionState()
7548      * and AudioService.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent()
7549      */
7550     @IntDef({
7551             BluetoothProfile.STATE_DISCONNECTED,
7552             BluetoothProfile.STATE_CONNECTED,
7553     })
7554     @Retention(RetentionPolicy.SOURCE)
7555     public @interface BtProfileConnectionState {}
7556 
7557     /**
7558      * @hide
7559      * The profiles that can be used with AudioService.handleBluetoothActiveDeviceChanged()
7560      */
7561     @IntDef({
7562             BluetoothProfile.HEARING_AID,
7563             BluetoothProfile.A2DP,
7564             BluetoothProfile.A2DP_SINK,
7565             BluetoothProfile.LE_AUDIO,
7566             BluetoothProfile.LE_AUDIO_BROADCAST,
7567     })
7568     @Retention(RetentionPolicy.SOURCE)
7569     public @interface BtProfile {}
7570 
7571 
7572     /**
7573      * See AudioManager.handleBluetoothActiveDeviceChanged(...)
7574      */
handleBluetoothActiveDeviceChanged(BluetoothDevice newDevice, BluetoothDevice previousDevice, @NonNull BluetoothProfileConnectionInfo info)7575     public void handleBluetoothActiveDeviceChanged(BluetoothDevice newDevice,
7576             BluetoothDevice previousDevice, @NonNull BluetoothProfileConnectionInfo info) {
7577         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.BLUETOOTH_STACK)
7578                 != PackageManager.PERMISSION_GRANTED) {
7579             throw new SecurityException("Bluetooth is the only caller allowed");
7580         }
7581         if (info == null) {
7582             throw new IllegalArgumentException("Illegal null BluetoothProfileConnectionInfo for"
7583                     + " device " + previousDevice + " -> " + newDevice);
7584         }
7585         final int profile = info.getProfile();
7586         if (profile != BluetoothProfile.A2DP && profile != BluetoothProfile.A2DP_SINK
7587                 && profile != BluetoothProfile.LE_AUDIO
7588                 && profile != BluetoothProfile.LE_AUDIO_BROADCAST
7589                 && profile != BluetoothProfile.HEARING_AID) {
7590             throw new IllegalArgumentException("Illegal BluetoothProfile profile for device "
7591                     + previousDevice + " -> " + newDevice + ". Got: " + profile);
7592         }
7593 
7594         sDeviceLogger.enqueue(new EventLogger.StringEvent("BlutoothActiveDeviceChanged for "
7595                 + BluetoothProfile.getProfileName(profile) + ", device update " + previousDevice
7596                 + " -> " + newDevice));
7597         AudioDeviceBroker.BtDeviceChangedData data =
7598                 new AudioDeviceBroker.BtDeviceChangedData(newDevice, previousDevice, info,
7599                         "AudioService");
7600         sendMsg(mAudioHandler, MSG_BT_DEV_CHANGED, SENDMSG_QUEUE, 0, 0,
7601                 /*obj*/ data, /*delay*/ 0);
7602     }
7603 
7604     /** only public for mocking/spying, do not call outside of AudioService */
7605     @VisibleForTesting
setMusicMute(boolean mute)7606     public void setMusicMute(boolean mute) {
7607         mStreamStates[AudioSystem.STREAM_MUSIC].muteInternally(mute);
7608     }
7609 
7610     private static final Set<Integer> DEVICE_MEDIA_UNMUTED_ON_PLUG_SET;
7611     static {
7612         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET = new HashSet<>();
7613         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADSET);
7614         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE);
7615         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_LINE);
7616         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_A2DP_SET);
7617         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_BLE_SET);
7618         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_USB_SET);
7619         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_HDMI);
7620     }
7621 
7622     /** only public for mocking/spying, do not call outside of AudioService */
7623     @VisibleForTesting
postAccessoryPlugMediaUnmute(int newDevice)7624     public void postAccessoryPlugMediaUnmute(int newDevice) {
7625         sendMsg(mAudioHandler, MSG_ACCESSORY_PLUG_MEDIA_UNMUTE, SENDMSG_QUEUE,
7626                 newDevice, 0, null, 0);
7627     }
7628 
onAccessoryPlugMediaUnmute(int newDevice)7629     private void onAccessoryPlugMediaUnmute(int newDevice) {
7630         if (DEBUG_VOL) {
7631             Log.i(TAG, String.format("onAccessoryPlugMediaUnmute newDevice=%d [%s]",
7632                     newDevice, AudioSystem.getOutputDeviceName(newDevice)));
7633         }
7634 
7635         if (mNm.getZenMode() != Settings.Global.ZEN_MODE_NO_INTERRUPTIONS
7636                 && !isStreamMutedByRingerOrZenMode(AudioSystem.STREAM_MUSIC)
7637                 && DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.contains(newDevice)
7638                 && mStreamStates[AudioSystem.STREAM_MUSIC].mIsMuted
7639                 && mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(newDevice) != 0
7640                 && getDeviceSetForStreamDirect(AudioSystem.STREAM_MUSIC).contains(newDevice)) {
7641             if (DEBUG_VOL) {
7642                 Log.i(TAG, String.format("onAccessoryPlugMediaUnmute unmuting device=%d [%s]",
7643                         newDevice, AudioSystem.getOutputDeviceName(newDevice)));
7644             }
7645             // Locking mSettingsLock to avoid inversion when calling vss.mute -> vss.doMute ->
7646             // vss.updateVolumeGroupIndex
7647             synchronized (mSettingsLock) {
7648                 mStreamStates[AudioSystem.STREAM_MUSIC].mute(false, "onAccessoryPlugMediaUnmute");
7649             }
7650         }
7651     }
7652 
7653     /**
7654      * See AudioManager.hasHapticChannels(Context, Uri).
7655      */
hasHapticChannels(Uri uri)7656     public boolean hasHapticChannels(Uri uri) {
7657         return AudioManager.hasHapticChannelsImpl(mContext, uri);
7658     }
7659 
7660     ///////////////////////////////////////////////////////////////////////////
7661     // Inner classes
7662     ///////////////////////////////////////////////////////////////////////////
7663     /**
7664      * Key is the AudioManager VolumeGroupId
7665      * Value is the VolumeGroupState
7666      */
7667     private static final SparseArray<VolumeGroupState> sVolumeGroupStates = new SparseArray<>();
7668 
initVolumeGroupStates()7669     private void initVolumeGroupStates() {
7670         for (final AudioVolumeGroup avg : getAudioVolumeGroups()) {
7671             try {
7672                 // if no valid attributes, this volume group is not controllable, throw exception
7673                 ensureValidAttributes(avg);
7674                 sVolumeGroupStates.append(avg.getId(), new VolumeGroupState(avg));
7675             } catch (IllegalArgumentException e) {
7676                 // Volume Groups without attributes are not controllable through set/get volume
7677                 // using attributes. Do not append them.
7678                 if (DEBUG_VOL) {
7679                     Log.d(TAG, "volume group " + avg.name() + " for internal policy needs");
7680                 }
7681                 continue;
7682             }
7683         }
7684 
7685         // need mSettingsLock for vgs.applyAllVolumes -> vss.setIndex which grabs this lock after
7686         // VSS.class. Locking order needs to be preserved
7687         synchronized (mSettingsLock) {
7688             for (int i = 0; i < sVolumeGroupStates.size(); i++) {
7689                 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
7690                 vgs.applyAllVolumes(/* userSwitch= */ false);
7691             }
7692         }
7693     }
7694 
ensureValidAttributes(AudioVolumeGroup avg)7695     private void ensureValidAttributes(AudioVolumeGroup avg) {
7696         boolean hasAtLeastOneValidAudioAttributes = avg.getAudioAttributes().stream()
7697                 .anyMatch(aa -> !aa.equals(AudioProductStrategy.getDefaultAttributes()));
7698         if (!hasAtLeastOneValidAudioAttributes) {
7699             throw new IllegalArgumentException("Volume Group " + avg.name()
7700                     + " has no valid audio attributes");
7701         }
7702     }
7703 
readVolumeGroupsSettings(boolean userSwitch)7704     private void readVolumeGroupsSettings(boolean userSwitch) {
7705         synchronized (mSettingsLock) {
7706             synchronized (VolumeStreamState.class) {
7707                 if (DEBUG_VOL) {
7708                     Log.d(TAG, "readVolumeGroupsSettings userSwitch=" + userSwitch);
7709                 }
7710                 for (int i = 0; i < sVolumeGroupStates.size(); i++) {
7711                     VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
7712                     // as for STREAM_MUSIC, preserve volume from one user to the next.
7713                     if (!(userSwitch && vgs.isMusic())) {
7714                         vgs.clearIndexCache();
7715                         vgs.readSettings();
7716                     }
7717                     vgs.applyAllVolumes(userSwitch);
7718                 }
7719             }
7720         }
7721     }
7722 
7723     // Called upon crash of AudioServer
restoreVolumeGroups()7724     private void restoreVolumeGroups() {
7725         if (DEBUG_VOL) {
7726             Log.v(TAG, "restoreVolumeGroups");
7727         }
7728 
7729         // need mSettingsLock for vgs.applyAllVolumes -> vss.setIndex which grabs this lock after
7730         // VSS.class. Locking order needs to be preserved
7731         synchronized (mSettingsLock) {
7732             for (int i = 0; i < sVolumeGroupStates.size(); i++) {
7733                 final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
7734                 vgs.applyAllVolumes(false/*userSwitch*/);
7735             }
7736         }
7737     }
7738 
dumpVolumeGroups(PrintWriter pw)7739     private void dumpVolumeGroups(PrintWriter pw) {
7740         pw.println("\nVolume Groups (device: index)");
7741         for (int i = 0; i < sVolumeGroupStates.size(); i++) {
7742             final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
7743             vgs.dump(pw);
7744             pw.println("");
7745         }
7746     }
7747 
isCallStream(int stream)7748     private static boolean isCallStream(int stream) {
7749         return stream == AudioSystem.STREAM_VOICE_CALL
7750                 || stream == AudioSystem.STREAM_BLUETOOTH_SCO;
7751     }
7752 
getVolumeGroupForStreamType(int stream)7753     private static int getVolumeGroupForStreamType(int stream) {
7754         AudioAttributes attributes =
7755                 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream);
7756         if (attributes.equals(new AudioAttributes.Builder().build())) {
7757             return AudioVolumeGroup.DEFAULT_VOLUME_GROUP;
7758         }
7759         return AudioProductStrategy.getVolumeGroupIdForAudioAttributes(
7760                 attributes, /* fallbackOnDefault= */ false);
7761     }
7762 
7763     // NOTE: Locking order for synchronized objects related to volume management:
7764     //  1     mSettingsLock
7765     //  2       VolumeStreamState.class
7766     private class VolumeGroupState {
7767         private final AudioVolumeGroup mAudioVolumeGroup;
7768         private final SparseIntArray mIndexMap = new SparseIntArray(8);
7769         private int mIndexMin;
7770         private int mIndexMax;
7771         private boolean mHasValidStreamType = false;
7772         private int mPublicStreamType = AudioSystem.STREAM_MUSIC;
7773         private AudioAttributes mAudioAttributes = AudioProductStrategy.getDefaultAttributes();
7774         private boolean mIsMuted = false;
7775         private String mSettingName;
7776 
7777         // No API in AudioSystem to get a device from strategy or from attributes.
7778         // Need a valid public stream type to use current API getDeviceForStream
getDeviceForVolume()7779         private int getDeviceForVolume() {
7780             return getDeviceForStream(mPublicStreamType);
7781         }
7782 
VolumeGroupState(AudioVolumeGroup avg)7783         private VolumeGroupState(AudioVolumeGroup avg) {
7784             mAudioVolumeGroup = avg;
7785             if (DEBUG_VOL) {
7786                 Log.v(TAG, "VolumeGroupState for " + avg.toString());
7787             }
7788             // mAudioAttributes is the default at this point
7789             for (AudioAttributes aa : avg.getAudioAttributes()) {
7790                 if (!aa.equals(mAudioAttributes)) {
7791                     mAudioAttributes = aa;
7792                     break;
7793                 }
7794             }
7795             int[] streamTypes = mAudioVolumeGroup.getLegacyStreamTypes();
7796             String streamSettingName = "";
7797             if (streamTypes.length != 0) {
7798                 // Uses already initialized MIN / MAX if a stream type is attached to group
7799                 for (int streamType : streamTypes) {
7800                     if (streamType != AudioSystem.STREAM_DEFAULT
7801                             && streamType < AudioSystem.getNumStreamTypes()) {
7802                         mPublicStreamType = streamType;
7803                         mHasValidStreamType = true;
7804                         streamSettingName = System.VOLUME_SETTINGS_INT[mPublicStreamType];
7805                         break;
7806                     }
7807                 }
7808                 mIndexMin = MIN_STREAM_VOLUME[mPublicStreamType];
7809                 mIndexMax = MAX_STREAM_VOLUME[mPublicStreamType];
7810             } else if (!avg.getAudioAttributes().isEmpty()) {
7811                 mIndexMin = AudioSystem.getMinVolumeIndexForAttributes(mAudioAttributes);
7812                 mIndexMax = AudioSystem.getMaxVolumeIndexForAttributes(mAudioAttributes);
7813             } else {
7814                 throw new IllegalArgumentException("volume group: " + mAudioVolumeGroup.name()
7815                         + " has neither valid attributes nor valid stream types assigned");
7816             }
7817             mSettingName = !streamSettingName.isEmpty() ? streamSettingName : ("volume_" + name());
7818             // Load volume indexes from data base
7819             readSettings();
7820         }
7821 
getLegacyStreamTypes()7822         public @NonNull int[] getLegacyStreamTypes() {
7823             return mAudioVolumeGroup.getLegacyStreamTypes();
7824         }
7825 
name()7826         public String name() {
7827             return mAudioVolumeGroup.name();
7828         }
7829 
7830         /**
7831          * Volume group with non null minimum index are considered as non mutable, thus
7832          * bijectivity is broken with potential associated stream type.
7833          * VOICE_CALL stream has minVolumeIndex > 0  but can be muted directly by an
7834          * app that has MODIFY_PHONE_STATE permission.
7835          */
isVssMuteBijective(int stream)7836         private boolean isVssMuteBijective(int stream) {
7837             return isStreamAffectedByMute(stream)
7838                     && (getMinIndex() == (mStreamStates[stream].mIndexMin + 5) / 10)
7839                     && (getMinIndex() == 0 || isCallStream(stream));
7840         }
7841 
isMutable()7842         private boolean isMutable() {
7843             return mIndexMin == 0 || (mHasValidStreamType && isVssMuteBijective(mPublicStreamType));
7844         }
7845         /**
7846          * Mute/unmute the volume group
7847          * @param muted the new mute state
7848          */
7849         @GuardedBy("AudioService.VolumeStreamState.class")
mute(boolean muted)7850         public boolean mute(boolean muted) {
7851             if (!isMutable()) {
7852                 // Non mutable volume group
7853                 if (DEBUG_VOL) {
7854                     Log.d(TAG, "invalid mute on unmutable volume group " + name());
7855                 }
7856                 return false;
7857             }
7858             boolean changed = (mIsMuted != muted);
7859             // As for VSS, mute shall apply minIndex to all devices found in IndexMap and default.
7860             if (changed) {
7861                 mIsMuted = muted;
7862                 applyAllVolumes(false /*userSwitch*/);
7863             }
7864             return changed;
7865         }
7866 
isMuted()7867         public boolean isMuted() {
7868             return mIsMuted;
7869         }
7870 
adjustVolume(int direction, int flags)7871         public void adjustVolume(int direction, int flags) {
7872             synchronized (mSettingsLock) {
7873                 synchronized (AudioService.VolumeStreamState.class) {
7874                     int device = getDeviceForVolume();
7875                     int previousIndex = getIndex(device);
7876                     if (isMuteAdjust(direction) && !isMutable()) {
7877                         // Non mutable volume group
7878                         if (DEBUG_VOL) {
7879                             Log.d(TAG, "invalid mute on unmutable volume group " + name());
7880                         }
7881                         return;
7882                     }
7883                     switch (direction) {
7884                         case AudioManager.ADJUST_TOGGLE_MUTE: {
7885                             // Note: If muted by volume 0, unmute will restore volume 0.
7886                             mute(!mIsMuted);
7887                             break;
7888                         }
7889                         case AudioManager.ADJUST_UNMUTE:
7890                             // Note: If muted by volume 0, unmute will restore volume 0.
7891                             mute(false);
7892                             break;
7893                         case AudioManager.ADJUST_MUTE:
7894                             // May be already muted by setvolume 0, prevent from setting same value
7895                             if (previousIndex != 0) {
7896                                 // bypass persist
7897                                 mute(true);
7898                             }
7899                             mIsMuted = true;
7900                             break;
7901                         case AudioManager.ADJUST_RAISE:
7902                             // As for stream, RAISE during mute will increment the index
7903                             setVolumeIndex(Math.min(previousIndex + 1, mIndexMax),  device, flags);
7904                             break;
7905                         case AudioManager.ADJUST_LOWER:
7906                             // For stream, ADJUST_LOWER on a muted VSS is a no-op
7907                             // If we decide to unmute on ADJUST_LOWER, cannot fallback on
7908                             // adjustStreamVolume for group associated to legacy stream type
7909                             if (isMuted() && previousIndex != 0) {
7910                                 mute(false);
7911                             } else {
7912                                 int newIndex = Math.max(previousIndex - 1, mIndexMin);
7913                                 setVolumeIndex(newIndex, device, flags);
7914                             }
7915                             break;
7916                     }
7917                 }
7918             }
7919         }
7920 
getVolumeIndex()7921         public int getVolumeIndex() {
7922             synchronized (AudioService.VolumeStreamState.class) {
7923                 return getIndex(getDeviceForVolume());
7924             }
7925         }
7926 
setVolumeIndex(int index, int flags)7927         public void setVolumeIndex(int index, int flags) {
7928             synchronized (mSettingsLock) {
7929                 synchronized (AudioService.VolumeStreamState.class) {
7930                     if (mUseFixedVolume) {
7931                         return;
7932                     }
7933                     setVolumeIndex(index, getDeviceForVolume(), flags);
7934                 }
7935             }
7936         }
7937 
7938         @GuardedBy("AudioService.VolumeStreamState.class")
setVolumeIndex(int index, int device, int flags)7939         private void setVolumeIndex(int index, int device, int flags) {
7940             // Update cache & persist (muted by volume 0 shall be persisted)
7941             updateVolumeIndex(index, device);
7942             // setting non-zero volume for a muted stream unmutes the stream and vice versa,
7943             boolean changed = mute(index == 0);
7944             if (!changed) {
7945                 // Set the volume index only if mute operation is a no-op
7946                 index = getValidIndex(index);
7947                 setVolumeIndexInt(index, device, flags);
7948             }
7949         }
7950 
7951         @GuardedBy("AudioService.VolumeStreamState.class")
updateVolumeIndex(int index, int device)7952         public void updateVolumeIndex(int index, int device) {
7953             // Filter persistency if already exist and the index has not changed
7954             if (mIndexMap.indexOfKey(device) < 0 || mIndexMap.get(device) != index) {
7955                 // Update local cache
7956                 mIndexMap.put(device, getValidIndex(index));
7957 
7958                 // update data base - post a persist volume group msg
7959                 sendMsg(mAudioHandler,
7960                         MSG_PERSIST_VOLUME_GROUP,
7961                         SENDMSG_QUEUE,
7962                         device,
7963                         0,
7964                         this,
7965                         PERSIST_DELAY);
7966             }
7967         }
7968 
7969         @GuardedBy("AudioService.VolumeStreamState.class")
setVolumeIndexInt(int index, int device, int flags)7970         private void setVolumeIndexInt(int index, int device, int flags) {
7971             // Reflect mute state of corresponding stream by forcing index to 0 if muted
7972             // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted.
7973             // This allows RX path muting by the audio HAL only when explicitly muted but not when
7974             // index is just set to 0 to repect BT requirements
7975             if (mHasValidStreamType && isVssMuteBijective(mPublicStreamType)
7976                     && mStreamStates[mPublicStreamType].isFullyMuted()) {
7977                 index = 0;
7978             } else if (mPublicStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0) {
7979                 index = 1;
7980             }
7981             // Set the volume index
7982             AudioSystem.setVolumeIndexForAttributes(mAudioAttributes, index, device);
7983         }
7984 
7985         @GuardedBy("AudioService.VolumeStreamState.class")
getIndex(int device)7986         private int getIndex(int device) {
7987             int index = mIndexMap.get(device, -1);
7988             // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
7989             return (index != -1) ? index : mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT);
7990         }
7991 
7992         @GuardedBy("AudioService.VolumeStreamState.class")
hasIndexForDevice(int device)7993         private boolean hasIndexForDevice(int device) {
7994             return (mIndexMap.get(device, -1) != -1);
7995         }
7996 
getMaxIndex()7997         public int getMaxIndex() {
7998             return mIndexMax;
7999         }
8000 
getMinIndex()8001         public int getMinIndex() {
8002             return mIndexMin;
8003         }
8004 
isValidStream(int stream)8005         private boolean isValidStream(int stream) {
8006             return (stream != AudioSystem.STREAM_DEFAULT) && (stream < mStreamStates.length);
8007         }
8008 
isMusic()8009         public boolean isMusic() {
8010             return mHasValidStreamType && mPublicStreamType == AudioSystem.STREAM_MUSIC;
8011         }
8012 
applyAllVolumes(boolean userSwitch)8013         public void applyAllVolumes(boolean userSwitch) {
8014             String caller = "from vgs";
8015             synchronized (AudioService.VolumeStreamState.class) {
8016                 // apply device specific volumes first
8017                 for (int i = 0; i < mIndexMap.size(); i++) {
8018                     int device = mIndexMap.keyAt(i);
8019                     int index = mIndexMap.valueAt(i);
8020                     boolean synced = false;
8021                     if (device != AudioSystem.DEVICE_OUT_DEFAULT) {
8022                         for (int stream : getLegacyStreamTypes()) {
8023                             if (isValidStream(stream)) {
8024                                 boolean streamMuted = mStreamStates[stream].mIsMuted;
8025                                 int deviceForStream = getDeviceForStream(stream);
8026                                 int indexForStream =
8027                                         (mStreamStates[stream].getIndex(deviceForStream) + 5) / 10;
8028                                 if (device == deviceForStream) {
8029                                     if (indexForStream == index && (isMuted() == streamMuted)
8030                                             && isVssMuteBijective(stream)) {
8031                                         synced = true;
8032                                         continue;
8033                                     }
8034                                     if (indexForStream != index) {
8035                                         mStreamStates[stream].setIndex(index * 10, device, caller,
8036                                                 true /*hasModifyAudioSettings*/);
8037                                     }
8038                                     if ((isMuted() != streamMuted) && isVssMuteBijective(stream)) {
8039                                         mStreamStates[stream].mute(isMuted(),
8040                                                 "VGS.applyAllVolumes#1");
8041                                     }
8042                                 }
8043                             }
8044                         }
8045                         if (!synced) {
8046                             if (DEBUG_VOL) {
8047                                 Log.d(TAG, "applyAllVolumes: apply index " + index + ", group "
8048                                         + mAudioVolumeGroup.name() + " and device "
8049                                         + AudioSystem.getOutputDeviceName(device));
8050                             }
8051                             setVolumeIndexInt(isMuted() ? 0 : index, device, 0 /*flags*/);
8052                         }
8053                     }
8054                 }
8055                 // apply default volume last: by convention , default device volume will be used
8056                 // by audio policy manager if no explicit volume is present for a given device type
8057                 int index = getIndex(AudioSystem.DEVICE_OUT_DEFAULT);
8058                 boolean synced = false;
8059                 int deviceForVolume = getDeviceForVolume();
8060                 boolean forceDeviceSync = userSwitch && (mIndexMap.indexOfKey(deviceForVolume) < 0);
8061                 for (int stream : getLegacyStreamTypes()) {
8062                     if (isValidStream(stream)) {
8063                         boolean streamMuted = mStreamStates[stream].mIsMuted;
8064                         int defaultStreamIndex = (mStreamStates[stream].getIndex(
8065                                         AudioSystem.DEVICE_OUT_DEFAULT) + 5) / 10;
8066                         if (forceDeviceSync) {
8067                             mStreamStates[stream].setIndex(index * 10, deviceForVolume, caller,
8068                                     true /*hasModifyAudioSettings*/);
8069                         }
8070                         if (defaultStreamIndex == index && (isMuted() == streamMuted)
8071                                 && isVssMuteBijective(stream)) {
8072                             synced = true;
8073                             continue;
8074                         }
8075                         if (defaultStreamIndex != index) {
8076                             mStreamStates[stream].setIndex(
8077                                     index * 10, AudioSystem.DEVICE_OUT_DEFAULT, caller,
8078                                     true /*hasModifyAudioSettings*/);
8079                         }
8080                         if ((isMuted() != streamMuted) && isVssMuteBijective(stream)) {
8081                             mStreamStates[stream].mute(isMuted(), "VGS.applyAllVolumes#2");
8082                         }
8083                     }
8084                 }
8085                 if (!synced) {
8086                     if (DEBUG_VOL) {
8087                         Log.d(TAG, "applyAllVolumes: apply default device index " + index
8088                                 + ", group " + mAudioVolumeGroup.name());
8089                     }
8090                     setVolumeIndexInt(
8091                             isMuted() ? 0 : index, AudioSystem.DEVICE_OUT_DEFAULT, 0 /*flags*/);
8092                 }
8093                 if (forceDeviceSync) {
8094                     if (DEBUG_VOL) {
8095                         Log.d(TAG, "applyAllVolumes: forceDeviceSync index " + index
8096                                 + ", device " + AudioSystem.getOutputDeviceName(deviceForVolume)
8097                                 + ", group " + mAudioVolumeGroup.name());
8098                     }
8099                     setVolumeIndexInt(isMuted() ? 0 : index, deviceForVolume, 0);
8100                 }
8101             }
8102         }
8103 
clearIndexCache()8104         public void clearIndexCache() {
8105             mIndexMap.clear();
8106         }
8107 
persistVolumeGroup(int device)8108         private void persistVolumeGroup(int device) {
8109             // No need to persist the index if the volume group is backed up
8110             // by a public stream type as this is redundant
8111             if (mUseFixedVolume || mHasValidStreamType) {
8112                 return;
8113             }
8114             if (DEBUG_VOL) {
8115                 Log.v(TAG, "persistVolumeGroup: storing index " + getIndex(device) + " for group "
8116                         + mAudioVolumeGroup.name()
8117                         + ", device " + AudioSystem.getOutputDeviceName(device)
8118                         + " and User=" + getCurrentUserId()
8119                         + " mSettingName: " + mSettingName);
8120             }
8121 
8122             boolean success = mSettings.putSystemIntForUser(mContentResolver,
8123                     getSettingNameForDevice(device),
8124                     getIndex(device),
8125                     isMusic() ? UserHandle.USER_SYSTEM : UserHandle.USER_CURRENT);
8126             if (!success) {
8127                 Log.e(TAG, "persistVolumeGroup failed for group " +  mAudioVolumeGroup.name());
8128             }
8129         }
8130 
readSettings()8131         public void readSettings() {
8132             synchronized (AudioService.VolumeStreamState.class) {
8133                 // force maximum volume on all streams if fixed volume property is set
8134                 if (mUseFixedVolume) {
8135                     mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
8136                     return;
8137                 }
8138                 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
8139                     // retrieve current volume for device
8140                     // if no volume stored for current volume group and device, use default volume
8141                     // if default device, continue otherwise
8142                     int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT)
8143                             ? AudioSystem.DEFAULT_STREAM_VOLUME[mPublicStreamType] : -1;
8144                     int index;
8145                     String name = getSettingNameForDevice(device);
8146                     index = mSettings.getSystemIntForUser(
8147                             mContentResolver, name, defaultIndex,
8148                             isMusic() ? UserHandle.USER_SYSTEM : UserHandle.USER_CURRENT);
8149                     if (index == -1) {
8150                         continue;
8151                     }
8152                     if (mPublicStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED
8153                             && mCameraSoundForced) {
8154                         index = mIndexMax;
8155                     }
8156                     if (DEBUG_VOL) {
8157                         Log.v(TAG, "readSettings: found stored index " + getValidIndex(index)
8158                                  + " for group " + mAudioVolumeGroup.name() + ", device: " + name
8159                                  + ", User=" + getCurrentUserId());
8160                     }
8161                     mIndexMap.put(device, getValidIndex(index));
8162                 }
8163             }
8164         }
8165 
8166         @GuardedBy("AudioService.VolumeStreamState.class")
getValidIndex(int index)8167         private int getValidIndex(int index) {
8168             if (index < mIndexMin) {
8169                 return mIndexMin;
8170             } else if (mUseFixedVolume || index > mIndexMax) {
8171                 return mIndexMax;
8172             }
8173             return index;
8174         }
8175 
getSettingNameForDevice(int device)8176         public @NonNull String getSettingNameForDevice(int device) {
8177             String suffix = AudioSystem.getOutputDeviceName(device);
8178             if (suffix.isEmpty()) {
8179                 return mSettingName;
8180             }
8181             return mSettingName + "_" + AudioSystem.getOutputDeviceName(device);
8182         }
8183 
setSettingName(String settingName)8184         void setSettingName(String settingName) {
8185             mSettingName = settingName;
8186         }
8187 
getSettingName()8188         String getSettingName() {
8189             return mSettingName;
8190         }
8191 
dump(PrintWriter pw)8192         private void dump(PrintWriter pw) {
8193             pw.println("- VOLUME GROUP " + mAudioVolumeGroup.name() + ":");
8194             pw.print("   Muted: ");
8195             pw.println(mIsMuted);
8196             pw.print("   Min: ");
8197             pw.println(mIndexMin);
8198             pw.print("   Max: ");
8199             pw.println(mIndexMax);
8200             pw.print("   Current: ");
8201             for (int i = 0; i < mIndexMap.size(); i++) {
8202                 if (i > 0) {
8203                     pw.print(", ");
8204                 }
8205                 int device = mIndexMap.keyAt(i);
8206                 pw.print(Integer.toHexString(device));
8207                 String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
8208                         : AudioSystem.getOutputDeviceName(device);
8209                 if (!deviceName.isEmpty()) {
8210                     pw.print(" (");
8211                     pw.print(deviceName);
8212                     pw.print(")");
8213                 }
8214                 pw.print(": ");
8215                 pw.print(mIndexMap.valueAt(i));
8216             }
8217             pw.println();
8218             pw.print("   Devices: ");
8219             int n = 0;
8220             int devices = getDeviceForVolume();
8221             for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
8222                 if ((devices & device) == device) {
8223                     if (n++ > 0) {
8224                         pw.print(", ");
8225                     }
8226                     pw.print(AudioSystem.getOutputDeviceName(device));
8227                 }
8228             }
8229             pw.println();
8230             pw.print("   Streams: ");
8231             Arrays.stream(getLegacyStreamTypes())
8232                     .forEach(stream -> pw.print(AudioSystem.streamToString(stream) + " "));
8233         }
8234     }
8235 
8236 
8237     // NOTE: Locking order for synchronized objects related to volume or ringer mode management:
8238     //  1 mScoclient OR mSafeMediaVolumeState
8239     //  2   mSetModeLock
8240     //  3     mSettingsLock
8241     //  4       VolumeStreamState.class
8242     /*package*/ class VolumeStreamState {
8243         private final int mStreamType;
8244         private VolumeGroupState mVolumeGroupState = null;
8245         private int mIndexMin;
8246         // min index when user doesn't have permission to change audio settings
8247         private int mIndexMinNoPerm;
8248         private int mIndexMax;
8249 
8250         private boolean mIsMuted = false;
8251         private boolean mIsMutedInternally = false;
8252         private String mVolumeIndexSettingName;
8253         @NonNull private Set<Integer> mObservedDeviceSet = new TreeSet<>();
8254 
8255         private final SparseIntArray mIndexMap = new SparseIntArray(8) {
8256             @Override
8257             public void put(int key, int value) {
8258                 super.put(key, value);
8259                 record("put", key, value);
8260             }
8261             @Override
8262             public void setValueAt(int index, int value) {
8263                 super.setValueAt(index, value);
8264                 record("setValueAt", keyAt(index), value);
8265             }
8266 
8267             // Record all changes in the VolumeStreamState
8268             private void record(String event, int key, int value) {
8269                 final String device = key == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
8270                         : AudioSystem.getOutputDeviceName(key);
8271                 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_VOLUME + MediaMetrics.SEPARATOR
8272                         + AudioSystem.streamToString(mStreamType)
8273                         + "." + device)
8274                         .set(MediaMetrics.Property.EVENT, event)
8275                         .set(MediaMetrics.Property.INDEX, value)
8276                         .set(MediaMetrics.Property.MIN_INDEX, mIndexMin)
8277                         .set(MediaMetrics.Property.MAX_INDEX, mIndexMax)
8278                         .record();
8279             }
8280         };
8281         private final Intent mVolumeChanged;
8282         private final Bundle mVolumeChangedOptions;
8283         private final Intent mStreamDevicesChanged;
8284         private final Bundle mStreamDevicesChangedOptions;
8285 
VolumeStreamState(String settingName, int streamType)8286         private VolumeStreamState(String settingName, int streamType) {
8287             mVolumeIndexSettingName = settingName;
8288 
8289             mStreamType = streamType;
8290             mIndexMin = MIN_STREAM_VOLUME[streamType] * 10;
8291             mIndexMinNoPerm = mIndexMin; // may be overwritten later in updateNoPermMinIndex()
8292             mIndexMax = MAX_STREAM_VOLUME[streamType] * 10;
8293             final int status = AudioSystem.initStreamVolume(
8294                     streamType, mIndexMin / 10, mIndexMax / 10);
8295             if (status != AudioSystem.AUDIO_STATUS_OK) {
8296                 sLifecycleLogger.enqueue(new EventLogger.StringEvent(
8297                          "VSS() stream:" + streamType + " initStreamVolume=" + status)
8298                         .printLog(ALOGE, TAG));
8299                 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0,
8300                         "VSS()" /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
8301             }
8302 
8303             readSettings();
8304             mVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION);
8305             mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
8306             final BroadcastOptions volumeChangedOptions = BroadcastOptions.makeBasic();
8307             // This allows us to discard older broadcasts still waiting to be delivered
8308             // which have the same namespace (VOLUME_CHANGED_ACTION) and key (mStreamType).
8309             volumeChangedOptions.setDeliveryGroupPolicy(DELIVERY_GROUP_POLICY_MOST_RECENT);
8310             volumeChangedOptions.setDeliveryGroupMatchingKey(
8311                     AudioManager.VOLUME_CHANGED_ACTION, String.valueOf(mStreamType));
8312             volumeChangedOptions.setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE);
8313             mVolumeChangedOptions = volumeChangedOptions.toBundle();
8314 
8315             mStreamDevicesChanged = new Intent(AudioManager.STREAM_DEVICES_CHANGED_ACTION);
8316             mStreamDevicesChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
8317             final BroadcastOptions streamDevicesChangedOptions = BroadcastOptions.makeBasic();
8318             streamDevicesChangedOptions.setDeliveryGroupPolicy(DELIVERY_GROUP_POLICY_MOST_RECENT);
8319             streamDevicesChangedOptions.setDeliveryGroupMatchingKey(
8320                     AudioManager.STREAM_DEVICES_CHANGED_ACTION, String.valueOf(mStreamType));
8321             streamDevicesChangedOptions.setDeferralPolicy(
8322                     BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE);
8323             mStreamDevicesChangedOptions = streamDevicesChangedOptions.toBundle();
8324         }
8325 
8326         /**
8327          * Associate a {@link volumeGroupState} on the {@link VolumeStreamState}.
8328          * <p> It helps to synchronize the index, mute attributes on the maching
8329          * {@link volumeGroupState}
8330          * @param volumeGroupState matching the {@link VolumeStreamState}
8331          */
setVolumeGroupState(VolumeGroupState volumeGroupState)8332         public void setVolumeGroupState(VolumeGroupState volumeGroupState) {
8333             mVolumeGroupState = volumeGroupState;
8334             if (mVolumeGroupState != null) {
8335                 mVolumeGroupState.setSettingName(mVolumeIndexSettingName);
8336             }
8337         }
8338         /**
8339          * Update the minimum index that can be used without MODIFY_AUDIO_SETTINGS permission
8340          * @param index minimum index expressed in "UI units", i.e. no 10x factor
8341          */
updateNoPermMinIndex(int index)8342         public void updateNoPermMinIndex(int index) {
8343             mIndexMinNoPerm = index * 10;
8344             if (mIndexMinNoPerm < mIndexMin) {
8345                 Log.e(TAG, "Invalid mIndexMinNoPerm for stream " + mStreamType);
8346                 mIndexMinNoPerm = mIndexMin;
8347             }
8348         }
8349 
8350         /**
8351          * Returns a list of devices associated with the stream type.
8352          *
8353          * This is a reference to the local list, do not modify.
8354          */
8355         @GuardedBy("VolumeStreamState.class")
8356         @NonNull
observeDevicesForStream_syncVSS( boolean checkOthers)8357         public Set<Integer> observeDevicesForStream_syncVSS(
8358                 boolean checkOthers) {
8359             if (!mSystemServer.isPrivileged()) {
8360                 return new TreeSet<Integer>();
8361             }
8362             final Set<Integer> deviceSet =
8363                     getDeviceSetForStreamDirect(mStreamType);
8364             if (deviceSet.equals(mObservedDeviceSet)) {
8365                 return mObservedDeviceSet;
8366             }
8367 
8368             // Use legacy bit masks for message signalling.
8369             // TODO(b/185386781): message needs update since it uses devices bit-mask.
8370             final int devices = AudioSystem.getDeviceMaskFromSet(deviceSet);
8371             final int prevDevices = AudioSystem.getDeviceMaskFromSet(mObservedDeviceSet);
8372 
8373             mObservedDeviceSet = deviceSet;
8374             if (checkOthers) {
8375                 // one stream's devices have changed, check the others
8376                 postObserveDevicesForAllStreams(mStreamType);
8377             }
8378             // log base stream changes to the event log
8379             if (mStreamVolumeAlias[mStreamType] == mStreamType) {
8380                 EventLogTags.writeStreamDevicesChanged(mStreamType, prevDevices, devices);
8381             }
8382             // send STREAM_DEVICES_CHANGED_ACTION on the message handler so it is scheduled after
8383             // the postObserveDevicesForStreams is handled
8384             final SomeArgs args = SomeArgs.obtain();
8385             args.arg1 = mStreamDevicesChanged;
8386             args.arg2 = mStreamDevicesChangedOptions;
8387             sendMsg(mAudioHandler,
8388                     MSG_STREAM_DEVICES_CHANGED,
8389                     SENDMSG_QUEUE, prevDevices /*arg1*/, devices /*arg2*/,
8390                     // ok to send reference to this object, it is final
8391                     args /*obj*/, 0 /*delay*/);
8392             return mObservedDeviceSet;
8393         }
8394 
getSettingNameForDevice(int device)8395         public @Nullable String getSettingNameForDevice(int device) {
8396             if (!hasValidSettingsName()) {
8397                 return null;
8398             }
8399             final String suffix = AudioSystem.getOutputDeviceName(device);
8400             if (suffix.isEmpty()) {
8401                 return mVolumeIndexSettingName;
8402             }
8403             return mVolumeIndexSettingName + "_" + suffix;
8404         }
8405 
hasValidSettingsName()8406         private boolean hasValidSettingsName() {
8407             return (mVolumeIndexSettingName != null && !mVolumeIndexSettingName.isEmpty());
8408         }
8409 
setSettingName(String settingName)8410         void setSettingName(String settingName) {
8411             mVolumeIndexSettingName = settingName;
8412             if (mVolumeGroupState != null) {
8413                 mVolumeGroupState.setSettingName(mVolumeIndexSettingName);
8414             }
8415         }
8416 
getSettingName()8417         String getSettingName() {
8418             return mVolumeIndexSettingName;
8419         }
8420 
readSettings()8421         public void readSettings() {
8422             synchronized (mSettingsLock) {
8423                 synchronized (VolumeStreamState.class) {
8424                     // force maximum volume on all streams if fixed volume property is set
8425                     if (mUseFixedVolume) {
8426                         mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
8427                         return;
8428                     }
8429                     // do not read system stream volume from settings: this stream is always aliased
8430                     // to another stream type and its volume is never persisted. Values in settings can
8431                     // only be stale values
8432                     if ((mStreamType == AudioSystem.STREAM_SYSTEM) ||
8433                             (mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED)) {
8434                         int index = 10 * AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType];
8435                         if (mCameraSoundForced) {
8436                             index = mIndexMax;
8437                         }
8438                         mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, index);
8439                         return;
8440                     }
8441                 }
8442             }
8443             synchronized (VolumeStreamState.class) {
8444                 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
8445 
8446                     // retrieve current volume for device
8447                     // if no volume stored for current stream and device, use default volume if default
8448                     // device, continue otherwise
8449                     int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) ?
8450                             AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType] : -1;
8451                     int index;
8452                     if (!hasValidSettingsName()) {
8453                         index = defaultIndex;
8454                     } else {
8455                         String name = getSettingNameForDevice(device);
8456                         index = mSettings.getSystemIntForUser(
8457                                 mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT);
8458                     }
8459                     if (index == -1) {
8460                         continue;
8461                     }
8462 
8463                     mIndexMap.put(device, getValidIndex(10 * index,
8464                             true /*hasModifyAudioSettings*/));
8465                 }
8466             }
8467         }
8468 
getAbsoluteVolumeIndex(int index)8469         private int getAbsoluteVolumeIndex(int index) {
8470             /* Special handling for Bluetooth Absolute Volume scenario
8471              * If we send full audio gain, some accessories are too loud even at its lowest
8472              * volume. We are not able to enumerate all such accessories, so here is the
8473              * workaround from phone side.
8474              * Pre-scale volume at lowest volume steps 1 2 and 3.
8475              * For volume step 0, set audio gain to 0 as some accessories won't mute on their end.
8476              */
8477             if (index == 0) {
8478                 // 0% for volume 0
8479                 index = 0;
8480             } else if (index > 0 && index <= 3) {
8481                 // Pre-scale for volume steps 1 2 and 3
8482                 index = (int) (mIndexMax * mPrescaleAbsoluteVolume[index - 1]) / 10;
8483             } else {
8484                 // otherwise, full gain
8485                 index = (mIndexMax + 5) / 10;
8486             }
8487             return index;
8488         }
8489 
setStreamVolumeIndex(int index, int device)8490         private void setStreamVolumeIndex(int index, int device) {
8491             // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted.
8492             // This allows RX path muting by the audio HAL only when explicitly muted but not when
8493             // index is just set to 0 to repect BT requirements
8494             if (mStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0
8495                     && !isFullyMuted()) {
8496                 index = 1;
8497             }
8498             mAudioSystem.setStreamVolumeIndexAS(mStreamType, index, device);
8499         }
8500 
8501         // must be called while synchronized VolumeStreamState.class
applyDeviceVolume_syncVSS(int device)8502         /*package*/ void applyDeviceVolume_syncVSS(int device) {
8503             int index;
8504             if (isFullyMuted()) {
8505                 index = 0;
8506             } else if (isAbsoluteVolumeDevice(device)
8507                     || isA2dpAbsoluteVolumeDevice(device)
8508                     || AudioSystem.isLeAudioDeviceType(device)) {
8509                 index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10);
8510             } else if (isFullVolumeDevice(device)) {
8511                 index = (mIndexMax + 5)/10;
8512             } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
8513                 index = (mIndexMax + 5)/10;
8514             } else {
8515                 index = (getIndex(device) + 5)/10;
8516             }
8517             setStreamVolumeIndex(index, device);
8518         }
8519 
applyAllVolumes()8520         public void applyAllVolumes() {
8521             synchronized (VolumeStreamState.class) {
8522                 // apply device specific volumes first
8523                 int index;
8524                 boolean isAbsoluteVolume = false;
8525                 for (int i = 0; i < mIndexMap.size(); i++) {
8526                     final int device = mIndexMap.keyAt(i);
8527                     if (device != AudioSystem.DEVICE_OUT_DEFAULT) {
8528                         if (isFullyMuted()) {
8529                             index = 0;
8530                         } else if (isAbsoluteVolumeDevice(device)
8531                                 || isA2dpAbsoluteVolumeDevice(device)
8532                                 || AudioSystem.isLeAudioDeviceType(device)) {
8533                             isAbsoluteVolume = true;
8534                             index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10);
8535                         } else if (isFullVolumeDevice(device)) {
8536                             index = (mIndexMax + 5)/10;
8537                         } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
8538                             index = (mIndexMax + 5)/10;
8539                         } else {
8540                             index = (mIndexMap.valueAt(i) + 5)/10;
8541                         }
8542 
8543                         sendMsg(mAudioHandler, SoundDoseHelper.MSG_CSD_UPDATE_ATTENUATION,
8544                                 SENDMSG_REPLACE, device,  isAbsoluteVolume ? 1 : 0, this,
8545                                 /*delay=*/0);
8546 
8547                         setStreamVolumeIndex(index, device);
8548                     }
8549                 }
8550                 // apply default volume last: by convention , default device volume will be used
8551                 // by audio policy manager if no explicit volume is present for a given device type
8552                 if (isFullyMuted()) {
8553                     index = 0;
8554                 } else {
8555                     index = (getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)/10;
8556                 }
8557                 setStreamVolumeIndex(index, AudioSystem.DEVICE_OUT_DEFAULT);
8558             }
8559         }
8560 
adjustIndex(int deltaIndex, int device, String caller, boolean hasModifyAudioSettings)8561         public boolean adjustIndex(int deltaIndex, int device, String caller,
8562                 boolean hasModifyAudioSettings) {
8563             return setIndex(getIndex(device) + deltaIndex, device, caller,
8564                     hasModifyAudioSettings);
8565         }
8566 
setIndex(int index, int device, String caller, boolean hasModifyAudioSettings)8567         public boolean setIndex(int index, int device, String caller,
8568                 boolean hasModifyAudioSettings) {
8569             boolean changed;
8570             int oldIndex;
8571             final boolean isCurrentDevice;
8572             synchronized (mSettingsLock) {
8573                 synchronized (VolumeStreamState.class) {
8574                     oldIndex = getIndex(device);
8575                     index = getValidIndex(index, hasModifyAudioSettings);
8576                     if ((mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED) && mCameraSoundForced) {
8577                         index = mIndexMax;
8578                     }
8579                     mIndexMap.put(device, index);
8580 
8581                     changed = oldIndex != index;
8582                     // Apply change to all streams using this one as alias if:
8583                     // - the index actually changed OR
8584                     // - there is no volume index stored for this device on alias stream.
8585                     // If changing volume of current device, also change volume of current
8586                     // device on aliased stream
8587                     isCurrentDevice = (device == getDeviceForStream(mStreamType));
8588                     final int numStreamTypes = AudioSystem.getNumStreamTypes();
8589                     for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
8590                         final VolumeStreamState aliasStreamState = mStreamStates[streamType];
8591                         if (streamType != mStreamType &&
8592                                 mStreamVolumeAlias[streamType] == mStreamType &&
8593                                 (changed || !aliasStreamState.hasIndexForDevice(device))) {
8594                             final int scaledIndex = rescaleIndex(index, mStreamType, streamType);
8595                             aliasStreamState.setIndex(scaledIndex, device, caller,
8596                                     hasModifyAudioSettings);
8597                             if (isCurrentDevice) {
8598                                 aliasStreamState.setIndex(scaledIndex,
8599                                         getDeviceForStream(streamType), caller,
8600                                         hasModifyAudioSettings);
8601                             }
8602                         }
8603                     }
8604                     // Mirror changes in SPEAKER ringtone volume on SCO when
8605                     if (changed && mStreamType == AudioSystem.STREAM_RING
8606                             && device == AudioSystem.DEVICE_OUT_SPEAKER) {
8607                         for (int i = 0; i < mIndexMap.size(); i++) {
8608                             int otherDevice = mIndexMap.keyAt(i);
8609                             if (AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(otherDevice)) {
8610                                 mIndexMap.put(otherDevice, index);
8611                             }
8612                         }
8613                     }
8614                 }
8615             }
8616             if (changed) {
8617                 // If associated to volume group, update group cache
8618                 updateVolumeGroupIndex(device, /* forceMuteState= */ false);
8619 
8620                 oldIndex = (oldIndex + 5) / 10;
8621                 index = (index + 5) / 10;
8622                 // log base stream changes to the event log
8623                 if (mStreamVolumeAlias[mStreamType] == mStreamType) {
8624                     if (caller == null) {
8625                         Log.w(TAG, "No caller for volume_changed event", new Throwable());
8626                     }
8627                     EventLogTags.writeVolumeChanged(mStreamType, oldIndex, index, mIndexMax / 10,
8628                             caller);
8629                 }
8630                 // fire changed intents for all streams, but only when the device it changed on
8631                 //  is the current device
8632                 if ((index != oldIndex) && isCurrentDevice) {
8633                     mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index);
8634                     mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex);
8635                     mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS,
8636                             mStreamVolumeAlias[mStreamType]);
8637                     AudioService.sVolumeLogger.enqueue(new VolChangedBroadcastEvent(
8638                             mStreamType, mStreamVolumeAlias[mStreamType], index));
8639                     sendBroadcastToAll(mVolumeChanged, mVolumeChangedOptions);
8640                 }
8641             }
8642             return changed;
8643         }
8644 
getIndex(int device)8645         public int getIndex(int device) {
8646             synchronized (VolumeStreamState.class) {
8647                 int index = mIndexMap.get(device, -1);
8648                 if (index == -1) {
8649                     // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
8650                     index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT);
8651                 }
8652                 return index;
8653             }
8654         }
8655 
getVolumeInfo(int device)8656         public @NonNull VolumeInfo getVolumeInfo(int device) {
8657             synchronized (VolumeStreamState.class) {
8658                 int index = mIndexMap.get(device, -1);
8659                 if (index == -1) {
8660                     // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
8661                     index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT);
8662                 }
8663                 final VolumeInfo vi = new VolumeInfo.Builder(mStreamType)
8664                         .setMinVolumeIndex(mIndexMin)
8665                         .setMaxVolumeIndex(mIndexMax)
8666                         .setVolumeIndex(index)
8667                         .setMuted(isFullyMuted())
8668                         .build();
8669                 return vi;
8670             }
8671         }
8672 
hasIndexForDevice(int device)8673         public boolean hasIndexForDevice(int device) {
8674             synchronized (VolumeStreamState.class) {
8675                 return (mIndexMap.get(device, -1) != -1);
8676             }
8677         }
8678 
getMaxIndex()8679         public int getMaxIndex() {
8680             return mIndexMax;
8681         }
8682 
8683         /**
8684          * @return the lowest index regardless of permissions
8685          */
getMinIndex()8686         public int getMinIndex() {
8687             return mIndexMin;
8688         }
8689 
8690         /**
8691          * @param isPrivileged true if the caller is privileged and not subject to minimum
8692          *                     volume index thresholds
8693          * @return the lowest index that this caller can set or adjust to
8694          */
getMinIndex(boolean isPrivileged)8695         public int getMinIndex(boolean isPrivileged) {
8696             return isPrivileged ? mIndexMin : mIndexMinNoPerm;
8697         }
8698 
8699         /**
8700          * Copies all device/index pairs from the given VolumeStreamState after initializing
8701          * them with the volume for DEVICE_OUT_DEFAULT. No-op if the source VolumeStreamState
8702          * has the same stream type as this instance.
8703          * @param srcStream
8704          * @param caller
8705          */
8706         // must be sync'd on mSettingsLock before VolumeStreamState.class
8707         @GuardedBy("VolumeStreamState.class")
setAllIndexes(VolumeStreamState srcStream, String caller)8708         public void setAllIndexes(VolumeStreamState srcStream, String caller) {
8709             if (mStreamType == srcStream.mStreamType) {
8710                 return;
8711             }
8712             int srcStreamType = srcStream.getStreamType();
8713             // apply default device volume from source stream to all devices first in case
8714             // some devices are present in this stream state but not in source stream state
8715             int index = srcStream.getIndex(AudioSystem.DEVICE_OUT_DEFAULT);
8716             index = rescaleIndex(index, srcStreamType, mStreamType);
8717             for (int i = 0; i < mIndexMap.size(); i++) {
8718                 mIndexMap.put(mIndexMap.keyAt(i), index);
8719             }
8720             // Now apply actual volume for devices in source stream state
8721             SparseIntArray srcMap = srcStream.mIndexMap;
8722             for (int i = 0; i < srcMap.size(); i++) {
8723                 int device = srcMap.keyAt(i);
8724                 index = srcMap.valueAt(i);
8725                 index = rescaleIndex(index, srcStreamType, mStreamType);
8726 
8727                 setIndex(index, device, caller, true /*hasModifyAudioSettings*/);
8728             }
8729         }
8730 
8731         // must be sync'd on mSettingsLock before VolumeStreamState.class
8732         @GuardedBy("VolumeStreamState.class")
setAllIndexesToMax()8733         public void setAllIndexesToMax() {
8734             for (int i = 0; i < mIndexMap.size(); i++) {
8735                 mIndexMap.put(mIndexMap.keyAt(i), mIndexMax);
8736             }
8737         }
8738 
8739         // If associated to volume group, update group cache
updateVolumeGroupIndex(int device, boolean forceMuteState)8740         private void updateVolumeGroupIndex(int device, boolean forceMuteState) {
8741             // need mSettingsLock when called from setIndex for vgs.mute -> vgs.applyAllVolumes ->
8742             // vss.setIndex which grabs this lock after VSS.class. Locking order needs to be
8743             // preserved
8744             synchronized (mSettingsLock) {
8745                 synchronized (VolumeStreamState.class) {
8746                     if (mVolumeGroupState != null) {
8747                         int groupIndex = (getIndex(device) + 5) / 10;
8748                         if (DEBUG_VOL) {
8749                             Log.d(TAG, "updateVolumeGroupIndex for stream " + mStreamType
8750                                     + ", muted=" + mIsMuted + ", device=" + device + ", index="
8751                                     + getIndex(device) + ", group " + mVolumeGroupState.name()
8752                                     + " Muted=" + mVolumeGroupState.isMuted() + ", Index="
8753                                     + groupIndex + ", forceMuteState=" + forceMuteState);
8754                         }
8755                         mVolumeGroupState.updateVolumeIndex(groupIndex, device);
8756                         // Only propage mute of stream when applicable
8757                         if (isMutable()) {
8758                             // For call stream, align mute only when muted, not when index is set to
8759                             // 0
8760                             mVolumeGroupState.mute(
8761                                     forceMuteState ? mIsMuted :
8762                                             (groupIndex == 0 && !isCallStream(mStreamType))
8763                                                     || mIsMuted);
8764                         }
8765                     }
8766                 }
8767             }
8768         }
8769 
8770         /**
8771          * Mute/unmute the stream
8772          * @param state the new mute state
8773          * @return true if the mute state was changed
8774          */
mute(boolean state, String source)8775         public boolean mute(boolean state, String source) {
8776             boolean changed = false;
8777             synchronized (VolumeStreamState.class) {
8778                 changed = mute(state, true, source);
8779             }
8780             if (changed) {
8781                 broadcastMuteSetting(mStreamType, state);
8782             }
8783             return changed;
8784         }
8785 
8786         /**
8787          * Mute/unmute the stream by AudioService
8788          * @param state the new mute state
8789          * @return true if the mute state was changed
8790          */
muteInternally(boolean state)8791         public boolean muteInternally(boolean state) {
8792             boolean changed = false;
8793             synchronized (VolumeStreamState.class) {
8794                 if (state != mIsMutedInternally) {
8795                     changed = true;
8796                     mIsMutedInternally = state;
8797                     // mute immediately to avoid delay and preemption when using a message.
8798                     applyAllVolumes();
8799                 }
8800             }
8801             if (changed) {
8802                 sVolumeLogger.enqueue(new VolumeEvent(
8803                         VolumeEvent.VOL_MUTE_STREAM_INT, mStreamType, state));
8804             }
8805             return changed;
8806         }
8807 
8808         @GuardedBy("VolumeStreamState.class")
isFullyMuted()8809         public boolean isFullyMuted() {
8810             return mIsMuted || mIsMutedInternally;
8811         }
8812 
8813 
isMutable()8814         private boolean isMutable() {
8815             return isStreamAffectedByMute(mStreamType)
8816                     && (mIndexMin == 0 || isCallStream(mStreamType));
8817         }
8818 
8819         /**
8820          * Mute/unmute the stream
8821          * @param state the new mute state
8822          * @param apply true to propagate to HW, or false just to update the cache. May be needed
8823          * to mute a stream and its aliases as applyAllVolume will force settings to aliases.
8824          * It prevents unnecessary calls to {@see AudioSystem#setStreamVolume}
8825          * @return true if the mute state was changed
8826          */
mute(boolean state, boolean apply, String src)8827         public boolean mute(boolean state, boolean apply, String src) {
8828             synchronized (VolumeStreamState.class) {
8829                 boolean changed = state != mIsMuted;
8830                 if (changed) {
8831                     sMuteLogger.enqueue(
8832                             new AudioServiceEvents.StreamMuteEvent(mStreamType, state, src));
8833                     // check to see if unmuting should not have happened due to ringer muted streams
8834                     if (!state && isStreamMutedByRingerOrZenMode(mStreamType)) {
8835                         Log.e(TAG, "Unmuting stream " + mStreamType
8836                                 + " despite ringer-zen muted stream 0x"
8837                                 + Integer.toHexString(AudioService.sRingerAndZenModeMutedStreams),
8838                                 new Exception()); // this will put a stack trace in the logs
8839                         sMuteLogger.enqueue(new AudioServiceEvents.StreamUnmuteErrorEvent(
8840                                 mStreamType, AudioService.sRingerAndZenModeMutedStreams));
8841                     }
8842                     mIsMuted = state;
8843                     if (apply) {
8844                         doMute();
8845                     }
8846                 }
8847                 return changed;
8848             }
8849         }
8850 
doMute()8851         public void doMute() {
8852             synchronized (VolumeStreamState.class) {
8853                 // If associated to volume group, update group cache
8854                 updateVolumeGroupIndex(getDeviceForStream(mStreamType), /* forceMuteState= */ true);
8855 
8856                 // Set the new mute volume. This propagates the values to
8857                 // the audio system, otherwise the volume won't be changed
8858                 // at the lower level.
8859                 sendMsg(mAudioHandler,
8860                         MSG_SET_ALL_VOLUMES,
8861                         SENDMSG_QUEUE,
8862                         0,
8863                         0,
8864                         this, 0);
8865             }
8866         }
8867 
getStreamType()8868         public int getStreamType() {
8869             return mStreamType;
8870         }
8871 
checkFixedVolumeDevices()8872         public void checkFixedVolumeDevices() {
8873             synchronized (VolumeStreamState.class) {
8874                 // ignore settings for fixed volume devices: volume should always be at max or 0
8875                 if (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_MUSIC) {
8876                     for (int i = 0; i < mIndexMap.size(); i++) {
8877                         int device = mIndexMap.keyAt(i);
8878                         int index = mIndexMap.valueAt(i);
8879                         if (isFullVolumeDevice(device)
8880                                 || (isFixedVolumeDevice(device) && index != 0)) {
8881                             mIndexMap.put(device, mIndexMax);
8882                         }
8883                         applyDeviceVolume_syncVSS(device);
8884                     }
8885                 }
8886             }
8887         }
8888 
getValidIndex(int index, boolean hasModifyAudioSettings)8889         private int getValidIndex(int index, boolean hasModifyAudioSettings) {
8890             final int indexMin = hasModifyAudioSettings ? mIndexMin : mIndexMinNoPerm;
8891             if (index < indexMin) {
8892                 return indexMin;
8893             } else if (mUseFixedVolume || index > mIndexMax) {
8894                 return mIndexMax;
8895             }
8896 
8897             return index;
8898         }
8899 
dump(PrintWriter pw)8900         private void dump(PrintWriter pw) {
8901             pw.print("   Muted: ");
8902             pw.println(mIsMuted);
8903             pw.print("   Muted Internally: ");
8904             pw.println(mIsMutedInternally);
8905             pw.print("   Min: ");
8906             pw.print((mIndexMin + 5) / 10);
8907             if (mIndexMin != mIndexMinNoPerm) {
8908                 pw.print(" w/o perm:");
8909                 pw.println((mIndexMinNoPerm + 5) / 10);
8910             } else {
8911                 pw.println();
8912             }
8913             pw.print("   Max: ");
8914             pw.println((mIndexMax + 5) / 10);
8915             pw.print("   streamVolume:"); pw.println(getStreamVolume(mStreamType));
8916             pw.print("   Current: ");
8917             for (int i = 0; i < mIndexMap.size(); i++) {
8918                 if (i > 0) {
8919                     pw.print(", ");
8920                 }
8921                 final int device = mIndexMap.keyAt(i);
8922                 pw.print(Integer.toHexString(device));
8923                 final String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
8924                         : AudioSystem.getOutputDeviceName(device);
8925                 if (!deviceName.isEmpty()) {
8926                     pw.print(" (");
8927                     pw.print(deviceName);
8928                     pw.print(")");
8929                 }
8930                 pw.print(": ");
8931                 final int index = (mIndexMap.valueAt(i) + 5) / 10;
8932                 pw.print(index);
8933             }
8934             pw.println();
8935             pw.print("   Devices: ");
8936             pw.print(AudioSystem.deviceSetToString(getDeviceSetForStream(mStreamType)));
8937             pw.println();
8938             pw.print("   Volume Group: ");
8939             pw.println(mVolumeGroupState != null ? mVolumeGroupState.name() : "n/a");
8940         }
8941     }
8942 
8943     /** Thread that handles native AudioSystem control. */
8944     private class AudioSystemThread extends Thread {
AudioSystemThread()8945         AudioSystemThread() {
8946             super("AudioService");
8947         }
8948 
8949         @Override
run()8950         public void run() {
8951             // Set this thread up so the handler will work on it
8952             Looper.prepare();
8953 
8954             synchronized(AudioService.this) {
8955                 mAudioHandler = new AudioHandler();
8956 
8957                 // Notify that the handler has been created
8958                 AudioService.this.notify();
8959             }
8960 
8961             // Listen for volume change requests that are set by VolumePanel
8962             Looper.loop();
8963         }
8964     }
8965 
8966     private static final class DeviceVolumeUpdate {
8967         final int mStreamType;
8968         final int mDevice;
8969         final @NonNull String mCaller;
8970         private static final int NO_NEW_INDEX = -2049;
8971         private final int mVssVolIndex;
8972 
8973         // Constructor with volume index, meant to cause this volume to be set and applied for the
8974         // given stream type on the given device
DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller)8975         DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller) {
8976             mStreamType = streamType;
8977             mVssVolIndex = vssVolIndex;
8978             mDevice = device;
8979             mCaller = caller;
8980         }
8981 
8982         // Constructor with no volume index, meant to cause re-apply of volume for the given
8983         // stream type on the given device
DeviceVolumeUpdate(int streamType, int device, @NonNull String caller)8984         DeviceVolumeUpdate(int streamType, int device, @NonNull String caller) {
8985             mStreamType = streamType;
8986             mVssVolIndex = NO_NEW_INDEX;
8987             mDevice = device;
8988             mCaller = caller;
8989         }
8990 
hasVolumeIndex()8991         boolean hasVolumeIndex() {
8992             return mVssVolIndex != NO_NEW_INDEX;
8993         }
8994 
getVolumeIndex()8995         int getVolumeIndex() throws IllegalStateException {
8996             Preconditions.checkState(mVssVolIndex != NO_NEW_INDEX);
8997             return mVssVolIndex;
8998         }
8999     }
9000 
9001     /** only public for mocking/spying, do not call outside of AudioService */
9002     @VisibleForTesting
postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device, String caller)9003     public void postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device,
9004                                                 String caller) {
9005         sendMsg(mAudioHandler,
9006                 MSG_SET_DEVICE_STREAM_VOLUME,
9007                 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/,
9008                 new DeviceVolumeUpdate(streamType, vssVolIndex, device, caller),
9009                 0 /*delay*/);
9010     }
9011 
postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller)9012     /*package*/ void postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller) {
9013         sendMsg(mAudioHandler,
9014                 MSG_SET_DEVICE_STREAM_VOLUME,
9015                 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/,
9016                 new DeviceVolumeUpdate(streamType, device, caller),
9017                 0 /*delay*/);
9018     }
9019 
onSetVolumeIndexOnDevice(@onNull DeviceVolumeUpdate update)9020     private void onSetVolumeIndexOnDevice(@NonNull DeviceVolumeUpdate update) {
9021         final VolumeStreamState streamState = mStreamStates[update.mStreamType];
9022         if (update.hasVolumeIndex()) {
9023             int index = update.getVolumeIndex();
9024             if (mSoundDoseHelper.checkSafeMediaVolume(update.mStreamType, index, update.mDevice)) {
9025                 index = mSoundDoseHelper.safeMediaVolumeIndex(update.mDevice);
9026             }
9027             streamState.setIndex(index, update.mDevice, update.mCaller,
9028                     // trusted as index is always validated before message is posted
9029                     true /*hasModifyAudioSettings*/);
9030             sVolumeLogger.enqueue(new EventLogger.StringEvent(update.mCaller + " dev:0x"
9031                     + Integer.toHexString(update.mDevice) + " volIdx:" + index));
9032         } else {
9033             sVolumeLogger.enqueue(new EventLogger.StringEvent(update.mCaller
9034                     + " update vol on dev:0x" + Integer.toHexString(update.mDevice)));
9035         }
9036         setDeviceVolume(streamState, update.mDevice);
9037     }
9038 
setDeviceVolume(VolumeStreamState streamState, int device)9039     /*package*/ void setDeviceVolume(VolumeStreamState streamState, int device) {
9040 
9041         synchronized (VolumeStreamState.class) {
9042             sendMsg(mAudioHandler, SoundDoseHelper.MSG_CSD_UPDATE_ATTENUATION, SENDMSG_REPLACE,
9043                     device, (isAbsoluteVolumeDevice(device) || isA2dpAbsoluteVolumeDevice(device)
9044                             || AudioSystem.isLeAudioDeviceType(device) ? 1 : 0),
9045                     streamState, /*delay=*/0);
9046             // Apply volume
9047             streamState.applyDeviceVolume_syncVSS(device);
9048 
9049             // Apply change to all streams using this one as alias
9050             int numStreamTypes = AudioSystem.getNumStreamTypes();
9051             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
9052                 if (streamType != streamState.mStreamType &&
9053                         mStreamVolumeAlias[streamType] == streamState.mStreamType) {
9054                     // Make sure volume is also maxed out on A2DP device for aliased stream
9055                     // that may have a different device selected
9056                     int streamDevice = getDeviceForStream(streamType);
9057                     if ((device != streamDevice)
9058                             && (isAbsoluteVolumeDevice(device)
9059                                 || isA2dpAbsoluteVolumeDevice(device)
9060                                 || AudioSystem.isLeAudioDeviceType(device))) {
9061                         mStreamStates[streamType].applyDeviceVolume_syncVSS(device);
9062                     }
9063                     mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice);
9064                 }
9065             }
9066         }
9067         // Post a persist volume msg
9068         sendMsg(mAudioHandler,
9069                 MSG_PERSIST_VOLUME,
9070                 SENDMSG_QUEUE,
9071                 device,
9072                 0,
9073                 streamState,
9074                 PERSIST_DELAY);
9075 
9076     }
9077 
9078     /** Handles internal volume messages in separate volume thread. */
9079     /*package*/ class AudioHandler extends Handler {
9080 
AudioHandler()9081         AudioHandler() {
9082             super();
9083         }
9084 
AudioHandler(Looper looper)9085         AudioHandler(Looper looper) {
9086             super(looper);
9087         }
9088 
setAllVolumes(VolumeStreamState streamState)9089         private void setAllVolumes(VolumeStreamState streamState) {
9090 
9091             // Apply volume
9092             streamState.applyAllVolumes();
9093 
9094             // Apply change to all streams using this one as alias
9095             int numStreamTypes = AudioSystem.getNumStreamTypes();
9096             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
9097                 if (streamType != streamState.mStreamType &&
9098                         mStreamVolumeAlias[streamType] == streamState.mStreamType) {
9099                     mStreamStates[streamType].applyAllVolumes();
9100                 }
9101             }
9102         }
9103 
persistVolume(VolumeStreamState streamState, int device)9104         private void persistVolume(VolumeStreamState streamState, int device) {
9105             if (mUseFixedVolume) {
9106                 return;
9107             }
9108             if (mIsSingleVolume && (streamState.mStreamType != AudioSystem.STREAM_MUSIC)) {
9109                 return;
9110             }
9111             if (streamState.hasValidSettingsName()) {
9112                 mSettings.putSystemIntForUser(mContentResolver,
9113                         streamState.getSettingNameForDevice(device),
9114                         (streamState.getIndex(device) + 5) / 10,
9115                         UserHandle.USER_CURRENT);
9116             }
9117         }
9118 
persistRingerMode(int ringerMode)9119         private void persistRingerMode(int ringerMode) {
9120             if (mUseFixedVolume) {
9121                 return;
9122             }
9123             mSettings.putGlobalInt(mContentResolver, Settings.Global.MODE_RINGER, ringerMode);
9124         }
9125 
onNotifyVolumeEvent(@onNull IAudioPolicyCallback apc, @AudioManager.VolumeAdjustment int direction)9126         private void onNotifyVolumeEvent(@NonNull IAudioPolicyCallback apc,
9127                 @AudioManager.VolumeAdjustment int direction) {
9128             try {
9129                 apc.notifyVolumeAdjust(direction);
9130             } catch(Exception e) {
9131                 // nothing we can do about this. Do not log error, too much potential for spam
9132             }
9133         }
9134 
9135         @Override
handleMessage(Message msg)9136         public void handleMessage(Message msg) {
9137             switch (msg.what) {
9138 
9139                 case MSG_SET_DEVICE_VOLUME:
9140                     setDeviceVolume((VolumeStreamState) msg.obj, msg.arg1);
9141                     break;
9142 
9143                 case MSG_SET_ALL_VOLUMES:
9144                     setAllVolumes((VolumeStreamState) msg.obj);
9145                     break;
9146 
9147                 case MSG_PERSIST_VOLUME:
9148                     persistVolume((VolumeStreamState) msg.obj, msg.arg1);
9149                     break;
9150 
9151                 case MSG_PERSIST_VOLUME_GROUP:
9152                     final VolumeGroupState vgs = (VolumeGroupState) msg.obj;
9153                     vgs.persistVolumeGroup(msg.arg1);
9154                     break;
9155 
9156                 case MSG_PERSIST_RINGER_MODE:
9157                     // note that the value persisted is the current ringer mode, not the
9158                     // value of ringer mode as of the time the request was made to persist
9159                     persistRingerMode(getRingerModeInternal());
9160                     break;
9161 
9162                 case MSG_AUDIO_SERVER_DIED:
9163                     onAudioServerDied();
9164                     break;
9165 
9166                 case MSG_DISPATCH_AUDIO_SERVER_STATE:
9167                     onDispatchAudioServerStateChange(msg.arg1 == 1);
9168                     break;
9169 
9170                 case MSG_UNLOAD_SOUND_EFFECTS:
9171                     mSfxHelper.unloadSoundEffects();
9172                     break;
9173 
9174                 case MSG_LOAD_SOUND_EFFECTS:
9175                 {
9176                     LoadSoundEffectReply reply = (LoadSoundEffectReply) msg.obj;
9177                     if (mSystemReady) {
9178                         mSfxHelper.loadSoundEffects(reply);
9179                     } else {
9180                         Log.w(TAG, "[schedule]loadSoundEffects() called before boot complete");
9181                         if (reply != null) {
9182                             reply.run(false);
9183                         }
9184                     }
9185                 }
9186                     break;
9187 
9188                 case MSG_PLAY_SOUND_EFFECT:
9189                     mSfxHelper.playSoundEffect(msg.arg1, msg.arg2);
9190                     break;
9191 
9192                 case MSG_SET_FORCE_USE:
9193                 {
9194                     final String eventSource = (String) msg.obj;
9195                     final int useCase = msg.arg1;
9196                     final int config = msg.arg2;
9197                     if (useCase == AudioSystem.FOR_MEDIA) {
9198                         Log.wtf(TAG, "Invalid force use FOR_MEDIA in AudioService from "
9199                                 + eventSource);
9200                         break;
9201                     }
9202                     new MediaMetrics.Item(MediaMetrics.Name.AUDIO_FORCE_USE
9203                             + MediaMetrics.SEPARATOR + AudioSystem.forceUseUsageToString(useCase))
9204                             .set(MediaMetrics.Property.EVENT, "setForceUse")
9205                             .set(MediaMetrics.Property.FORCE_USE_DUE_TO, eventSource)
9206                             .set(MediaMetrics.Property.FORCE_USE_MODE,
9207                                     AudioSystem.forceUseConfigToString(config))
9208                             .record();
9209                     sForceUseLogger.enqueue(
9210                             new AudioServiceEvents.ForceUseEvent(useCase, config, eventSource));
9211                     mAudioSystem.setForceUse(useCase, config);
9212                 }
9213                     break;
9214 
9215                 case MSG_DISABLE_AUDIO_FOR_UID:
9216                     mPlaybackMonitor.disableAudioForUid( msg.arg1 == 1 /* disable */,
9217                             msg.arg2 /* uid */);
9218                     mAudioEventWakeLock.release();
9219                     break;
9220 
9221                 case MSG_INIT_STREAMS_VOLUMES:
9222                     onInitStreamsAndVolumes();
9223                     mAudioEventWakeLock.release();
9224                     break;
9225 
9226                 case MSG_INIT_ADI_DEVICE_STATES:
9227                     onInitAdiDeviceStates();
9228                     mAudioEventWakeLock.release();
9229                     break;
9230 
9231                 case MSG_INIT_SPATIALIZER:
9232                     onInitSpatializer();
9233                     mAudioEventWakeLock.release();
9234                     break;
9235 
9236                 case MSG_INIT_HEADTRACKING_SENSORS:
9237                     mSpatializerHelper.onInitSensors();
9238                     break;
9239 
9240                 case MSG_RESET_SPATIALIZER:
9241                     mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect);
9242                     break;
9243 
9244                 case MSG_SYSTEM_READY:
9245                     onSystemReady();
9246                     break;
9247 
9248                 case MSG_INDICATE_SYSTEM_READY:
9249                     onIndicateSystemReady();
9250                     break;
9251 
9252                 case MSG_ACCESSORY_PLUG_MEDIA_UNMUTE:
9253                     onAccessoryPlugMediaUnmute(msg.arg1);
9254                     break;
9255 
9256                 case MSG_UNMUTE_STREAM:
9257                     onUnmuteStream(msg.arg1, msg.arg2);
9258                     break;
9259 
9260                 case MSG_DYN_POLICY_MIX_STATE_UPDATE:
9261                     onDynPolicyMixStateUpdate((String) msg.obj, msg.arg1);
9262                     break;
9263 
9264                 case MSG_NOTIFY_VOL_EVENT:
9265                     onNotifyVolumeEvent((IAudioPolicyCallback) msg.obj, msg.arg1);
9266                     break;
9267 
9268                 case MSG_ENABLE_SURROUND_FORMATS:
9269                     onEnableSurroundFormats((ArrayList<Integer>) msg.obj);
9270                     break;
9271 
9272                 case MSG_UPDATE_RINGER_MODE:
9273                     onUpdateRingerModeServiceInt();
9274                     break;
9275 
9276                 case MSG_SET_DEVICE_STREAM_VOLUME:
9277                     onSetVolumeIndexOnDevice((DeviceVolumeUpdate) msg.obj);
9278                     break;
9279 
9280                 case MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS:
9281                     onObserveDevicesForAllStreams(/*skipStream*/ msg.arg1);
9282                     break;
9283 
9284                 case MSG_HDMI_VOLUME_CHECK:
9285                     onCheckVolumeCecOnHdmiConnection(msg.arg1, (String) msg.obj);
9286                     break;
9287 
9288                 case MSG_PLAYBACK_CONFIG_CHANGE:
9289                     onPlaybackConfigChange((List<AudioPlaybackConfiguration>) msg.obj);
9290                     break;
9291                 case MSG_RECORDING_CONFIG_CHANGE:
9292                     onRecordingConfigChange((List<AudioRecordingConfiguration>) msg.obj);
9293                     break;
9294 
9295                 case MSG_BROADCAST_MICROPHONE_MUTE:
9296                     mSystemServer.sendMicrophoneMuteChangedIntent();
9297                     break;
9298 
9299                 case MSG_CHECK_MODE_FOR_UID:
9300                     synchronized (mDeviceBroker.mSetModeLock) {
9301                         if (msg.obj == null) {
9302                             break;
9303                         }
9304                         // Update active playback/recording for apps requesting IN_COMMUNICATION
9305                         // mode after a grace period following the mode change
9306                         SetModeDeathHandler h = (SetModeDeathHandler) msg.obj;
9307                         if (mSetModeDeathHandlers.indexOf(h) < 0) {
9308                             break;
9309                         }
9310                         boolean wasActive = h.isActive();
9311                         h.setPlaybackActive(isPlaybackActiveForUid(h.getUid()));
9312                         h.setRecordingActive(isRecordingActiveForUid(h.getUid()));
9313                         if (wasActive != h.isActive()) {
9314                             onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(),
9315                                     mContext.getPackageName(), false /*force*/);
9316                         }
9317                     }
9318                     break;
9319 
9320                 case MSG_STREAM_DEVICES_CHANGED:
9321                     final SomeArgs args = (SomeArgs) msg.obj;
9322                     final Intent intent = (Intent) args.arg1;
9323                     final Bundle options = (Bundle) args.arg2;
9324                     args.recycle();
9325                     sendBroadcastToAll(intent
9326                             .putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_DEVICES, msg.arg1)
9327                             .putExtra(AudioManager.EXTRA_VOLUME_STREAM_DEVICES, msg.arg2),
9328                             options);
9329                     break;
9330 
9331                 case MSG_UPDATE_VOLUME_STATES_FOR_DEVICE:
9332                     onUpdateVolumeStatesForAudioDevice(msg.arg1, (String) msg.obj);
9333                     break;
9334 
9335                 case MSG_REINIT_VOLUMES:
9336                     onReinitVolumes((String) msg.obj);
9337                     break;
9338 
9339                 case MSG_UPDATE_A11Y_SERVICE_UIDS:
9340                     onUpdateAccessibilityServiceUids();
9341                     break;
9342 
9343                 case MSG_UPDATE_AUDIO_MODE:
9344                     synchronized (mDeviceBroker.mSetModeLock) {
9345                         onUpdateAudioMode(msg.arg1, msg.arg2, (String) msg.obj, false /*force*/);
9346                     }
9347                     break;
9348 
9349                 case MSG_BT_DEV_CHANGED:
9350                     mDeviceBroker.queueOnBluetoothActiveDeviceChanged(
9351                             (AudioDeviceBroker.BtDeviceChangedData) msg.obj);
9352                     break;
9353 
9354                 case MSG_DISPATCH_AUDIO_MODE:
9355                     dispatchMode(msg.arg1);
9356                     break;
9357 
9358                 case MSG_ROUTING_UPDATED:
9359                     onRoutingUpdatedFromAudioThread();
9360                     break;
9361 
9362                 case MSG_ADD_ASSISTANT_SERVICE_UID:
9363                     onAddAssistantServiceUids(new int[]{msg.arg1});
9364                     break;
9365 
9366                 case MSG_REMOVE_ASSISTANT_SERVICE_UID:
9367                     onRemoveAssistantServiceUids(new int[]{msg.arg1});
9368                     break;
9369                 case MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID:
9370                     updateActiveAssistantServiceUids();
9371                     break;
9372 
9373                 case MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR:
9374                     dispatchDeviceVolumeBehavior((AudioDeviceAttributes) msg.obj, msg.arg1);
9375                     break;
9376 
9377                 case MSG_ROTATION_UPDATE:
9378                     // rotation parameter format: "rotation=x" where x is one of 0, 90, 180, 270
9379                     mAudioSystem.setParameters((String) msg.obj);
9380                     break;
9381 
9382                 case MSG_FOLD_UPDATE:
9383                     // fold parameter format: "device_folded=x" where x is one of on, off
9384                     mAudioSystem.setParameters((String) msg.obj);
9385                     break;
9386 
9387                 case MSG_NO_LOG_FOR_PLAYER_I:
9388                     mPlaybackMonitor.ignorePlayerIId(msg.arg1);
9389                     break;
9390 
9391                 case MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES:
9392                     onDispatchPreferredMixerAttributesChanged(msg.getData(), msg.arg1);
9393                     break;
9394 
9395                 case MSG_LOWER_VOLUME_TO_RS1:
9396                     onLowerVolumeToRs1();
9397                     break;
9398 
9399                 case MSG_CONFIGURATION_CHANGED:
9400                     onConfigurationChanged();
9401                     break;
9402 
9403                 default:
9404                     if (msg.what >= SAFE_MEDIA_VOLUME_MSG_START) {
9405                         // msg could be for the SoundDoseHelper
9406                         mSoundDoseHelper.handleMessage(msg);
9407                     }
9408             }
9409         }
9410     }
9411 
9412     private class SettingsObserver extends ContentObserver {
9413 
SettingsObserver()9414         SettingsObserver() {
9415             super(new Handler());
9416             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
9417                     Settings.Global.ZEN_MODE), false, this);
9418             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
9419                     Settings.Global.ZEN_MODE_CONFIG_ETAG), false, this);
9420             mContentResolver.registerContentObserver(Settings.System.getUriFor(
9421                 Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this);
9422             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
9423                 Settings.Global.DOCK_AUDIO_MEDIA_ENABLED), false, this);
9424             mContentResolver.registerContentObserver(Settings.System.getUriFor(
9425                     Settings.System.MASTER_MONO), false, this);
9426             mContentResolver.registerContentObserver(Settings.System.getUriFor(
9427                     Settings.System.MASTER_BALANCE), false, this);
9428 
9429             mEncodedSurroundMode = mSettings.getGlobalInt(
9430                     mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT,
9431                     Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
9432             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
9433                     Settings.Global.ENCODED_SURROUND_OUTPUT), false, this);
9434             mEnabledSurroundFormats = mSettings.getGlobalString(
9435                     mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
9436             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
9437                     Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS), false, this);
9438 
9439             mContentResolver.registerContentObserver(Settings.Secure.getUriFor(
9440                     Settings.Secure.VOICE_INTERACTION_SERVICE), false, this);
9441         }
9442 
9443         @Override
onChange(boolean selfChange)9444         public void onChange(boolean selfChange) {
9445             super.onChange(selfChange);
9446             // FIXME This synchronized is not necessary if mSettingsLock only protects mRingerMode.
9447             //       However there appear to be some missing locks around sRingerAndZenModeMutedStreams
9448             //       and mRingerModeAffectedStreams, so will leave this synchronized for now.
9449             //       sRingerAndZenModeMutedStreams and mMuteAffectedStreams are safe (only accessed once).
9450             synchronized (mSettingsLock) {
9451                 if (updateRingerAndZenModeAffectedStreams()) {
9452                     /*
9453                      * Ensure all stream types that should be affected by ringer mode
9454                      * are in the proper state.
9455                      */
9456                     setRingerModeInt(getRingerModeInternal(), false);
9457                 }
9458                 readDockAudioSettings(mContentResolver);
9459                 updateMasterMono(mContentResolver);
9460                 updateMasterBalance(mContentResolver);
9461                 updateEncodedSurroundOutput();
9462                 sendEnabledSurroundFormats(mContentResolver, mSurroundModeChanged);
9463                 updateAssistantUIdLocked(/* forceUpdate= */ false);
9464             }
9465         }
9466 
updateEncodedSurroundOutput()9467         private void updateEncodedSurroundOutput() {
9468             int newSurroundMode = mSettings.getGlobalInt(
9469                 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT,
9470                 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
9471             // Did it change?
9472             if (mEncodedSurroundMode != newSurroundMode) {
9473                 // Send to AudioPolicyManager
9474                 sendEncodedSurroundMode(newSurroundMode, "SettingsObserver");
9475                 mDeviceBroker.toggleHdmiIfConnected_Async();
9476                 mEncodedSurroundMode = newSurroundMode;
9477                 mSurroundModeChanged = true;
9478             } else {
9479                 mSurroundModeChanged = false;
9480             }
9481         }
9482     }
9483 
avrcpSupportsAbsoluteVolume(String address, boolean support)9484     private void avrcpSupportsAbsoluteVolume(String address, boolean support) {
9485         // address is not used for now, but may be used when multiple a2dp devices are supported
9486         sVolumeLogger.enqueue(new EventLogger.StringEvent("avrcpSupportsAbsoluteVolume addr="
9487                 + address + " support=" + support).printLog(TAG));
9488         mDeviceBroker.setAvrcpAbsoluteVolumeSupported(support);
9489         setAvrcpAbsoluteVolumeSupported(support);
9490     }
9491 
setAvrcpAbsoluteVolumeSupported(boolean support)9492     /*package*/ void setAvrcpAbsoluteVolumeSupported(boolean support) {
9493         mAvrcpAbsVolSupported = support;
9494         sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE,
9495                     AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0,
9496                     mStreamStates[AudioSystem.STREAM_MUSIC], 0);
9497     }
9498 
9499     /**
9500      * @return true if there is currently a registered dynamic mixing policy that affects media
9501      * and is not a render + loopback policy
9502      */
9503     // only public for mocking/spying
9504     @VisibleForTesting
hasMediaDynamicPolicy()9505     public boolean hasMediaDynamicPolicy() {
9506         synchronized (mAudioPolicies) {
9507             if (mAudioPolicies.isEmpty()) {
9508                 return false;
9509             }
9510             final Collection<AudioPolicyProxy> appColl = mAudioPolicies.values();
9511             for (AudioPolicyProxy app : appColl) {
9512                 if (app.hasMixAffectingUsage(AudioAttributes.USAGE_MEDIA,
9513                         AudioMix.ROUTE_FLAG_LOOP_BACK_RENDER)) {
9514                     return true;
9515                 }
9516             }
9517             return false;
9518         }
9519     }
9520 
9521     /** only public for mocking/spying, do not call outside of AudioService */
9522     @VisibleForTesting
checkMusicActive(int deviceType, String caller)9523     public void checkMusicActive(int deviceType, String caller) {
9524         if (mSoundDoseHelper.safeDevicesContains(deviceType)) {
9525             mSoundDoseHelper.scheduleMusicActiveCheck();
9526         }
9527     }
9528 
9529     /**
9530      * Receiver for misc intent broadcasts the Phone app cares about.
9531      */
9532     private class AudioServiceBroadcastReceiver extends BroadcastReceiver {
9533         @Override
onReceive(Context context, Intent intent)9534         public void onReceive(Context context, Intent intent) {
9535             final String action = intent.getAction();
9536             int outDevice;
9537             int inDevice;
9538             int state;
9539 
9540             if (action.equals(Intent.ACTION_DOCK_EVENT)) {
9541                 int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
9542                         Intent.EXTRA_DOCK_STATE_UNDOCKED);
9543                 int config;
9544                 switch (dockState) {
9545                     case Intent.EXTRA_DOCK_STATE_DESK:
9546                         config = AudioSystem.FORCE_BT_DESK_DOCK;
9547                         break;
9548                     case Intent.EXTRA_DOCK_STATE_CAR:
9549                         config = AudioSystem.FORCE_BT_CAR_DOCK;
9550                         break;
9551                     case Intent.EXTRA_DOCK_STATE_LE_DESK:
9552                         config = AudioSystem.FORCE_ANALOG_DOCK;
9553                         break;
9554                     case Intent.EXTRA_DOCK_STATE_HE_DESK:
9555                         config = AudioSystem.FORCE_DIGITAL_DOCK;
9556                         break;
9557                     case Intent.EXTRA_DOCK_STATE_UNDOCKED:
9558                     default:
9559                         config = AudioSystem.FORCE_NONE;
9560                 }
9561                 // Low end docks have a menu to enable or disable audio
9562                 // (see mDockAudioMediaEnabled)
9563                 if (!((dockState == Intent.EXTRA_DOCK_STATE_LE_DESK)
9564                         || ((dockState == Intent.EXTRA_DOCK_STATE_UNDOCKED)
9565                                 && (mDockState == Intent.EXTRA_DOCK_STATE_LE_DESK)))) {
9566                     mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, config,
9567                             "ACTION_DOCK_EVENT intent");
9568                 }
9569                 mDockState = dockState;
9570             } else if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED)
9571                     || action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
9572                 mDeviceBroker.postReceiveBtEvent(intent);
9573             } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
9574                 if (mMonitorRotation) {
9575                     RotationHelper.enable();
9576                 }
9577                 AudioSystem.setParameters("screen_state=on");
9578             } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
9579                 if (mMonitorRotation) {
9580                     //reduce wakeups (save current) by only listening when display is on
9581                     RotationHelper.disable();
9582                 }
9583                 AudioSystem.setParameters("screen_state=off");
9584             } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
9585                 sendMsg(mAudioHandler,
9586                         MSG_CONFIGURATION_CHANGED,
9587                         SENDMSG_REPLACE,
9588                         0,
9589                         0,
9590                         null, 0);
9591             } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
9592                 if (mUserSwitchedReceived) {
9593                     // attempt to stop music playback for background user except on first user
9594                     // switch (i.e. first boot)
9595                     mDeviceBroker.postBroadcastBecomingNoisy();
9596                 }
9597                 mUserSwitchedReceived = true;
9598                 // the current audio focus owner is no longer valid
9599                 mMediaFocusControl.discardAudioFocusOwner();
9600 
9601                 if (mSupportsMicPrivacyToggle) {
9602                     mMicMuteFromPrivacyToggle = mSensorPrivacyManagerInternal
9603                             .isSensorPrivacyEnabled(getCurrentUserId(),
9604                                     SensorPrivacyManager.Sensors.MICROPHONE);
9605                     setMicrophoneMuteNoCallerCheck(getCurrentUserId());
9606                 }
9607 
9608                 // load volume settings for new user
9609                 readAudioSettings(true /*userSwitch*/);
9610                 // preserve STREAM_MUSIC volume from one user to the next.
9611                 sendMsg(mAudioHandler,
9612                         MSG_SET_ALL_VOLUMES,
9613                         SENDMSG_QUEUE,
9614                         0,
9615                         0,
9616                         mStreamStates[AudioSystem.STREAM_MUSIC], 0);
9617             } else if (action.equals(Intent.ACTION_USER_BACKGROUND)) {
9618                 // Disable audio recording for the background user/profile
9619                 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
9620                 if (userId >= 0) {
9621                     // TODO Kill recording streams instead of killing processes holding permission
9622                     UserInfo userInfo = UserManagerService.getInstance().getUserInfo(userId);
9623                     killBackgroundUserProcessesWithRecordAudioPermission(userInfo);
9624                 }
9625                 try {
9626                     UserManagerService.getInstance().setUserRestriction(
9627                             UserManager.DISALLOW_RECORD_AUDIO, true, userId);
9628                 } catch (IllegalArgumentException e) {
9629                     Slog.w(TAG, "Failed to apply DISALLOW_RECORD_AUDIO restriction: " + e);
9630                 }
9631             } else if (action.equals(Intent.ACTION_USER_FOREGROUND)) {
9632                 // Enable audio recording for foreground user/profile
9633                 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
9634                 try {
9635                     UserManagerService.getInstance().setUserRestriction(
9636                             UserManager.DISALLOW_RECORD_AUDIO, false, userId);
9637                 } catch (IllegalArgumentException e) {
9638                     Slog.w(TAG, "Failed to apply DISALLOW_RECORD_AUDIO restriction: " + e);
9639                 }
9640             } else if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION) ||
9641                     action.equals(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION)) {
9642                 handleAudioEffectBroadcast(context, intent);
9643             } else if (action.equals(Intent.ACTION_PACKAGES_SUSPENDED)) {
9644                 final int[] suspendedUids = intent.getIntArrayExtra(Intent.EXTRA_CHANGED_UID_LIST);
9645                 final String[] suspendedPackages =
9646                         intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
9647                 if (suspendedPackages == null || suspendedUids == null
9648                         || suspendedPackages.length != suspendedUids.length) {
9649                     return;
9650                 }
9651                 for (int i = 0; i < suspendedUids.length; i++) {
9652                     if (!TextUtils.isEmpty(suspendedPackages[i])) {
9653                         mMediaFocusControl.noFocusForSuspendedApp(
9654                                 suspendedPackages[i], suspendedUids[i]);
9655                     }
9656                 }
9657             } else if (action.equals(ACTION_CHECK_MUSIC_ACTIVE)) {
9658                 mSoundDoseHelper.onCheckMusicActive(ACTION_CHECK_MUSIC_ACTIVE,
9659                         mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0));
9660             }
9661         }
9662     } // end class AudioServiceBroadcastReceiver
9663 
9664     private class AudioServiceUserRestrictionsListener implements UserRestrictionsListener {
9665 
9666         @Override
onUserRestrictionsChanged(int userId, Bundle newRestrictions, Bundle prevRestrictions)9667         public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
9668                 Bundle prevRestrictions) {
9669             // Update mic mute state.
9670             {
9671                 final boolean wasRestricted =
9672                         prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE);
9673                 final boolean isRestricted =
9674                         newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE);
9675                 if (wasRestricted != isRestricted) {
9676                     mMicMuteFromRestrictions = isRestricted;
9677                     setMicrophoneMuteNoCallerCheck(userId);
9678                 }
9679             }
9680 
9681             // Update speaker mute state.
9682             {
9683                 final boolean wasRestricted =
9684                         prevRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME)
9685                                 || prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE);
9686                 final boolean isRestricted =
9687                         newRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME)
9688                                 || newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE);
9689                 if (wasRestricted != isRestricted) {
9690                     setMasterMuteInternalNoCallerCheck(isRestricted, /* flags =*/ 0, userId);
9691                 }
9692             }
9693         }
9694     } // end class AudioServiceUserRestrictionsListener
9695 
handleAudioEffectBroadcast(Context context, Intent intent)9696     private void handleAudioEffectBroadcast(Context context, Intent intent) {
9697         String target = intent.getPackage();
9698         if (target != null) {
9699             Log.w(TAG, "effect broadcast already targeted to " + target);
9700             return;
9701         }
9702         intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
9703         // TODO this should target a user-selected panel
9704         List<ResolveInfo> ril = context.getPackageManager().queryBroadcastReceivers(
9705                 intent, 0 /* flags */);
9706         if (ril != null && ril.size() != 0) {
9707             ResolveInfo ri = ril.get(0);
9708             if (ri != null && ri.activityInfo != null && ri.activityInfo.packageName != null) {
9709                 intent.setPackage(ri.activityInfo.packageName);
9710                 context.sendBroadcastAsUser(intent, UserHandle.ALL);
9711                 return;
9712             }
9713         }
9714         Log.w(TAG, "couldn't find receiver package for effect intent");
9715     }
9716 
killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser)9717     private void killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser) {
9718         PackageManager pm = mContext.getPackageManager();
9719         // Find the home activity of the user. It should not be killed to avoid expensive restart,
9720         // when the user switches back. For managed profiles, we should kill all recording apps
9721         ComponentName homeActivityName = null;
9722         if (!oldUser.isManagedProfile()) {
9723             homeActivityName = LocalServices.getService(
9724                     ActivityTaskManagerInternal.class).getHomeActivityForUser(oldUser.id);
9725         }
9726         final String[] permissions = { Manifest.permission.RECORD_AUDIO };
9727         List<PackageInfo> packages;
9728         try {
9729             packages = AppGlobals.getPackageManager()
9730                     .getPackagesHoldingPermissions(permissions, 0, oldUser.id).getList();
9731         } catch (RemoteException e) {
9732             throw new AndroidRuntimeException(e);
9733         }
9734         for (int j = packages.size() - 1; j >= 0; j--) {
9735             PackageInfo pkg = packages.get(j);
9736             // Skip system processes
9737             if (UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID) {
9738                 continue;
9739             }
9740             // Skip packages that have permission to interact across users
9741             if (pm.checkPermission(Manifest.permission.INTERACT_ACROSS_USERS, pkg.packageName)
9742                     == PackageManager.PERMISSION_GRANTED) {
9743                 continue;
9744             }
9745             if (homeActivityName != null
9746                     && pkg.packageName.equals(homeActivityName.getPackageName())
9747                     && pkg.applicationInfo.isSystemApp()) {
9748                 continue;
9749             }
9750             try {
9751                 final int uid = pkg.applicationInfo.uid;
9752                 ActivityManager.getService().killUid(UserHandle.getAppId(uid),
9753                         UserHandle.getUserId(uid),
9754                         "killBackgroundUserProcessesWithAudioRecordPermission");
9755             } catch (RemoteException e) {
9756                 Log.w(TAG, "Error calling killUid", e);
9757             }
9758         }
9759     }
9760 
9761 
9762     //==========================================================================================
9763     // Audio Focus
9764     //==========================================================================================
9765     /**
9766      * Returns whether a focus request is eligible to force ducking.
9767      * Will return true if:
9768      * - the AudioAttributes have a usage of USAGE_ASSISTANCE_ACCESSIBILITY,
9769      * - the focus request is AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK,
9770      * - the associated Bundle has KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING set to true,
9771      * - the uid of the requester is a known accessibility service or root.
9772      * @param aa AudioAttributes of the focus request
9773      * @param uid uid of the focus requester
9774      * @return true if ducking is to be forced
9775      */
forceFocusDuckingForAccessibility(@ullable AudioAttributes aa, int request, int uid)9776     private boolean forceFocusDuckingForAccessibility(@Nullable AudioAttributes aa,
9777             int request, int uid) {
9778         if (aa == null || aa.getUsage() != AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY
9779                 || request != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) {
9780             return false;
9781         }
9782         final Bundle extraInfo = aa.getBundle();
9783         if (extraInfo == null ||
9784                 !extraInfo.getBoolean(AudioFocusRequest.KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING)) {
9785             return false;
9786         }
9787         if (uid == 0) {
9788             return true;
9789         }
9790         synchronized (mAccessibilityServiceUidsLock) {
9791             if (mAccessibilityServiceUids != null) {
9792                 int callingUid = Binder.getCallingUid();
9793                 for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
9794                     if (mAccessibilityServiceUids[i] == callingUid) {
9795                         return true;
9796                     }
9797                 }
9798             }
9799         }
9800         return false;
9801     }
9802 
isSupportedSystemUsage(@udioAttributes.AttributeUsage int usage)9803     private boolean isSupportedSystemUsage(@AudioAttributes.AttributeUsage int usage) {
9804         synchronized (mSupportedSystemUsagesLock) {
9805             for (int i = 0; i < mSupportedSystemUsages.length; i++) {
9806                 if (mSupportedSystemUsages[i] == usage) {
9807                     return true;
9808                 }
9809             }
9810             return false;
9811         }
9812     }
9813 
validateAudioAttributesUsage(@onNull AudioAttributes audioAttributes)9814     private void validateAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) {
9815         @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage();
9816         if (AudioAttributes.isSystemUsage(usage)) {
9817             if ((usage == AudioAttributes.USAGE_CALL_ASSISTANT
9818                     && (audioAttributes.getAllFlags() & AudioAttributes.FLAG_CALL_REDIRECTION) != 0
9819                     && callerHasPermission(Manifest.permission.CALL_AUDIO_INTERCEPTION))
9820                     || callerHasPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)) {
9821                 if (!isSupportedSystemUsage(usage)) {
9822                     throw new IllegalArgumentException(
9823                             "Unsupported usage " + AudioAttributes.usageToString(usage));
9824                 }
9825             } else {
9826                 throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission");
9827             }
9828         }
9829     }
9830 
isValidAudioAttributesUsage(@onNull AudioAttributes audioAttributes)9831     private boolean isValidAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) {
9832         @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage();
9833         if (AudioAttributes.isSystemUsage(usage)) {
9834             return isSupportedSystemUsage(usage)
9835                     && ((usage == AudioAttributes.USAGE_CALL_ASSISTANT
9836                         && (audioAttributes.getAllFlags()
9837                             & AudioAttributes.FLAG_CALL_REDIRECTION) != 0
9838                         && callerHasPermission(Manifest.permission.CALL_AUDIO_INTERCEPTION))
9839                         || callerHasPermission(Manifest.permission.MODIFY_AUDIO_ROUTING));
9840         }
9841         return true;
9842     }
9843 
requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb, IAudioFocusDispatcher fd, String clientId, String callingPackageName, String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk)9844     public int requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb,
9845             IAudioFocusDispatcher fd, String clientId, String callingPackageName,
9846             String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk) {
9847         if ((flags & AudioManager.AUDIOFOCUS_FLAG_TEST) != 0) {
9848             throw new IllegalArgumentException("Invalid test flag");
9849         }
9850         final int uid = Binder.getCallingUid();
9851         MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus")
9852                 .setUid(uid)
9853                 //.putInt("durationHint", durationHint)
9854                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName)
9855                 .set(MediaMetrics.Property.CLIENT_NAME, clientId)
9856                 .set(MediaMetrics.Property.EVENT, "requestAudioFocus")
9857                 .set(MediaMetrics.Property.FLAGS, flags);
9858 
9859         // permission checks
9860         if (aa != null && !isValidAudioAttributesUsage(aa)) {
9861             final String reason = "Request using unsupported usage";
9862             Log.w(TAG, reason);
9863             mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
9864                     .record();
9865             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9866         }
9867         if ((flags & AudioManager.AUDIOFOCUS_FLAG_LOCK) == AudioManager.AUDIOFOCUS_FLAG_LOCK) {
9868             if (AudioSystem.IN_VOICE_COMM_FOCUS_ID.equals(clientId)) {
9869                 if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
9870                             android.Manifest.permission.MODIFY_PHONE_STATE)) {
9871                     final String reason = "Invalid permission to (un)lock audio focus";
9872                     Log.e(TAG, reason, new Exception());
9873                     mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
9874                             .record();
9875                     return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9876                 }
9877             } else {
9878                 // only a registered audio policy can be used to lock focus
9879                 synchronized (mAudioPolicies) {
9880                     if (!mAudioPolicies.containsKey(pcb.asBinder())) {
9881                         final String reason =
9882                                 "Invalid unregistered AudioPolicy to (un)lock audio focus";
9883                         Log.e(TAG, reason);
9884                         mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
9885                                 .record();
9886                         return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9887                     }
9888                 }
9889             }
9890         }
9891 
9892         if (callingPackageName == null || clientId == null || aa == null) {
9893             final String reason = "Invalid null parameter to request audio focus";
9894             Log.e(TAG, reason);
9895             mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
9896                     .record();
9897             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9898         }
9899         mmi.record();
9900         return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd,
9901                 clientId, callingPackageName, attributionTag, flags, sdk,
9902                 forceFocusDuckingForAccessibility(aa, durationHint, uid), -1 /*testUid, ignored*/);
9903     }
9904 
9905     /** see {@link AudioManager#requestAudioFocusForTest(AudioFocusRequest, String, int, int)} */
requestAudioFocusForTest(AudioAttributes aa, int durationHint, IBinder cb, IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags, int fakeUid, int sdk)9906     public int requestAudioFocusForTest(AudioAttributes aa, int durationHint, IBinder cb,
9907             IAudioFocusDispatcher fd, String clientId, String callingPackageName,
9908             int flags, int fakeUid, int sdk) {
9909         if (!enforceQueryAudioStateForTest("focus request")) {
9910             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9911         }
9912         if (callingPackageName == null || clientId == null || aa == null) {
9913             final String reason = "Invalid null parameter to request audio focus";
9914             Log.e(TAG, reason);
9915             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9916         }
9917         return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd,
9918                 clientId, callingPackageName, null, flags,
9919                 sdk, false /*forceDuck*/, fakeUid);
9920     }
9921 
abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)9922     public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa,
9923             String callingPackageName) {
9924         MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus")
9925                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName)
9926                 .set(MediaMetrics.Property.CLIENT_NAME, clientId)
9927                 .set(MediaMetrics.Property.EVENT, "abandonAudioFocus");
9928 
9929         if (aa != null && !isValidAudioAttributesUsage(aa)) {
9930             Log.w(TAG, "Request using unsupported usage.");
9931             mmi.set(MediaMetrics.Property.EARLY_RETURN, "unsupported usage").record();
9932 
9933             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9934         }
9935         mmi.record();
9936         return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName);
9937     }
9938 
9939     /** see {@link AudioManager#abandonAudioFocusForTest(AudioFocusRequest, String)} */
abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)9940     public int abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId,
9941             AudioAttributes aa, String callingPackageName) {
9942         if (!enforceQueryAudioStateForTest("focus abandon")) {
9943             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9944         }
9945         return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName);
9946     }
9947 
unregisterAudioFocusClient(String clientId)9948     public void unregisterAudioFocusClient(String clientId) {
9949         new MediaMetrics.Item(mMetricsId + "focus")
9950                 .set(MediaMetrics.Property.CLIENT_NAME, clientId)
9951                 .set(MediaMetrics.Property.EVENT, "unregisterAudioFocusClient")
9952                 .record();
9953         mMediaFocusControl.unregisterAudioFocusClient(clientId);
9954     }
9955 
getCurrentAudioFocus()9956     public int getCurrentAudioFocus() {
9957         return mMediaFocusControl.getCurrentAudioFocus();
9958     }
9959 
getFocusRampTimeMs(int focusGain, AudioAttributes attr)9960     public int getFocusRampTimeMs(int focusGain, AudioAttributes attr) {
9961         return mMediaFocusControl.getFocusRampTimeMs(focusGain, attr);
9962     }
9963 
9964     /** only public for mocking/spying, do not call outside of AudioService */
9965     @VisibleForTesting
hasAudioFocusUsers()9966     public boolean hasAudioFocusUsers() {
9967         return mMediaFocusControl.hasAudioFocusUsers();
9968     }
9969 
9970     /** see {@link AudioManager#getFadeOutDurationOnFocusLossMillis(AudioAttributes)} */
getFadeOutDurationOnFocusLossMillis(AudioAttributes aa)9971     public long getFadeOutDurationOnFocusLossMillis(AudioAttributes aa) {
9972         if (!enforceQueryAudioStateForTest("fade out duration")) {
9973             return 0;
9974         }
9975         return mMediaFocusControl.getFadeOutDurationOnFocusLossMillis(aa);
9976     }
9977 
enforceQueryAudioStateForTest(String mssg)9978     private boolean enforceQueryAudioStateForTest(String mssg) {
9979         if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
9980                 Manifest.permission.QUERY_AUDIO_STATE)) {
9981             final String reason = "Doesn't have QUERY_AUDIO_STATE permission for "
9982                     + mssg + " test API";
9983             Log.e(TAG, reason, new Exception());
9984             return false;
9985         }
9986         return true;
9987     }
9988 
9989     //==========================================================================================
9990     private final @NonNull SpatializerHelper mSpatializerHelper;
9991     /**
9992      * Initialized from property ro.audio.spatializer_enabled
9993      * Should only be 1 when the device ships with a Spatializer effect
9994      */
9995     private final boolean mHasSpatializerEffect;
9996     /**
9997      * Default value for the spatial audio feature
9998      */
9999     private static final boolean SPATIAL_AUDIO_ENABLED_DEFAULT = true;
10000 
enforceModifyDefaultAudioEffectsPermission()10001     private void enforceModifyDefaultAudioEffectsPermission() {
10002         if (mContext.checkCallingOrSelfPermission(
10003                 android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10004                 != PackageManager.PERMISSION_GRANTED) {
10005             throw new SecurityException("Missing MODIFY_DEFAULT_AUDIO_EFFECTS permission");
10006         }
10007     }
10008 
10009     /**
10010      * Returns the immersive audio level that the platform is capable of
10011      * @see Spatializer#getImmersiveAudioLevel()
10012      */
getSpatializerImmersiveAudioLevel()10013     public int getSpatializerImmersiveAudioLevel() {
10014         return mSpatializerHelper.getCapableImmersiveAudioLevel();
10015     }
10016 
10017     /** @see Spatializer#isEnabled() */
isSpatializerEnabled()10018     public boolean isSpatializerEnabled() {
10019         return mSpatializerHelper.isEnabled();
10020     }
10021 
10022     /** @see Spatializer#isAvailable() */
isSpatializerAvailable()10023     public boolean isSpatializerAvailable() {
10024         return mSpatializerHelper.isAvailable();
10025     }
10026 
10027     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10028     /** @see Spatializer#isAvailableForDevice(AudioDeviceAttributes) */
isSpatializerAvailableForDevice(@onNull AudioDeviceAttributes device)10029     public boolean isSpatializerAvailableForDevice(@NonNull AudioDeviceAttributes device)  {
10030         super.isSpatializerAvailableForDevice_enforcePermission();
10031 
10032         return mSpatializerHelper.isAvailableForDevice(Objects.requireNonNull(device));
10033     }
10034 
10035     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10036     /** @see Spatializer#hasHeadTracker(AudioDeviceAttributes) */
hasHeadTracker(@onNull AudioDeviceAttributes device)10037     public boolean hasHeadTracker(@NonNull AudioDeviceAttributes device) {
10038         super.hasHeadTracker_enforcePermission();
10039 
10040         return mSpatializerHelper.hasHeadTracker(Objects.requireNonNull(device));
10041     }
10042 
10043     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10044     /** @see Spatializer#setHeadTrackerEnabled(boolean, AudioDeviceAttributes) */
setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device)10045     public void setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device) {
10046         super.setHeadTrackerEnabled_enforcePermission();
10047 
10048         mSpatializerHelper.setHeadTrackerEnabled(enabled, Objects.requireNonNull(device));
10049     }
10050 
10051     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10052     /** @see Spatializer#isHeadTrackerEnabled(AudioDeviceAttributes) */
isHeadTrackerEnabled(@onNull AudioDeviceAttributes device)10053     public boolean isHeadTrackerEnabled(@NonNull AudioDeviceAttributes device) {
10054         super.isHeadTrackerEnabled_enforcePermission();
10055 
10056         return mSpatializerHelper.isHeadTrackerEnabled(Objects.requireNonNull(device));
10057     }
10058 
10059     /** @see Spatializer#isHeadTrackerAvailable() */
isHeadTrackerAvailable()10060     public boolean isHeadTrackerAvailable() {
10061         return mSpatializerHelper.isHeadTrackerAvailable();
10062     }
10063 
10064     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10065     /** @see Spatializer#setSpatializerEnabled(boolean) */
setSpatializerEnabled(boolean enabled)10066     public void setSpatializerEnabled(boolean enabled) {
10067         super.setSpatializerEnabled_enforcePermission();
10068 
10069         mSpatializerHelper.setFeatureEnabled(enabled);
10070     }
10071 
10072     /** @see Spatializer#canBeSpatialized() */
canBeSpatialized( @onNull AudioAttributes attributes, @NonNull AudioFormat format)10073     public boolean canBeSpatialized(
10074             @NonNull AudioAttributes attributes, @NonNull AudioFormat format) {
10075         Objects.requireNonNull(attributes);
10076         Objects.requireNonNull(format);
10077         return mSpatializerHelper.canBeSpatialized(attributes, format);
10078     }
10079 
10080     /** @see Spatializer.SpatializerInfoDispatcherStub */
registerSpatializerCallback( @onNull ISpatializerCallback cb)10081     public void registerSpatializerCallback(
10082             @NonNull ISpatializerCallback cb) {
10083         Objects.requireNonNull(cb);
10084         mSpatializerHelper.registerStateCallback(cb);
10085     }
10086 
10087     /** @see Spatializer.SpatializerInfoDispatcherStub */
unregisterSpatializerCallback( @onNull ISpatializerCallback cb)10088     public void unregisterSpatializerCallback(
10089             @NonNull ISpatializerCallback cb) {
10090         Objects.requireNonNull(cb);
10091         mSpatializerHelper.unregisterStateCallback(cb);
10092     }
10093 
10094     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10095     /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */
registerSpatializerHeadTrackingCallback( @onNull ISpatializerHeadTrackingModeCallback cb)10096     public void registerSpatializerHeadTrackingCallback(
10097             @NonNull ISpatializerHeadTrackingModeCallback cb) {
10098         super.registerSpatializerHeadTrackingCallback_enforcePermission();
10099 
10100         Objects.requireNonNull(cb);
10101         mSpatializerHelper.registerHeadTrackingModeCallback(cb);
10102     }
10103 
10104     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10105     /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */
unregisterSpatializerHeadTrackingCallback( @onNull ISpatializerHeadTrackingModeCallback cb)10106     public void unregisterSpatializerHeadTrackingCallback(
10107             @NonNull ISpatializerHeadTrackingModeCallback cb) {
10108         super.unregisterSpatializerHeadTrackingCallback_enforcePermission();
10109 
10110         Objects.requireNonNull(cb);
10111         mSpatializerHelper.unregisterHeadTrackingModeCallback(cb);
10112     }
10113 
10114     /** @see Spatializer.SpatializerHeadTrackerAvailableDispatcherStub */
registerSpatializerHeadTrackerAvailableCallback( @onNull ISpatializerHeadTrackerAvailableCallback cb, boolean register)10115     public void registerSpatializerHeadTrackerAvailableCallback(
10116             @NonNull ISpatializerHeadTrackerAvailableCallback cb, boolean register) {
10117         Objects.requireNonNull(cb);
10118         mSpatializerHelper.registerHeadTrackerAvailableCallback(cb, register);
10119     }
10120 
10121     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10122     /** @see Spatializer#setOnHeadToSoundstagePoseUpdatedListener */
registerHeadToSoundstagePoseCallback( @onNull ISpatializerHeadToSoundStagePoseCallback cb)10123     public void registerHeadToSoundstagePoseCallback(
10124             @NonNull ISpatializerHeadToSoundStagePoseCallback cb) {
10125         super.registerHeadToSoundstagePoseCallback_enforcePermission();
10126 
10127         Objects.requireNonNull(cb);
10128         mSpatializerHelper.registerHeadToSoundstagePoseCallback(cb);
10129     }
10130 
10131     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10132     /** @see Spatializer#clearOnHeadToSoundstagePoseUpdatedListener */
unregisterHeadToSoundstagePoseCallback( @onNull ISpatializerHeadToSoundStagePoseCallback cb)10133     public void unregisterHeadToSoundstagePoseCallback(
10134             @NonNull ISpatializerHeadToSoundStagePoseCallback cb) {
10135         super.unregisterHeadToSoundstagePoseCallback_enforcePermission();
10136 
10137         Objects.requireNonNull(cb);
10138         mSpatializerHelper.unregisterHeadToSoundstagePoseCallback(cb);
10139     }
10140 
10141     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10142     /** @see Spatializer#getSpatializerCompatibleAudioDevices() */
getSpatializerCompatibleAudioDevices()10143     public @NonNull List<AudioDeviceAttributes> getSpatializerCompatibleAudioDevices() {
10144         super.getSpatializerCompatibleAudioDevices_enforcePermission();
10145 
10146         return mSpatializerHelper.getCompatibleAudioDevices();
10147     }
10148 
10149     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10150     /** @see Spatializer#addSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */
addSpatializerCompatibleAudioDevice(@onNull AudioDeviceAttributes ada)10151     public void addSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
10152         super.addSpatializerCompatibleAudioDevice_enforcePermission();
10153 
10154         Objects.requireNonNull(ada);
10155         mSpatializerHelper.addCompatibleAudioDevice(ada);
10156     }
10157 
10158     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10159     /** @see Spatializer#removeSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */
removeSpatializerCompatibleAudioDevice(@onNull AudioDeviceAttributes ada)10160     public void removeSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
10161         super.removeSpatializerCompatibleAudioDevice_enforcePermission();
10162 
10163         Objects.requireNonNull(ada);
10164         mSpatializerHelper.removeCompatibleAudioDevice(ada);
10165     }
10166 
10167     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10168     /** @see Spatializer#getSupportedHeadTrackingModes() */
getSupportedHeadTrackingModes()10169     public int[] getSupportedHeadTrackingModes() {
10170         super.getSupportedHeadTrackingModes_enforcePermission();
10171 
10172         return mSpatializerHelper.getSupportedHeadTrackingModes();
10173     }
10174 
10175     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10176     /** @see Spatializer#getHeadTrackingMode() */
getActualHeadTrackingMode()10177     public int getActualHeadTrackingMode() {
10178         super.getActualHeadTrackingMode_enforcePermission();
10179 
10180         return mSpatializerHelper.getActualHeadTrackingMode();
10181     }
10182 
10183     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10184     /** @see Spatializer#getDesiredHeadTrackingMode() */
getDesiredHeadTrackingMode()10185     public int getDesiredHeadTrackingMode() {
10186         super.getDesiredHeadTrackingMode_enforcePermission();
10187 
10188         return mSpatializerHelper.getDesiredHeadTrackingMode();
10189     }
10190 
10191     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10192     /** @see Spatializer#setGlobalTransform */
setSpatializerGlobalTransform(@onNull float[] transform)10193     public void setSpatializerGlobalTransform(@NonNull float[] transform) {
10194         super.setSpatializerGlobalTransform_enforcePermission();
10195 
10196         Objects.requireNonNull(transform);
10197         mSpatializerHelper.setGlobalTransform(transform);
10198     }
10199 
10200     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10201     /** @see Spatializer#recenterHeadTracker() */
recenterHeadTracker()10202     public void recenterHeadTracker() {
10203         super.recenterHeadTracker_enforcePermission();
10204 
10205         mSpatializerHelper.recenterHeadTracker();
10206     }
10207 
10208     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10209     /** @see Spatializer#setDesiredHeadTrackingMode */
setDesiredHeadTrackingMode(@patializer.HeadTrackingModeSet int mode)10210     public void setDesiredHeadTrackingMode(@Spatializer.HeadTrackingModeSet int mode) {
10211         super.setDesiredHeadTrackingMode_enforcePermission();
10212 
10213         switch(mode) {
10214             case Spatializer.HEAD_TRACKING_MODE_DISABLED:
10215             case Spatializer.HEAD_TRACKING_MODE_RELATIVE_WORLD:
10216             case Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE:
10217                 break;
10218             default:
10219                 return;
10220         }
10221         mSpatializerHelper.setDesiredHeadTrackingMode(mode);
10222     }
10223 
10224     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10225     /** @see Spatializer#setEffectParameter */
setSpatializerParameter(int key, @NonNull byte[] value)10226     public void setSpatializerParameter(int key, @NonNull byte[] value) {
10227         super.setSpatializerParameter_enforcePermission();
10228 
10229         Objects.requireNonNull(value);
10230         mSpatializerHelper.setEffectParameter(key, value);
10231     }
10232 
10233     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10234     /** @see Spatializer#getEffectParameter */
getSpatializerParameter(int key, @NonNull byte[] value)10235     public void getSpatializerParameter(int key, @NonNull byte[] value) {
10236         super.getSpatializerParameter_enforcePermission();
10237 
10238         Objects.requireNonNull(value);
10239         mSpatializerHelper.getEffectParameter(key, value);
10240     }
10241 
10242     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10243     /** @see Spatializer#getOutput */
getSpatializerOutput()10244     public int getSpatializerOutput() {
10245         super.getSpatializerOutput_enforcePermission();
10246 
10247         return mSpatializerHelper.getOutput();
10248     }
10249 
10250     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10251     /** @see Spatializer#setOnSpatializerOutputChangedListener */
registerSpatializerOutputCallback(ISpatializerOutputCallback cb)10252     public void registerSpatializerOutputCallback(ISpatializerOutputCallback cb) {
10253         super.registerSpatializerOutputCallback_enforcePermission();
10254 
10255         Objects.requireNonNull(cb);
10256         mSpatializerHelper.registerSpatializerOutputCallback(cb);
10257     }
10258 
10259     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
10260     /** @see Spatializer#clearOnSpatializerOutputChangedListener */
unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb)10261     public void unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb) {
10262         super.unregisterSpatializerOutputCallback_enforcePermission();
10263 
10264         Objects.requireNonNull(cb);
10265         mSpatializerHelper.unregisterSpatializerOutputCallback(cb);
10266     }
10267 
10268     /**
10269      * post a message to schedule init/release of head tracking sensors
10270      * whether to initialize or release sensors is based on the state of spatializer
10271      */
postInitSpatializerHeadTrackingSensors()10272     void postInitSpatializerHeadTrackingSensors() {
10273         sendMsg(mAudioHandler,
10274                 MSG_INIT_HEADTRACKING_SENSORS,
10275                 SENDMSG_REPLACE,
10276                 /*arg1*/ 0, /*arg2*/ 0, TAG, /*delay*/ 0);
10277     }
10278 
10279     /**
10280      * post a message to schedule a reset of the spatializer state
10281      */
postResetSpatializer()10282     void postResetSpatializer() {
10283         sendMsg(mAudioHandler,
10284                 MSG_RESET_SPATIALIZER,
10285                 SENDMSG_REPLACE,
10286                 /*arg1*/ 0, /*arg2*/ 0, TAG, /*delay*/ 0);
10287     }
10288 
onInitAdiDeviceStates()10289     void onInitAdiDeviceStates() {
10290         mDeviceBroker.onReadAudioDeviceSettings();
10291         mSoundDoseHelper.initCachedAudioDeviceCategories(
10292                 mDeviceBroker.getImmutableDeviceInventory());
10293     }
10294 
onInitSpatializer()10295     void onInitSpatializer() {
10296         mSpatializerHelper.init(/*effectExpected*/ mHasSpatializerEffect);
10297         mSpatializerHelper.setFeatureEnabled(mHasSpatializerEffect);
10298     }
10299 
10300     //==========================================================================================
10301 
10302     // camera sound is forced if any of the resources corresponding to one active SIM
10303     // demands it.
readCameraSoundForced()10304     private boolean readCameraSoundForced() {
10305         if (SystemProperties.getBoolean("audio.camerasound.force", false)
10306                 || mContext.getResources().getBoolean(
10307                         com.android.internal.R.bool.config_camera_sound_forced)) {
10308             return true;
10309         }
10310 
10311         SubscriptionManager subscriptionManager = mContext.getSystemService(
10312                 SubscriptionManager.class);
10313         if (subscriptionManager == null) {
10314             Log.e(TAG, "readCameraSoundForced cannot create SubscriptionManager!");
10315             return false;
10316         }
10317         int[] subscriptionIds = subscriptionManager.getActiveSubscriptionIdList(false);
10318         for (int subId : subscriptionIds) {
10319             if (SubscriptionManager.getResourcesForSubId(mContext, subId).getBoolean(
10320                     com.android.internal.R.bool.config_camera_sound_forced)) {
10321                 return true;
10322             }
10323         }
10324         return false;
10325     }
10326 
10327     //==========================================================================================
10328     private final Object mMuteAwaitConnectionLock = new Object();
10329 
10330     /**
10331      * The device that is expected to be connected soon, and causes players to be muted until
10332      * its connection, or it times out.
10333      * Null when no active muting command, or it has timed out.
10334      */
10335     @GuardedBy("mMuteAwaitConnectionLock")
10336     private AudioDeviceAttributes mMutingExpectedDevice;
10337     @GuardedBy("mMuteAwaitConnectionLock")
10338     private @Nullable int[] mMutedUsagesAwaitingConnection;
10339 
10340     /** @see AudioManager#muteAwaitConnection */
10341     @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection
muteAwaitConnection(@onNull int[] usages, @NonNull AudioDeviceAttributes device, long timeOutMs)10342     public void muteAwaitConnection(@NonNull int[] usages,
10343             @NonNull AudioDeviceAttributes device, long timeOutMs) {
10344         Objects.requireNonNull(usages);
10345         Objects.requireNonNull(device);
10346         enforceModifyAudioRoutingPermission();
10347         if (timeOutMs <= 0 || usages.length == 0) {
10348             throw new IllegalArgumentException("Invalid timeOutMs/usagesToMute");
10349         }
10350         Log.i(TAG, "muteAwaitConnection dev:" + device + " timeOutMs:" + timeOutMs
10351                 + " usages:" + Arrays.toString(usages));
10352 
10353         if (mDeviceBroker.isDeviceConnected(device)) {
10354             // not throwing an exception as there could be a race between a connection (server-side,
10355             // notification of connection in flight) and a mute operation (client-side)
10356             Log.i(TAG, "muteAwaitConnection ignored, device (" + device + ") already connected");
10357             return;
10358         }
10359         synchronized (mMuteAwaitConnectionLock) {
10360             if (mMutingExpectedDevice != null) {
10361                 Log.e(TAG, "muteAwaitConnection ignored, another in progress for device:"
10362                         + mMutingExpectedDevice);
10363                 throw new IllegalStateException("muteAwaitConnection already in progress");
10364             }
10365             mMutingExpectedDevice = device;
10366             mMutedUsagesAwaitingConnection = usages;
10367             mPlaybackMonitor.muteAwaitConnection(usages, device, timeOutMs);
10368         }
10369         dispatchMuteAwaitConnection(cb -> { try {
10370             cb.dispatchOnMutedUntilConnection(device, usages); } catch (RemoteException e) { } });
10371     }
10372 
10373     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
10374     /** @see AudioManager#getMutingExpectedDevice */
getMutingExpectedDevice()10375     public @Nullable AudioDeviceAttributes getMutingExpectedDevice() {
10376         super.getMutingExpectedDevice_enforcePermission();
10377 
10378         synchronized (mMuteAwaitConnectionLock) {
10379             return mMutingExpectedDevice;
10380         }
10381     }
10382 
10383     /** @see AudioManager#cancelMuteAwaitConnection */
10384     @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection
cancelMuteAwaitConnection(@onNull AudioDeviceAttributes device)10385     public void cancelMuteAwaitConnection(@NonNull AudioDeviceAttributes device) {
10386         Objects.requireNonNull(device);
10387         enforceModifyAudioRoutingPermission();
10388         Log.i(TAG, "cancelMuteAwaitConnection for device:" + device);
10389         final int[] mutedUsages;
10390         synchronized (mMuteAwaitConnectionLock) {
10391             if (mMutingExpectedDevice == null) {
10392                 // not throwing an exception as there could be a race between a timeout
10393                 // (server-side) and a cancel operation (client-side)
10394                 Log.i(TAG, "cancelMuteAwaitConnection ignored, no expected device");
10395                 return;
10396             }
10397             if (!device.equalTypeAddress(mMutingExpectedDevice)) {
10398                 Log.e(TAG, "cancelMuteAwaitConnection ignored, got " + device
10399                         + "] but expected device is" + mMutingExpectedDevice);
10400                 throw new IllegalStateException("cancelMuteAwaitConnection for wrong device");
10401             }
10402             mutedUsages = mMutedUsagesAwaitingConnection;
10403             mMutingExpectedDevice = null;
10404             mMutedUsagesAwaitingConnection = null;
10405             mPlaybackMonitor.cancelMuteAwaitConnection("cancelMuteAwaitConnection dev:" + device);
10406         }
10407         dispatchMuteAwaitConnection(cb -> { try { cb.dispatchOnUnmutedEvent(
10408                     AudioManager.MuteAwaitConnectionCallback.EVENT_CANCEL, device, mutedUsages);
10409             } catch (RemoteException e) { } });
10410     }
10411 
10412     final RemoteCallbackList<IMuteAwaitConnectionCallback> mMuteAwaitConnectionDispatchers =
10413             new RemoteCallbackList<IMuteAwaitConnectionCallback>();
10414 
10415     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
10416     /** @see AudioManager#registerMuteAwaitConnectionCallback */
registerMuteAwaitConnectionDispatcher(@onNull IMuteAwaitConnectionCallback cb, boolean register)10417     public void registerMuteAwaitConnectionDispatcher(@NonNull IMuteAwaitConnectionCallback cb,
10418             boolean register) {
10419         super.registerMuteAwaitConnectionDispatcher_enforcePermission();
10420 
10421         if (register) {
10422             mMuteAwaitConnectionDispatchers.register(cb);
10423         } else {
10424             mMuteAwaitConnectionDispatchers.unregister(cb);
10425         }
10426     }
10427 
10428     @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection
checkMuteAwaitConnection()10429     void checkMuteAwaitConnection() {
10430         final AudioDeviceAttributes device;
10431         final int[] mutedUsages;
10432         synchronized (mMuteAwaitConnectionLock) {
10433             if (mMutingExpectedDevice == null) {
10434                 return;
10435             }
10436             device = mMutingExpectedDevice;
10437             mutedUsages = mMutedUsagesAwaitingConnection;
10438             if (!mDeviceBroker.isDeviceConnected(device)) {
10439                 return;
10440             }
10441             mMutingExpectedDevice = null;
10442             mMutedUsagesAwaitingConnection = null;
10443             mPlaybackMonitor.cancelMuteAwaitConnection(
10444                     "checkMuteAwaitConnection device " + device + " connected, unmuting");
10445         }
10446         dispatchMuteAwaitConnection(cb -> { try { cb.dispatchOnUnmutedEvent(
10447                 AudioManager.MuteAwaitConnectionCallback.EVENT_CONNECTION, device, mutedUsages);
10448             } catch (RemoteException e) { } });
10449     }
10450 
10451     /**
10452      * Called by PlaybackActivityMonitor when the timeout hit for the mute on device connection
10453      */
10454     @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection
onMuteAwaitConnectionTimeout(@onNull AudioDeviceAttributes timedOutDevice)10455     void onMuteAwaitConnectionTimeout(@NonNull AudioDeviceAttributes timedOutDevice) {
10456         final int[] mutedUsages;
10457         synchronized (mMuteAwaitConnectionLock) {
10458             if (!timedOutDevice.equals(mMutingExpectedDevice)) {
10459                 return;
10460             }
10461             Log.i(TAG, "muteAwaitConnection timeout, clearing expected device "
10462                     + mMutingExpectedDevice);
10463             mutedUsages = mMutedUsagesAwaitingConnection;
10464             mMutingExpectedDevice = null;
10465             mMutedUsagesAwaitingConnection = null;
10466         }
10467         dispatchMuteAwaitConnection(cb -> { try {
10468                 cb.dispatchOnUnmutedEvent(
10469                         AudioManager.MuteAwaitConnectionCallback.EVENT_TIMEOUT,
10470                         timedOutDevice, mutedUsages);
10471             } catch (RemoteException e) { } });
10472     }
10473 
dispatchMuteAwaitConnection( java.util.function.Consumer<IMuteAwaitConnectionCallback> callback)10474     private void dispatchMuteAwaitConnection(
10475             java.util.function.Consumer<IMuteAwaitConnectionCallback> callback) {
10476         final int nbDispatchers = mMuteAwaitConnectionDispatchers.beginBroadcast();
10477         // lazy initialization as errors unlikely
10478         ArrayList<IMuteAwaitConnectionCallback> errorList = null;
10479         for (int i = 0; i < nbDispatchers; i++) {
10480             try {
10481                 callback.accept(mMuteAwaitConnectionDispatchers.getBroadcastItem(i));
10482             } catch (Exception e) {
10483                 if (errorList == null) {
10484                     errorList = new ArrayList<>(1);
10485                 }
10486                 errorList.add(mMuteAwaitConnectionDispatchers.getBroadcastItem(i));
10487             }
10488         }
10489         if (errorList != null) {
10490             for (IMuteAwaitConnectionCallback errorItem : errorList) {
10491                 mMuteAwaitConnectionDispatchers.unregister(errorItem);
10492             }
10493         }
10494         mMuteAwaitConnectionDispatchers.finishBroadcast();
10495     }
10496 
10497     final RemoteCallbackList<IDeviceVolumeBehaviorDispatcher> mDeviceVolumeBehaviorDispatchers =
10498             new RemoteCallbackList<IDeviceVolumeBehaviorDispatcher>();
10499 
10500     /**
10501      *  @see AudioDeviceVolumeManager#addOnDeviceVolumeBehaviorChangedListener and
10502      *  AudioDeviceVolumeManager#removeOnDeviceVolumeBehaviorChangedListener
10503      */
registerDeviceVolumeBehaviorDispatcher(boolean register, @NonNull IDeviceVolumeBehaviorDispatcher dispatcher)10504     public void registerDeviceVolumeBehaviorDispatcher(boolean register,
10505             @NonNull IDeviceVolumeBehaviorDispatcher dispatcher) {
10506         enforceQueryStateOrModifyRoutingPermission();
10507         Objects.requireNonNull(dispatcher);
10508         if (register) {
10509             mDeviceVolumeBehaviorDispatchers.register(dispatcher);
10510         } else {
10511             mDeviceVolumeBehaviorDispatchers.unregister(dispatcher);
10512         }
10513     }
10514 
dispatchDeviceVolumeBehavior(AudioDeviceAttributes device, int volumeBehavior)10515     private void dispatchDeviceVolumeBehavior(AudioDeviceAttributes device, int volumeBehavior) {
10516         final int dispatchers = mDeviceVolumeBehaviorDispatchers.beginBroadcast();
10517         for (int i = 0; i < dispatchers; i++) {
10518             try {
10519                 mDeviceVolumeBehaviorDispatchers.getBroadcastItem(i)
10520                         .dispatchDeviceVolumeBehaviorChanged(device, volumeBehavior);
10521             } catch (RemoteException e) {
10522             }
10523         }
10524         mDeviceVolumeBehaviorDispatchers.finishBroadcast();
10525     }
10526 
10527     //==========================================================================================
10528     // Device orientation
10529     //==========================================================================================
10530     /**
10531      * Handles device configuration changes that may map to a change in rotation.
10532      * Monitoring rotation is optional, and is defined by the definition and value
10533      * of the "ro.audio.monitorRotation" system property.
10534      */
onConfigurationChanged()10535     private void onConfigurationChanged() {
10536         try {
10537             // reading new configuration "safely" (i.e. under try catch) in case anything
10538             // goes wrong.
10539             Configuration config = mContext.getResources().getConfiguration();
10540             mSoundDoseHelper.configureSafeMedia(/*forced*/false, TAG);
10541 
10542             boolean cameraSoundForced = readCameraSoundForced();
10543             synchronized (mSettingsLock) {
10544                 final boolean cameraSoundForcedChanged = (cameraSoundForced != mCameraSoundForced);
10545                 mCameraSoundForced = cameraSoundForced;
10546                 if (cameraSoundForcedChanged) {
10547                     if (!mIsSingleVolume) {
10548                         synchronized (VolumeStreamState.class) {
10549                             VolumeStreamState s = mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED];
10550                             if (cameraSoundForced) {
10551                                 s.setAllIndexesToMax();
10552                                 mRingerModeAffectedStreams &=
10553                                         ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
10554                             } else {
10555                                 s.setAllIndexes(mStreamStates[AudioSystem.STREAM_SYSTEM], TAG);
10556                                 mRingerModeAffectedStreams |=
10557                                         (1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
10558                             }
10559                         }
10560                         // take new state into account for streams muted by ringer mode
10561                         setRingerModeInt(getRingerModeInternal(), false);
10562                     }
10563                     mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM,
10564                             cameraSoundForced ?
10565                                     AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE,
10566                             "onConfigurationChanged");
10567                     sendMsg(mAudioHandler,
10568                             MSG_SET_ALL_VOLUMES,
10569                             SENDMSG_QUEUE,
10570                             0,
10571                             0,
10572                             mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED], 0);
10573 
10574                 }
10575             }
10576             mVolumeController.setLayoutDirection(config.getLayoutDirection());
10577         } catch (Exception e) {
10578             Log.e(TAG, "Error handling configuration change: ", e);
10579         }
10580     }
10581 
10582     @Override
setRingtonePlayer(IRingtonePlayer player)10583     public void setRingtonePlayer(IRingtonePlayer player) {
10584         mContext.enforceCallingOrSelfPermission(REMOTE_AUDIO_PLAYBACK, null);
10585         mRingtonePlayer = player;
10586     }
10587 
10588     @Override
getRingtonePlayer()10589     public IRingtonePlayer getRingtonePlayer() {
10590         return mRingtonePlayer;
10591     }
10592 
10593     @Override
startWatchingRoutes(IAudioRoutesObserver observer)10594     public AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) {
10595         return mDeviceBroker.startWatchingRoutes(observer);
10596     }
10597 
10598     @Override
disableSafeMediaVolume(String callingPackage)10599     public void disableSafeMediaVolume(String callingPackage) {
10600         enforceVolumeController("disable the safe media volume");
10601         mSoundDoseHelper.disableSafeMediaVolume(callingPackage);
10602     }
10603 
10604     @Override
lowerVolumeToRs1(String callingPackage)10605     public void lowerVolumeToRs1(String callingPackage) {
10606         enforceVolumeController("lowerVolumeToRs1");
10607         postLowerVolumeToRs1();
10608     }
10609 
postLowerVolumeToRs1()10610     /*package*/ void postLowerVolumeToRs1() {
10611         sendMsg(mAudioHandler, MSG_LOWER_VOLUME_TO_RS1, SENDMSG_QUEUE,
10612                 // no params, no delay
10613                 0, 0, null, 0);
10614     }
10615 
10616     /**
10617      * Called when handling MSG_LOWER_VOLUME_TO_RS1
10618      */
onLowerVolumeToRs1()10619     private void onLowerVolumeToRs1() {
10620         final ArrayList<AudioDeviceAttributes> devices = getDevicesForAttributesInt(
10621                 new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build(), true);
10622         final int nativeDeviceType;
10623         final AudioDeviceAttributes ada;
10624         if (!devices.isEmpty()) {
10625             ada = devices.get(0);
10626             nativeDeviceType = ada.getInternalType();
10627         } else {
10628             nativeDeviceType = AudioSystem.DEVICE_OUT_USB_HEADSET;
10629             ada = new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_USB_HEADSET, "");
10630         }
10631         final int index = mSoundDoseHelper.safeMediaVolumeIndex(nativeDeviceType);
10632         setStreamVolumeWithAttributionInt(STREAM_MUSIC, index, /*flags*/ 0, ada,
10633                 "com.android.server.audio", "AudioService");
10634     }
10635 
10636     @Override
10637     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
getOutputRs2UpperBound()10638     public float getOutputRs2UpperBound() {
10639         super.getOutputRs2UpperBound_enforcePermission();
10640         return mSoundDoseHelper.getOutputRs2UpperBound();
10641     }
10642 
10643     @Override
10644     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setOutputRs2UpperBound(float rs2Value)10645     public void setOutputRs2UpperBound(float rs2Value) {
10646         super.setOutputRs2UpperBound_enforcePermission();
10647         mSoundDoseHelper.setOutputRs2UpperBound(rs2Value);
10648     }
10649 
10650     @Override
10651     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
getCsd()10652     public float getCsd() {
10653         super.getCsd_enforcePermission();
10654         return mSoundDoseHelper.getCsd();
10655     }
10656 
10657     @Override
10658     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setCsd(float csd)10659     public void setCsd(float csd) {
10660         super.setCsd_enforcePermission();
10661         if (csd < 0.0f) {
10662             mSoundDoseHelper.resetCsdTimeouts();
10663         } else {
10664             mSoundDoseHelper.setCsd(csd);
10665         }
10666     }
10667 
10668     @Override
10669     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
forceUseFrameworkMel(boolean useFrameworkMel)10670     public void forceUseFrameworkMel(boolean useFrameworkMel) {
10671         super.forceUseFrameworkMel_enforcePermission();
10672         mSoundDoseHelper.forceUseFrameworkMel(useFrameworkMel);
10673     }
10674 
10675     @Override
10676     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
forceComputeCsdOnAllDevices(boolean computeCsdOnAllDevices)10677     public void forceComputeCsdOnAllDevices(boolean computeCsdOnAllDevices) {
10678         super.forceComputeCsdOnAllDevices_enforcePermission();
10679         mSoundDoseHelper.forceComputeCsdOnAllDevices(computeCsdOnAllDevices);
10680     }
10681 
10682     @Override
10683     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
isCsdEnabled()10684     public boolean isCsdEnabled() {
10685         super.isCsdEnabled_enforcePermission();
10686         return mSoundDoseHelper.isCsdEnabled();
10687     }
10688 
10689     @Override
10690     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
isCsdAsAFeatureAvailable()10691     public boolean isCsdAsAFeatureAvailable() {
10692         super.isCsdAsAFeatureAvailable_enforcePermission();
10693         return mSoundDoseHelper.isCsdAsAFeatureAvailable();
10694     }
10695 
10696     @Override
10697     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
isCsdAsAFeatureEnabled()10698     public boolean isCsdAsAFeatureEnabled() {
10699         super.isCsdAsAFeatureEnabled_enforcePermission();
10700         return mSoundDoseHelper.isCsdAsAFeatureEnabled();
10701     }
10702 
10703     @Override
10704     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setCsdAsAFeatureEnabled(boolean csdToggleValue)10705     public void setCsdAsAFeatureEnabled(boolean csdToggleValue) {
10706         super.setCsdAsAFeatureEnabled_enforcePermission();
10707         mSoundDoseHelper.setCsdAsAFeatureEnabled(csdToggleValue);
10708     }
10709 
10710     @Override
10711     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
setBluetoothAudioDeviceCategory(@onNull String address, boolean isBle, @AudioDeviceCategory int btAudioDeviceCategory)10712     public void setBluetoothAudioDeviceCategory(@NonNull String address, boolean isBle,
10713             @AudioDeviceCategory int btAudioDeviceCategory) {
10714         super.setBluetoothAudioDeviceCategory_enforcePermission();
10715 
10716         final String addr = Objects.requireNonNull(address);
10717 
10718         AdiDeviceState deviceState = mDeviceBroker.findBtDeviceStateForAddress(addr, isBle);
10719 
10720         int internalType = !isBle ? DEVICE_OUT_BLUETOOTH_A2DP
10721                 : ((btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES)
10722                         ? DEVICE_OUT_BLE_HEADSET : DEVICE_OUT_BLE_SPEAKER);
10723         int deviceType = !isBle ? TYPE_BLUETOOTH_A2DP
10724                 : ((btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES) ? TYPE_BLE_HEADSET
10725                         : TYPE_BLE_SPEAKER);
10726 
10727         if (deviceState == null) {
10728             deviceState = new AdiDeviceState(deviceType, internalType, addr);
10729         }
10730 
10731         deviceState.setAudioDeviceCategory(btAudioDeviceCategory);
10732 
10733         mDeviceBroker.addOrUpdateBtAudioDeviceCategoryInInventory(deviceState);
10734         mDeviceBroker.persistAudioDeviceSettings();
10735 
10736         mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes());
10737         mSoundDoseHelper.setAudioDeviceCategory(addr, internalType,
10738                 btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES);
10739     }
10740 
10741     @Override
10742     @android.annotation.EnforcePermission(MODIFY_AUDIO_SETTINGS_PRIVILEGED)
10743     @AudioDeviceCategory
getBluetoothAudioDeviceCategory(@onNull String address, boolean isBle)10744     public int getBluetoothAudioDeviceCategory(@NonNull String address, boolean isBle) {
10745         super.getBluetoothAudioDeviceCategory_enforcePermission();
10746 
10747         final AdiDeviceState deviceState = mDeviceBroker.findBtDeviceStateForAddress(
10748                 Objects.requireNonNull(address), isBle);
10749         if (deviceState == null) {
10750             return AUDIO_DEVICE_CATEGORY_UNKNOWN;
10751         }
10752 
10753         return deviceState.getAudioDeviceCategory();
10754     }
10755 
10756     //==========================================================================================
10757     // Hdmi CEC:
10758     // - System audio mode:
10759     //     If Hdmi Cec's system audio mode is on, audio service should send the volume change
10760     //     to HdmiControlService so that the audio receiver can handle it.
10761     // - CEC sink:
10762     //     OUT_HDMI becomes a "full volume device", i.e. output is always at maximum level
10763     //     and volume changes won't be taken into account on this device. Volume adjustments
10764     //     are transformed into key events for the HDMI playback client.
10765     //==========================================================================================
10766 
10767     @GuardedBy("mHdmiClientLock")
updateHdmiCecSinkLocked(boolean hdmiCecSink)10768     private void updateHdmiCecSinkLocked(boolean hdmiCecSink) {
10769         if (!hasDeviceVolumeBehavior(AudioSystem.DEVICE_OUT_HDMI)) {
10770             if (hdmiCecSink) {
10771                 if (DEBUG_VOL) {
10772                     Log.d(TAG, "CEC sink: setting HDMI as full vol device");
10773                 }
10774                 setDeviceVolumeBehaviorInternal(
10775                         new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""),
10776                         AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL,
10777                         "AudioService.updateHdmiCecSinkLocked()");
10778             } else {
10779                 if (DEBUG_VOL) {
10780                     Log.d(TAG, "TV, no CEC: setting HDMI as regular vol device");
10781                 }
10782                 // Android TV devices without CEC service apply software volume on
10783                 // HDMI output
10784                 setDeviceVolumeBehaviorInternal(
10785                         new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""),
10786                         AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE,
10787                         "AudioService.updateHdmiCecSinkLocked()");
10788             }
10789             postUpdateVolumeStatesForAudioDevice(AudioSystem.DEVICE_OUT_HDMI,
10790                     "HdmiPlaybackClient.DisplayStatusCallback");
10791         }
10792     }
10793 
10794     private class MyHdmiControlStatusChangeListenerCallback
10795             implements HdmiControlManager.HdmiControlStatusChangeListener {
onStatusChange(@dmiControlManager.HdmiCecControl int isCecEnabled, boolean isCecAvailable)10796         public void onStatusChange(@HdmiControlManager.HdmiCecControl int isCecEnabled,
10797                 boolean isCecAvailable) {
10798             synchronized (mHdmiClientLock) {
10799                 if (mHdmiManager == null) return;
10800                 boolean cecEnabled = isCecEnabled == HdmiControlManager.HDMI_CEC_CONTROL_ENABLED;
10801                 updateHdmiCecSinkLocked(cecEnabled ? isCecAvailable : false);
10802             }
10803         }
10804     };
10805 
10806     private class MyHdmiCecVolumeControlFeatureListener
10807             implements HdmiControlManager.HdmiCecVolumeControlFeatureListener {
onHdmiCecVolumeControlFeature( @dmiControlManager.VolumeControl int hdmiCecVolumeControl)10808         public void onHdmiCecVolumeControlFeature(
10809                 @HdmiControlManager.VolumeControl int hdmiCecVolumeControl) {
10810             synchronized (mHdmiClientLock) {
10811                 if (mHdmiManager == null) return;
10812                 mHdmiCecVolumeControlEnabled =
10813                         hdmiCecVolumeControl == HdmiControlManager.VOLUME_CONTROL_ENABLED;
10814             }
10815         }
10816     };
10817 
10818     private final Object mHdmiClientLock = new Object();
10819 
10820     // If HDMI-CEC system audio is supported
10821     // Note that for CEC volume commands mHdmiCecVolumeControlEnabled will play a role on volume
10822     // commands
10823     private boolean mHdmiSystemAudioSupported = false;
10824     // Set only when device is tv.
10825     @GuardedBy("mHdmiClientLock")
10826     private HdmiTvClient mHdmiTvClient;
10827     // true if the device has system feature PackageManager.FEATURE_LEANBACK.
10828     // cached HdmiControlManager interface
10829     @GuardedBy("mHdmiClientLock")
10830     private HdmiControlManager mHdmiManager;
10831     // Set only when device is a set-top box.
10832     @GuardedBy("mHdmiClientLock")
10833     private HdmiPlaybackClient mHdmiPlaybackClient;
10834     // Set only when device is an audio system.
10835     @GuardedBy("mHdmiClientLock")
10836     private HdmiAudioSystemClient mHdmiAudioSystemClient;
10837     // True when volume control over HDMI CEC is used when CEC is enabled (meaningless otherwise)
10838     @GuardedBy("mHdmiClientLock")
10839     private boolean mHdmiCecVolumeControlEnabled;
10840 
10841     private MyHdmiControlStatusChangeListenerCallback mHdmiControlStatusChangeListenerCallback =
10842             new MyHdmiControlStatusChangeListenerCallback();
10843 
10844     private MyHdmiCecVolumeControlFeatureListener mMyHdmiCecVolumeControlFeatureListener =
10845             new MyHdmiCecVolumeControlFeatureListener();
10846 
10847     @Override
setHdmiSystemAudioSupported(boolean on)10848     public int setHdmiSystemAudioSupported(boolean on) {
10849         int device = AudioSystem.DEVICE_NONE;
10850         synchronized (mHdmiClientLock) {
10851             if (mHdmiManager != null) {
10852                 if (mHdmiTvClient == null && mHdmiAudioSystemClient == null) {
10853                     Log.w(TAG, "Only Hdmi-Cec enabled TV or audio system device supports"
10854                             + "system audio mode.");
10855                     return device;
10856                 }
10857                 if (mHdmiSystemAudioSupported != on) {
10858                     mHdmiSystemAudioSupported = on;
10859                     final int config = on ? AudioSystem.FORCE_HDMI_SYSTEM_AUDIO_ENFORCED :
10860                         AudioSystem.FORCE_NONE;
10861                     mDeviceBroker.setForceUse_Async(AudioSystem.FOR_HDMI_SYSTEM_AUDIO, config,
10862                             "setHdmiSystemAudioSupported");
10863                 }
10864                 // TODO(b/185386781): Update AudioManager API to use device list.
10865                 // So far, this value appears to be advisory for debug log.
10866                 device = getDeviceMaskForStream(AudioSystem.STREAM_MUSIC);
10867             }
10868         }
10869         return device;
10870     }
10871 
10872     @Override
isHdmiSystemAudioSupported()10873     public boolean isHdmiSystemAudioSupported() {
10874         return mHdmiSystemAudioSupported;
10875     }
10876 
10877     //==========================================================================================
10878     // Accessibility
10879 
initA11yMonitoring()10880     private void initA11yMonitoring() {
10881         final AccessibilityManager accessibilityManager =
10882                 (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
10883         updateDefaultStreamOverrideDelay(accessibilityManager.isTouchExplorationEnabled());
10884         updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive());
10885         accessibilityManager.addTouchExplorationStateChangeListener(this, null);
10886         accessibilityManager.addAccessibilityServicesStateChangeListener(this);
10887     }
10888 
10889     //---------------------------------------------------------------------------------
10890     // A11y: taking touch exploration into account for selecting the default
10891     //   stream override timeout when adjusting volume
10892     //---------------------------------------------------------------------------------
10893 
10894     // - STREAM_NOTIFICATION on tablets during this period after a notification stopped
10895     // - STREAM_RING on phones during this period after a notification stopped
10896     // - STREAM_MUSIC otherwise
10897 
10898     private static final int DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS = 0;
10899     private static final int TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS = 1000;
10900 
10901     private static int sStreamOverrideDelayMs;
10902 
10903     @Override
onTouchExplorationStateChanged(boolean enabled)10904     public void onTouchExplorationStateChanged(boolean enabled) {
10905         updateDefaultStreamOverrideDelay(enabled);
10906     }
10907 
updateDefaultStreamOverrideDelay(boolean touchExploreEnabled)10908     private void updateDefaultStreamOverrideDelay(boolean touchExploreEnabled) {
10909         if (touchExploreEnabled) {
10910             sStreamOverrideDelayMs = TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS;
10911         } else {
10912             sStreamOverrideDelayMs = DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS;
10913         }
10914         if (DEBUG_VOL) Log.d(TAG, "Touch exploration enabled=" + touchExploreEnabled
10915                 + " stream override delay is now " + sStreamOverrideDelayMs + " ms");
10916     }
10917 
10918     //---------------------------------------------------------------------------------
10919     // A11y: taking a11y state into account for the handling of a11y prompts volume
10920     //---------------------------------------------------------------------------------
10921 
10922     private static boolean sIndependentA11yVolume = false;
10923 
10924     // implementation of AccessibilityServicesStateChangeListener
10925     @Override
onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager)10926     public void onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager) {
10927         updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive());
10928     }
10929 
updateA11yVolumeAlias(boolean a11VolEnabled)10930     private void updateA11yVolumeAlias(boolean a11VolEnabled) {
10931         if (DEBUG_VOL) Log.d(TAG, "Accessibility volume enabled = " + a11VolEnabled);
10932         if (sIndependentA11yVolume != a11VolEnabled) {
10933             sIndependentA11yVolume = a11VolEnabled;
10934             // update the volume mapping scheme
10935             updateStreamVolumeAlias(true /*updateVolumes*/, TAG);
10936             // update the volume controller behavior
10937             mVolumeController.setA11yMode(sIndependentA11yVolume ?
10938                     VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME :
10939                         VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME);
10940             mVolumeController.postVolumeChanged(AudioManager.STREAM_ACCESSIBILITY, 0);
10941         }
10942     }
10943 
10944     //==========================================================================================
10945     // Camera shutter sound policy.
10946     // config_camera_sound_forced configuration option in config.xml defines if the camera shutter
10947     // sound is forced (sound even if the device is in silent mode) or not. This option is false by
10948     // default and can be overridden by country specific overlay in values-mccXXX/config.xml.
10949     //==========================================================================================
10950 
10951     // cached value of com.android.internal.R.bool.config_camera_sound_forced
10952     @GuardedBy("mSettingsLock")
10953     private boolean mCameraSoundForced;
10954 
10955     // called by android.hardware.Camera to populate CameraInfo.canDisableShutterSound
isCameraSoundForced()10956     public boolean isCameraSoundForced() {
10957         synchronized (mSettingsLock) {
10958             return mCameraSoundForced;
10959         }
10960     }
10961 
10962     //==========================================================================================
10963     // AudioService logging and dumpsys
10964     //==========================================================================================
10965     static final int LOG_NB_EVENTS_LIFECYCLE = 20;
10966     static final int LOG_NB_EVENTS_PHONE_STATE = 20;
10967     static final int LOG_NB_EVENTS_DEVICE_CONNECTION = 50;
10968     static final int LOG_NB_EVENTS_FORCE_USE = 20;
10969     static final int LOG_NB_EVENTS_VOLUME = 100;
10970     static final int LOG_NB_EVENTS_DYN_POLICY = 10;
10971     static final int LOG_NB_EVENTS_SPATIAL = 30;
10972     static final int LOG_NB_EVENTS_SOUND_DOSE = 30;
10973 
10974     static final EventLogger
10975             sLifecycleLogger = new EventLogger(LOG_NB_EVENTS_LIFECYCLE,
10976             "audio services lifecycle");
10977 
10978     static final EventLogger sMuteLogger = new EventLogger(30,
10979             "mute commands");
10980 
10981     final private EventLogger
10982             mModeLogger = new EventLogger(LOG_NB_EVENTS_PHONE_STATE,
10983             "phone state (logged after successful call to AudioSystem.setPhoneState(int, int))");
10984 
10985     // logs for wired + A2DP device connections:
10986     // - wired: logged before onSetWiredDeviceConnectionState() is executed
10987     // - A2DP: logged at reception of method call
10988     /*package*/ static final EventLogger
10989             sDeviceLogger = new EventLogger(
10990             LOG_NB_EVENTS_DEVICE_CONNECTION, "wired/A2DP/hearing aid device connection");
10991 
10992     static final EventLogger
10993             sForceUseLogger = new EventLogger(
10994             LOG_NB_EVENTS_FORCE_USE,
10995             "force use (logged before setForceUse() is executed)");
10996 
10997     static final EventLogger
10998             sVolumeLogger = new EventLogger(LOG_NB_EVENTS_VOLUME,
10999             "volume changes (logged when command received by AudioService)");
11000 
11001     static final EventLogger
11002             sSpatialLogger = new EventLogger(LOG_NB_EVENTS_SPATIAL,
11003             "spatial audio");
11004 
11005     final private EventLogger
11006             mDynPolicyLogger = new EventLogger(LOG_NB_EVENTS_DYN_POLICY,
11007             "dynamic policy events (logged when command received by AudioService)");
11008 
11009     private static final String[] RINGER_MODE_NAMES = new String[] {
11010             "SILENT",
11011             "VIBRATE",
11012             "NORMAL"
11013     };
11014 
dumpRingerMode(PrintWriter pw)11015     private void dumpRingerMode(PrintWriter pw) {
11016         pw.println("\nRinger mode: ");
11017         pw.println("- mode (internal) = " + RINGER_MODE_NAMES[mRingerMode]);
11018         pw.println("- mode (external) = " + RINGER_MODE_NAMES[mRingerModeExternal]);
11019         pw.println("- zen mode:" + Settings.Global.zenModeToString(mNm.getZenMode()));
11020         dumpRingerModeStreams(pw, "affected", mRingerModeAffectedStreams);
11021         dumpRingerModeStreams(pw, "muted", sRingerAndZenModeMutedStreams);
11022         pw.print("- delegate = "); pw.println(mRingerModeDelegate);
11023     }
11024 
dumpRingerModeStreams(PrintWriter pw, String type, int streams)11025     private void dumpRingerModeStreams(PrintWriter pw, String type, int streams) {
11026         pw.print("- ringer mode "); pw.print(type); pw.print(" streams = 0x");
11027         pw.print(Integer.toHexString(streams));
11028         if (streams != 0) {
11029             pw.print(" (");
11030             boolean first = true;
11031             for (int i = 0; i < AudioSystem.STREAM_NAMES.length; i++) {
11032                 final int stream = (1 << i);
11033                 if ((streams & stream) != 0) {
11034                     if (!first) pw.print(',');
11035                     pw.print(AudioSystem.STREAM_NAMES[i]);
11036                     streams &= ~stream;
11037                     first = false;
11038                 }
11039             }
11040             if (streams != 0) {
11041                 if (!first) pw.print(',');
11042                 pw.print(streams);
11043             }
11044             pw.print(')');
11045         }
11046         pw.println();
11047     }
11048 
getAbsoluteVolumeDevicesWithBehavior(int behavior)11049     private Set<Integer> getAbsoluteVolumeDevicesWithBehavior(int behavior) {
11050         return mAbsoluteVolumeDeviceInfoMap.entrySet().stream()
11051                 .filter(entry -> entry.getValue().mDeviceVolumeBehavior == behavior)
11052                 .map(Map.Entry::getKey)
11053                 .collect(Collectors.toSet());
11054     }
11055 
dumpDeviceTypes(@onNull Set<Integer> deviceTypes)11056     private String dumpDeviceTypes(@NonNull Set<Integer> deviceTypes) {
11057         Iterator<Integer> it = deviceTypes.iterator();
11058         if (!it.hasNext()) {
11059             return "";
11060         }
11061         final StringBuilder sb = new StringBuilder();
11062         sb.append("0x" + Integer.toHexString(it.next()));
11063         while (it.hasNext()) {
11064             sb.append("," + "0x" + Integer.toHexString(it.next()));
11065         }
11066         return sb.toString();
11067     }
11068 
11069     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)11070     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11071         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
11072 
11073         sLifecycleLogger.dump(pw);
11074         if (mAudioHandler != null) {
11075             pw.println("\nMessage handler (watch for unhandled messages):");
11076             mAudioHandler.dump(new PrintWriterPrinter(pw), "  ");
11077         } else {
11078             pw.println("\nMessage handler is null");
11079         }
11080         mMediaFocusControl.dump(pw);
11081         dumpStreamStates(pw);
11082         dumpVolumeGroups(pw);
11083         dumpRingerMode(pw);
11084         dumpAudioMode(pw);
11085         pw.println("\nAudio routes:");
11086         pw.print("  mMainType=0x"); pw.println(Integer.toHexString(
11087                 mDeviceBroker.getCurAudioRoutes().mainType));
11088         pw.print("  mBluetoothName="); pw.println(mDeviceBroker.getCurAudioRoutes().bluetoothName);
11089 
11090         pw.println("\nOther state:");
11091         pw.print("  mUseVolumeGroupAliases="); pw.println(mUseVolumeGroupAliases);
11092         pw.print("  mVolumeController="); pw.println(mVolumeController);
11093         mSoundDoseHelper.dump(pw);
11094         pw.print("  sIndependentA11yVolume="); pw.println(sIndependentA11yVolume);
11095         pw.print("  mCameraSoundForced="); pw.println(isCameraSoundForced());
11096         pw.print("  mHasVibrator="); pw.println(mHasVibrator);
11097         pw.print("  mVolumePolicy="); pw.println(mVolumePolicy);
11098         pw.print("  mAvrcpAbsVolSupported="); pw.println(mAvrcpAbsVolSupported);
11099         pw.print("  mBtScoOnByApp="); pw.println(mBtScoOnByApp);
11100         pw.print("  mIsSingleVolume="); pw.println(mIsSingleVolume);
11101         pw.print("  mUseFixedVolume="); pw.println(mUseFixedVolume);
11102         pw.print("  mNotifAliasRing="); pw.println(mNotifAliasRing);
11103         pw.print("  mFixedVolumeDevices="); pw.println(dumpDeviceTypes(mFixedVolumeDevices));
11104         pw.print("  mFullVolumeDevices="); pw.println(dumpDeviceTypes(mFullVolumeDevices));
11105         pw.print("  absolute volume devices="); pw.println(dumpDeviceTypes(
11106                 getAbsoluteVolumeDevicesWithBehavior(
11107                         AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE)));
11108         pw.print("  adjust-only absolute volume devices="); pw.println(dumpDeviceTypes(
11109                 getAbsoluteVolumeDevicesWithBehavior(
11110                         AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY)));
11111         pw.print("  mExtVolumeController="); pw.println(mExtVolumeController);
11112         pw.print("  mHdmiAudioSystemClient="); pw.println(mHdmiAudioSystemClient);
11113         pw.print("  mHdmiPlaybackClient="); pw.println(mHdmiPlaybackClient);
11114         pw.print("  mHdmiTvClient="); pw.println(mHdmiTvClient);
11115         pw.print("  mHdmiSystemAudioSupported="); pw.println(mHdmiSystemAudioSupported);
11116         synchronized (mHdmiClientLock) {
11117             pw.print("  mHdmiCecVolumeControlEnabled="); pw.println(mHdmiCecVolumeControlEnabled);
11118         }
11119         pw.print("  mIsCallScreeningModeSupported="); pw.println(mIsCallScreeningModeSupported);
11120         pw.print("  mic mute FromSwitch=" + mMicMuteFromSwitch
11121                         + " FromRestrictions=" + mMicMuteFromRestrictions
11122                         + " FromApi=" + mMicMuteFromApi
11123                         + " from system=" + mMicMuteFromSystemCached);
11124         dumpAccessibilityServiceUids(pw);
11125         dumpAssistantServicesUids(pw);
11126 
11127         pw.print("  supportsBluetoothVariableLatency=");
11128         pw.println(AudioSystem.supportsBluetoothVariableLatency());
11129         pw.print("  isBluetoothVariableLatencyEnabled=");
11130         pw.println(AudioSystem.isBluetoothVariableLatencyEnabled());
11131 
11132         dumpAudioPolicies(pw);
11133         mDynPolicyLogger.dump(pw);
11134         mPlaybackMonitor.dump(pw);
11135         mRecordMonitor.dump(pw);
11136 
11137         pw.println("\nAudioDeviceBroker:");
11138         mDeviceBroker.dump(pw, "  ");
11139         pw.println("\nSoundEffects:");
11140         mSfxHelper.dump(pw, "  ");
11141 
11142         pw.println("\n");
11143         pw.println("\nEvent logs:");
11144         mModeLogger.dump(pw);
11145         pw.println("\n");
11146         sDeviceLogger.dump(pw);
11147         pw.println("\n");
11148         sForceUseLogger.dump(pw);
11149         pw.println("\n");
11150         sVolumeLogger.dump(pw);
11151         pw.println("\n");
11152         sMuteLogger.dump(pw);
11153         pw.println("\n");
11154         dumpSupportedSystemUsage(pw);
11155 
11156         pw.println("\n");
11157         pw.println("\nSpatial audio:");
11158         pw.println("mHasSpatializerEffect:" + mHasSpatializerEffect + " (effect present)");
11159         pw.println("isSpatializerEnabled:" + isSpatializerEnabled() + " (routing dependent)");
11160         mSpatializerHelper.dump(pw);
11161         sSpatialLogger.dump(pw);
11162 
11163         mAudioSystem.dump(pw);
11164     }
11165 
dumpSupportedSystemUsage(PrintWriter pw)11166     private void dumpSupportedSystemUsage(PrintWriter pw) {
11167         pw.println("Supported System Usages:");
11168         synchronized (mSupportedSystemUsagesLock) {
11169             for (int i = 0; i < mSupportedSystemUsages.length; i++) {
11170                 pw.printf("\t%s\n", AudioAttributes.usageToString(mSupportedSystemUsages[i]));
11171             }
11172         }
11173     }
11174 
dumpAssistantServicesUids(PrintWriter pw)11175     private void dumpAssistantServicesUids(PrintWriter pw) {
11176         synchronized (mSettingsLock) {
11177             if (mAssistantUids.size() > 0) {
11178                 pw.println("  Assistant service UIDs:");
11179                 for (int uid : mAssistantUids) {
11180                     pw.println("  - " + uid);
11181                 }
11182             } else {
11183                 pw.println("  No Assistant service Uids.");
11184             }
11185         }
11186     }
11187 
dumpAccessibilityServiceUids(PrintWriter pw)11188     private void dumpAccessibilityServiceUids(PrintWriter pw) {
11189         synchronized (mSupportedSystemUsagesLock) {
11190             if (mAccessibilityServiceUids != null && mAccessibilityServiceUids.length > 0) {
11191                 pw.println("  Accessibility service Uids:");
11192                 for (int uid : mAccessibilityServiceUids) {
11193                     pw.println("  - " + uid);
11194                 }
11195             } else {
11196                 pw.println("  No accessibility service Uids.");
11197             }
11198         }
11199     }
11200 
11201     /**
11202      * Audio Analytics ids.
11203      */
11204     private static final String mMetricsId = MediaMetrics.Name.AUDIO_SERVICE
11205             + MediaMetrics.SEPARATOR;
11206 
11207     // Inform AudioFlinger of our device's low RAM attribute
readAndSetLowRamDevice()11208     private static void readAndSetLowRamDevice()
11209     {
11210         boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic();
11211         long totalMemory = 1024 * 1024 * 1024; // 1GB is the default if ActivityManager fails.
11212 
11213         try {
11214             final ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();
11215             ActivityManager.getService().getMemoryInfo(info);
11216             totalMemory = info.totalMem;
11217         } catch (RemoteException e) {
11218             Log.w(TAG, "Cannot obtain MemoryInfo from ActivityManager, assume low memory device");
11219             isLowRamDevice = true;
11220         }
11221 
11222         final int status = AudioSystem.setLowRamDevice(isLowRamDevice, totalMemory);
11223         if (status != 0) {
11224             Log.w(TAG, "AudioFlinger informed of device's low RAM attribute; status " + status);
11225         }
11226     }
11227 
enforceVolumeController(String action)11228     private void enforceVolumeController(String action) {
11229         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE,
11230                 "Only SystemUI can " + action);
11231     }
11232 
11233     @Override
setVolumeController(final IVolumeController controller)11234     public void setVolumeController(final IVolumeController controller) {
11235         enforceVolumeController("set the volume controller");
11236 
11237         // return early if things are not actually changing
11238         if (mVolumeController.isSameBinder(controller)) {
11239             return;
11240         }
11241 
11242         // dismiss the old volume controller
11243         mVolumeController.postDismiss();
11244         if (controller != null) {
11245             // we are about to register a new controller, listen for its death
11246             try {
11247                 controller.asBinder().linkToDeath(new DeathRecipient() {
11248                     @Override
11249                     public void binderDied() {
11250                         if (mVolumeController.isSameBinder(controller)) {
11251                             Log.w(TAG, "Current remote volume controller died, unregistering");
11252                             setVolumeController(null);
11253                         }
11254                     }
11255                 }, 0);
11256             } catch (RemoteException e) {
11257                 // noop
11258             }
11259         }
11260         mVolumeController.setController(controller);
11261         if (DEBUG_VOL) Log.d(TAG, "Volume controller: " + mVolumeController);
11262     }
11263 
11264     @Override
11265     @Nullable
getVolumeController()11266     public IVolumeController getVolumeController() {
11267         enforceVolumeController("get the volume controller");
11268         if (DEBUG_VOL) Log.d(TAG, "Volume controller: " + mVolumeController);
11269 
11270         return mVolumeController.getController();
11271     }
11272 
11273     @Override
notifyVolumeControllerVisible(final IVolumeController controller, boolean visible)11274     public void notifyVolumeControllerVisible(final IVolumeController controller, boolean visible) {
11275         enforceVolumeController("notify about volume controller visibility");
11276 
11277         // return early if the controller is not current
11278         if (!mVolumeController.isSameBinder(controller)) {
11279             return;
11280         }
11281 
11282         mVolumeController.setVisible(visible);
11283         if (DEBUG_VOL) Log.d(TAG, "Volume controller visible: " + visible);
11284     }
11285 
11286     @Override
setVolumePolicy(VolumePolicy policy)11287     public void setVolumePolicy(VolumePolicy policy) {
11288         enforceVolumeController("set volume policy");
11289         if (policy != null && !policy.equals(mVolumePolicy)) {
11290             mVolumePolicy = policy;
11291             if (DEBUG_VOL) Log.d(TAG, "Volume policy changed: " + mVolumePolicy);
11292         }
11293     }
11294 
11295     /** Interface used for enforcing the safe hearing standard. */
11296     public interface ISafeHearingVolumeController {
11297         /** Displays an instructional safeguard as required by the safe hearing standard. */
postDisplaySafeVolumeWarning(int flags)11298         void postDisplaySafeVolumeWarning(int flags);
11299 
11300         /** Displays a warning about transient exposure to high level playback */
postDisplayCsdWarning(@udioManager.CsdWarning int csdEvent, int displayDurationMs)11301         void postDisplayCsdWarning(@AudioManager.CsdWarning int csdEvent, int displayDurationMs);
11302     }
11303 
11304     /** Wrapper which encapsulates the {@link IVolumeController} functionality. */
11305     public class VolumeController implements ISafeHearingVolumeController {
11306         private static final String TAG = "VolumeController";
11307 
11308         private IVolumeController mController;
11309         private boolean mVisible;
11310         private long mNextLongPress;
11311         private int mLongPressTimeout;
11312 
setController(IVolumeController controller)11313         public void setController(IVolumeController controller) {
11314             mController = controller;
11315             mVisible = false;
11316         }
11317 
getController()11318         public IVolumeController getController() {
11319             return mController;
11320         }
11321 
loadSettings(ContentResolver cr)11322         public void loadSettings(ContentResolver cr) {
11323             mLongPressTimeout = mSettings.getSecureIntForUser(cr,
11324                     Settings.Secure.LONG_PRESS_TIMEOUT, 500, UserHandle.USER_CURRENT);
11325         }
11326 
suppressAdjustment(int resolvedStream, int flags, boolean isMute)11327         public boolean suppressAdjustment(int resolvedStream, int flags, boolean isMute) {
11328             if (isMute) {
11329                 return false;
11330             }
11331             boolean suppress = false;
11332             // Intended behavior:
11333             // 1/ if the stream is not the default UI stream, do not suppress (as it is not involved
11334             //    in bringing up the UI)
11335             // 2/ if the resolved and default stream is MUSIC, and media is playing, do not suppress
11336             // 3/ otherwise suppress the first adjustments that occur during the "long press
11337             //    timeout" interval. Note this is true regardless of whether this is a "real long
11338             //    press" (where the user keeps pressing on the volume button), or repeated single
11339             //    presses (here we don't know if we are in a real long press, or repeated fast
11340             //    button presses).
11341             //    Once the long press timeout occurs (mNextLongPress reset to 0), do not suppress.
11342             // Example: for a default and resolved stream of MUSIC, this allows modifying rapidly
11343             // the volume when media is playing (whether by long press or repeated individual
11344             // presses), or to bring up the volume UI when media is not playing, in order to make
11345             // another change (e.g. switch ringer modes) without changing media volume.
11346             if (resolvedStream == DEFAULT_VOL_STREAM_NO_PLAYBACK && mController != null) {
11347                 // never suppress media vol adjustement during media playback
11348                 if (resolvedStream == AudioSystem.STREAM_MUSIC
11349                         && mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, mLongPressTimeout))
11350                 {
11351                     // media is playing, adjust the volume right away
11352                     return false;
11353                 }
11354 
11355                 final long now = SystemClock.uptimeMillis();
11356                 if ((flags & AudioManager.FLAG_SHOW_UI) != 0 && !mVisible) {
11357                     // UI is not visible yet, adjustment is ignored
11358                     if (mNextLongPress < now) {
11359                         mNextLongPress = now + mLongPressTimeout;
11360                     }
11361                     suppress = true;
11362                 } else if (mNextLongPress > 0) {  // in a long-press
11363                     if (now > mNextLongPress) {
11364                         // long press triggered, no more suppression
11365                         mNextLongPress = 0;
11366                     } else {
11367                         // keep suppressing until the long press triggers
11368                         suppress = true;
11369                     }
11370                 }
11371             }
11372             return suppress;
11373         }
11374 
setVisible(boolean visible)11375         public void setVisible(boolean visible) {
11376             mVisible = visible;
11377         }
11378 
isSameBinder(IVolumeController controller)11379         public boolean isSameBinder(IVolumeController controller) {
11380             return Objects.equals(asBinder(), binder(controller));
11381         }
11382 
asBinder()11383         public IBinder asBinder() {
11384             return binder(mController);
11385         }
11386 
binder(IVolumeController controller)11387         private IBinder binder(IVolumeController controller) {
11388             return controller == null ? null : controller.asBinder();
11389         }
11390 
11391         @Override
toString()11392         public String toString() {
11393             return "VolumeController(" + asBinder() + ",mVisible=" + mVisible + ")";
11394         }
11395 
11396         @Override
postDisplaySafeVolumeWarning(int flags)11397         public void postDisplaySafeVolumeWarning(int flags) {
11398             if (mController == null)
11399                 return;
11400             flags = flags | AudioManager.FLAG_SHOW_UI;
11401             try {
11402                 mController.displaySafeVolumeWarning(flags);
11403             } catch (RemoteException e) {
11404                 Log.w(TAG, "Error calling displaySafeVolumeWarning", e);
11405             }
11406         }
11407 
11408         @Override
postDisplayCsdWarning( @udioManager.CsdWarning int csdWarning, int displayDurationMs)11409         public void postDisplayCsdWarning(
11410                 @AudioManager.CsdWarning int csdWarning, int displayDurationMs) {
11411             if (mController == null) {
11412                 Log.e(TAG, "Unable to display CSD warning, no controller");
11413                 return;
11414             }
11415             try {
11416                 mController.displayCsdWarning(csdWarning, displayDurationMs);
11417             } catch (RemoteException e) {
11418                 Log.w(TAG, "Error calling displayCsdWarning for warning " + csdWarning, e);
11419             }
11420         }
11421 
postVolumeChanged(int streamType, int flags)11422         public void postVolumeChanged(int streamType, int flags) {
11423             if (mController == null)
11424                 return;
11425             try {
11426                 mController.volumeChanged(streamType, flags);
11427             } catch (RemoteException e) {
11428                 Log.w(TAG, "Error calling volumeChanged", e);
11429             }
11430         }
11431 
postMasterMuteChanged(int flags)11432         public void postMasterMuteChanged(int flags) {
11433             if (mController == null)
11434                 return;
11435             try {
11436                 mController.masterMuteChanged(flags);
11437             } catch (RemoteException e) {
11438                 Log.w(TAG, "Error calling masterMuteChanged", e);
11439             }
11440         }
11441 
setLayoutDirection(int layoutDirection)11442         public void setLayoutDirection(int layoutDirection) {
11443             if (mController == null)
11444                 return;
11445             try {
11446                 mController.setLayoutDirection(layoutDirection);
11447             } catch (RemoteException e) {
11448                 Log.w(TAG, "Error calling setLayoutDirection", e);
11449             }
11450         }
11451 
postDismiss()11452         public void postDismiss() {
11453             if (mController == null)
11454                 return;
11455             try {
11456                 mController.dismiss();
11457             } catch (RemoteException e) {
11458                 Log.w(TAG, "Error calling dismiss", e);
11459             }
11460         }
11461 
setA11yMode(int a11yMode)11462         public void setA11yMode(int a11yMode) {
11463             if (mController == null)
11464                 return;
11465             try {
11466                 mController.setA11yMode(a11yMode);
11467             } catch (RemoteException e) {
11468                 Log.w(TAG, "Error calling setA11Mode", e);
11469             }
11470         }
11471     }
11472 
11473     /**
11474      * Interface for system components to get some extra functionality through
11475      * LocalServices.
11476      */
11477     final class AudioServiceInternal extends AudioManagerInternal {
11478         @Override
setRingerModeDelegate(RingerModeDelegate delegate)11479         public void setRingerModeDelegate(RingerModeDelegate delegate) {
11480             mRingerModeDelegate = delegate;
11481             if (mRingerModeDelegate != null) {
11482                 synchronized (mSettingsLock) {
11483                     updateRingerAndZenModeAffectedStreams();
11484                 }
11485                 setRingerModeInternal(getRingerModeInternal(), TAG + ".setRingerModeDelegate");
11486             }
11487         }
11488 
11489         @Override
getRingerModeInternal()11490         public int getRingerModeInternal() {
11491             return AudioService.this.getRingerModeInternal();
11492         }
11493 
11494         @Override
setRingerModeInternal(int ringerMode, String caller)11495         public void setRingerModeInternal(int ringerMode, String caller) {
11496             AudioService.this.setRingerModeInternal(ringerMode, caller);
11497         }
11498 
11499         @Override
silenceRingerModeInternal(String caller)11500         public void silenceRingerModeInternal(String caller) {
11501             AudioService.this.silenceRingerModeInternal(caller);
11502         }
11503 
11504         @Override
updateRingerModeAffectedStreamsInternal()11505         public void updateRingerModeAffectedStreamsInternal() {
11506             synchronized (mSettingsLock) {
11507                 if (updateRingerAndZenModeAffectedStreams()) {
11508                     setRingerModeInt(getRingerModeInternal(), false);
11509                 }
11510             }
11511         }
11512 
11513         @Override
addAssistantServiceUid(int uid)11514         public void addAssistantServiceUid(int uid) {
11515             sendMsg(mAudioHandler, MSG_ADD_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE,
11516                     uid, 0, null, 0);
11517         }
11518 
11519         @Override
removeAssistantServiceUid(int uid)11520         public void removeAssistantServiceUid(int uid) {
11521             sendMsg(mAudioHandler, MSG_REMOVE_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE,
11522                     uid, 0, null, 0);
11523         }
11524 
11525         @Override
setActiveAssistantServicesUids(IntArray activeUids)11526         public void setActiveAssistantServicesUids(IntArray activeUids) {
11527             synchronized (mSettingsLock) {
11528                 if (activeUids.size() == 0) {
11529                     mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS;
11530                 } else {
11531                     boolean changed = (mActiveAssistantServiceUids == null)
11532                             || (mActiveAssistantServiceUids.length != activeUids.size());
11533                     if (!changed) {
11534                         for (int i = 0; i < mActiveAssistantServiceUids.length; i++) {
11535                             if (activeUids.get(i) != mActiveAssistantServiceUids[i]) {
11536                                 changed = true;
11537                                 break;
11538                             }
11539                         }
11540                     }
11541                     if (changed) {
11542                         mActiveAssistantServiceUids = activeUids.toArray();
11543                     }
11544                 }
11545             }
11546             sendMsg(mAudioHandler, MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID, SENDMSG_REPLACE,
11547                     0, 0, null, 0);
11548         }
11549 
11550         @Override
setAccessibilityServiceUids(IntArray uids)11551         public void setAccessibilityServiceUids(IntArray uids) {
11552             // TODO(b/233287010): Fix voice interaction and a11y concurrency in audio policy service
11553             if (isPlatformAutomotive()) {
11554                 return;
11555             }
11556 
11557             synchronized (mAccessibilityServiceUidsLock) {
11558                 if (uids.size() == 0) {
11559                     mAccessibilityServiceUids = null;
11560                 } else {
11561                     boolean changed = (mAccessibilityServiceUids == null)
11562                             || (mAccessibilityServiceUids.length != uids.size());
11563                     if (!changed) {
11564                         for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
11565                             if (uids.get(i) != mAccessibilityServiceUids[i]) {
11566                                 changed = true;
11567                                 break;
11568                             }
11569                         }
11570                     }
11571                     if (changed) {
11572                         mAccessibilityServiceUids = uids.toArray();
11573                     }
11574                 }
11575                 sendMsg(mAudioHandler, MSG_UPDATE_A11Y_SERVICE_UIDS, SENDMSG_REPLACE,
11576                         0, 0, null, 0);
11577             }
11578         }
11579 
11580         /**
11581          * {@inheritDoc}
11582          */
11583         @Override
setInputMethodServiceUid(int uid)11584         public void setInputMethodServiceUid(int uid) {
11585             synchronized (mInputMethodServiceUidLock) {
11586                 if (mInputMethodServiceUid != uid) {
11587                     mAudioSystem.setCurrentImeUid(uid);
11588                     mInputMethodServiceUid = uid;
11589                 }
11590             }
11591         }
11592     }
11593 
onUpdateAccessibilityServiceUids()11594     private void onUpdateAccessibilityServiceUids() {
11595         int[] accessibilityServiceUids;
11596         synchronized (mAccessibilityServiceUidsLock) {
11597             accessibilityServiceUids = mAccessibilityServiceUids;
11598         }
11599         AudioSystem.setA11yServicesUids(accessibilityServiceUids);
11600     }
11601 
11602     //==========================================================================================
11603     // Audio policy management
11604     //==========================================================================================
registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection)11605     public String registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb,
11606             boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy,
11607             boolean isVolumeController, IMediaProjection projection) {
11608         AudioSystem.setDynamicPolicyCallback(mDynPolicyCallback);
11609 
11610         if (!isPolicyRegisterAllowed(policyConfig,
11611                                      isFocusPolicy || isTestFocusPolicy || hasFocusListener,
11612                                      isVolumeController,
11613                                      projection)) {
11614             Slog.w(TAG, "Permission denied to register audio policy for pid "
11615                     + Binder.getCallingPid() + " / uid " + Binder.getCallingUid()
11616                     + ", need system permission or a MediaProjection that can project audio");
11617             return null;
11618         }
11619 
11620         String regId = null;
11621         synchronized (mAudioPolicies) {
11622             if (mAudioPolicies.containsKey(pcb.asBinder())) {
11623                 Slog.e(TAG, "Cannot re-register policy");
11624                 return null;
11625             }
11626             try {
11627                 AudioPolicyProxy app = new AudioPolicyProxy(policyConfig, pcb, hasFocusListener,
11628                         isFocusPolicy, isTestFocusPolicy, isVolumeController, projection);
11629                 pcb.asBinder().linkToDeath(app, 0/*flags*/);
11630 
11631                 // logging after registration so we have the registration id
11632                 mDynPolicyLogger.enqueue((new EventLogger.StringEvent("registerAudioPolicy for "
11633                         + pcb.asBinder() + " u/pid:" + Binder.getCallingUid() + "/"
11634                         + Binder.getCallingPid() + " with config:" + app.toCompactLogString()))
11635                         .printLog(TAG));
11636 
11637                 regId = app.getRegistrationId();
11638                 mAudioPolicies.put(pcb.asBinder(), app);
11639             } catch (RemoteException e) {
11640                 // audio policy owner has already died!
11641                 Slog.w(TAG, "Audio policy registration failed, could not link to " + pcb +
11642                         " binder death", e);
11643                 return null;
11644             } catch (IllegalStateException e) {
11645                 Slog.w(TAG, "Audio policy registration failed for binder " + pcb, e);
11646                 return null;
11647             }
11648         }
11649         return regId;
11650     }
11651 
11652     /**
11653      * Called by an AudioPolicyProxy when the client dies.
11654      * Checks if an active playback for media use case is currently routed to one of the
11655      * remote submix devices owned by this dynamic policy and broadcasts a becoming noisy
11656      * intend in this case.
11657      * @param addresses list of remote submix device addresses to check.
11658      */
onPolicyClientDeath(List<String> addresses)11659     private void onPolicyClientDeath(List<String> addresses) {
11660         for (String address : addresses) {
11661             if (mPlaybackMonitor.hasActiveMediaPlaybackOnSubmixWithAddress(address)) {
11662                 mDeviceBroker.postBroadcastBecomingNoisy();
11663                 return;
11664             }
11665         }
11666     }
11667     /**
11668      * Apps with MODIFY_AUDIO_ROUTING can register any policy.
11669      * Apps with an audio capable MediaProjection are allowed to register a RENDER|LOOPBACK policy
11670      * as those policy do not modify the audio routing.
11671      */
isPolicyRegisterAllowed(AudioPolicyConfig policyConfig, boolean hasFocusAccess, boolean isVolumeController, IMediaProjection projection)11672     private boolean isPolicyRegisterAllowed(AudioPolicyConfig policyConfig,
11673                                             boolean hasFocusAccess,
11674                                             boolean isVolumeController,
11675                                             IMediaProjection projection) {
11676 
11677         boolean requireValidProjection = false;
11678         boolean requireCaptureAudioOrMediaOutputPerm = false;
11679         boolean requireModifyRouting = false;
11680         boolean requireCallAudioInterception = false;
11681         ArrayList<AudioMix> voiceCommunicationCaptureMixes = null;
11682 
11683 
11684         if (hasFocusAccess || isVolumeController) {
11685             requireModifyRouting |= true;
11686         } else if (policyConfig.getMixes().isEmpty()) {
11687             // An empty policy could be used to lock the focus or add mixes later
11688             requireModifyRouting |= true;
11689         }
11690         for (AudioMix mix : policyConfig.getMixes()) {
11691             // If mix is requesting privileged capture
11692             if (mix.getRule().allowPrivilegedMediaPlaybackCapture()) {
11693                 // then its format must be low quality enough
11694                 String privilegedMediaCaptureError =
11695                         mix.canBeUsedForPrivilegedMediaCapture(mix.getFormat());
11696                 if (privilegedMediaCaptureError != null) {
11697                     Log.e(TAG, privilegedMediaCaptureError);
11698                     return false;
11699                 }
11700                 // and it must have CAPTURE_MEDIA_OUTPUT or CAPTURE_AUDIO_OUTPUT permission
11701                 requireCaptureAudioOrMediaOutputPerm |= true;
11702 
11703             }
11704             // If mix is trying to explicitly capture USAGE_VOICE_COMMUNICATION
11705             if (mix.containsMatchAttributeRuleForUsage(
11706                     AudioAttributes.USAGE_VOICE_COMMUNICATION)
11707                     && (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER)) {
11708                 // It must have CAPTURE_USAGE_VOICE_COMMUNICATION_OUTPUT permission
11709                 // Note that for UID, USERID or EXCLDUE rules, the capture will be silenced
11710                 // in AudioPolicyMix
11711                 if (voiceCommunicationCaptureMixes == null) {
11712                     voiceCommunicationCaptureMixes = new ArrayList<AudioMix>();
11713                 }
11714                 voiceCommunicationCaptureMixes.add(mix);
11715             }
11716 
11717             // If mix is RENDER|LOOPBACK, then an audio MediaProjection is enough
11718             // otherwise MODIFY_AUDIO_ROUTING permission is required
11719             if (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER && projection != null) {
11720                 requireValidProjection |= true;
11721             } else if (mix.isForCallRedirection()) {
11722                 requireCallAudioInterception |= true;
11723             } else if (mix.containsMatchAttributeRuleForUsage(
11724                             AudioAttributes.USAGE_VOICE_COMMUNICATION)) {
11725                 requireModifyRouting |= true;
11726             }
11727         }
11728 
11729         if (requireCaptureAudioOrMediaOutputPerm
11730                 && !callerHasPermission(android.Manifest.permission.CAPTURE_MEDIA_OUTPUT)
11731                 && !callerHasPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT)) {
11732             Log.e(TAG, "Privileged audio capture requires CAPTURE_MEDIA_OUTPUT or "
11733                       + "CAPTURE_AUDIO_OUTPUT system permission");
11734             return false;
11735         }
11736 
11737         if (voiceCommunicationCaptureMixes != null && voiceCommunicationCaptureMixes.size() > 0) {
11738             if (!callerHasPermission(
11739                     android.Manifest.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT)) {
11740                 Log.e(TAG, "Audio capture for voice communication requires "
11741                         + "CAPTURE_VOICE_COMMUNICATION_OUTPUT system permission");
11742                 return false;
11743             }
11744 
11745             // If permission check succeeded, we set the flag in each of the mixing rules
11746             for (AudioMix mix : voiceCommunicationCaptureMixes) {
11747                 mix.getRule().setVoiceCommunicationCaptureAllowed(true);
11748             }
11749         }
11750 
11751         if (requireValidProjection && !canProjectAudio(projection)) {
11752             return false;
11753         }
11754 
11755         if (requireModifyRouting
11756                 && !callerHasPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)) {
11757             Log.e(TAG, "Can not capture audio without MODIFY_AUDIO_ROUTING");
11758             return false;
11759         }
11760 
11761         if (requireCallAudioInterception
11762                 && !callerHasPermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION)) {
11763             Log.e(TAG, "Can not capture audio without CALL_AUDIO_INTERCEPTION");
11764             return false;
11765         }
11766 
11767         return true;
11768     }
11769 
callerHasPermission(String permission)11770     private boolean callerHasPermission(String permission) {
11771         return mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED;
11772     }
11773 
11774     /** @return true if projection is a valid MediaProjection that can project audio. */
canProjectAudio(IMediaProjection projection)11775     private boolean canProjectAudio(IMediaProjection projection) {
11776         if (projection == null) {
11777             Log.e(TAG, "MediaProjection is null");
11778             return false;
11779         }
11780 
11781         IMediaProjectionManager projectionService = getProjectionService();
11782         if (projectionService == null) {
11783             Log.e(TAG, "Can't get service IMediaProjectionManager");
11784             return false;
11785         }
11786 
11787         final long token = Binder.clearCallingIdentity();
11788         try {
11789             if (!projectionService.isCurrentProjection(projection)) {
11790                 Log.w(TAG, "App passed invalid MediaProjection token");
11791                 return false;
11792             }
11793         } catch (RemoteException e) {
11794             Log.e(TAG, "Can't call .isCurrentProjection() on IMediaProjectionManager"
11795                     + projectionService.asBinder(), e);
11796             return false;
11797         } finally {
11798             Binder.restoreCallingIdentity(token);
11799         }
11800 
11801         try {
11802             if (!projection.canProjectAudio()) {
11803                 Log.w(TAG, "App passed MediaProjection that can not project audio");
11804                 return false;
11805             }
11806         } catch (RemoteException e) {
11807             Log.e(TAG, "Can't call .canProjectAudio() on valid IMediaProjection"
11808                     + projection.asBinder(), e);
11809             return false;
11810         }
11811 
11812         return true;
11813     }
11814 
getProjectionService()11815     private IMediaProjectionManager getProjectionService() {
11816         if (mProjectionService == null) {
11817             IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE);
11818             mProjectionService = IMediaProjectionManager.Stub.asInterface(b);
11819         }
11820         return mProjectionService;
11821     }
11822 
11823     /**
11824      * See {@link AudioManager#unregisterAudioPolicyAsync(AudioPolicy)}
11825      * Declared oneway
11826      * @param pcb nullable because on service interface
11827      */
unregisterAudioPolicyAsync(@ullable IAudioPolicyCallback pcb)11828     public void unregisterAudioPolicyAsync(@Nullable IAudioPolicyCallback pcb) {
11829         if (pcb == null) {
11830             return;
11831         }
11832         unregisterAudioPolicyInt(pcb, "unregisterAudioPolicyAsync");
11833     }
11834 
11835     /**
11836      * See {@link AudioManager#unregisterAudioPolicy(AudioPolicy)}
11837      * @param pcb nullable because on service interface
11838      */
unregisterAudioPolicy(@ullable IAudioPolicyCallback pcb)11839     public void unregisterAudioPolicy(@Nullable IAudioPolicyCallback pcb) {
11840         if (pcb == null) {
11841             return;
11842         }
11843         unregisterAudioPolicyInt(pcb, "unregisterAudioPolicy");
11844     }
11845 
11846 
unregisterAudioPolicyInt(@onNull IAudioPolicyCallback pcb, String operationName)11847     private void unregisterAudioPolicyInt(@NonNull IAudioPolicyCallback pcb, String operationName) {
11848         mDynPolicyLogger.enqueue((new EventLogger.StringEvent(operationName + " for "
11849                 + pcb.asBinder()).printLog(TAG)));
11850         synchronized (mAudioPolicies) {
11851             AudioPolicyProxy app = mAudioPolicies.remove(pcb.asBinder());
11852             if (app == null) {
11853                 Slog.w(TAG, "Trying to unregister unknown audio policy for pid "
11854                         + Binder.getCallingPid() + " / uid " + Binder.getCallingUid());
11855                 return;
11856             } else {
11857                 pcb.asBinder().unlinkToDeath(app, 0/*flags*/);
11858             }
11859             app.release();
11860         }
11861         // TODO implement clearing mix attribute matching info in native audio policy
11862     }
11863 
11864     /**
11865      * Checks whether caller has MODIFY_AUDIO_ROUTING permission, and the policy is registered.
11866      * @param errorMsg log warning if permission check failed.
11867      * @return null if the operation on the audio mixes should be cancelled.
11868      */
11869     @GuardedBy("mAudioPolicies")
checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg)11870     private AudioPolicyProxy checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg) {
11871         // permission check
11872         final boolean hasPermissionForPolicy =
11873                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
11874                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
11875         if (!hasPermissionForPolicy) {
11876             Slog.w(TAG, errorMsg + " for pid " +
11877                     + Binder.getCallingPid() + " / uid "
11878                     + Binder.getCallingUid() + ", need MODIFY_AUDIO_ROUTING");
11879             return null;
11880         }
11881         // policy registered?
11882         final AudioPolicyProxy app = mAudioPolicies.get(pcb.asBinder());
11883         if (app == null) {
11884             Slog.w(TAG, errorMsg + " for pid " +
11885                     + Binder.getCallingPid() + " / uid "
11886                     + Binder.getCallingUid() + ", unregistered policy");
11887             return null;
11888         }
11889         return app;
11890     }
11891 
addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)11892     public int addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) {
11893         if (DEBUG_AP) { Log.d(TAG, "addMixForPolicy for " + pcb.asBinder()
11894                 + " with config:" + policyConfig); }
11895         synchronized (mAudioPolicies) {
11896             final AudioPolicyProxy app =
11897                     checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy");
11898             if (app == null){
11899                 return AudioManager.ERROR;
11900             }
11901             return app.addMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS
11902                 ? AudioManager.SUCCESS : AudioManager.ERROR;
11903         }
11904     }
11905 
removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)11906     public int removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) {
11907         if (DEBUG_AP) { Log.d(TAG, "removeMixForPolicy for " + pcb.asBinder()
11908                 + " with config:" + policyConfig); }
11909         synchronized (mAudioPolicies) {
11910             final AudioPolicyProxy app =
11911                     checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy");
11912             if (app == null) {
11913                 return AudioManager.ERROR;
11914             }
11915             return app.removeMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS
11916                 ? AudioManager.SUCCESS : AudioManager.ERROR;
11917         }
11918     }
11919 
11920     /** see AudioPolicy.setUidDeviceAffinity() */
setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)11921     public int setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid,
11922             @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) {
11923         if (DEBUG_AP) {
11924             Log.d(TAG, "setUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid);
11925         }
11926         synchronized (mAudioPolicies) {
11927             final AudioPolicyProxy app =
11928                     checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy");
11929             if (app == null) {
11930                 return AudioManager.ERROR;
11931             }
11932             if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) {
11933                 return AudioManager.ERROR;
11934             }
11935             return app.setUidDeviceAffinities(uid, deviceTypes, deviceAddresses);
11936         }
11937     }
11938 
11939     /** see AudioPolicy.setUserIdDeviceAffinity() */
setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)11940     public int setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId,
11941             @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) {
11942         if (DEBUG_AP) {
11943             Log.d(TAG, "setUserIdDeviceAffinity for " + pcb.asBinder() + " user:" + userId);
11944         }
11945 
11946         synchronized (mAudioPolicies) {
11947             final AudioPolicyProxy app =
11948                     checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy");
11949             if (app == null) {
11950                 return AudioManager.ERROR;
11951             }
11952             if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) {
11953                 return AudioManager.ERROR;
11954             }
11955             return app.setUserIdDeviceAffinities(userId, deviceTypes, deviceAddresses);
11956         }
11957     }
11958 
11959     /** see AudioPolicy.removeUidDeviceAffinity() */
removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid)11960     public int removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid) {
11961         if (DEBUG_AP) {
11962             Log.d(TAG, "removeUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid);
11963         }
11964         synchronized (mAudioPolicies) {
11965             final AudioPolicyProxy app =
11966                     checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy");
11967             if (app == null) {
11968                 return AudioManager.ERROR;
11969             }
11970             return app.removeUidDeviceAffinities(uid);
11971         }
11972     }
11973 
11974     /** see AudioPolicy.removeUserIdDeviceAffinity() */
removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId)11975     public int removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId) {
11976         if (DEBUG_AP) {
11977             Log.d(TAG, "removeUserIdDeviceAffinity for " + pcb.asBinder()
11978                     + " userId:" + userId);
11979         }
11980         synchronized (mAudioPolicies) {
11981             final AudioPolicyProxy app =
11982                     checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy");
11983             if (app == null) {
11984                 return AudioManager.ERROR;
11985             }
11986             return app.removeUserIdDeviceAffinities(userId);
11987         }
11988     }
11989 
setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb)11990     public int setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb) {
11991         if (DEBUG_AP) Log.d(TAG, "setFocusPropertiesForPolicy() duck behavior=" + duckingBehavior
11992                 + " policy " +  pcb.asBinder());
11993         synchronized (mAudioPolicies) {
11994             final AudioPolicyProxy app =
11995                     checkUpdateForPolicy(pcb, "Cannot change audio policy focus properties");
11996             if (app == null){
11997                 return AudioManager.ERROR;
11998             }
11999             if (!mAudioPolicies.containsKey(pcb.asBinder())) {
12000                 Slog.e(TAG, "Cannot change audio policy focus properties, unregistered policy");
12001                 return AudioManager.ERROR;
12002             }
12003             if (duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) {
12004                 // is there already one policy managing ducking?
12005                 for (AudioPolicyProxy policy : mAudioPolicies.values()) {
12006                     if (policy.mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) {
12007                         Slog.e(TAG, "Cannot change audio policy ducking behavior, already handled");
12008                         return AudioManager.ERROR;
12009                     }
12010                 }
12011             }
12012             app.mFocusDuckBehavior = duckingBehavior;
12013             mMediaFocusControl.setDuckingInExtPolicyAvailable(
12014                     duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY);
12015         }
12016         return AudioManager.SUCCESS;
12017     }
12018 
12019     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
12020     /** @see AudioPolicy#getFocusStack() */
getFocusStack()12021     public List<AudioFocusInfo> getFocusStack() {
12022         super.getFocusStack_enforcePermission();
12023 
12024         return mMediaFocusControl.getFocusStack();
12025     }
12026 
12027     /** @see AudioPolicy#sendFocusLoss */
sendFocusLoss(@onNull AudioFocusInfo focusLoser, @NonNull IAudioPolicyCallback apcb)12028     public boolean sendFocusLoss(@NonNull AudioFocusInfo focusLoser,
12029             @NonNull IAudioPolicyCallback apcb) {
12030         Objects.requireNonNull(focusLoser);
12031         Objects.requireNonNull(apcb);
12032         enforceModifyAudioRoutingPermission();
12033         if (!mAudioPolicies.containsKey(apcb.asBinder())) {
12034             throw new IllegalStateException("Only registered AudioPolicy can change focus");
12035         }
12036         if (!mAudioPolicies.get(apcb.asBinder()).mHasFocusListener) {
12037             throw new IllegalStateException("AudioPolicy must have focus listener to change focus");
12038         }
12039         return mMediaFocusControl.sendFocusLoss(focusLoser);
12040     }
12041 
12042     /**
12043      * @see AudioManager#getHalVersion
12044      */
getHalVersion()12045     public @Nullable AudioHalVersionInfo getHalVersion() {
12046         for (AudioHalVersionInfo version : AudioHalVersionInfo.VERSIONS) {
12047             try {
12048                 // TODO: check AIDL service.
12049                 String versionStr = version.getMajorVersion() + "." + version.getMinorVersion();
12050                 HwBinder.getService(
12051                         String.format("android.hardware.audio@%s::IDevicesFactory", versionStr),
12052                         "default");
12053                 return version;
12054             } catch (NoSuchElementException e) {
12055                 // Ignore, the specified HAL interface is not found.
12056             } catch (RemoteException re) {
12057                 Log.e(TAG, "Remote exception when getting hardware audio service:", re);
12058             }
12059         }
12060         return null;
12061     }
12062 
12063     /** see AudioManager.hasRegisteredDynamicPolicy */
hasRegisteredDynamicPolicy()12064     public boolean hasRegisteredDynamicPolicy() {
12065         synchronized (mAudioPolicies) {
12066             return !mAudioPolicies.isEmpty();
12067         }
12068     }
12069 
12070     /**
12071      * @see AudioManager#setPreferredMixerAttributes(
12072      *      AudioAttributes, AudioDeviceInfo, AudioMixerAttributes)
12073      */
setPreferredMixerAttributes(AudioAttributes attributes, int portId, AudioMixerAttributes mixerAttributes)12074     public int setPreferredMixerAttributes(AudioAttributes attributes,
12075             int portId, AudioMixerAttributes mixerAttributes) {
12076         Objects.requireNonNull(attributes);
12077         Objects.requireNonNull(mixerAttributes);
12078         if (!checkAudioSettingsPermission("setPreferredMixerAttributes()")) {
12079             return AudioSystem.PERMISSION_DENIED;
12080         }
12081         final int uid = Binder.getCallingUid();
12082         final int pid = Binder.getCallingPid();
12083         int status = AudioSystem.SUCCESS;
12084         final long token = Binder.clearCallingIdentity();
12085         try {
12086             final String logString = TextUtils.formatSimple(
12087                     "setPreferredMixerAttributes u/pid:%d/%d attr:%s mixerAttributes:%s portId:%d",
12088                     uid, pid, attributes.toString(), mixerAttributes.toString(), portId);
12089             sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
12090 
12091             status = mAudioSystem.setPreferredMixerAttributes(
12092                     attributes, portId, uid, mixerAttributes);
12093             if (status == AudioSystem.SUCCESS) {
12094                 dispatchPreferredMixerAttributesChanged(attributes, portId, mixerAttributes);
12095             } else {
12096                 Log.e(TAG, TextUtils.formatSimple("Error %d in %s)", status, logString));
12097             }
12098         } finally {
12099             Binder.restoreCallingIdentity(token);
12100         }
12101         return status;
12102     }
12103 
12104     /**
12105      * @see AudioManager#clearPreferredMixerAttributes(AudioAttributes, AudioDeviceInfo)
12106      */
clearPreferredMixerAttributes(AudioAttributes attributes, int portId)12107     public int clearPreferredMixerAttributes(AudioAttributes attributes, int portId) {
12108         Objects.requireNonNull(attributes);
12109         if (!checkAudioSettingsPermission("clearPreferredMixerAttributes()")) {
12110             return AudioSystem.PERMISSION_DENIED;
12111         }
12112         final int uid = Binder.getCallingUid();
12113         final int pid = Binder.getCallingPid();
12114         int status = AudioSystem.SUCCESS;
12115         final long token = Binder.clearCallingIdentity();
12116         try {
12117             final String logString = TextUtils.formatSimple(
12118                     "clearPreferredMixerAttributes u/pid:%d/%d attr:%s",
12119                     uid, pid, attributes.toString());
12120             sDeviceLogger.enqueue(new EventLogger.StringEvent(logString).printLog(TAG));
12121 
12122             status = mAudioSystem.clearPreferredMixerAttributes(attributes, portId, uid);
12123             if (status == AudioSystem.SUCCESS) {
12124                 dispatchPreferredMixerAttributesChanged(attributes, portId, null /*mixerAttr*/);
12125             } else {
12126                 Log.e(TAG, TextUtils.formatSimple("Error %d in %s)", status, logString));
12127             }
12128         } finally {
12129             Binder.restoreCallingIdentity(token);
12130         }
12131         return status;
12132     }
12133 
dispatchPreferredMixerAttributesChanged( AudioAttributes attr, int deviceId, AudioMixerAttributes mixerAttr)12134     void dispatchPreferredMixerAttributesChanged(
12135             AudioAttributes attr, int deviceId, AudioMixerAttributes mixerAttr) {
12136         Bundle bundle = new Bundle();
12137         bundle.putParcelable(KEY_AUDIO_ATTRIBUTES, attr);
12138         bundle.putParcelable(KEY_AUDIO_MIXER_ATTRIBUTES, mixerAttr);
12139         sendBundleMsg(mAudioHandler, MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES, SENDMSG_QUEUE,
12140                 deviceId, 0, null, bundle, 0);
12141     }
12142 
12143     final RemoteCallbackList<IPreferredMixerAttributesDispatcher> mPrefMixerAttrDispatcher =
12144             new RemoteCallbackList<IPreferredMixerAttributesDispatcher>();
12145     private static final String KEY_AUDIO_ATTRIBUTES = "audio_attributes";
12146     private static final String KEY_AUDIO_MIXER_ATTRIBUTES = "audio_mixer_attributes";
12147 
12148     /** @see AudioManager#addOnPreferredMixerAttributesChangedListener(
12149      *       Executor, AudioManager.OnPreferredMixerAttributesChangedListener)
12150      */
registerPreferredMixerAttributesDispatcher( @ullable IPreferredMixerAttributesDispatcher dispatcher)12151     public void registerPreferredMixerAttributesDispatcher(
12152             @Nullable IPreferredMixerAttributesDispatcher dispatcher) {
12153         if (dispatcher == null) {
12154             return;
12155         }
12156         mPrefMixerAttrDispatcher.register(dispatcher);
12157     }
12158 
12159     /** @see AudioManager#removeOnPreferredMixerAttributesChangedListener(
12160      *       AudioManager.OnPreferredMixerAttributesChangedListener)
12161      */
unregisterPreferredMixerAttributesDispatcher( @ullable IPreferredMixerAttributesDispatcher dispatcher)12162     public void unregisterPreferredMixerAttributesDispatcher(
12163             @Nullable IPreferredMixerAttributesDispatcher dispatcher) {
12164         if (dispatcher == null) {
12165             return;
12166         }
12167         mPrefMixerAttrDispatcher.unregister(dispatcher);
12168     }
12169 
onDispatchPreferredMixerAttributesChanged(Bundle data, int deviceId)12170     protected void onDispatchPreferredMixerAttributesChanged(Bundle data, int deviceId) {
12171         final int nbDispathers = mPrefMixerAttrDispatcher.beginBroadcast();
12172         final AudioAttributes attr = data.getParcelable(
12173                 KEY_AUDIO_ATTRIBUTES, AudioAttributes.class);
12174         final AudioMixerAttributes mixerAttr = data.getParcelable(
12175                 KEY_AUDIO_MIXER_ATTRIBUTES, AudioMixerAttributes.class);
12176         for (int i = 0; i < nbDispathers; i++) {
12177             try {
12178                 mPrefMixerAttrDispatcher.getBroadcastItem(i)
12179                         .dispatchPrefMixerAttributesChanged(attr, deviceId, mixerAttr);
12180             } catch (RemoteException e) {
12181                 Log.e(TAG, "Can't call dispatchPrefMixerAttributesChanged() "
12182                         + "IPreferredMixerAttributesDispatcher "
12183                         + mPrefMixerAttrDispatcher.getBroadcastItem(i).asBinder(), e);
12184             }
12185         }
12186         mPrefMixerAttrDispatcher.finishBroadcast();
12187     }
12188 
12189 
12190     /** @see AudioManager#supportsBluetoothVariableLatency() */
12191     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
supportsBluetoothVariableLatency()12192     public boolean supportsBluetoothVariableLatency() {
12193         super.supportsBluetoothVariableLatency_enforcePermission();
12194         try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
12195             return AudioSystem.supportsBluetoothVariableLatency();
12196         }
12197     }
12198 
12199     /** @see AudioManager#setBluetoothVariableLatencyEnabled(boolean) */
12200     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
setBluetoothVariableLatencyEnabled(boolean enabled)12201     public void setBluetoothVariableLatencyEnabled(boolean enabled) {
12202         super.setBluetoothVariableLatencyEnabled_enforcePermission();
12203         try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
12204             AudioSystem.setBluetoothVariableLatencyEnabled(enabled);
12205         }
12206     }
12207 
12208     /** @see AudioManager#isBluetoothVariableLatencyEnabled(boolean) */
12209     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
isBluetoothVariableLatencyEnabled()12210     public boolean isBluetoothVariableLatencyEnabled() {
12211         super.isBluetoothVariableLatencyEnabled_enforcePermission();
12212         try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
12213             return AudioSystem.isBluetoothVariableLatencyEnabled();
12214         }
12215     }
12216 
12217     private final Object mExtVolumeControllerLock = new Object();
12218     private IAudioPolicyCallback mExtVolumeController;
setExtVolumeController(IAudioPolicyCallback apc)12219     private void setExtVolumeController(IAudioPolicyCallback apc) {
12220         if (!mContext.getResources().getBoolean(
12221                 com.android.internal.R.bool.config_handleVolumeKeysInWindowManager)) {
12222             Log.e(TAG, "Cannot set external volume controller: device not set for volume keys" +
12223                     " handled in PhoneWindowManager");
12224             return;
12225         }
12226         synchronized (mExtVolumeControllerLock) {
12227             if (mExtVolumeController != null && !mExtVolumeController.asBinder().pingBinder()) {
12228                 Log.e(TAG, "Cannot set external volume controller: existing controller");
12229             }
12230             mExtVolumeController = apc;
12231         }
12232     }
12233 
dumpAudioPolicies(PrintWriter pw)12234     private void dumpAudioPolicies(PrintWriter pw) {
12235         pw.println("\nAudio policies:");
12236         synchronized (mAudioPolicies) {
12237             for (AudioPolicyProxy policy : mAudioPolicies.values()) {
12238                 pw.println(policy.toLogFriendlyString());
12239             }
12240         }
12241     }
12242 
12243     //======================
12244     // Audio policy callbacks from AudioSystem for dynamic policies
12245     //======================
12246     private final AudioSystem.DynamicPolicyCallback mDynPolicyCallback =
12247             new AudioSystem.DynamicPolicyCallback() {
12248         public void onDynamicPolicyMixStateUpdate(String regId, int state) {
12249             if (!TextUtils.isEmpty(regId)) {
12250                 sendMsg(mAudioHandler, MSG_DYN_POLICY_MIX_STATE_UPDATE, SENDMSG_QUEUE,
12251                         state /*arg1*/, 0 /*arg2 ignored*/, regId /*obj*/, 0 /*delay*/);
12252             }
12253         }
12254     };
12255 
onDynPolicyMixStateUpdate(String regId, int state)12256     private void onDynPolicyMixStateUpdate(String regId, int state) {
12257         if (DEBUG_AP) Log.d(TAG, "onDynamicPolicyMixStateUpdate("+ regId + ", " + state +")");
12258         synchronized (mAudioPolicies) {
12259             for (AudioPolicyProxy policy : mAudioPolicies.values()) {
12260                 for (AudioMix mix : policy.getMixes()) {
12261                     if (mix.getRegistration().equals(regId)) {
12262                         try {
12263                             policy.mPolicyCallback.notifyMixStateUpdate(regId, state);
12264                         } catch (RemoteException e) {
12265                             Log.e(TAG, "Can't call notifyMixStateUpdate() on IAudioPolicyCallback "
12266                                     + policy.mPolicyCallback.asBinder(), e);
12267                         }
12268                         return;
12269                     }
12270                 }
12271             }
12272         }
12273     }
12274 
12275     //======================
12276     // Audio policy callbacks from AudioSystem for recording configuration updates
12277     //======================
12278     private final RecordingActivityMonitor mRecordMonitor;
12279 
registerRecordingCallback(IRecordingConfigDispatcher rcdb)12280     public void registerRecordingCallback(IRecordingConfigDispatcher rcdb) {
12281         final boolean isPrivileged =
12282                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
12283                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
12284         mRecordMonitor.registerRecordingCallback(rcdb, isPrivileged);
12285     }
12286 
unregisterRecordingCallback(IRecordingConfigDispatcher rcdb)12287     public void unregisterRecordingCallback(IRecordingConfigDispatcher rcdb) {
12288         mRecordMonitor.unregisterRecordingCallback(rcdb);
12289     }
12290 
getActiveRecordingConfigurations()12291     public List<AudioRecordingConfiguration> getActiveRecordingConfigurations() {
12292         final boolean isPrivileged = Binder.getCallingUid() == Process.SYSTEM_UID
12293                 || (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
12294                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
12295         return mRecordMonitor.getActiveRecordingConfigurations(isPrivileged);
12296     }
12297 
12298     //======================
12299     // Audio recording state notification from clients
12300     //======================
12301     /**
12302      * Track a recorder provided by the client
12303      */
trackRecorder(IBinder recorder)12304     public int trackRecorder(IBinder recorder) {
12305         return mRecordMonitor.trackRecorder(recorder);
12306     }
12307 
12308     /**
12309      * Receive an event from the client about a tracked recorder
12310      */
recorderEvent(int riid, int event)12311     public void recorderEvent(int riid, int event) {
12312         mRecordMonitor.recorderEvent(riid, event);
12313     }
12314 
12315     /**
12316      * Stop tracking the recorder
12317      */
releaseRecorder(int riid)12318     public void releaseRecorder(int riid) {
12319         mRecordMonitor.releaseRecorder(riid);
12320     }
12321 
12322     //======================
12323     // Audio playback notification
12324     //======================
12325     private final PlaybackActivityMonitor mPlaybackMonitor;
12326 
registerPlaybackCallback(IPlaybackConfigDispatcher pcdb)12327     public void registerPlaybackCallback(IPlaybackConfigDispatcher pcdb) {
12328         final boolean isPrivileged =
12329                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
12330                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
12331         mPlaybackMonitor.registerPlaybackCallback(pcdb, isPrivileged);
12332     }
12333 
unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb)12334     public void unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb) {
12335         mPlaybackMonitor.unregisterPlaybackCallback(pcdb);
12336     }
12337 
getActivePlaybackConfigurations()12338     public List<AudioPlaybackConfiguration> getActivePlaybackConfigurations() {
12339         final boolean isPrivileged =
12340                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
12341                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
12342         return mPlaybackMonitor.getActivePlaybackConfigurations(isPrivileged);
12343     }
12344 
trackPlayer(PlayerBase.PlayerIdCard pic)12345     public int trackPlayer(PlayerBase.PlayerIdCard pic) {
12346         if (pic != null && pic.mAttributes != null) {
12347             validateAudioAttributesUsage(pic.mAttributes);
12348         }
12349         return mPlaybackMonitor.trackPlayer(pic);
12350     }
12351 
playerAttributes(int piid, AudioAttributes attr)12352     public void playerAttributes(int piid, AudioAttributes attr) {
12353         if (attr != null) {
12354             validateAudioAttributesUsage(attr);
12355         }
12356         mPlaybackMonitor.playerAttributes(piid, attr, Binder.getCallingUid());
12357     }
12358 
12359     /**
12360      * Update player session ID
12361      * @param piid Player id to update
12362      * @param sessionId The new audio session ID
12363      */
playerSessionId(int piid, int sessionId)12364     public void playerSessionId(int piid, int sessionId) {
12365         if (sessionId <= AudioSystem.AUDIO_SESSION_ALLOCATE) {
12366             throw new IllegalArgumentException("invalid session Id " + sessionId);
12367         }
12368         mPlaybackMonitor.playerSessionId(piid, sessionId, Binder.getCallingUid());
12369     }
12370 
12371     /**
12372      * Update player event
12373      * @param piid Player id to update
12374      * @param event The new player event
12375      * @param eventValue The value associated with this event
12376      */
playerEvent(int piid, int event, int eventValue)12377     public void playerEvent(int piid, int event, int eventValue) {
12378         mPlaybackMonitor.playerEvent(piid, event, eventValue, Binder.getCallingUid());
12379     }
12380 
12381     /**
12382      * Update event for port id
12383      * @param portId Port id to update
12384      * @param event The new event for the given port
12385      * @param extras Bundle of extra values to describe the event
12386      */
portEvent(int portId, int event, @Nullable PersistableBundle extras)12387     public void portEvent(int portId, int event, @Nullable PersistableBundle extras) {
12388         mPlaybackMonitor.portEvent(portId, event, extras, Binder.getCallingUid());
12389     }
12390 
playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio)12391     public void playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio) {
12392         mPlaybackMonitor.playerHasOpPlayAudio(piid, hasOpPlayAudio, Binder.getCallingUid());
12393     }
12394 
releasePlayer(int piid)12395     public void releasePlayer(int piid) {
12396         mPlaybackMonitor.releasePlayer(piid, Binder.getCallingUid());
12397     }
12398 
12399     /**
12400      * Specifies whether the audio played by this app may or may not be captured by other apps or
12401      * the system.
12402      *
12403      * @param capturePolicy one of
12404      *     {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL},
12405      *     {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM},
12406      *     {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}.
12407      * @return AudioSystem.AUDIO_STATUS_OK if set allowed capture policy succeed.
12408      * @throws IllegalArgumentException if the argument is not a valid value.
12409      */
setAllowedCapturePolicy(int capturePolicy)12410     public int setAllowedCapturePolicy(int capturePolicy) {
12411         int callingUid = Binder.getCallingUid();
12412         int flags = AudioAttributes.capturePolicyToFlags(capturePolicy, 0x0);
12413         final long identity = Binder.clearCallingIdentity();
12414         try {
12415             synchronized (mPlaybackMonitor) {
12416                 int result = mAudioSystem.setAllowedCapturePolicy(callingUid, flags);
12417                 if (result == AudioSystem.AUDIO_STATUS_OK) {
12418                     mPlaybackMonitor.setAllowedCapturePolicy(callingUid, capturePolicy);
12419                 }
12420                 return result;
12421             }
12422         } finally {
12423             Binder.restoreCallingIdentity(identity);
12424         }
12425     }
12426 
12427     /**
12428      * Return the capture policy.
12429      * @return the cached capture policy for the calling uid.
12430      */
getAllowedCapturePolicy()12431     public int getAllowedCapturePolicy() {
12432         int callingUid = Binder.getCallingUid();
12433         final long identity = Binder.clearCallingIdentity();
12434         try {
12435             return mPlaybackMonitor.getAllowedCapturePolicy(callingUid);
12436         } finally {
12437             Binder.restoreCallingIdentity(identity);
12438         }
12439     }
12440 
12441     /* package */
isPlaybackActiveForUid(int uid)12442     boolean isPlaybackActiveForUid(int uid) {
12443         return mPlaybackMonitor.isPlaybackActiveForUid(uid);
12444     }
12445 
12446     /* package */
isRecordingActiveForUid(int uid)12447     boolean isRecordingActiveForUid(int uid) {
12448         return mRecordMonitor.isRecordingActiveForUid(uid);
12449     }
12450 
12451     //======================
12452     // Audio device management
12453     //======================
12454     private final AudioDeviceBroker mDeviceBroker;
12455 
12456     //======================
12457     // Audio policy proxy
12458     //======================
12459     private static final class AudioDeviceArray {
12460         final @NonNull int[] mDeviceTypes;
12461         final @NonNull String[] mDeviceAddresses;
AudioDeviceArray(@onNull int[] types, @NonNull String[] addresses)12462         AudioDeviceArray(@NonNull int[] types,  @NonNull String[] addresses) {
12463             mDeviceTypes = types;
12464             mDeviceAddresses = addresses;
12465         }
12466     }
12467 
12468     /**
12469      * This internal class inherits from AudioPolicyConfig, each instance contains all the
12470      * mixes of an AudioPolicy and their configurations.
12471      */
12472     public class AudioPolicyProxy extends AudioPolicyConfig implements IBinder.DeathRecipient {
12473         private static final String TAG = "AudioPolicyProxy";
12474         final IAudioPolicyCallback mPolicyCallback;
12475         final boolean mHasFocusListener;
12476         final boolean mIsVolumeController;
12477         final HashMap<Integer, AudioDeviceArray> mUidDeviceAffinities =
12478                 new HashMap<Integer, AudioDeviceArray>();
12479 
12480         final HashMap<Integer, AudioDeviceArray> mUserIdDeviceAffinities =
12481                 new HashMap<>();
12482 
12483         final IMediaProjection mProjection;
12484         private final class UnregisterOnStopCallback extends IMediaProjectionCallback.Stub {
onStop()12485             public void onStop() {
12486                 unregisterAudioPolicyAsync(mPolicyCallback);
12487             }
12488 
12489             @Override
onCapturedContentResize(int width, int height)12490             public void onCapturedContentResize(int width, int height) {
12491                 // Ignore resize of the captured content.
12492             }
12493 
12494             @Override
onCapturedContentVisibilityChanged(boolean isVisible)12495             public void onCapturedContentVisibilityChanged(boolean isVisible) {
12496                 // Ignore visibility changes of the captured content.
12497             }
12498         };
12499         UnregisterOnStopCallback mProjectionCallback;
12500 
12501         /**
12502          * Audio focus ducking behavior for an audio policy.
12503          * This variable reflects the value that was successfully set in
12504          * {@link AudioService#setFocusPropertiesForPolicy(int, IAudioPolicyCallback)}. This
12505          * implies that a value of FOCUS_POLICY_DUCKING_IN_POLICY means the corresponding policy
12506          * is handling ducking for audio focus.
12507          */
12508         int mFocusDuckBehavior = AudioPolicy.FOCUS_POLICY_DUCKING_DEFAULT;
12509         boolean mIsFocusPolicy = false;
12510         boolean mIsTestFocusPolicy = false;
12511 
AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection)12512         AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token,
12513                 boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy,
12514                 boolean isVolumeController, IMediaProjection projection) {
12515             super(config);
12516             setRegistration(new String(config.hashCode() + ":ap:" + mAudioPolicyCounter++));
12517             mPolicyCallback = token;
12518             mHasFocusListener = hasFocusListener;
12519             mIsVolumeController = isVolumeController;
12520             mProjection = projection;
12521             if (mHasFocusListener) {
12522                 mMediaFocusControl.addFocusFollower(mPolicyCallback);
12523                 // can only ever be true if there is a focus listener
12524                 if (isFocusPolicy) {
12525                     mIsFocusPolicy = true;
12526                     mIsTestFocusPolicy = isTestFocusPolicy;
12527                     mMediaFocusControl.setFocusPolicy(mPolicyCallback, mIsTestFocusPolicy);
12528                 }
12529             }
12530             if (mIsVolumeController) {
12531                 setExtVolumeController(mPolicyCallback);
12532             }
12533             if (mProjection != null) {
12534                 mProjectionCallback = new UnregisterOnStopCallback();
12535                 try {
12536                     mProjection.registerCallback(mProjectionCallback);
12537                 } catch (RemoteException e) {
12538                     release();
12539                     throw new IllegalStateException("MediaProjection callback registration failed, "
12540                             + "could not link to " + projection + " binder death", e);
12541                 }
12542             }
12543             int status = connectMixes();
12544             if (status != AudioSystem.SUCCESS) {
12545                 release();
12546                 throw new IllegalStateException("Could not connect mix, error: " + status);
12547             }
12548         }
12549 
binderDied()12550         public void binderDied() {
12551             mDynPolicyLogger.enqueue((new EventLogger.StringEvent("AudioPolicy "
12552                     + mPolicyCallback.asBinder() + " died").printLog(TAG)));
12553 
12554             List<String> addresses = new ArrayList<>();
12555             for (AudioMix mix : mMixes) {
12556                 addresses.add(mix.getRegistration());
12557             }
12558             onPolicyClientDeath(addresses);
12559 
12560             release();
12561         }
12562 
getRegistrationId()12563         String getRegistrationId() {
12564             return getRegistration();
12565         }
12566 
release()12567         void release() {
12568             if (mIsFocusPolicy) {
12569                 mMediaFocusControl.unsetFocusPolicy(mPolicyCallback, mIsTestFocusPolicy);
12570             }
12571             if (mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) {
12572                 mMediaFocusControl.setDuckingInExtPolicyAvailable(false);
12573             }
12574             if (mHasFocusListener) {
12575                 mMediaFocusControl.removeFocusFollower(mPolicyCallback);
12576             }
12577             if (mProjectionCallback != null) {
12578                 try {
12579                     mProjection.unregisterCallback(mProjectionCallback);
12580                 } catch (RemoteException e) {
12581                     Log.e(TAG, "Fail to unregister Audiopolicy callback from MediaProjection");
12582                 }
12583             }
12584             if (mIsVolumeController) {
12585                 synchronized (mExtVolumeControllerLock) {
12586                     mExtVolumeController = null;
12587                 }
12588             }
12589             final long identity = Binder.clearCallingIdentity();
12590             try {
12591                 mAudioSystem.registerPolicyMixes(mMixes, false);
12592             } finally {
12593                 Binder.restoreCallingIdentity(identity);
12594             }
12595             synchronized (mAudioPolicies) {
12596                 mAudioPolicies.remove(mPolicyCallback.asBinder());
12597             }
12598             try {
12599                 mPolicyCallback.notifyUnregistration();
12600             } catch (RemoteException e) { }
12601         }
12602 
hasMixAffectingUsage(int usage, int excludedFlags)12603         boolean hasMixAffectingUsage(int usage, int excludedFlags) {
12604             for (AudioMix mix : mMixes) {
12605                 if (mix.isAffectingUsage(usage)
12606                         && ((mix.getRouteFlags() & excludedFlags) != excludedFlags)) {
12607                     return true;
12608                 }
12609             }
12610             return false;
12611         }
12612 
12613         // Verify all the devices in the array are served by mixes defined in this policy
hasMixRoutedToDevices(@onNull int[] deviceTypes, @NonNull String[] deviceAddresses)12614         boolean hasMixRoutedToDevices(@NonNull int[] deviceTypes,
12615                 @NonNull String[] deviceAddresses) {
12616             for (int i = 0; i < deviceTypes.length; i++) {
12617                 boolean hasDevice = false;
12618                 for (AudioMix mix : mMixes) {
12619                     // this will check both that the mix has ROUTE_FLAG_RENDER and the device
12620                     // is reached by this mix
12621                     if (mix.isRoutedToDevice(deviceTypes[i], deviceAddresses[i])) {
12622                         hasDevice = true;
12623                         break;
12624                     }
12625                 }
12626                 if (!hasDevice) {
12627                     return false;
12628                 }
12629             }
12630             return true;
12631         }
12632 
addMixes(@onNull ArrayList<AudioMix> mixes)12633         int addMixes(@NonNull ArrayList<AudioMix> mixes) {
12634             synchronized (mMixes) {
12635                 this.add(mixes);
12636                 return mAudioSystem.registerPolicyMixes(mixes, true);
12637             }
12638         }
12639 
removeMixes(@onNull ArrayList<AudioMix> mixes)12640         int removeMixes(@NonNull ArrayList<AudioMix> mixes) {
12641             synchronized (mMixes) {
12642                 this.remove(mixes);
12643                 return mAudioSystem.registerPolicyMixes(mixes, false);
12644             }
12645         }
12646 
connectMixes()12647         @AudioSystem.AudioSystemError int connectMixes() {
12648             final long identity = Binder.clearCallingIdentity();
12649             try {
12650                 return mAudioSystem.registerPolicyMixes(mMixes, true);
12651             } finally {
12652                 Binder.restoreCallingIdentity(identity);
12653             }
12654 
12655         }
12656 
setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses)12657         int setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses) {
12658             final Integer Uid = new Integer(uid);
12659             if (mUidDeviceAffinities.remove(Uid) != null) {
12660                 if (removeUidDeviceAffinitiesFromSystem(uid) != AudioSystem.SUCCESS) {
12661                     Log.e(TAG, "AudioSystem. removeUidDeviceAffinities(" + uid + ") failed, "
12662                             + " cannot call AudioSystem.setUidDeviceAffinities");
12663                     return AudioManager.ERROR;
12664                 }
12665             }
12666             AudioDeviceArray deviceArray = new AudioDeviceArray(types, addresses);
12667             if (setUidDeviceAffinitiesOnSystem(uid, deviceArray) == AudioSystem.SUCCESS) {
12668                 mUidDeviceAffinities.put(Uid, deviceArray);
12669                 return AudioManager.SUCCESS;
12670             }
12671             Log.e(TAG, "AudioSystem. setUidDeviceAffinities(" + uid + ") failed");
12672             return AudioManager.ERROR;
12673         }
12674 
removeUidDeviceAffinities(int uid)12675         int removeUidDeviceAffinities(int uid) {
12676             if (mUidDeviceAffinities.remove(new Integer(uid)) != null) {
12677                 if (removeUidDeviceAffinitiesFromSystem(uid) == AudioSystem.SUCCESS) {
12678                     return AudioManager.SUCCESS;
12679                 }
12680             }
12681             Log.e(TAG, "AudioSystem. removeUidDeviceAffinities failed");
12682             return AudioManager.ERROR;
12683         }
12684 
removeUidDeviceAffinitiesFromSystem(int uid)12685         @AudioSystem.AudioSystemError private int removeUidDeviceAffinitiesFromSystem(int uid) {
12686             final long identity = Binder.clearCallingIdentity();
12687             try {
12688                 return mAudioSystem.removeUidDeviceAffinities(uid);
12689             } finally {
12690                 Binder.restoreCallingIdentity(identity);
12691             }
12692         }
12693 
setUidDeviceAffinitiesOnSystem(int uid, AudioDeviceArray deviceArray)12694         @AudioSystem.AudioSystemError private int setUidDeviceAffinitiesOnSystem(int uid,
12695                 AudioDeviceArray deviceArray) {
12696             final long identity = Binder.clearCallingIdentity();
12697             try {
12698                 return mAudioSystem.setUidDeviceAffinities(uid, deviceArray.mDeviceTypes,
12699                         deviceArray.mDeviceAddresses);
12700             } finally {
12701                 Binder.restoreCallingIdentity(identity);
12702             }
12703         }
12704 
setUserIdDeviceAffinities(int userId, @NonNull int[] types, @NonNull String[] addresses)12705         int setUserIdDeviceAffinities(int userId,
12706                 @NonNull int[] types, @NonNull String[] addresses) {
12707             final Integer UserId = new Integer(userId);
12708             if (mUserIdDeviceAffinities.remove(UserId) != null) {
12709                 if (removeUserIdDeviceAffinitiesFromSystem(userId) != AudioSystem.SUCCESS) {
12710                     Log.e(TAG, "AudioSystem. removeUserIdDeviceAffinities("
12711                             + UserId + ") failed, "
12712                             + " cannot call AudioSystem.setUserIdDeviceAffinities");
12713                     return AudioManager.ERROR;
12714                 }
12715             }
12716             AudioDeviceArray audioDeviceArray = new AudioDeviceArray(types, addresses);
12717             if (setUserIdDeviceAffinitiesOnSystem(userId, audioDeviceArray)
12718                     == AudioSystem.SUCCESS) {
12719                 mUserIdDeviceAffinities.put(UserId, audioDeviceArray);
12720                 return AudioManager.SUCCESS;
12721             }
12722             Log.e(TAG, "AudioSystem.setUserIdDeviceAffinities(" + userId + ") failed");
12723             return AudioManager.ERROR;
12724         }
12725 
removeUserIdDeviceAffinities(int userId)12726         int removeUserIdDeviceAffinities(int userId) {
12727             if (mUserIdDeviceAffinities.remove(new Integer(userId)) != null) {
12728                 if (removeUserIdDeviceAffinitiesFromSystem(userId) == AudioSystem.SUCCESS) {
12729                     return AudioManager.SUCCESS;
12730                 }
12731             }
12732             Log.e(TAG, "AudioSystem.removeUserIdDeviceAffinities failed");
12733             return AudioManager.ERROR;
12734         }
12735 
removeUserIdDeviceAffinitiesFromSystem( @serIdInt int userId)12736         @AudioSystem.AudioSystemError private int removeUserIdDeviceAffinitiesFromSystem(
12737                 @UserIdInt int userId) {
12738             final long identity = Binder.clearCallingIdentity();
12739             try {
12740                 return mAudioSystem.removeUserIdDeviceAffinities(userId);
12741             } finally {
12742                 Binder.restoreCallingIdentity(identity);
12743             }
12744         }
12745 
setUserIdDeviceAffinitiesOnSystem( @serIdInt int userId, AudioDeviceArray deviceArray)12746         @AudioSystem.AudioSystemError private int setUserIdDeviceAffinitiesOnSystem(
12747                 @UserIdInt int userId, AudioDeviceArray deviceArray) {
12748             final long identity = Binder.clearCallingIdentity();
12749             try {
12750                 return mAudioSystem.setUserIdDeviceAffinities(userId, deviceArray.mDeviceTypes,
12751                         deviceArray.mDeviceAddresses);
12752             } finally {
12753                 Binder.restoreCallingIdentity(identity);
12754             }
12755         }
12756 
setupDeviceAffinities()12757         @AudioSystem.AudioSystemError int setupDeviceAffinities() {
12758             for (Map.Entry<Integer, AudioDeviceArray> uidEntry : mUidDeviceAffinities.entrySet()) {
12759                 int uidStatus = removeUidDeviceAffinitiesFromSystem(uidEntry.getKey());
12760                 if (uidStatus != AudioSystem.SUCCESS) {
12761                     Log.e(TAG,
12762                             "setupDeviceAffinities failed to remove device affinity for uid "
12763                                     + uidEntry.getKey());
12764                     return uidStatus;
12765                 }
12766                 uidStatus = setUidDeviceAffinitiesOnSystem(uidEntry.getKey(), uidEntry.getValue());
12767                 if (uidStatus != AudioSystem.SUCCESS) {
12768                     Log.e(TAG,
12769                             "setupDeviceAffinities failed to set device affinity for uid "
12770                                     + uidEntry.getKey());
12771                     return uidStatus;
12772                 }
12773             }
12774 
12775             for (Map.Entry<Integer, AudioDeviceArray> userIdEntry :
12776                     mUserIdDeviceAffinities.entrySet()) {
12777                 int userIdStatus = removeUserIdDeviceAffinitiesFromSystem(userIdEntry.getKey());
12778                 if (userIdStatus != AudioSystem.SUCCESS) {
12779                     Log.e(TAG,
12780                             "setupDeviceAffinities failed to remove device affinity for userId "
12781                                     + userIdEntry.getKey());
12782                     return userIdStatus;
12783                 }
12784                 userIdStatus = setUserIdDeviceAffinitiesOnSystem(userIdEntry.getKey(),
12785                                 userIdEntry.getValue());
12786                 if (userIdStatus != AudioSystem.SUCCESS) {
12787                     Log.e(TAG,
12788                             "setupDeviceAffinities failed to set device affinity for userId "
12789                                     + userIdEntry.getKey());
12790                     return userIdStatus;
12791                 }
12792             }
12793             return AudioSystem.SUCCESS;
12794         }
12795 
12796         /** @return human readable debug informations summarizing the state of the object. */
toLogFriendlyString()12797         public String toLogFriendlyString() {
12798             String textDump = super.toLogFriendlyString();
12799             textDump += " Uid Device Affinities:\n";
12800             String spacer = "     ";
12801             textDump += logFriendlyAttributeDeviceArrayMap("Uid",
12802                     mUidDeviceAffinities, spacer);
12803             textDump += " UserId Device Affinities:\n";
12804             textDump += logFriendlyAttributeDeviceArrayMap("UserId",
12805                     mUserIdDeviceAffinities, spacer);
12806             textDump += " Proxy:\n";
12807             textDump += "   is focus policy= " + mIsFocusPolicy + "\n";
12808             if (mIsFocusPolicy) {
12809                 textDump += "     focus duck behaviour= " + mFocusDuckBehavior + "\n";
12810                 textDump += "     is test focus policy= " + mIsTestFocusPolicy + "\n";
12811                 textDump += "     has focus listener= " + mHasFocusListener  + "\n";
12812             }
12813             textDump += "   media projection= " + mProjection + "\n";
12814             return textDump;
12815         }
12816 
logFriendlyAttributeDeviceArrayMap(String attribute, Map<Integer, AudioDeviceArray> map, String spacer)12817         private String logFriendlyAttributeDeviceArrayMap(String attribute,
12818                 Map<Integer, AudioDeviceArray> map, String spacer) {
12819             final StringBuilder stringBuilder = new StringBuilder();
12820             for (Map.Entry<Integer, AudioDeviceArray> mapEntry : map.entrySet()) {
12821                 stringBuilder.append(spacer).append(attribute).append(": ")
12822                         .append(mapEntry.getKey()).append("\n");
12823                 AudioDeviceArray deviceArray = mapEntry.getValue();
12824                 String deviceSpacer = spacer + "   ";
12825                 for (int i = 0; i < deviceArray.mDeviceTypes.length; i++) {
12826                     stringBuilder.append(deviceSpacer).append("Type: 0x")
12827                             .append(Integer.toHexString(deviceArray.mDeviceTypes[i]))
12828                             .append(" Address: ").append(deviceArray.mDeviceAddresses[i])
12829                                     .append("\n");
12830                 }
12831             }
12832             return stringBuilder.toString();
12833         }
12834     };
12835 
12836     //======================
12837     // Audio policy: focus
12838     //======================
12839     /**  */
dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb)12840     public int dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb) {
12841         if (afi == null) {
12842             throw new IllegalArgumentException("Illegal null AudioFocusInfo");
12843         }
12844         if (pcb == null) {
12845             throw new IllegalArgumentException("Illegal null AudioPolicy callback");
12846         }
12847         synchronized (mAudioPolicies) {
12848             if (!mAudioPolicies.containsKey(pcb.asBinder())) {
12849                 throw new IllegalStateException("Unregistered AudioPolicy for focus dispatch");
12850             }
12851             return mMediaFocusControl.dispatchFocusChange(afi, focusChange);
12852         }
12853     }
12854 
setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult, IAudioPolicyCallback pcb)12855     public void setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult,
12856             IAudioPolicyCallback pcb) {
12857         if (afi == null) {
12858             throw new IllegalArgumentException("Illegal null AudioFocusInfo");
12859         }
12860         if (pcb == null) {
12861             throw new IllegalArgumentException("Illegal null AudioPolicy callback");
12862         }
12863         synchronized (mAudioPolicies) {
12864             if (!mAudioPolicies.containsKey(pcb.asBinder())) {
12865                 throw new IllegalStateException("Unregistered AudioPolicy for external focus");
12866             }
12867             mMediaFocusControl.setFocusRequestResultFromExtPolicy(afi, requestResult);
12868         }
12869     }
12870 
12871 
12872     //======================
12873     // Audioserver state dispatch
12874     //======================
12875     private class AsdProxy implements IBinder.DeathRecipient {
12876         private final IAudioServerStateDispatcher mAsd;
12877 
AsdProxy(IAudioServerStateDispatcher asd)12878         AsdProxy(IAudioServerStateDispatcher asd) {
12879             mAsd = asd;
12880         }
12881 
binderDied()12882         public void binderDied() {
12883             synchronized (mAudioServerStateListeners) {
12884                 mAudioServerStateListeners.remove(mAsd.asBinder());
12885             }
12886         }
12887 
callback()12888         IAudioServerStateDispatcher callback() {
12889             return mAsd;
12890         }
12891     }
12892 
12893     private final HashMap<IBinder, AsdProxy> mAudioServerStateListeners =
12894             new HashMap<IBinder, AsdProxy>();
12895 
checkMonitorAudioServerStatePermission()12896     private void checkMonitorAudioServerStatePermission() {
12897         if (!(mContext.checkCallingOrSelfPermission(
12898                     android.Manifest.permission.MODIFY_PHONE_STATE) ==
12899                 PackageManager.PERMISSION_GRANTED ||
12900               mContext.checkCallingOrSelfPermission(
12901                     android.Manifest.permission.MODIFY_AUDIO_ROUTING) ==
12902                 PackageManager.PERMISSION_GRANTED)) {
12903             throw new SecurityException("Not allowed to monitor audioserver state");
12904         }
12905     }
12906 
registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd)12907     public void registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd) {
12908         checkMonitorAudioServerStatePermission();
12909         synchronized (mAudioServerStateListeners) {
12910             if (mAudioServerStateListeners.containsKey(asd.asBinder())) {
12911                 Slog.w(TAG, "Cannot re-register audio server state dispatcher");
12912                 return;
12913             }
12914             AsdProxy asdp = new AsdProxy(asd);
12915             try {
12916                 asd.asBinder().linkToDeath(asdp, 0/*flags*/);
12917             } catch (RemoteException e) {
12918 
12919             }
12920             mAudioServerStateListeners.put(asd.asBinder(), asdp);
12921         }
12922     }
12923 
unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd)12924     public void unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd) {
12925         checkMonitorAudioServerStatePermission();
12926         synchronized (mAudioServerStateListeners) {
12927             AsdProxy asdp = mAudioServerStateListeners.remove(asd.asBinder());
12928             if (asdp == null) {
12929                 Slog.w(TAG, "Trying to unregister unknown audioserver state dispatcher for pid "
12930                         + Binder.getCallingPid() + " / uid " + Binder.getCallingUid());
12931                 return;
12932             } else {
12933                 asd.asBinder().unlinkToDeath(asdp, 0/*flags*/);
12934             }
12935         }
12936     }
12937 
isAudioServerRunning()12938     public boolean isAudioServerRunning() {
12939         checkMonitorAudioServerStatePermission();
12940         return (AudioSystem.checkAudioFlinger() == AudioSystem.AUDIO_STATUS_OK);
12941     }
12942 
12943     //======================
12944     // Audio HAL process dump
12945     //======================
12946 
12947     private static final String AUDIO_HAL_SERVICE_PREFIX = "android.hardware.audio";
12948 
getAudioAidlHalPids(HashSet<Integer> pids)12949     private void getAudioAidlHalPids(HashSet<Integer> pids) {
12950         try {
12951             ServiceDebugInfo[] infos = ServiceManager.getServiceDebugInfo();
12952             if (infos == null) return;
12953             for (ServiceDebugInfo info : infos) {
12954                 if (info.debugPid > 0 && info.name.startsWith(AUDIO_HAL_SERVICE_PREFIX)) {
12955                     pids.add(info.debugPid);
12956                 }
12957             }
12958         } catch (RuntimeException e) {
12959             // ignored, pid hashset does not change
12960         }
12961     }
12962 
getAudioHalHidlPids(HashSet<Integer> pids)12963     private void getAudioHalHidlPids(HashSet<Integer> pids) {
12964         try {
12965             IServiceManager serviceManager = IServiceManager.getService();
12966             ArrayList<IServiceManager.InstanceDebugInfo> dump =
12967                     serviceManager.debugDump();
12968             for (IServiceManager.InstanceDebugInfo info : dump) {
12969                 if (info.pid != IServiceManager.PidConstant.NO_PID
12970                         && info.interfaceName != null
12971                         && info.interfaceName.startsWith(AUDIO_HAL_SERVICE_PREFIX)) {
12972                     pids.add(info.pid);
12973                 }
12974             }
12975         } catch (RemoteException | RuntimeException e) {
12976             // ignored, pid hashset does not change
12977         }
12978     }
12979 
getAudioHalPids()12980     private Set<Integer> getAudioHalPids() {
12981         HashSet<Integer> pids = new HashSet<>();
12982         getAudioAidlHalPids(pids);
12983         getAudioHalHidlPids(pids);
12984         return pids;
12985     }
12986 
updateAudioHalPids()12987     private void updateAudioHalPids() {
12988         Set<Integer> pidsSet = getAudioHalPids();
12989         if (pidsSet.isEmpty()) {
12990             Slog.w(TAG, "Could not retrieve audio HAL service pids");
12991             return;
12992         }
12993         int[] pidsArray = pidsSet.stream().mapToInt(Integer::intValue).toArray();
12994         AudioSystem.setAudioHalPids(pidsArray);
12995     }
12996 
12997     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
12998     //======================
12999     // Multi Audio Focus
13000     //======================
setMultiAudioFocusEnabled(boolean enabled)13001     public void setMultiAudioFocusEnabled(boolean enabled) {
13002         super.setMultiAudioFocusEnabled_enforcePermission();
13003 
13004         if (mMediaFocusControl != null) {
13005             boolean mafEnabled = mMediaFocusControl.getMultiAudioFocusEnabled();
13006             if (mafEnabled != enabled) {
13007                 mMediaFocusControl.updateMultiAudioFocus(enabled);
13008                 if (!enabled) {
13009                     mDeviceBroker.postBroadcastBecomingNoisy();
13010                 }
13011             }
13012         }
13013     }
13014 
13015     /**
13016      * @hide
13017      * Sets an additional audio output device delay in milliseconds.
13018      *
13019      * The additional output delay is a request to the output device to
13020      * delay audio presentation (generally with respect to video presentation for better
13021      * synchronization).
13022      * It may not be supported by all output devices,
13023      * and typically increases the audio latency by the amount of additional
13024      * audio delay requested.
13025      *
13026      * If additional audio delay is supported by an audio output device,
13027      * it is expected to be supported for all output streams (and configurations)
13028      * opened on that device.
13029      *
13030      * @param deviceType
13031      * @param address
13032      * @param delayMillis delay in milliseconds desired.  This should be in range of {@code 0}
13033      *     to the value returned by {@link #getMaxAdditionalOutputDeviceDelay()}.
13034      * @return true if successful, false if the device does not support output device delay
13035      *     or the delay is not in range of {@link #getMaxAdditionalOutputDeviceDelay()}.
13036      */
13037     @Override
13038     //@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
setAdditionalOutputDeviceDelay( @onNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis)13039     public boolean setAdditionalOutputDeviceDelay(
13040             @NonNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis) {
13041         Objects.requireNonNull(device, "device must not be null");
13042         enforceModifyAudioRoutingPermission();
13043         final String getterKey = "additional_output_device_delay="
13044                 + device.getInternalType() + "," + device.getAddress(); // "getter" key as an id.
13045         final String setterKey = getterKey + "," + delayMillis;     // append the delay for setter
13046         return mRestorableParameters.setParameters(getterKey, setterKey)
13047                 == AudioSystem.AUDIO_STATUS_OK;
13048     }
13049 
13050     /**
13051      * @hide
13052      * Returns the current additional audio output device delay in milliseconds.
13053      *
13054      * @param deviceType
13055      * @param address
13056      * @return the additional output device delay. This is a non-negative number.
13057      *     {@code 0} is returned if unsupported.
13058      */
13059     @Override
13060     @IntRange(from = 0)
getAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)13061     public long getAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) {
13062         Objects.requireNonNull(device, "device must not be null");
13063         final String key = "additional_output_device_delay";
13064         final String reply = AudioSystem.getParameters(
13065                 key + "=" + device.getInternalType() + "," + device.getAddress());
13066         long delayMillis;
13067         try {
13068             delayMillis = Long.parseLong(reply.substring(key.length() + 1));
13069         } catch (NullPointerException e) {
13070             delayMillis = 0;
13071         }
13072         return delayMillis;
13073     }
13074 
13075     /**
13076      * @hide
13077      * Returns the maximum additional audio output device delay in milliseconds.
13078      *
13079      * @param deviceType
13080      * @param address
13081      * @return the maximum output device delay in milliseconds that can be set.
13082      *     This is a non-negative number
13083      *     representing the additional audio delay supported for the device.
13084      *     {@code 0} is returned if unsupported.
13085      */
13086     @Override
13087     @IntRange(from = 0)
getMaxAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)13088     public long getMaxAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) {
13089         Objects.requireNonNull(device, "device must not be null");
13090         final String key = "max_additional_output_device_delay";
13091         final String reply = AudioSystem.getParameters(
13092                 key + "=" + device.getInternalType() + "," + device.getAddress());
13093         long delayMillis;
13094         try {
13095             delayMillis = Long.parseLong(reply.substring(key.length() + 1));
13096         } catch (NullPointerException e) {
13097             delayMillis = 0;
13098         }
13099         return delayMillis;
13100     }
13101 
13102     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
13103     /** @see AudioManager#addAssistantServicesUids(int []) */
13104     @Override
addAssistantServicesUids(int [] assistantUids)13105     public void addAssistantServicesUids(int [] assistantUids) {
13106         super.addAssistantServicesUids_enforcePermission();
13107 
13108         Objects.requireNonNull(assistantUids);
13109 
13110         synchronized (mSettingsLock) {
13111             addAssistantServiceUidsLocked(assistantUids);
13112         }
13113     }
13114 
13115     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
13116     /** @see AudioManager#removeAssistantServicesUids(int []) */
13117     @Override
removeAssistantServicesUids(int [] assistantUids)13118     public void removeAssistantServicesUids(int [] assistantUids) {
13119         super.removeAssistantServicesUids_enforcePermission();
13120 
13121         Objects.requireNonNull(assistantUids);
13122         synchronized (mSettingsLock) {
13123             removeAssistantServiceUidsLocked(assistantUids);
13124         }
13125     }
13126 
13127     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
13128     /** @see AudioManager#getAssistantServicesUids() */
13129     @Override
getAssistantServicesUids()13130     public int[] getAssistantServicesUids() {
13131         super.getAssistantServicesUids_enforcePermission();
13132 
13133         int [] assistantUids;
13134         synchronized (mSettingsLock) {
13135             assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray();
13136         }
13137         return assistantUids;
13138     }
13139 
13140     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
13141     /** @see AudioManager#setActiveAssistantServiceUids(int []) */
13142     @Override
setActiveAssistantServiceUids(int [] activeAssistantUids)13143     public void setActiveAssistantServiceUids(int [] activeAssistantUids) {
13144         super.setActiveAssistantServiceUids_enforcePermission();
13145 
13146         Objects.requireNonNull(activeAssistantUids);
13147         synchronized (mSettingsLock) {
13148             mActiveAssistantServiceUids = activeAssistantUids;
13149         }
13150         updateActiveAssistantServiceUids();
13151     }
13152 
13153     @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
13154     /** @see AudioManager#getActiveAssistantServiceUids() */
13155     @Override
getActiveAssistantServiceUids()13156     public int[] getActiveAssistantServiceUids() {
13157         super.getActiveAssistantServiceUids_enforcePermission();
13158 
13159         int [] activeAssistantUids;
13160         synchronized (mSettingsLock) {
13161             activeAssistantUids = mActiveAssistantServiceUids.clone();
13162         }
13163         return activeAssistantUids;
13164     }
13165 
getDeviceSensorUuid(AudioDeviceAttributes device)13166     UUID getDeviceSensorUuid(AudioDeviceAttributes device) {
13167         return mDeviceBroker.getDeviceSensorUuid(device);
13168     }
13169 
13170     //======================
13171     // misc
13172     //======================
13173     private final HashMap<IBinder, AudioPolicyProxy> mAudioPolicies =
13174             new HashMap<IBinder, AudioPolicyProxy>();
13175     @GuardedBy("mAudioPolicies")
13176     private int mAudioPolicyCounter = 0;
13177 
13178     //======================
13179     // Helper functions for full and fixed volume device
13180     //======================
isFixedVolumeDevice(int deviceType)13181     private boolean isFixedVolumeDevice(int deviceType) {
13182         if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX
13183                 && mRecordMonitor.isLegacyRemoteSubmixActive()) {
13184             return false;
13185         }
13186         return mFixedVolumeDevices.contains(deviceType);
13187     }
13188 
isFullVolumeDevice(int deviceType)13189     private boolean isFullVolumeDevice(int deviceType) {
13190         if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX
13191                 && mRecordMonitor.isLegacyRemoteSubmixActive()) {
13192             return false;
13193         }
13194         return mFullVolumeDevices.contains(deviceType);
13195     }
13196 
13197     /**
13198      * Returns whether the input device uses absolute volume behavior, including its variants.
13199      * For included volume behaviors, see {@link AudioManager.AbsoluteDeviceVolumeBehavior}.
13200      *
13201      * This is distinct from Bluetooth A2DP absolute volume behavior
13202      * ({@link #isA2dpAbsoluteVolumeDevice}).
13203      */
isAbsoluteVolumeDevice(int deviceType)13204     private boolean isAbsoluteVolumeDevice(int deviceType) {
13205         return mAbsoluteVolumeDeviceInfoMap.containsKey(deviceType);
13206     }
13207 
13208     /**
13209      * Returns whether the input device is a Bluetooth A2dp device that uses absolute volume
13210      * behavior. This is distinct from the general implementation of absolute volume behavior
13211      * ({@link #isAbsoluteVolumeDevice}).
13212      */
isA2dpAbsoluteVolumeDevice(int deviceType)13213     private boolean isA2dpAbsoluteVolumeDevice(int deviceType) {
13214         return mAvrcpAbsVolSupported && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(deviceType);
13215     }
13216 
13217     //====================
13218     // Helper functions for {set,get}DeviceVolumeBehavior
13219     //====================
getSettingsNameForDeviceVolumeBehavior(int deviceType)13220     private static String getSettingsNameForDeviceVolumeBehavior(int deviceType) {
13221         return "AudioService_DeviceVolumeBehavior_" + AudioSystem.getOutputDeviceName(deviceType);
13222     }
13223 
persistDeviceVolumeBehavior(int deviceType, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior)13224     private void persistDeviceVolumeBehavior(int deviceType,
13225             @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior) {
13226         if (DEBUG_VOL) {
13227             Log.d(TAG, "Persisting Volume Behavior for DeviceType: " + deviceType);
13228         }
13229         final long callingIdentity = Binder.clearCallingIdentity();
13230         try {
13231             mSettings.putSystemIntForUser(mContentResolver,
13232                     getSettingsNameForDeviceVolumeBehavior(deviceType),
13233                     deviceVolumeBehavior,
13234                     UserHandle.USER_CURRENT);
13235         } finally {
13236             Binder.restoreCallingIdentity(callingIdentity);
13237         }
13238     }
13239 
13240     @AudioManager.DeviceVolumeBehaviorState
retrieveStoredDeviceVolumeBehavior(int deviceType)13241     private int retrieveStoredDeviceVolumeBehavior(int deviceType) {
13242         return mSettings.getSystemIntForUser(mContentResolver,
13243                 getSettingsNameForDeviceVolumeBehavior(deviceType),
13244                 AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET,
13245                 UserHandle.USER_CURRENT);
13246     }
13247 
restoreDeviceVolumeBehavior()13248     private void restoreDeviceVolumeBehavior() {
13249         for (int deviceType : AudioSystem.DEVICE_OUT_ALL_SET) {
13250             if (DEBUG_VOL) {
13251                 Log.d(TAG, "Retrieving Volume Behavior for DeviceType: " + deviceType);
13252             }
13253             int deviceVolumeBehavior = retrieveStoredDeviceVolumeBehavior(deviceType);
13254             if (deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET) {
13255                 if (DEBUG_VOL) {
13256                     Log.d(TAG, "Skipping Setting Volume Behavior for DeviceType: " + deviceType);
13257                 }
13258                 continue;
13259             }
13260 
13261             setDeviceVolumeBehaviorInternal(new AudioDeviceAttributes(deviceType, ""),
13262                     deviceVolumeBehavior, "AudioService.restoreDeviceVolumeBehavior()");
13263         }
13264     }
13265 
13266     /**
13267      * @param audioSystemDeviceOut one of AudioSystem.DEVICE_OUT_*
13268      * @return whether {@code audioSystemDeviceOut} has previously been set to a specific volume
13269      * behavior
13270      */
hasDeviceVolumeBehavior( int audioSystemDeviceOut)13271     private boolean hasDeviceVolumeBehavior(
13272             int audioSystemDeviceOut) {
13273         return retrieveStoredDeviceVolumeBehavior(audioSystemDeviceOut)
13274                 != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET;
13275     }
13276 
addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut)13277     private boolean addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut) {
13278         if (DEBUG_VOL) {
13279             Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
13280                     + " to mFixedVolumeDevices");
13281         }
13282         return mFixedVolumeDevices.add(audioSystemDeviceOut);
13283     }
13284 
removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut)13285     private boolean removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut) {
13286         if (DEBUG_VOL) {
13287             Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
13288                     + " from mFixedVolumeDevices");
13289         }
13290         return mFixedVolumeDevices.remove(audioSystemDeviceOut);
13291     }
13292 
addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut)13293     private boolean addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut) {
13294         if (DEBUG_VOL) {
13295             Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
13296                     + " to mFullVolumeDevices");
13297         }
13298         return mFullVolumeDevices.add(audioSystemDeviceOut);
13299     }
13300 
removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut)13301     private boolean removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut) {
13302         if (DEBUG_VOL) {
13303             Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
13304                     + " from mFullVolumeDevices");
13305         }
13306         return mFullVolumeDevices.remove(audioSystemDeviceOut);
13307     }
13308 
addAudioSystemDeviceOutToAbsVolumeDevices(int audioSystemDeviceOut, AbsoluteVolumeDeviceInfo info)13309     private void addAudioSystemDeviceOutToAbsVolumeDevices(int audioSystemDeviceOut,
13310             AbsoluteVolumeDeviceInfo info) {
13311         if (DEBUG_VOL) {
13312             Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
13313                     + " to mAbsoluteVolumeDeviceInfoMap with behavior "
13314                     + AudioDeviceVolumeManager.volumeBehaviorName(info.mDeviceVolumeBehavior)
13315             );
13316         }
13317         mAbsoluteVolumeDeviceInfoMap.put(audioSystemDeviceOut, info);
13318     }
13319 
removeAudioSystemDeviceOutFromAbsVolumeDevices( int audioSystemDeviceOut)13320     private AbsoluteVolumeDeviceInfo removeAudioSystemDeviceOutFromAbsVolumeDevices(
13321             int audioSystemDeviceOut) {
13322         if (DEBUG_VOL) {
13323             Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
13324                     + " from mAbsoluteVolumeDeviceInfoMap");
13325         }
13326         return mAbsoluteVolumeDeviceInfoMap.remove(audioSystemDeviceOut);
13327     }
13328 
13329     //====================
13330     // Helper functions for app ops
13331     //====================
13332     /**
13333      * Validates, and notes an app op for a given uid and package name.
13334      * Validation comes from exception catching: a security exception indicates the package
13335      * doesn't exist, an IAE indicates the uid and package don't match. The code only checks
13336      * if exception was thrown for robustness to code changes in op validation
13337      * @param op the app op to check
13338      * @param uid the uid of the caller
13339      * @param packageName the package to check
13340      * @return true if the origin of the call is valid (no uid / package mismatch) and the caller
13341      *      is allowed to perform the operation
13342      */
checkNoteAppOp(int op, int uid, String packageName, String attributionTag)13343     private boolean checkNoteAppOp(int op, int uid, String packageName, String attributionTag) {
13344         try {
13345             if (mAppOps.noteOp(op, uid, packageName, attributionTag, null)
13346                     != AppOpsManager.MODE_ALLOWED) {
13347                 return false;
13348             }
13349         } catch (Exception e) {
13350             Log.e(TAG, "Error noting op:" + op + " on uid:" + uid + " for package:"
13351                     + packageName, e);
13352             return false;
13353         }
13354         return true;
13355     }
13356 }
13357