• 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.REMOTE_AUDIO_PLAYBACK;
20 import static android.media.AudioManager.RINGER_MODE_NORMAL;
21 import static android.media.AudioManager.RINGER_MODE_SILENT;
22 import static android.media.AudioManager.RINGER_MODE_VIBRATE;
23 import static android.media.AudioManager.STREAM_SYSTEM;
24 import static android.os.Process.FIRST_APPLICATION_UID;
25 import static android.os.Process.INVALID_UID;
26 import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE;
27 import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
28 import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE;
29 
30 import static com.android.server.audio.AudioEventLogger.Event.ALOGE;
31 import static com.android.server.audio.AudioEventLogger.Event.ALOGI;
32 import static com.android.server.audio.AudioEventLogger.Event.ALOGW;
33 
34 import android.Manifest;
35 import android.annotation.IntDef;
36 import android.annotation.IntRange;
37 import android.annotation.NonNull;
38 import android.annotation.Nullable;
39 import android.annotation.RequiresPermission;
40 import android.annotation.SuppressLint;
41 import android.annotation.UserIdInt;
42 import android.app.ActivityManager;
43 import android.app.ActivityManagerInternal;
44 import android.app.ActivityThread;
45 import android.app.AlarmManager;
46 import android.app.AppGlobals;
47 import android.app.AppOpsManager;
48 import android.app.IUidObserver;
49 import android.app.NotificationManager;
50 import android.app.PendingIntent;
51 import android.app.role.OnRoleHoldersChangedListener;
52 import android.app.role.RoleManager;
53 import android.bluetooth.BluetoothAdapter;
54 import android.bluetooth.BluetoothDevice;
55 import android.bluetooth.BluetoothHeadset;
56 import android.bluetooth.BluetoothProfile;
57 import android.content.BroadcastReceiver;
58 import android.content.ComponentName;
59 import android.content.ContentResolver;
60 import android.content.Context;
61 import android.content.Intent;
62 import android.content.IntentFilter;
63 import android.content.pm.ApplicationInfo;
64 import android.content.pm.PackageInfo;
65 import android.content.pm.PackageManager;
66 import android.content.pm.ResolveInfo;
67 import android.content.pm.UserInfo;
68 import android.content.res.Configuration;
69 import android.content.res.Resources;
70 import android.database.ContentObserver;
71 import android.hardware.SensorPrivacyManager;
72 import android.hardware.SensorPrivacyManagerInternal;
73 import android.hardware.hdmi.HdmiAudioSystemClient;
74 import android.hardware.hdmi.HdmiClient;
75 import android.hardware.hdmi.HdmiControlManager;
76 import android.hardware.hdmi.HdmiPlaybackClient;
77 import android.hardware.hdmi.HdmiTvClient;
78 import android.hardware.input.InputManager;
79 import android.hardware.usb.UsbManager;
80 import android.hidl.manager.V1_0.IServiceManager;
81 import android.media.AudioAttributes;
82 import android.media.AudioAttributes.AttributeSystemUsage;
83 import android.media.AudioDeviceAttributes;
84 import android.media.AudioDeviceInfo;
85 import android.media.AudioDeviceVolumeManager;
86 import android.media.AudioFocusInfo;
87 import android.media.AudioFocusRequest;
88 import android.media.AudioFormat;
89 import android.media.AudioManager;
90 import android.media.AudioManagerInternal;
91 import android.media.AudioPlaybackConfiguration;
92 import android.media.AudioRecordingConfiguration;
93 import android.media.AudioRoutesInfo;
94 import android.media.AudioSystem;
95 import android.media.BluetoothProfileConnectionInfo;
96 import android.media.IAudioDeviceVolumeDispatcher;
97 import android.media.IAudioFocusDispatcher;
98 import android.media.IAudioModeDispatcher;
99 import android.media.IAudioRoutesObserver;
100 import android.media.IAudioServerStateDispatcher;
101 import android.media.IAudioService;
102 import android.media.ICapturePresetDevicesRoleDispatcher;
103 import android.media.ICommunicationDeviceDispatcher;
104 import android.media.IDeviceVolumeBehaviorDispatcher;
105 import android.media.IMuteAwaitConnectionCallback;
106 import android.media.IPlaybackConfigDispatcher;
107 import android.media.IRecordingConfigDispatcher;
108 import android.media.IRingtonePlayer;
109 import android.media.ISpatializerCallback;
110 import android.media.ISpatializerHeadToSoundStagePoseCallback;
111 import android.media.ISpatializerHeadTrackerAvailableCallback;
112 import android.media.ISpatializerHeadTrackingModeCallback;
113 import android.media.ISpatializerOutputCallback;
114 import android.media.IStrategyPreferredDevicesDispatcher;
115 import android.media.IVolumeController;
116 import android.media.MediaMetrics;
117 import android.media.MediaRecorder.AudioSource;
118 import android.media.PlayerBase;
119 import android.media.Spatializer;
120 import android.media.VolumeInfo;
121 import android.media.VolumePolicy;
122 import android.media.audiofx.AudioEffect;
123 import android.media.audiopolicy.AudioMix;
124 import android.media.audiopolicy.AudioPolicy;
125 import android.media.audiopolicy.AudioPolicyConfig;
126 import android.media.audiopolicy.AudioProductStrategy;
127 import android.media.audiopolicy.AudioVolumeGroup;
128 import android.media.audiopolicy.IAudioPolicyCallback;
129 import android.media.projection.IMediaProjection;
130 import android.media.projection.IMediaProjectionCallback;
131 import android.media.projection.IMediaProjectionManager;
132 import android.net.Uri;
133 import android.os.Binder;
134 import android.os.Build;
135 import android.os.Bundle;
136 import android.os.Handler;
137 import android.os.HwBinder;
138 import android.os.IBinder;
139 import android.os.Looper;
140 import android.os.Message;
141 import android.os.PowerManager;
142 import android.os.Process;
143 import android.os.RemoteCallbackList;
144 import android.os.RemoteException;
145 import android.os.ResultReceiver;
146 import android.os.ServiceManager;
147 import android.os.ShellCallback;
148 import android.os.SystemClock;
149 import android.os.SystemProperties;
150 import android.os.UserHandle;
151 import android.os.UserManager;
152 import android.os.VibrationAttributes;
153 import android.os.VibrationEffect;
154 import android.os.Vibrator;
155 import android.os.VibratorManager;
156 import android.provider.DeviceConfig;
157 import android.provider.Settings;
158 import android.provider.Settings.System;
159 import android.service.notification.ZenModeConfig;
160 import android.telecom.TelecomManager;
161 import android.text.TextUtils;
162 import android.util.AndroidRuntimeException;
163 import android.util.ArrayMap;
164 import android.util.ArraySet;
165 import android.util.IntArray;
166 import android.util.Log;
167 import android.util.MathUtils;
168 import android.util.PrintWriterPrinter;
169 import android.util.Slog;
170 import android.util.SparseArray;
171 import android.util.SparseIntArray;
172 import android.view.KeyEvent;
173 import android.view.accessibility.AccessibilityManager;
174 import android.widget.Toast;
175 
176 import com.android.internal.annotations.GuardedBy;
177 import com.android.internal.annotations.VisibleForTesting;
178 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
179 import com.android.internal.util.DumpUtils;
180 import com.android.internal.util.Preconditions;
181 import com.android.server.EventLogTags;
182 import com.android.server.LocalServices;
183 import com.android.server.SystemService;
184 import com.android.server.audio.AudioServiceEvents.DeviceVolumeEvent;
185 import com.android.server.audio.AudioServiceEvents.PhoneStateEvent;
186 import com.android.server.audio.AudioServiceEvents.VolChangedBroadcastEvent;
187 import com.android.server.audio.AudioServiceEvents.VolumeEvent;
188 import com.android.server.pm.UserManagerInternal;
189 import com.android.server.pm.UserManagerInternal.UserRestrictionsListener;
190 import com.android.server.pm.UserManagerService;
191 import com.android.server.wm.ActivityTaskManagerInternal;
192 
193 import java.io.FileDescriptor;
194 import java.io.PrintWriter;
195 import java.lang.annotation.Retention;
196 import java.lang.annotation.RetentionPolicy;
197 import java.text.SimpleDateFormat;
198 import java.util.ArrayList;
199 import java.util.Arrays;
200 import java.util.Collection;
201 import java.util.Date;
202 import java.util.HashMap;
203 import java.util.HashSet;
204 import java.util.Iterator;
205 import java.util.LinkedHashMap;
206 import java.util.List;
207 import java.util.Map;
208 import java.util.NoSuchElementException;
209 import java.util.Objects;
210 import java.util.Set;
211 import java.util.TreeSet;
212 import java.util.UUID;
213 import java.util.concurrent.Executor;
214 import java.util.concurrent.atomic.AtomicBoolean;
215 import java.util.concurrent.atomic.AtomicInteger;
216 import java.util.function.BooleanSupplier;
217 import java.util.stream.Collectors;
218 
219 /**
220  * The implementation of the audio service for volume, audio focus, device management...
221  * <p>
222  * This implementation focuses on delivering a responsive UI. Most methods are
223  * asynchronous to external calls. For example, the task of setting a volume
224  * will update our internal state, but in a separate thread will set the system
225  * volume and later persist to the database. Similarly, setting the ringer mode
226  * will update the state and broadcast a change and in a separate thread later
227  * persist the ringer mode.
228  *
229  * @hide
230  */
231 public class AudioService extends IAudioService.Stub
232         implements AccessibilityManager.TouchExplorationStateChangeListener,
233             AccessibilityManager.AccessibilityServicesStateChangeListener,
234             AudioSystemAdapter.OnRoutingUpdatedListener,
235             AudioSystemAdapter.OnVolRangeInitRequestListener {
236 
237     private static final String TAG = "AS.AudioService";
238     private static final boolean CONFIG_DEFAULT_VAL = false;
239 
240     private final AudioSystemAdapter mAudioSystem;
241     private final SystemServerAdapter mSystemServer;
242     private final SettingsAdapter mSettings;
243 
244     /** Debug audio mode */
245     protected static final boolean DEBUG_MODE = false;
246 
247     /** Debug audio policy feature */
248     protected static final boolean DEBUG_AP = false;
249 
250     /** Debug volumes */
251     protected static final boolean DEBUG_VOL = false;
252 
253     /** debug calls to devices APIs */
254     protected static final boolean DEBUG_DEVICES = false;
255 
256     /** Debug communication route */
257     protected static final boolean DEBUG_COMM_RTE = false;
258 
259     /** Debug log sound fx (touchsounds...) in dumpsys */
260     protected static final boolean DEBUG_LOG_SOUND_FX = false;
261 
262     /** How long to delay before persisting a change in volume/ringer mode. */
263     private static final int PERSIST_DELAY = 500;
264 
265     /** How long to delay after a volume down event before unmuting a stream */
266     private static final int UNMUTE_STREAM_DELAY = 350;
267 
268     /**
269      * Delay before disconnecting a device that would cause BECOMING_NOISY intent to be sent,
270      * to give a chance to applications to pause.
271      */
272     @VisibleForTesting
273     public static final int BECOMING_NOISY_DELAY_MS = 1000;
274 
275     /**
276      * Only used in the result from {@link #checkForRingerModeChange(int, int, int)}
277      */
278     private static final int FLAG_ADJUST_VOLUME = 1;
279 
280     final Context mContext;
281     private final ContentResolver mContentResolver;
282     private final AppOpsManager mAppOps;
283 
284     // the platform type affects volume and silent mode behavior
285     private final int mPlatformType;
286 
287     // indicates whether the system maps all streams to a single stream.
288     private final boolean mIsSingleVolume;
289 
290     /**
291      * indicates whether STREAM_NOTIFICATION is aliased to STREAM_RING
292      *     not final due to test method, see {@link #setNotifAliasRingForTest(boolean)}.
293      */
294     private boolean mNotifAliasRing;
295 
296     /**
297      * Test method to temporarily override whether STREAM_NOTIFICATION is aliased to STREAM_RING,
298      * volumes will be updated in case of a change.
299      * @param alias if true, STREAM_NOTIFICATION is aliased to STREAM_RING
300      */
setNotifAliasRingForTest(boolean alias)301     /*package*/ void setNotifAliasRingForTest(boolean alias) {
302         boolean update = (mNotifAliasRing != alias);
303         mNotifAliasRing = alias;
304         if (update) {
305             updateStreamVolumeAlias(true, "AudioServiceTest");
306         }
307     }
308 
isPlatformVoice()309     /*package*/ boolean isPlatformVoice() {
310         return mPlatformType == AudioSystem.PLATFORM_VOICE;
311     }
312 
isPlatformTelevision()313     /*package*/ boolean isPlatformTelevision() {
314         return mPlatformType == AudioSystem.PLATFORM_TELEVISION;
315     }
316 
isPlatformAutomotive()317     /*package*/ boolean isPlatformAutomotive() {
318         return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
319     }
320 
321     /** The controller for the volume UI. */
322     private final VolumeController mVolumeController = new VolumeController();
323 
324     // sendMsg() flags
325     /** If the msg is already queued, replace it with this one. */
326     private static final int SENDMSG_REPLACE = 0;
327     /** If the msg is already queued, ignore this one and leave the old. */
328     private static final int SENDMSG_NOOP = 1;
329     /** If the msg is already queued, queue this one and leave the old. */
330     private static final int SENDMSG_QUEUE = 2;
331 
332     // AudioHandler messages
333     private static final int MSG_SET_DEVICE_VOLUME = 0;
334     private static final int MSG_PERSIST_VOLUME = 1;
335     private static final int MSG_PERSIST_VOLUME_GROUP = 2;
336     private static final int MSG_PERSIST_RINGER_MODE = 3;
337     private static final int MSG_AUDIO_SERVER_DIED = 4;
338     private static final int MSG_PLAY_SOUND_EFFECT = 5;
339     private static final int MSG_LOAD_SOUND_EFFECTS = 7;
340     private static final int MSG_SET_FORCE_USE = 8;
341     private static final int MSG_BT_HEADSET_CNCT_FAILED = 9;
342     private static final int MSG_SET_ALL_VOLUMES = 10;
343     private static final int MSG_CHECK_MUSIC_ACTIVE = 11;
344     private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME = 12;
345     private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED = 13;
346     private static final int MSG_PERSIST_SAFE_VOLUME_STATE = 14;
347     private static final int MSG_UNLOAD_SOUND_EFFECTS = 15;
348     private static final int MSG_SYSTEM_READY = 16;
349     private static final int MSG_PERSIST_MUSIC_ACTIVE_MS = 17;
350     private static final int MSG_UNMUTE_STREAM = 18;
351     private static final int MSG_DYN_POLICY_MIX_STATE_UPDATE = 19;
352     private static final int MSG_INDICATE_SYSTEM_READY = 20;
353     private static final int MSG_ACCESSORY_PLUG_MEDIA_UNMUTE = 21;
354     private static final int MSG_NOTIFY_VOL_EVENT = 22;
355     private static final int MSG_DISPATCH_AUDIO_SERVER_STATE = 23;
356     private static final int MSG_ENABLE_SURROUND_FORMATS = 24;
357     private static final int MSG_UPDATE_RINGER_MODE = 25;
358     private static final int MSG_SET_DEVICE_STREAM_VOLUME = 26;
359     private static final int MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS = 27;
360     private static final int MSG_HDMI_VOLUME_CHECK = 28;
361     private static final int MSG_PLAYBACK_CONFIG_CHANGE = 29;
362     private static final int MSG_BROADCAST_MICROPHONE_MUTE = 30;
363     private static final int MSG_CHECK_MODE_FOR_UID = 31;
364     private static final int MSG_STREAM_DEVICES_CHANGED = 32;
365     private static final int MSG_UPDATE_VOLUME_STATES_FOR_DEVICE = 33;
366     private static final int MSG_REINIT_VOLUMES = 34;
367     private static final int MSG_UPDATE_A11Y_SERVICE_UIDS = 35;
368     private static final int MSG_UPDATE_AUDIO_MODE = 36;
369     private static final int MSG_RECORDING_CONFIG_CHANGE = 37;
370     private static final int MSG_BT_DEV_CHANGED = 38;
371 
372     private static final int MSG_DISPATCH_AUDIO_MODE = 40;
373     private static final int MSG_ROUTING_UPDATED = 41;
374     private static final int MSG_INIT_HEADTRACKING_SENSORS = 42;
375     private static final int MSG_PERSIST_SPATIAL_AUDIO_DEVICE_SETTINGS = 43;
376     private static final int MSG_ADD_ASSISTANT_SERVICE_UID = 44;
377     private static final int MSG_REMOVE_ASSISTANT_SERVICE_UID = 45;
378     private static final int MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID = 46;
379     private static final int MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR = 47;
380     private static final int MSG_ROTATION_UPDATE = 48;
381     private static final int MSG_FOLD_UPDATE = 49;
382     private static final int MSG_RESET_SPATIALIZER = 50;
383     private static final int MSG_NO_LOG_FOR_PLAYER_I = 51;
384 
385     // start of messages handled under wakelock
386     //   these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
387     //   and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
388     private static final int MSG_DISABLE_AUDIO_FOR_UID = 100;
389     private static final int MSG_INIT_STREAMS_VOLUMES = 101;
390     private static final int MSG_INIT_SPATIALIZER = 102;
391 
392     // end of messages handled under wakelock
393 
394     // retry delay in case of failure to indicate system ready to AudioFlinger
395     private static final int INDICATE_SYSTEM_READY_RETRY_DELAY_MS = 1000;
396 
397     // List of empty UIDs used to reset the active assistant list
398     private static final int[] NO_ACTIVE_ASSISTANT_SERVICE_UIDS = new int[0];
399 
400     /** @see AudioSystemThread */
401     private AudioSystemThread mAudioSystemThread;
402     /** @see AudioHandler */
403     private AudioHandler mAudioHandler;
404     /** @see VolumeStreamState */
405     private VolumeStreamState[] mStreamStates;
406 
getVssVolumeForDevice(int stream, int device)407     /*package*/ int getVssVolumeForDevice(int stream, int device) {
408         return mStreamStates[stream].getIndex(device);
409     }
410 
getMaxVssVolumeForStream(int stream)411     /*package*/ int getMaxVssVolumeForStream(int stream) {
412         return mStreamStates[stream].getMaxIndex();
413     }
414 
415     private SettingsObserver mSettingsObserver;
416 
417     private AtomicInteger mMode = new AtomicInteger(AudioSystem.MODE_NORMAL);
418 
419     // protects mRingerMode
420     private final Object mSettingsLock = new Object();
421 
422    /** Maximum volume index values for audio streams */
423     protected static int[] MAX_STREAM_VOLUME = new int[] {
424         5,  // STREAM_VOICE_CALL
425         7,  // STREAM_SYSTEM
426         7,  // STREAM_RING            // configured by config_audio_ring_vol_steps
427         15, // STREAM_MUSIC
428         7,  // STREAM_ALARM
429         7,  // STREAM_NOTIFICATION    // configured by config_audio_notif_vol_steps
430         15, // STREAM_BLUETOOTH_SCO
431         7,  // STREAM_SYSTEM_ENFORCED
432         15, // STREAM_DTMF
433         15, // STREAM_TTS
434         15, // STREAM_ACCESSIBILITY
435         15  // STREAM_ASSISTANT
436     };
437 
438     /** Minimum volume index values for audio streams */
439     protected static int[] MIN_STREAM_VOLUME = new int[] {
440         1,  // STREAM_VOICE_CALL
441         0,  // STREAM_SYSTEM
442         0,  // STREAM_RING
443         0,  // STREAM_MUSIC
444         1,  // STREAM_ALARM
445         0,  // STREAM_NOTIFICATION
446         0,  // STREAM_BLUETOOTH_SCO
447         0,  // STREAM_SYSTEM_ENFORCED
448         0,  // STREAM_DTMF
449         0,  // STREAM_TTS
450         1,  // STREAM_ACCESSIBILITY
451         0   // STREAM_ASSISTANT
452     };
453 
454     /* mStreamVolumeAlias[] indicates for each stream if it uses the volume settings
455      * of another stream: This avoids multiplying the volume settings for hidden
456      * stream types that follow other stream behavior for volume settings
457      * NOTE: do not create loops in aliases!
458      * Some streams alias to different streams according to device category (phone or tablet) or
459      * use case (in call vs off call...). See updateStreamVolumeAlias() for more details.
460      *  mStreamVolumeAlias contains STREAM_VOLUME_ALIAS_VOICE aliases for a voice capable device
461      *  (phone), STREAM_VOLUME_ALIAS_TELEVISION for a television or set-top box and
462      *  STREAM_VOLUME_ALIAS_DEFAULT for other devices (e.g. tablets).*/
463     private final int[] STREAM_VOLUME_ALIAS_VOICE = new int[] {
464         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
465         AudioSystem.STREAM_RING,            // STREAM_SYSTEM
466         AudioSystem.STREAM_RING,            // STREAM_RING
467         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
468         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
469         AudioSystem.STREAM_RING,            // STREAM_NOTIFICATION
470         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
471         AudioSystem.STREAM_RING,            // STREAM_SYSTEM_ENFORCED
472         AudioSystem.STREAM_RING,            // STREAM_DTMF
473         AudioSystem.STREAM_MUSIC,           // STREAM_TTS
474         AudioSystem.STREAM_MUSIC,           // STREAM_ACCESSIBILITY
475         AudioSystem.STREAM_MUSIC            // STREAM_ASSISTANT
476     };
477     private final int[] STREAM_VOLUME_ALIAS_TELEVISION = new int[] {
478         AudioSystem.STREAM_MUSIC,       // STREAM_VOICE_CALL
479         AudioSystem.STREAM_MUSIC,       // STREAM_SYSTEM
480         AudioSystem.STREAM_MUSIC,       // STREAM_RING
481         AudioSystem.STREAM_MUSIC,       // STREAM_MUSIC
482         AudioSystem.STREAM_MUSIC,       // STREAM_ALARM
483         AudioSystem.STREAM_MUSIC,       // STREAM_NOTIFICATION
484         AudioSystem.STREAM_BLUETOOTH_SCO,       // STREAM_BLUETOOTH_SCO
485         AudioSystem.STREAM_MUSIC,       // STREAM_SYSTEM_ENFORCED
486         AudioSystem.STREAM_MUSIC,       // STREAM_DTMF
487         AudioSystem.STREAM_MUSIC,       // STREAM_TTS
488         AudioSystem.STREAM_MUSIC,       // STREAM_ACCESSIBILITY
489         AudioSystem.STREAM_MUSIC        // STREAM_ASSISTANT
490     };
491     /**
492      * Using Volume groups configuration allows to control volume per attributes
493      * and group definition may differ from stream aliases.
494      * So, do not alias any stream on one another when using volume groups.
495      * TODO(b/181140246): volume group definition hosting alias definition.
496      */
497     private final int[] STREAM_VOLUME_ALIAS_NONE = new int[] {
498         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
499         AudioSystem.STREAM_SYSTEM,          // STREAM_SYSTEM
500         AudioSystem.STREAM_RING,            // STREAM_RING
501         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
502         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
503         AudioSystem.STREAM_NOTIFICATION,    // STREAM_NOTIFICATION
504         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
505         AudioSystem.STREAM_SYSTEM_ENFORCED, // STREAM_SYSTEM_ENFORCED
506         AudioSystem.STREAM_DTMF,            // STREAM_DTMF
507         AudioSystem.STREAM_TTS,             // STREAM_TTS
508         AudioSystem.STREAM_ACCESSIBILITY,   // STREAM_ACCESSIBILITY
509         AudioSystem.STREAM_ASSISTANT        // STREAM_ASSISTANT
510     };
511     private final int[] STREAM_VOLUME_ALIAS_DEFAULT = new int[] {
512         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
513         AudioSystem.STREAM_RING,            // STREAM_SYSTEM
514         AudioSystem.STREAM_RING,            // STREAM_RING
515         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
516         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
517         AudioSystem.STREAM_RING,            // STREAM_NOTIFICATION
518         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
519         AudioSystem.STREAM_RING,            // STREAM_SYSTEM_ENFORCED
520         AudioSystem.STREAM_RING,            // STREAM_DTMF
521         AudioSystem.STREAM_MUSIC,           // STREAM_TTS
522         AudioSystem.STREAM_MUSIC,           // STREAM_ACCESSIBILITY
523         AudioSystem.STREAM_MUSIC            // STREAM_ASSISTANT
524     };
525     protected static int[] mStreamVolumeAlias;
526     private static final int UNSET_INDEX = -1;
527 
528     /**
529      * Map AudioSystem.STREAM_* constants to app ops.  This should be used
530      * after mapping through mStreamVolumeAlias.
531      */
532     private static final int[] STREAM_VOLUME_OPS = new int[] {
533         AppOpsManager.OP_AUDIO_VOICE_VOLUME,            // STREAM_VOICE_CALL
534         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_SYSTEM
535         AppOpsManager.OP_AUDIO_RING_VOLUME,             // STREAM_RING
536         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_MUSIC
537         AppOpsManager.OP_AUDIO_ALARM_VOLUME,            // STREAM_ALARM
538         AppOpsManager.OP_AUDIO_NOTIFICATION_VOLUME,     // STREAM_NOTIFICATION
539         AppOpsManager.OP_AUDIO_BLUETOOTH_VOLUME,        // STREAM_BLUETOOTH_SCO
540         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_SYSTEM_ENFORCED
541         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_DTMF
542         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_TTS
543         AppOpsManager.OP_AUDIO_ACCESSIBILITY_VOLUME,    // STREAM_ACCESSIBILITY
544         AppOpsManager.OP_AUDIO_MEDIA_VOLUME             // STREAM_ASSISTANT
545     };
546 
547     private final boolean mUseFixedVolume;
548     private final boolean mUseVolumeGroupAliases;
549 
550     // If absolute volume is supported in AVRCP device
551     private volatile boolean mAvrcpAbsVolSupported = false;
552 
553     /**
554     * Default stream type used for volume control in the absence of playback
555     * e.g. user on homescreen, no app playing anything, presses hardware volume buttons, this
556     *    stream type is controlled.
557     */
558     protected static final int DEFAULT_VOL_STREAM_NO_PLAYBACK = AudioSystem.STREAM_MUSIC;
559 
560     private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() {
561         public void onError(int error) {
562             switch (error) {
563                 case AudioSystem.AUDIO_STATUS_SERVER_DIED:
564                     // check for null in case error callback is called during instance creation
565                     if (mRecordMonitor != null) {
566                         mRecordMonitor.onAudioServerDied();
567                     }
568                     sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED,
569                             SENDMSG_NOOP, 0, 0, null, 0);
570                     sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE,
571                             SENDMSG_QUEUE, 0, 0, null, 0);
572                     break;
573                 default:
574                     break;
575             }
576         }
577     };
578 
579     /**
580      * Current ringer mode from one of {@link AudioManager#RINGER_MODE_NORMAL},
581      * {@link AudioManager#RINGER_MODE_SILENT}, or
582      * {@link AudioManager#RINGER_MODE_VIBRATE}.
583      */
584     @GuardedBy("mSettingsLock")
585     private int mRingerMode;  // internal ringer mode, affects muting of underlying streams
586     @GuardedBy("mSettingsLock")
587     private int mRingerModeExternal = -1;  // reported ringer mode to outside clients (AudioManager)
588 
589     /** @see System#MODE_RINGER_STREAMS_AFFECTED */
590     private int mRingerModeAffectedStreams = 0;
591 
592     private int mZenModeAffectedStreams = 0;
593 
594     // Streams currently muted by ringer mode and dnd
595     private int mRingerAndZenModeMutedStreams;
596 
597     /** Streams that can be muted. Do not resolve to aliases when checking.
598      * @see System#MUTE_STREAMS_AFFECTED */
599     private int mMuteAffectedStreams;
600 
601     @NonNull
602     private SoundEffectsHelper mSfxHelper;
603 
604     /**
605      * NOTE: setVibrateSetting(), getVibrateSetting(), shouldVibrate() are deprecated.
606      * mVibrateSetting is just maintained during deprecation period but vibration policy is
607      * now only controlled by mHasVibrator and mRingerMode
608      */
609     private int mVibrateSetting;
610 
611     // Is there a vibrator
612     private final boolean mHasVibrator;
613     // Used to play vibrations
614     private Vibrator mVibrator;
615     private static final VibrationAttributes TOUCH_VIBRATION_ATTRIBUTES =
616             VibrationAttributes.createForUsage(VibrationAttributes.USAGE_TOUCH);
617 
618     // Broadcast receiver for device connections intent broadcasts
619     private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver();
620 
621     private IMediaProjectionManager mProjectionService; // to validate projection token
622 
623     /** Interface for UserManagerService. */
624     private final UserManagerInternal mUserManagerInternal;
625     private final ActivityManagerInternal mActivityManagerInternal;
626     private final SensorPrivacyManagerInternal mSensorPrivacyManagerInternal;
627 
628     private final UserRestrictionsListener mUserRestrictionsListener =
629             new AudioServiceUserRestrictionsListener();
630 
631     // List of binder death handlers for setMode() client processes.
632     // The last process to have called setMode() is at the top of the list.
633     // package-private so it can be accessed in AudioDeviceBroker.getSetModeDeathHandlers
634     //TODO candidate to be moved to separate class that handles synchronization
635     @GuardedBy("mDeviceBroker.mSetModeLock")
636     /*package*/ final ArrayList<SetModeDeathHandler> mSetModeDeathHandlers =
637             new ArrayList<SetModeDeathHandler>();
638 
639     // true if boot sequence has been completed
640     private boolean mSystemReady;
641     // true if Intent.ACTION_USER_SWITCHED has ever been received
642     private boolean mUserSwitchedReceived;
643     // previous volume adjustment direction received by checkForRingerModeChange()
644     private int mPrevVolDirection = AudioManager.ADJUST_SAME;
645     // mVolumeControlStream is set by VolumePanel to temporarily force the stream type which volume
646     // is controlled by Vol keys.
647     private int mVolumeControlStream = -1;
648     // interpretation of whether the volume stream has been selected by the user by clicking on a
649     // volume slider to change which volume is controlled by the volume keys. Is false
650     // when mVolumeControlStream is -1.
651     private boolean mUserSelectedVolumeControlStream = false;
652     private final Object mForceControlStreamLock = new Object();
653     // VolumePanel is currently the only client of forceVolumeControlStream() and runs in system
654     // server process so in theory it is not necessary to monitor the client death.
655     // However it is good to be ready for future evolutions.
656     private ForceControlStreamClient mForceControlStreamClient = null;
657     // Used to play ringtones outside system_server
658     private volatile IRingtonePlayer mRingtonePlayer;
659 
660     // Devices for which the volume is fixed (volume is either max or muted)
661     Set<Integer> mFixedVolumeDevices = new HashSet<>(Arrays.asList(
662             AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET,
663             AudioSystem.DEVICE_OUT_AUX_LINE));
664     // Devices for which the volume is always max, no volume panel
665     Set<Integer> mFullVolumeDevices = new HashSet<>(Arrays.asList(
666             AudioSystem.DEVICE_OUT_HDMI_ARC,
667             AudioSystem.DEVICE_OUT_HDMI_EARC
668     ));
669 
670     // Devices where the framework sends a full scale audio signal, and controls the volume of
671     // the external audio system separately.
672     Map<Integer, AbsoluteVolumeDeviceInfo> mAbsoluteVolumeDeviceInfoMap = new ArrayMap<>();
673 
674     /**
675      * Stores information about a device using absolute volume behavior.
676      */
677     private static final class AbsoluteVolumeDeviceInfo {
678         private final AudioDeviceAttributes mDevice;
679         private final List<VolumeInfo> mVolumeInfos;
680         private final IAudioDeviceVolumeDispatcher mCallback;
681         private final boolean mHandlesVolumeAdjustment;
682 
AbsoluteVolumeDeviceInfo(AudioDeviceAttributes device, List<VolumeInfo> volumeInfos, IAudioDeviceVolumeDispatcher callback, boolean handlesVolumeAdjustment)683         private AbsoluteVolumeDeviceInfo(AudioDeviceAttributes device, List<VolumeInfo> volumeInfos,
684                 IAudioDeviceVolumeDispatcher callback, boolean handlesVolumeAdjustment) {
685             this.mDevice = device;
686             this.mVolumeInfos = volumeInfos;
687             this.mCallback = callback;
688             this.mHandlesVolumeAdjustment = handlesVolumeAdjustment;
689         }
690 
691         /**
692          * Given a stream type, returns a matching VolumeInfo.
693          */
694         @Nullable
getMatchingVolumeInfoForStream(int streamType)695         private VolumeInfo getMatchingVolumeInfoForStream(int streamType) {
696             for (VolumeInfo volumeInfo : mVolumeInfos) {
697                 boolean streamTypeMatches = volumeInfo.hasStreamType()
698                         && volumeInfo.getStreamType() == streamType;
699                 boolean volumeGroupMatches = volumeInfo.hasVolumeGroup()
700                         && Arrays.stream(volumeInfo.getVolumeGroup().getLegacyStreamTypes())
701                         .anyMatch(s -> s == streamType);
702                 if (streamTypeMatches || volumeGroupMatches) {
703                     return volumeInfo;
704                 }
705             }
706             return null;
707         }
708     }
709 
710     // Devices for the which use the "absolute volume" concept (framework sends audio signal
711     // full scale, and volume control separately) and can be used for multiple use cases reflected
712     // by the audio mode (e.g. media playback in MODE_NORMAL, and phone calls in MODE_IN_CALL).
713     Set<Integer> mAbsVolumeMultiModeCaseDevices = new HashSet<>(
714             Arrays.asList(AudioSystem.DEVICE_OUT_HEARING_AID));
715 
716     private final boolean mMonitorRotation;
717 
718     private boolean mDockAudioMediaEnabled = true;
719 
720     /**
721      * RestorableParameters is a thread-safe class used to store a
722      * first-in first-out history of parameters for replay / restoration.
723      *
724      * The idealized implementation of restoration would have a list of setting methods and
725      * values to be called for restoration.  Explicitly managing such setters and
726      * values would be tedious - a simpler method is to store the values and the
727      * method implicitly by lambda capture (the values must be immutable or synchronization
728      * needs to be taken).
729      *
730      * We provide queueRestoreWithRemovalIfTrue() to allow
731      * the caller to provide a BooleanSupplier lambda, which conveniently packages
732      * the setter and its parameters needed for restoration.  If during restoration,
733      * the BooleanSupplier returns true, e.g. on error, it is removed from the mMap
734      * so as not to be called on a subsequent restore.
735      *
736      * We provide a setParameters() method as an example helper method.
737      */
738     private static class RestorableParameters {
739         /**
740          * Sets a parameter and queues for restoration if successful.
741          *
742          * @param id a string handle associated with this parameter.
743          * @param parameter the actual parameter string.
744          * @return the result of AudioSystem.setParameters
745          */
setParameters(@onNull String id, @NonNull String parameter)746         public int setParameters(@NonNull String id, @NonNull String parameter) {
747             Objects.requireNonNull(id, "id must not be null");
748             Objects.requireNonNull(parameter, "parameter must not be null");
749             synchronized (mMap) {
750                 final int status = AudioSystem.setParameters(parameter);
751                 if (status == AudioSystem.AUDIO_STATUS_OK) { // Java uses recursive mutexes.
752                     queueRestoreWithRemovalIfTrue(id, () -> { // remove me if set fails.
753                         return AudioSystem.setParameters(parameter) != AudioSystem.AUDIO_STATUS_OK;
754                     });
755                 }
756                 // Implementation detail: We do not mMap.remove(id); on failure.
757                 return status;
758             }
759         }
760 
761         /**
762          * Queues a restore method which is executed on restoreAll().
763          *
764          * If the supplier null, the id is removed from the restore map.
765          *
766          * Note: When the BooleanSupplier restore method is executed
767          * during restoreAll, if it returns true, it is removed from the
768          * restore map.
769          *
770          * @param id a unique tag associated with the restore method.
771          * @param supplier is a BooleanSupplier lambda.
772          */
queueRestoreWithRemovalIfTrue( @onNull String id, @Nullable BooleanSupplier supplier)773         public void queueRestoreWithRemovalIfTrue(
774                 @NonNull String id, @Nullable BooleanSupplier supplier) {
775             Objects.requireNonNull(id, "id must not be null");
776             synchronized (mMap) {
777                 if (supplier != null) {
778                     mMap.put(id, supplier);
779                 } else {
780                     mMap.remove(id);
781                 }
782             }
783         }
784 
785         /**
786          * Restore all parameters
787          *
788          * During restoration after audioserver death, any BooleanSupplier that returns
789          * true, for example on parameter restoration error, will be removed from mMap
790          * so as not to be executed on a subsequent restoreAll().
791          */
restoreAll()792         public void restoreAll() {
793             synchronized (mMap) {
794                 // Note: removing from values() also removes from the backing map.
795                 // TODO: Consider catching exceptions?
796                 mMap.values().removeIf(v -> {
797                     return v.getAsBoolean(); // this iterates the setters().
798                 });
799             }
800         }
801 
802         /**
803          * mMap is a LinkedHashMap<Key, Value> of parameters restored by restore().
804          * The Key is a unique id tag for identification.
805          * The Value is a lambda expression which returns true if the entry is to
806          *     be removed.
807          *
808          * 1) For memory limitation purposes, mMap keeps the latest MAX_ENTRIES
809          *    accessed in the map.
810          * 2) Parameters are restored in order of queuing, first in first out,
811          *    from earliest to latest.
812          */
813         @GuardedBy("mMap")
814         private Map</* @NonNull */ String, /* @NonNull */ BooleanSupplier> mMap =
815                 new LinkedHashMap<>() {
816             // TODO: do we need this memory limitation?
817             private static final int MAX_ENTRIES = 1000;  // limit our memory for now.
818             @Override
819             protected boolean removeEldestEntry(Map.Entry eldest) {
820                 if (size() <= MAX_ENTRIES) return false;
821                 Log.w(TAG, "Parameter map exceeds "
822                         + MAX_ENTRIES + " removing " + eldest.getKey()); // don't silently remove.
823                 return true;
824             }
825         };
826     }
827 
828     // We currently have one instance for mRestorableParameters used for
829     // setAdditionalOutputDeviceDelay().  Other methods requiring restoration could share this
830     // or use their own instance.
831     private RestorableParameters mRestorableParameters = new RestorableParameters();
832 
833     private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
834 
835     // Used when safe volume warning message display is requested by setStreamVolume(). In this
836     // case, the new requested volume, stream type and device are stored in mPendingVolumeCommand
837     // and used later when/if disableSafeMediaVolume() is called.
838     private StreamVolumeCommand mPendingVolumeCommand;
839 
840     private PowerManager.WakeLock mAudioEventWakeLock;
841 
842     private final MediaFocusControl mMediaFocusControl;
843 
844     // Pre-scale for Bluetooth Absolute Volume
845     private float[] mPrescaleAbsoluteVolume = new float[] {
846         0.6f,    // Pre-scale for index 1
847         0.8f,    // Pre-scale for index 2
848         0.9f,   // Pre-scale for index 3
849     };
850 
851     private NotificationManager mNm;
852     private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate;
853     private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT;
854     private long mLoweredFromNormalToVibrateTime;
855 
856     // Array of Uids of valid assistant services to check if caller is one of them
857     @GuardedBy("mSettingsLock")
858     private final ArraySet<Integer> mAssistantUids = new ArraySet<>();
859     @GuardedBy("mSettingsLock")
860     private int mPrimaryAssistantUid = INVALID_UID;
861 
862     // Array of Uids of valid active assistant service to check if caller is one of them
863     @GuardedBy("mSettingsLock")
864     private int[] mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS;
865 
866     // Array of Uids of valid accessibility services to check if caller is one of them
867     private final Object mAccessibilityServiceUidsLock = new Object();
868     @GuardedBy("mAccessibilityServiceUidsLock")
869     private int[] mAccessibilityServiceUids;
870 
871     // Uid of the active input method service to check if caller is the one or not.
872     private int mInputMethodServiceUid = android.os.Process.INVALID_UID;
873     private final Object mInputMethodServiceUidLock = new Object();
874 
875     private int mEncodedSurroundMode;
876     private String mEnabledSurroundFormats;
877     private boolean mSurroundModeChanged;
878 
879     private boolean mSupportsMicPrivacyToggle;
880 
881     private boolean mMicMuteFromSwitch;
882     private boolean mMicMuteFromApi;
883     private boolean mMicMuteFromRestrictions;
884     private boolean mMicMuteFromPrivacyToggle;
885     // caches the value returned by AudioSystem.isMicrophoneMuted()
886     private boolean mMicMuteFromSystemCached;
887 
888     private boolean mNavigationRepeatSoundEffectsEnabled;
889     private boolean mHomeSoundEffectEnabled;
890 
891     @GuardedBy("mSettingsLock")
892     private int mCurrentImeUid;
893 
894     private final Object mSupportedSystemUsagesLock = new Object();
895     @GuardedBy("mSupportedSystemUsagesLock")
896     private @AttributeSystemUsage int[] mSupportedSystemUsages =
897             new int[]{AudioAttributes.USAGE_CALL_ASSISTANT};
898 
899     // Defines the format for the connection "address" for ALSA devices
makeAlsaAddressString(int card, int device)900     public static String makeAlsaAddressString(int card, int device) {
901         return "card=" + card + ";device=" + device + ";";
902     }
903 
904     public static final class Lifecycle extends SystemService {
905         private AudioService mService;
906 
Lifecycle(Context context)907         public Lifecycle(Context context) {
908             super(context);
909             mService = new AudioService(context);
910         }
911 
912         @Override
onStart()913         public void onStart() {
914             publishBinderService(Context.AUDIO_SERVICE, mService);
915         }
916 
917         @Override
onBootPhase(int phase)918         public void onBootPhase(int phase) {
919             if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
920                 mService.systemReady();
921             }
922         }
923     }
924 
925     final private IUidObserver mUidObserver = new IUidObserver.Stub() {
926         @Override public void onUidStateChanged(int uid, int procState, long procStateSeq,
927             int capability) {
928         }
929 
930         @Override public void onUidGone(int uid, boolean disabled) {
931             // Once the uid is no longer running, no need to keep trying to disable its audio.
932             disableAudioForUid(false, uid);
933         }
934 
935         @Override public void onUidActive(int uid) throws RemoteException {
936         }
937 
938         @Override public void onUidIdle(int uid, boolean disabled) {
939         }
940 
941         @Override public void onUidCachedChanged(int uid, boolean cached) {
942             disableAudioForUid(cached, uid);
943         }
944 
945         @Override public void onUidProcAdjChanged(int uid) {
946         }
947 
948         private void disableAudioForUid(boolean disable, int uid) {
949             queueMsgUnderWakeLock(mAudioHandler, MSG_DISABLE_AUDIO_FOR_UID,
950                     disable ? 1 : 0 /* arg1 */,  uid /* arg2 */,
951                     null /* obj */,  0 /* delay */);
952         }
953     };
954 
955     @GuardedBy("mSettingsLock")
956     private boolean mRttEnabled = false;
957 
958     ///////////////////////////////////////////////////////////////////////////
959     // Construction
960     ///////////////////////////////////////////////////////////////////////////
961 
962     /** @hide */
AudioService(Context context)963     public AudioService(Context context) {
964         this(context,
965                 AudioSystemAdapter.getDefaultAdapter(),
966                 SystemServerAdapter.getDefaultAdapter(context),
967                 SettingsAdapter.getDefaultAdapter(),
968                 null);
969     }
970 
971     /**
972      * @param context
973      * @param audioSystem Adapter for {@link AudioSystem}
974      * @param systemServer Adapter for privilieged functionality for system server components
975      * @param settings Adapter for {@link Settings}
976      * @param looper Looper to use for the service's message handler. If this is null, an
977      *               {@link AudioSystemThread} is created as the messaging thread instead.
978      */
AudioService(Context context, AudioSystemAdapter audioSystem, SystemServerAdapter systemServer, SettingsAdapter settings, @Nullable Looper looper)979     public AudioService(Context context, AudioSystemAdapter audioSystem,
980             SystemServerAdapter systemServer, SettingsAdapter settings, @Nullable Looper looper) {
981         this (context, audioSystem, systemServer, settings, looper,
982                 context.getSystemService(AppOpsManager.class));
983     }
984 
985     /**
986      * @param context
987      * @param audioSystem Adapter for {@link AudioSystem}
988      * @param systemServer Adapter for privilieged functionality for system server components
989      * @param settings Adapter for {@link Settings}
990      * @param looper Looper to use for the service's message handler. If this is null, an
991      *               {@link AudioSystemThread} is created as the messaging thread instead.
992      */
993     @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
AudioService(Context context, AudioSystemAdapter audioSystem, SystemServerAdapter systemServer, SettingsAdapter settings, @Nullable Looper looper, AppOpsManager appOps)994     public AudioService(Context context, AudioSystemAdapter audioSystem,
995             SystemServerAdapter systemServer, SettingsAdapter settings, @Nullable Looper looper,
996             AppOpsManager appOps) {
997         sLifecycleLogger.log(new AudioEventLogger.StringEvent("AudioService()"));
998         mContext = context;
999         mContentResolver = context.getContentResolver();
1000         mAppOps = appOps;
1001 
1002         mAudioSystem = audioSystem;
1003         mSystemServer = systemServer;
1004         mSettings = settings;
1005 
1006         mPlatformType = AudioSystem.getPlatformType(context);
1007 
1008         mIsSingleVolume = AudioSystem.isSingleVolume(context);
1009 
1010         mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
1011         mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
1012         mSensorPrivacyManagerInternal =
1013                 LocalServices.getService(SensorPrivacyManagerInternal.class);
1014 
1015         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
1016         mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent");
1017 
1018         mSfxHelper = new SoundEffectsHelper(mContext, playerBase -> ignorePlayerLogs(playerBase));
1019 
1020         final boolean binauralEnabledDefault = SystemProperties.getBoolean(
1021                 "ro.audio.spatializer_binaural_enabled_default", true);
1022         final boolean transauralEnabledDefault = SystemProperties.getBoolean(
1023                 "ro.audio.spatializer_transaural_enabled_default", true);
1024         final boolean headTrackingEnabledDefault = mContext.getResources().getBoolean(
1025                 com.android.internal.R.bool.config_spatial_audio_head_tracking_enabled_default);
1026         mSpatializerHelper = new SpatializerHelper(this, mAudioSystem,
1027                 binauralEnabledDefault, transauralEnabledDefault, headTrackingEnabledDefault);
1028 
1029         mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
1030         mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator();
1031 
1032         mSupportsMicPrivacyToggle = context.getSystemService(SensorPrivacyManager.class)
1033                 .supportsSensorToggle(SensorPrivacyManager.Sensors.MICROPHONE);
1034 
1035         mUseVolumeGroupAliases = mContext.getResources().getBoolean(
1036                 com.android.internal.R.bool.config_handleVolumeAliasesUsingVolumeGroups);
1037 
1038         mNotifAliasRing = !DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
1039                 SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, false);
1040 
1041         DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
1042                 ActivityThread.currentApplication().getMainExecutor(),
1043                 this::onDeviceConfigChange);
1044 
1045         // Initialize volume
1046         // Priority 1 - Android Property
1047         // Priority 2 - Audio Policy Service
1048         // Priority 3 - Default Value
1049         if (AudioProductStrategy.getAudioProductStrategies().size() > 0) {
1050             int numStreamTypes = AudioSystem.getNumStreamTypes();
1051 
1052             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
1053                 AudioAttributes attr =
1054                         AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(
1055                                 streamType);
1056                 int maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr);
1057                 if (maxVolume != -1) {
1058                     MAX_STREAM_VOLUME[streamType] = maxVolume;
1059                 }
1060                 int minVolume = AudioSystem.getMinVolumeIndexForAttributes(attr);
1061                 if (minVolume != -1) {
1062                     MIN_STREAM_VOLUME[streamType] = minVolume;
1063                 }
1064             }
1065             if (mUseVolumeGroupAliases) {
1066                 // Set all default to uninitialized.
1067                 for (int stream = 0; stream < AudioSystem.DEFAULT_STREAM_VOLUME.length; stream++) {
1068                     AudioSystem.DEFAULT_STREAM_VOLUME[stream] = UNSET_INDEX;
1069                 }
1070             }
1071         }
1072 
1073         int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1);
1074         if (maxCallVolume != -1) {
1075             MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxCallVolume;
1076         }
1077 
1078         int defaultCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_default", -1);
1079         if (defaultCallVolume != -1 &&
1080                 defaultCallVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] &&
1081                 defaultCallVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]) {
1082             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = defaultCallVolume;
1083         } else {
1084             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] =
1085                     (MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] * 3) / 4;
1086         }
1087 
1088         int maxMusicVolume = SystemProperties.getInt("ro.config.media_vol_steps", -1);
1089         if (maxMusicVolume != -1) {
1090             MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxMusicVolume;
1091         }
1092 
1093         int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", -1);
1094         if (defaultMusicVolume != -1 &&
1095                 defaultMusicVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] &&
1096                 defaultMusicVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) {
1097             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = defaultMusicVolume;
1098         } else {
1099             if (isPlatformTelevision()) {
1100                 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] =
1101                         MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 4;
1102             } else {
1103                 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] =
1104                         MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 3;
1105             }
1106         }
1107 
1108         int maxAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_steps", -1);
1109         if (maxAlarmVolume != -1) {
1110             MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = maxAlarmVolume;
1111         }
1112 
1113         int defaultAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_default", -1);
1114         if (defaultAlarmVolume != -1 &&
1115                 defaultAlarmVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]) {
1116             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = defaultAlarmVolume;
1117         } else {
1118             // Default is 6 out of 7 (default maximum), so scale accordingly.
1119             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] =
1120                         6 * MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] / 7;
1121         }
1122 
1123         int maxSystemVolume = SystemProperties.getInt("ro.config.system_vol_steps", -1);
1124         if (maxSystemVolume != -1) {
1125             MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = maxSystemVolume;
1126         }
1127 
1128         int defaultSystemVolume = SystemProperties.getInt("ro.config.system_vol_default", -1);
1129         if (defaultSystemVolume != -1 &&
1130                 defaultSystemVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]) {
1131             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = defaultSystemVolume;
1132         } else {
1133             // Default is to use maximum.
1134             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] =
1135                         MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM];
1136         }
1137 
1138         // Read following properties to configure max volume (number of steps) and default volume
1139         //   for STREAM_NOTIFICATION and STREAM_RING:
1140         //      config_audio_notif_vol_default
1141         //      config_audio_notif_vol_steps
1142         //      config_audio_ring_vol_default
1143         //      config_audio_ring_vol_steps
1144         int[] streams = { AudioSystem.STREAM_NOTIFICATION, AudioSystem.STREAM_RING };
1145         int[] stepsResId = { com.android.internal.R.integer.config_audio_notif_vol_steps,
1146                 com.android.internal.R.integer.config_audio_ring_vol_steps };
1147         int[] defaultResId = { com.android.internal.R.integer.config_audio_notif_vol_default,
1148                 com.android.internal.R.integer.config_audio_ring_vol_default };
1149         for (int s = 0; s < streams.length; s++) {
1150             try {
1151                 final int maxVol = mContext.getResources().getInteger(stepsResId[s]);
1152                 if (maxVol <= 0) {
1153                     throw new IllegalArgumentException("Invalid negative max volume for stream "
1154                             + streams[s]);
1155                 }
1156                 Log.i(TAG, "Stream " + streams[s] + ": using max vol of " + maxVol);
1157                 MAX_STREAM_VOLUME[streams[s]] = maxVol;
1158             } catch (Resources.NotFoundException e) {
1159                 Log.e(TAG, "Error querying max vol for stream type " + streams[s], e);
1160             }
1161             try {
1162                 final int defaultVol = mContext.getResources().getInteger(defaultResId[s]);
1163                 if (defaultVol > MAX_STREAM_VOLUME[streams[s]]) {
1164                     throw new IllegalArgumentException("Invalid default volume (" + defaultVol
1165                             + ") for stream " + streams[s] + ", greater than max volume of "
1166                             + MAX_STREAM_VOLUME[streams[s]]);
1167                 }
1168                 if (defaultVol < MIN_STREAM_VOLUME[streams[s]]) {
1169                     throw new IllegalArgumentException("Invalid default volume (" + defaultVol
1170                             + ") for stream " + streams[s] + ", lower than min volume of "
1171                             + MIN_STREAM_VOLUME[streams[s]]);
1172                 }
1173                 Log.i(TAG, "Stream " + streams[s] + ": using default vol of " + defaultVol);
1174                 AudioSystem.DEFAULT_STREAM_VOLUME[streams[s]] = defaultVol;
1175             } catch (Resources.NotFoundException e) {
1176                 Log.e(TAG, "Error querying default vol for stream type " + streams[s], e);
1177             }
1178         }
1179 
1180         if (looper == null) {
1181             createAudioSystemThread();
1182         } else {
1183             mAudioHandler = new AudioHandler(looper);
1184         }
1185 
1186         AudioSystem.setErrorCallback(mAudioSystemCallback);
1187 
1188         updateAudioHalPids();
1189 
1190         boolean cameraSoundForced = readCameraSoundForced();
1191         mCameraSoundForced = new Boolean(cameraSoundForced);
1192         sendMsg(mAudioHandler,
1193                 MSG_SET_FORCE_USE,
1194                 SENDMSG_QUEUE,
1195                 AudioSystem.FOR_SYSTEM,
1196                 cameraSoundForced ?
1197                         AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE,
1198                 new String("AudioService ctor"),
1199                 0);
1200 
1201         mSafeMediaVolumeState = mSettings.getGlobalInt(mContentResolver,
1202                                             Settings.Global.AUDIO_SAFE_VOLUME_STATE,
1203                                             SAFE_MEDIA_VOLUME_NOT_CONFIGURED);
1204         // The default safe volume index read here will be replaced by the actual value when
1205         // the mcc is read by onConfigureSafeVolume()
1206         mSafeMediaVolumeIndex = mContext.getResources().getInteger(
1207                 com.android.internal.R.integer.config_safe_media_volume_index) * 10;
1208 
1209         mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
1210 
1211         mUseFixedVolume = mContext.getResources().getBoolean(
1212                 com.android.internal.R.bool.config_useFixedVolume);
1213 
1214         mDeviceBroker = new AudioDeviceBroker(mContext, this, mAudioSystem);
1215 
1216         mRecordMonitor = new RecordingActivityMonitor(mContext);
1217         mRecordMonitor.registerRecordingCallback(mVoiceRecordingActivityMonitor, true);
1218 
1219         // must be called before readPersistedSettings() which needs a valid mStreamVolumeAlias[]
1220         // array initialized by updateStreamVolumeAlias()
1221         updateStreamVolumeAlias(false /*updateVolumes*/, TAG);
1222         readPersistedSettings();
1223         readUserRestrictions();
1224 
1225         mPlaybackMonitor =
1226                 new PlaybackActivityMonitor(context, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM],
1227                         device -> onMuteAwaitConnectionTimeout(device));
1228         mPlaybackMonitor.registerPlaybackCallback(mPlaybackActivityMonitor, true);
1229 
1230         mMediaFocusControl = new MediaFocusControl(mContext, mPlaybackMonitor);
1231 
1232         readAndSetLowRamDevice();
1233 
1234         mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported();
1235 
1236         if (mSystemServer.isPrivileged()) {
1237             LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal());
1238 
1239             mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
1240 
1241             mRecordMonitor.initMonitor();
1242         }
1243 
1244         mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false);
1245 
1246         mHasSpatializerEffect = SystemProperties.getBoolean("ro.audio.spatializer_enabled", false);
1247 
1248         // monitor routing updates coming from native
1249         mAudioSystem.setRoutingListener(this);
1250         // monitor requests for volume range initialization coming from native (typically when
1251         // errors are found by AudioPolicyManager
1252         mAudioSystem.setVolRangeInitReqListener(this);
1253 
1254         // done with service initialization, continue additional work in our Handler thread
1255         queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_STREAMS_VOLUMES,
1256                 0 /* arg1 */,  0 /* arg2 */, null /* obj */,  0 /* delay */);
1257         queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_SPATIALIZER,
1258                 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */);
1259     }
1260 
initVolumeStreamStates()1261     private void initVolumeStreamStates() {
1262         int numStreamTypes = AudioSystem.getNumStreamTypes();
1263         synchronized (VolumeStreamState.class) {
1264             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
1265                 VolumeStreamState streamState = mStreamStates[streamType];
1266                 int groupId = getVolumeGroupForStreamType(streamType);
1267                 if (groupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP
1268                         && sVolumeGroupStates.indexOfKey(groupId) >= 0) {
1269                     streamState.setVolumeGroupState(sVolumeGroupStates.get(groupId));
1270                 }
1271             }
1272         }
1273     }
1274 
1275     /**
1276      * Separating notification volume from ring is NOT of aliasing the corresponding streams
1277      * @param properties
1278      */
onDeviceConfigChange(DeviceConfig.Properties properties)1279     private void onDeviceConfigChange(DeviceConfig.Properties properties) {
1280         Set<String> changeSet = properties.getKeyset();
1281         if (changeSet.contains(SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION)) {
1282             boolean newNotifAliasRing = !properties.getBoolean(
1283                     SystemUiDeviceConfigFlags.VOLUME_SEPARATE_NOTIFICATION, CONFIG_DEFAULT_VAL);
1284             if (mNotifAliasRing != newNotifAliasRing) {
1285                 mNotifAliasRing = newNotifAliasRing;
1286                 updateStreamVolumeAlias(true, TAG);
1287             }
1288         }
1289     }
1290 
1291     /**
1292      * Called by handling of MSG_INIT_STREAMS_VOLUMES
1293      */
onInitStreamsAndVolumes()1294     private void onInitStreamsAndVolumes() {
1295         createStreamStates();
1296 
1297         // must be called after createStreamStates() as it uses MUSIC volume as default if no
1298         // persistent data
1299         initVolumeGroupStates();
1300 
1301         // mSafeUsbMediaVolumeIndex must be initialized after createStreamStates() because it
1302         // relies on audio policy having correct ranges for volume indexes.
1303         mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex();
1304         // Link VGS on VSS
1305         initVolumeStreamStates();
1306 
1307         // Call setRingerModeInt() to apply correct mute
1308         // state on streams affected by ringer mode.
1309         mRingerAndZenModeMutedStreams = 0;
1310         setRingerModeInt(getRingerModeInternal(), false);
1311 
1312         final float[] preScale = new float[3];
1313         preScale[0] = mContext.getResources().getFraction(
1314                 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index1,
1315                 1, 1);
1316         preScale[1] = mContext.getResources().getFraction(
1317                 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index2,
1318                 1, 1);
1319         preScale[2] = mContext.getResources().getFraction(
1320                 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index3,
1321                 1, 1);
1322         for (int i = 0; i < preScale.length; i++) {
1323             if (0.0f <= preScale[i] && preScale[i] <= 1.0f) {
1324                 mPrescaleAbsoluteVolume[i] = preScale[i];
1325             }
1326         }
1327 
1328         initExternalEventReceivers();
1329 
1330         // check on volume initialization
1331         checkVolumeRangeInitialization("AudioService()");
1332     }
1333 
1334     /**
1335      * Initialize intent receives and settings observers for this service.
1336      * Must be called after createStreamStates() as the handling of some events
1337      * may affect or need volumes, e.g. BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED
1338      * (for intent receiver), or Settings.Global.ZEN_MODE (for settings observer)
1339      */
initExternalEventReceivers()1340     private void initExternalEventReceivers() {
1341         mSettingsObserver = new SettingsObserver();
1342 
1343         // Register for device connection intent broadcasts.
1344         IntentFilter intentFilter =
1345                 new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
1346         intentFilter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED);
1347         intentFilter.addAction(Intent.ACTION_DOCK_EVENT);
1348         intentFilter.addAction(Intent.ACTION_SCREEN_ON);
1349         intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
1350         intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
1351         intentFilter.addAction(Intent.ACTION_USER_BACKGROUND);
1352         intentFilter.addAction(Intent.ACTION_USER_FOREGROUND);
1353         intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
1354         intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
1355         intentFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
1356 
1357         intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
1358         if (mMonitorRotation) {
1359             RotationHelper.init(mContext, mAudioHandler,
1360                     rotation -> onRotationUpdate(rotation),
1361                     foldState -> onFoldStateUpdate(foldState));
1362         }
1363 
1364         intentFilter.addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION);
1365         intentFilter.addAction(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION);
1366         intentFilter.addAction(ACTION_CHECK_MUSIC_ACTIVE);
1367 
1368         mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null,
1369                 Context.RECEIVER_EXPORTED);
1370 
1371     }
1372 
systemReady()1373     public void systemReady() {
1374         sendMsg(mAudioHandler, MSG_SYSTEM_READY, SENDMSG_QUEUE,
1375                 0, 0, null, 0);
1376         if (false) {
1377             // This is turned off for now, because it is racy and thus causes apps to break.
1378             // Currently banning a uid means that if an app tries to start playing an audio
1379             // stream, that will be preventing, and unbanning it will not allow that stream
1380             // to resume.  However these changes in uid state are racy with what the app is doing,
1381             // so that after taking a process out of the cached state we can't guarantee that
1382             // we will unban the uid before the app actually tries to start playing audio.
1383             // (To do that, the activity manager would need to wait until it knows for sure
1384             // that the ban has been removed, before telling the app to do whatever it is
1385             // supposed to do that caused it to go out of the cached state.)
1386             try {
1387                 ActivityManager.getService().registerUidObserver(mUidObserver,
1388                         ActivityManager.UID_OBSERVER_CACHED | ActivityManager.UID_OBSERVER_GONE,
1389                         ActivityManager.PROCESS_STATE_UNKNOWN, null);
1390             } catch (RemoteException e) {
1391                 // ignored; both services live in system_server
1392             }
1393         }
1394     }
1395 
updateVibratorInfos()1396     private void updateVibratorInfos() {
1397         VibratorManager vibratorManager = mContext.getSystemService(VibratorManager.class);
1398         if (vibratorManager == null) {
1399             Slog.e(TAG, "Vibrator manager is not found");
1400             return;
1401         }
1402         int[] vibratorIds = vibratorManager.getVibratorIds();
1403         if (vibratorIds.length == 0) {
1404             Slog.d(TAG, "No vibrator found");
1405             return;
1406         }
1407         List<Vibrator> vibrators = new ArrayList<>(vibratorIds.length);
1408         for (int id : vibratorIds) {
1409             Vibrator vibrator = vibratorManager.getVibrator(id);
1410             if (vibrator != null) {
1411                 vibrators.add(vibrator);
1412             } else {
1413                 Slog.w(TAG, "Vibrator(" + id + ") is not found");
1414             }
1415         }
1416         if (vibrators.isEmpty()) {
1417             Slog.w(TAG, "Cannot find any available vibrator");
1418             return;
1419         }
1420         AudioSystem.setVibratorInfos(vibrators);
1421     }
1422 
onSystemReady()1423     public void onSystemReady() {
1424         mSystemReady = true;
1425         scheduleLoadSoundEffects();
1426 
1427         mDeviceBroker.onSystemReady();
1428 
1429         if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_HDMI_CEC)) {
1430             synchronized (mHdmiClientLock) {
1431                 mHdmiManager = mContext.getSystemService(HdmiControlManager.class);
1432                 if (mHdmiManager != null) {
1433                     mHdmiManager.addHdmiControlStatusChangeListener(
1434                             mHdmiControlStatusChangeListenerCallback);
1435                     mHdmiManager.addHdmiCecVolumeControlFeatureListener(mContext.getMainExecutor(),
1436                             mMyHdmiCecVolumeControlFeatureListener);
1437                 }
1438                 mHdmiTvClient = mHdmiManager.getTvClient();
1439                 if (mHdmiTvClient != null) {
1440                     mFixedVolumeDevices.removeAll(
1441                             AudioSystem.DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET);
1442                 }
1443                 mHdmiPlaybackClient = mHdmiManager.getPlaybackClient();
1444                 mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient();
1445             }
1446         }
1447 
1448         if (mSupportsMicPrivacyToggle) {
1449             mSensorPrivacyManagerInternal.addSensorPrivacyListenerForAllUsers(
1450                     SensorPrivacyManager.Sensors.MICROPHONE, (userId, enabled) -> {
1451                         if (userId == getCurrentUserId()) {
1452                             mMicMuteFromPrivacyToggle = enabled;
1453                             setMicrophoneMuteNoCallerCheck(getCurrentUserId());
1454                         }
1455                     });
1456         }
1457 
1458         mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
1459 
1460         sendMsg(mAudioHandler,
1461                 MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED,
1462                 SENDMSG_REPLACE,
1463                 0,
1464                 0,
1465                 TAG,
1466                 SystemProperties.getBoolean("audio.safemedia.bypass", false) ?
1467                         0 : SAFE_VOLUME_CONFIGURE_TIMEOUT_MS);
1468 
1469         initA11yMonitoring();
1470 
1471         mRoleObserver = new RoleObserver();
1472         mRoleObserver.register();
1473 
1474         onIndicateSystemReady();
1475 
1476         mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted();
1477         setMicMuteFromSwitchInput();
1478 
1479         initMinStreamVolumeWithoutModifyAudioSettings();
1480 
1481         updateVibratorInfos();
1482 
1483         synchronized (mSupportedSystemUsagesLock) {
1484             AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages);
1485         }
1486     }
1487 
1488     //-----------------------------------------------------------------
1489     // routing monitoring from AudioSystemAdapter
1490     @Override
onRoutingUpdatedFromNative()1491     public void onRoutingUpdatedFromNative() {
1492         sendMsg(mAudioHandler,
1493                 MSG_ROUTING_UPDATED,
1494                 SENDMSG_REPLACE, 0, 0, null,
1495                 /*delay*/ 0);
1496     }
1497 
1498     /**
1499      * called when handling MSG_ROUTING_UPDATED
1500      */
onRoutingUpdatedFromAudioThread()1501     void onRoutingUpdatedFromAudioThread() {
1502         if (mHasSpatializerEffect) {
1503             mSpatializerHelper.onRoutingUpdated();
1504         }
1505         checkMuteAwaitConnection();
1506     }
1507 
1508     //-----------------------------------------------------------------
1509     // rotation/fold updates coming from RotationHelper
onRotationUpdate(Integer rotation)1510     void onRotationUpdate(Integer rotation) {
1511         mSpatializerHelper.setDisplayOrientation((float) (rotation * Math.PI / 180.));
1512         // use REPLACE as only the last rotation matters
1513         final String rotationParameter = "rotation=" + rotation;
1514         sendMsg(mAudioHandler, MSG_ROTATION_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0,
1515                 /*obj*/ rotationParameter, /*delay*/ 0);
1516     }
1517 
onFoldStateUpdate(Boolean foldState)1518     void onFoldStateUpdate(Boolean foldState) {
1519         mSpatializerHelper.setFoldState(foldState);
1520         // use REPLACE as only the last fold state matters
1521         final String foldStateParameter = "device_folded=" + (foldState ? "on" : "off");
1522         sendMsg(mAudioHandler, MSG_FOLD_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0,
1523                 /*obj*/ foldStateParameter, /*delay*/ 0);
1524     }
1525 
1526     //-----------------------------------------------------------------
1527     // Communicate to PlayackActivityMonitor whether to log or not
1528     // the sound FX activity (useful for removing touch sounds in the activity logs)
ignorePlayerLogs(@onNull PlayerBase playerToIgnore)1529     void ignorePlayerLogs(@NonNull PlayerBase playerToIgnore) {
1530         if (DEBUG_LOG_SOUND_FX) {
1531             return;
1532         }
1533         sendMsg(mAudioHandler, MSG_NO_LOG_FOR_PLAYER_I, SENDMSG_REPLACE,
1534                 /*arg1, piid of the player*/ playerToIgnore.getPlayerIId(),
1535                 /*arg2 ignored*/ 0, /*obj ignored*/ null, /*delay*/ 0);
1536     }
1537 
1538     //-----------------------------------------------------------------
1539     // monitoring requests for volume range initialization
1540     @Override // AudioSystemAdapter.OnVolRangeInitRequestListener
onVolumeRangeInitRequestFromNative()1541     public void onVolumeRangeInitRequestFromNative() {
1542         sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_REPLACE, 0, 0,
1543                 "onVolumeRangeInitRequestFromNative" /*obj: caller, for dumpsys*/, /*delay*/ 0);
1544     }
1545 
1546     //-----------------------------------------------------------------
1547     RoleObserver mRoleObserver;
1548 
1549     class RoleObserver implements OnRoleHoldersChangedListener {
1550         private RoleManager mRm;
1551         private final Executor mExecutor;
1552 
RoleObserver()1553         RoleObserver() {
1554             mExecutor = mContext.getMainExecutor();
1555         }
1556 
register()1557         public void register() {
1558             mRm = (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE);
1559             if (mRm != null) {
1560                 mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.ALL);
1561                 synchronized (mSettingsLock) {
1562                     updateAssistantUIdLocked(/* forceUpdate= */ true);
1563                 }
1564             }
1565         }
1566 
1567         @Override
onRoleHoldersChanged(@onNull String roleName, @NonNull UserHandle user)1568         public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
1569             if (RoleManager.ROLE_ASSISTANT.equals(roleName)) {
1570                 synchronized (mSettingsLock) {
1571                     updateAssistantUIdLocked(/* forceUpdate= */ false);
1572                 }
1573             }
1574         }
1575 
getAssistantRoleHolder()1576         public String getAssistantRoleHolder() {
1577             String assitantPackage = "";
1578             if (mRm != null) {
1579                 List<String> assistants = mRm.getRoleHolders(RoleManager.ROLE_ASSISTANT);
1580                 assitantPackage = assistants.size() == 0 ? "" : assistants.get(0);
1581             }
1582             return assitantPackage;
1583         }
1584     }
1585 
onIndicateSystemReady()1586     void onIndicateSystemReady() {
1587         if (AudioSystem.systemReady() == AudioSystem.SUCCESS) {
1588             return;
1589         }
1590         sendMsg(mAudioHandler,
1591                 MSG_INDICATE_SYSTEM_READY,
1592                 SENDMSG_REPLACE,
1593                 0,
1594                 0,
1595                 null,
1596                 INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
1597     }
1598 
onAudioServerDied()1599     public void onAudioServerDied() {
1600         if (!mSystemReady ||
1601                 (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) {
1602             Log.e(TAG, "Audioserver died.");
1603             sLifecycleLogger.log(new AudioEventLogger.StringEvent(
1604                     "onAudioServerDied() audioserver died"));
1605             sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, SENDMSG_NOOP, 0, 0,
1606                     null, 500);
1607             return;
1608         }
1609         Log.i(TAG, "Audioserver started.");
1610         sLifecycleLogger.log(new AudioEventLogger.StringEvent(
1611                 "onAudioServerDied() audioserver started"));
1612 
1613         updateAudioHalPids();
1614 
1615         // indicate to audio HAL that we start the reconfiguration phase after a media
1616         // server crash
1617         // Note that we only execute this when the media server
1618         // process restarts after a crash, not the first time it is started.
1619         AudioSystem.setParameters("restarting=true");
1620 
1621         readAndSetLowRamDevice();
1622 
1623         mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported();
1624 
1625         // Restore device connection states, BT state
1626         mDeviceBroker.onAudioServerDied();
1627 
1628         // Restore call state
1629         synchronized (mDeviceBroker.mSetModeLock) {
1630             onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(),
1631                     mContext.getPackageName(), true /*force*/);
1632         }
1633         final int forSys;
1634         synchronized (mSettingsLock) {
1635             forSys = mCameraSoundForced ?
1636                     AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE;
1637         }
1638 
1639         mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, forSys, "onAudioServerDied");
1640 
1641         // Restore stream volumes
1642         onReinitVolumes("after audioserver restart");
1643 
1644         // Restore audio volume groups
1645         restoreVolumeGroups();
1646 
1647         // Restore mono mode
1648         updateMasterMono(mContentResolver);
1649 
1650         // Restore audio balance
1651         updateMasterBalance(mContentResolver);
1652 
1653         // Restore ringer mode
1654         setRingerModeInt(getRingerModeInternal(), false);
1655 
1656         // Reset device rotation (if monitored for this device)
1657         if (mMonitorRotation) {
1658             RotationHelper.updateOrientation();
1659         }
1660 
1661         // Restore setParameters and other queued setters.
1662         mRestorableParameters.restoreAll();
1663 
1664         synchronized (mSettingsLock) {
1665             final int forDock = mDockAudioMediaEnabled ?
1666                     AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE;
1667             mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, forDock, "onAudioServerDied");
1668             sendEncodedSurroundMode(mContentResolver, "onAudioServerDied");
1669             sendEnabledSurroundFormats(mContentResolver, true);
1670             AudioSystem.setRttEnabled(mRttEnabled);
1671             resetAssistantServicesUidsLocked();
1672         }
1673 
1674         synchronized (mAccessibilityServiceUidsLock) {
1675             AudioSystem.setA11yServicesUids(mAccessibilityServiceUids);
1676         }
1677         synchronized (mInputMethodServiceUidLock) {
1678             mAudioSystem.setCurrentImeUid(mInputMethodServiceUid);
1679         }
1680         synchronized (mHdmiClientLock) {
1681             if (mHdmiManager != null && mHdmiTvClient != null) {
1682                 setHdmiSystemAudioSupported(mHdmiSystemAudioSupported);
1683             }
1684         }
1685 
1686         synchronized (mSupportedSystemUsagesLock) {
1687             AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages);
1688         }
1689 
1690         synchronized (mAudioPolicies) {
1691             ArrayList<AudioPolicyProxy> invalidProxies = new ArrayList<>();
1692             for (AudioPolicyProxy policy : mAudioPolicies.values()) {
1693                 final int status = policy.connectMixes();
1694                 if (status != AudioSystem.SUCCESS) {
1695                     // note that PERMISSION_DENIED may also indicate trouble getting to APService
1696                     Log.e(TAG, "onAudioServerDied: error "
1697                             + AudioSystem.audioSystemErrorToString(status)
1698                             + " when connecting mixes for policy " + policy.toLogFriendlyString());
1699                     invalidProxies.add(policy);
1700                 } else {
1701                     final int deviceAffinitiesStatus = policy.setupDeviceAffinities();
1702                     if (deviceAffinitiesStatus != AudioSystem.SUCCESS) {
1703                         Log.e(TAG, "onAudioServerDied: error "
1704                                 + AudioSystem.audioSystemErrorToString(deviceAffinitiesStatus)
1705                                 + " when connecting device affinities for policy "
1706                                 + policy.toLogFriendlyString());
1707                         invalidProxies.add(policy);
1708                     }
1709                 }
1710             }
1711             invalidProxies.forEach((policy) -> policy.release());
1712 
1713         }
1714 
1715         // Restore capture policies
1716         synchronized (mPlaybackMonitor) {
1717             HashMap<Integer, Integer> allowedCapturePolicies =
1718                     mPlaybackMonitor.getAllAllowedCapturePolicies();
1719             for (HashMap.Entry<Integer, Integer> entry : allowedCapturePolicies.entrySet()) {
1720                 int result = mAudioSystem.setAllowedCapturePolicy(
1721                         entry.getKey(),
1722                         AudioAttributes.capturePolicyToFlags(entry.getValue(), 0x0));
1723                 if (result != AudioSystem.AUDIO_STATUS_OK) {
1724                     Log.e(TAG, "Failed to restore capture policy, uid: "
1725                             + entry.getKey() + ", capture policy: " + entry.getValue()
1726                             + ", result: " + result);
1727                     // When restoring capture policy failed, set the capture policy as
1728                     // ALLOW_CAPTURE_BY_ALL, which will result in removing the cached
1729                     // capture policy in PlaybackActivityMonitor.
1730                     mPlaybackMonitor.setAllowedCapturePolicy(
1731                             entry.getKey(), AudioAttributes.ALLOW_CAPTURE_BY_ALL);
1732                 }
1733             }
1734         }
1735 
1736         mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect);
1737 
1738         // Restore rotation information.
1739         if (mMonitorRotation) {
1740             RotationHelper.forceUpdate();
1741         }
1742 
1743         onIndicateSystemReady();
1744         // indicate the end of reconfiguration phase to audio HAL
1745         AudioSystem.setParameters("restarting=false");
1746 
1747         sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE,
1748                 SENDMSG_QUEUE, 1, 0, null, 0);
1749 
1750         setMicrophoneMuteNoCallerCheck(getCurrentUserId()); // will also update the mic mute cache
1751         setMicMuteFromSwitchInput();
1752 
1753         // Restore vibrator info
1754         updateVibratorInfos();
1755     }
1756 
onRemoveAssistantServiceUids(int[] uids)1757     private void onRemoveAssistantServiceUids(int[] uids) {
1758         synchronized (mSettingsLock) {
1759             removeAssistantServiceUidsLocked(uids);
1760         }
1761     }
1762 
1763     @GuardedBy("mSettingsLock")
removeAssistantServiceUidsLocked(int[] uids)1764     private void removeAssistantServiceUidsLocked(int[] uids) {
1765         boolean changed = false;
1766         for (int index = 0; index < uids.length; index++) {
1767             if (!mAssistantUids.remove(uids[index])) {
1768                 Slog.e(TAG, TextUtils.formatSimple(
1769                         "Cannot remove assistant service, uid(%d) not present", uids[index]));
1770                 continue;
1771             }
1772             changed = true;
1773         }
1774         if (changed) {
1775             updateAssistantServicesUidsLocked();
1776         }
1777     }
1778 
onAddAssistantServiceUids(int[] uids)1779     private void onAddAssistantServiceUids(int[] uids) {
1780         synchronized (mSettingsLock) {
1781             addAssistantServiceUidsLocked(uids);
1782         }
1783     }
1784 
1785     @GuardedBy("mSettingsLock")
addAssistantServiceUidsLocked(int[] uids)1786     private void addAssistantServiceUidsLocked(int[] uids) {
1787         boolean changed = false;
1788         for (int index = 0; index < uids.length; index++) {
1789             if (uids[index] == INVALID_UID) {
1790                 continue;
1791             }
1792             if (!mAssistantUids.add(uids[index])) {
1793                 Slog.e(TAG, TextUtils.formatSimple(
1794                                 "Cannot add assistant service, uid(%d) already present",
1795                                 uids[index]));
1796                 continue;
1797             }
1798             changed = true;
1799         }
1800         if (changed) {
1801             updateAssistantServicesUidsLocked();
1802         }
1803     }
1804 
1805     @GuardedBy("mSettingsLock")
resetAssistantServicesUidsLocked()1806     private void resetAssistantServicesUidsLocked() {
1807         mAssistantUids.clear();
1808         updateAssistantUIdLocked(/* forceUpdate= */ true);
1809     }
1810 
1811     @GuardedBy("mSettingsLock")
updateAssistantServicesUidsLocked()1812     private void updateAssistantServicesUidsLocked() {
1813         int[] assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray();
1814         AudioSystem.setAssistantServicesUids(assistantUids);
1815     }
1816 
updateActiveAssistantServiceUids()1817     private void updateActiveAssistantServiceUids() {
1818         int [] activeAssistantServiceUids;
1819         synchronized (mSettingsLock) {
1820             activeAssistantServiceUids = mActiveAssistantServiceUids;
1821         }
1822         AudioSystem.setActiveAssistantServicesUids(activeAssistantServiceUids);
1823     }
1824 
onReinitVolumes(@onNull String caller)1825     private void onReinitVolumes(@NonNull String caller) {
1826         final int numStreamTypes = AudioSystem.getNumStreamTypes();
1827         // keep track of any error during stream volume initialization
1828         int status = AudioSystem.AUDIO_STATUS_OK;
1829         for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
1830             VolumeStreamState streamState = mStreamStates[streamType];
1831             final int res = AudioSystem.initStreamVolume(
1832                     streamType, streamState.mIndexMin / 10, streamState.mIndexMax / 10);
1833             if (res != AudioSystem.AUDIO_STATUS_OK) {
1834                 status = res;
1835                 Log.e(TAG, "Failed to initStreamVolume (" + res + ") for stream " + streamType);
1836                 // stream volume initialization failed, no need to try the others, it will be
1837                 // attempted again when MSG_REINIT_VOLUMES is handled
1838                 break;
1839             }
1840             streamState.applyAllVolumes();
1841         }
1842 
1843         // did it work? check based on status
1844         if (status != AudioSystem.AUDIO_STATUS_OK) {
1845             sLifecycleLogger.log(new AudioEventLogger.StringEvent(
1846                     caller + ": initStreamVolume failed with " + status + " will retry")
1847                     .printLog(ALOGE, TAG));
1848             sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0,
1849                     caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
1850             return;
1851         }
1852 
1853         // did it work? check based on min/max values of some basic streams
1854         if (!checkVolumeRangeInitialization(caller)) {
1855             return;
1856         }
1857 
1858         // success
1859         sLifecycleLogger.log(new AudioEventLogger.StringEvent(
1860                 caller + ": initStreamVolume succeeded").printLog(ALOGI, TAG));
1861     }
1862 
1863     /**
1864      * Check volume ranges were properly initialized
1865      * @return true if volume ranges were successfully initialized
1866      */
checkVolumeRangeInitialization(String caller)1867     private boolean checkVolumeRangeInitialization(String caller) {
1868         boolean success = true;
1869         final int[] basicStreams = { AudioSystem.STREAM_ALARM, AudioSystem.STREAM_RING,
1870                 AudioSystem.STREAM_MUSIC, AudioSystem.STREAM_VOICE_CALL,
1871                 AudioSystem.STREAM_ACCESSIBILITY };
1872         for (int streamType : basicStreams) {
1873             final AudioAttributes aa = new AudioAttributes.Builder()
1874                     .setInternalLegacyStreamType(streamType).build();
1875             if (AudioSystem.getMaxVolumeIndexForAttributes(aa) < 0
1876                     || AudioSystem.getMinVolumeIndexForAttributes(aa) < 0) {
1877                 success = false;
1878                 break;
1879             }
1880         }
1881         if (!success) {
1882             sLifecycleLogger.log(new AudioEventLogger.StringEvent(
1883                     caller + ": initStreamVolume succeeded but invalid mix/max levels, will retry")
1884                     .printLog(ALOGW, TAG));
1885             sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0,
1886                     caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
1887         }
1888         return success;
1889     }
1890 
onDispatchAudioServerStateChange(boolean state)1891     private void onDispatchAudioServerStateChange(boolean state) {
1892         synchronized (mAudioServerStateListeners) {
1893             for (AsdProxy asdp : mAudioServerStateListeners.values()) {
1894                 try {
1895                     asdp.callback().dispatchAudioServerStateChange(state);
1896                 } catch (RemoteException e) {
1897                     Log.w(TAG, "Could not call dispatchAudioServerStateChange()", e);
1898                 }
1899             }
1900         }
1901     }
1902 
createAudioSystemThread()1903     private void createAudioSystemThread() {
1904         mAudioSystemThread = new AudioSystemThread();
1905         mAudioSystemThread.start();
1906         waitForAudioHandlerCreation();
1907     }
1908 
1909     /** Waits for the volume handler to be created by the other thread. */
waitForAudioHandlerCreation()1910     private void waitForAudioHandlerCreation() {
1911         synchronized(this) {
1912             while (mAudioHandler == null) {
1913                 try {
1914                     // Wait for mAudioHandler to be set by the other thread
1915                     wait();
1916                 } catch (InterruptedException e) {
1917                     Log.e(TAG, "Interrupted while waiting on volume handler.");
1918                 }
1919             }
1920         }
1921     }
1922 
1923     /**
1924      * @see AudioManager#setSupportedSystemUsages(int[])
1925      */
setSupportedSystemUsages(@onNull @ttributeSystemUsage int[] systemUsages)1926     public void setSupportedSystemUsages(@NonNull @AttributeSystemUsage int[] systemUsages) {
1927         enforceModifyAudioRoutingPermission();
1928         verifySystemUsages(systemUsages);
1929 
1930         synchronized (mSupportedSystemUsagesLock) {
1931             AudioSystem.setSupportedSystemUsages(systemUsages);
1932             mSupportedSystemUsages = systemUsages;
1933         }
1934     }
1935 
1936     /**
1937      * @see AudioManager#getSupportedSystemUsages()
1938      */
getSupportedSystemUsages()1939     public @NonNull @AttributeSystemUsage int[] getSupportedSystemUsages() {
1940         enforceModifyAudioRoutingPermission();
1941         synchronized (mSupportedSystemUsagesLock) {
1942             return Arrays.copyOf(mSupportedSystemUsages, mSupportedSystemUsages.length);
1943         }
1944     }
1945 
verifySystemUsages(@onNull int[] systemUsages)1946     private void verifySystemUsages(@NonNull int[] systemUsages) {
1947         for (int i = 0; i < systemUsages.length; i++) {
1948             if (!AudioAttributes.isSystemUsage(systemUsages[i])) {
1949                 throw new IllegalArgumentException("Non-system usage provided: " + systemUsages[i]);
1950             }
1951         }
1952     }
1953 
1954     /**
1955      * @return the {@link android.media.audiopolicy.AudioProductStrategy} discovered from the
1956      * platform configuration file.
1957      */
1958     @NonNull
getAudioProductStrategies()1959     public List<AudioProductStrategy> getAudioProductStrategies() {
1960         // verify permissions
1961         enforceModifyAudioRoutingPermission();
1962         return AudioProductStrategy.getAudioProductStrategies();
1963     }
1964 
1965     /**
1966      * @return the List of {@link android.media.audiopolicy.AudioVolumeGroup} discovered from the
1967      * platform configuration file.
1968      */
1969     @NonNull
getAudioVolumeGroups()1970     public List<AudioVolumeGroup> getAudioVolumeGroups() {
1971         // verify permissions
1972         enforceModifyAudioRoutingPermission();
1973         return AudioVolumeGroup.getAudioVolumeGroups();
1974     }
1975 
checkAllAliasStreamVolumes()1976     private void checkAllAliasStreamVolumes() {
1977         synchronized (mSettingsLock) {
1978             synchronized (VolumeStreamState.class) {
1979                 int numStreamTypes = AudioSystem.getNumStreamTypes();
1980                 for (int streamType = 0; streamType < numStreamTypes; streamType++) {
1981                     mStreamStates[streamType]
1982                             .setAllIndexes(mStreamStates[mStreamVolumeAlias[streamType]], TAG);
1983                     // apply stream volume
1984                     if (!mStreamStates[streamType].mIsMuted) {
1985                         mStreamStates[streamType].applyAllVolumes();
1986                     }
1987                 }
1988             }
1989         }
1990     }
1991 
1992 
1993     /**
1994      * Called from AudioDeviceBroker when DEVICE_OUT_HDMI is connected or disconnected.
1995      */
postCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)1996     /*package*/ void postCheckVolumeCecOnHdmiConnection(
1997             @AudioService.ConnectionState  int state, String caller) {
1998         sendMsg(mAudioHandler, MSG_HDMI_VOLUME_CHECK, SENDMSG_REPLACE,
1999                 state /*arg1*/, 0 /*arg2 ignored*/, caller /*obj*/, 0 /*delay*/);
2000     }
2001 
onCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)2002     private void onCheckVolumeCecOnHdmiConnection(
2003             @AudioService.ConnectionState int state, String caller) {
2004         if (state == AudioService.CONNECTION_STATE_CONNECTED) {
2005             // DEVICE_OUT_HDMI is now connected
2006             if (mSafeMediaVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI)) {
2007                 scheduleMusicActiveCheck();
2008             }
2009 
2010             if (isPlatformTelevision()) {
2011                 synchronized (mHdmiClientLock) {
2012                     if (mHdmiManager != null && mHdmiPlaybackClient != null) {
2013                         updateHdmiCecSinkLocked(
2014                                 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI));
2015                     }
2016                 }
2017             }
2018             sendEnabledSurroundFormats(mContentResolver, true);
2019         } else {
2020             // DEVICE_OUT_HDMI disconnected
2021             if (isPlatformTelevision()) {
2022                 synchronized (mHdmiClientLock) {
2023                     if (mHdmiManager != null) {
2024                         updateHdmiCecSinkLocked(
2025                                 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI));
2026                     }
2027                 }
2028             }
2029         }
2030     }
2031 
2032     /**
2033      * Asynchronously update volume states for the given device.
2034      *
2035      * @param device a single audio device, ensure that this is not a devices bitmask
2036      * @param caller caller of this method
2037      */
postUpdateVolumeStatesForAudioDevice(int device, String caller)2038     private void postUpdateVolumeStatesForAudioDevice(int device, String caller) {
2039         sendMsg(mAudioHandler,
2040                 MSG_UPDATE_VOLUME_STATES_FOR_DEVICE,
2041                 SENDMSG_QUEUE, device /*arg1*/, 0 /*arg2*/, caller /*obj*/,
2042                 0 /*delay*/);
2043     }
2044 
2045     /**
2046      * Update volume states for the given device.
2047      *
2048      * This will initialize the volume index if no volume index is available.
2049      * If the device is the currently routed device, fixed/full volume policies will be applied.
2050      *
2051      * @param device a single audio device, ensure that this is not a devices bitmask
2052      * @param caller caller of this method
2053      */
onUpdateVolumeStatesForAudioDevice(int device, String caller)2054     private void onUpdateVolumeStatesForAudioDevice(int device, String caller) {
2055         final int numStreamTypes = AudioSystem.getNumStreamTypes();
2056         synchronized (mSettingsLock) {
2057             synchronized (VolumeStreamState.class) {
2058                 for (int streamType = 0; streamType < numStreamTypes; streamType++) {
2059                     updateVolumeStates(device, streamType, caller);
2060                 }
2061             }
2062         }
2063     }
2064 
2065     /**
2066      * Update volume states for the given device and given stream.
2067      *
2068      * This will initialize the volume index if no volume index is available.
2069      * If the device is the currently routed device, fixed/full volume policies will be applied.
2070      *
2071      * @param device a single audio device, ensure that this is not a devices bitmask
2072      * @param streamType streamType to be updated
2073      * @param caller caller of this method
2074      */
updateVolumeStates(int device, int streamType, String caller)2075     private void updateVolumeStates(int device, int streamType, String caller) {
2076         // Handle device volume aliasing of SPEAKER_SAFE.
2077         if (device == AudioSystem.DEVICE_OUT_SPEAKER_SAFE) {
2078             device = AudioSystem.DEVICE_OUT_SPEAKER;
2079         }
2080         if (!mStreamStates[streamType].hasIndexForDevice(device)) {
2081             // set the default value, if device is affected by a full/fix/abs volume rule, it
2082             // will taken into account in checkFixedVolumeDevices()
2083             mStreamStates[streamType].setIndex(
2084                     mStreamStates[mStreamVolumeAlias[streamType]]
2085                             .getIndex(AudioSystem.DEVICE_OUT_DEFAULT),
2086                     device, caller, true /*hasModifyAudioSettings*/);
2087         }
2088 
2089         // Check if device to be updated is routed for the given audio stream
2090         // This may include devices such as SPEAKER_SAFE.
2091         List<AudioDeviceAttributes> devicesForAttributes = getDevicesForAttributesInt(
2092                 new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build(),
2093                 true /* forVolume */);
2094         for (AudioDeviceAttributes deviceAttributes : devicesForAttributes) {
2095             if (deviceAttributes.getType() == AudioDeviceInfo.convertInternalDeviceToDeviceType(
2096                     device)) {
2097                 mStreamStates[streamType].checkFixedVolumeDevices();
2098 
2099                 // Unmute streams if required and device is full volume
2100                 if (isStreamMute(streamType) && mFullVolumeDevices.contains(device)) {
2101                     mStreamStates[streamType].mute(false);
2102                 }
2103             }
2104         }
2105     }
2106 
checkAllFixedVolumeDevices()2107     private void checkAllFixedVolumeDevices()
2108     {
2109         int numStreamTypes = AudioSystem.getNumStreamTypes();
2110         for (int streamType = 0; streamType < numStreamTypes; streamType++) {
2111             mStreamStates[streamType].checkFixedVolumeDevices();
2112         }
2113     }
2114 
checkAllFixedVolumeDevices(int streamType)2115     private void checkAllFixedVolumeDevices(int streamType) {
2116         mStreamStates[streamType].checkFixedVolumeDevices();
2117     }
2118 
checkMuteAffectedStreams()2119     private void checkMuteAffectedStreams() {
2120         // any stream with a min level > 0 is not muteable by definition
2121         // STREAM_VOICE_CALL and STREAM_BLUETOOTH_SCO can be muted by applications
2122         // that has the the MODIFY_PHONE_STATE permission.
2123         for (int i = 0; i < mStreamStates.length; i++) {
2124             final VolumeStreamState vss = mStreamStates[i];
2125             if (vss.mIndexMin > 0 &&
2126                 (vss.mStreamType != AudioSystem.STREAM_VOICE_CALL &&
2127                 vss.mStreamType != AudioSystem.STREAM_BLUETOOTH_SCO)) {
2128                 mMuteAffectedStreams &= ~(1 << vss.mStreamType);
2129             }
2130         }
2131     }
2132 
createStreamStates()2133     private void createStreamStates() {
2134         int numStreamTypes = AudioSystem.getNumStreamTypes();
2135         VolumeStreamState[] streams = mStreamStates = new VolumeStreamState[numStreamTypes];
2136 
2137         for (int i = 0; i < numStreamTypes; i++) {
2138             streams[i] =
2139                     new VolumeStreamState(System.VOLUME_SETTINGS_INT[mStreamVolumeAlias[i]], i);
2140         }
2141 
2142         checkAllFixedVolumeDevices();
2143         checkAllAliasStreamVolumes();
2144         checkMuteAffectedStreams();
2145         updateDefaultVolumes();
2146     }
2147 
2148     /**
2149      * Update default indexes from aliased streams. Must be called after mStreamStates is created
2150      * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for default
2151      * index. Need to make default index configurable and independent of streams.
2152      * Fallback on music stream for default initialization to take benefit of property based default
2153      * initialization.
2154      * For other volume groups not linked to any streams, default music stream index is considered.
2155      */
updateDefaultVolumes()2156     private void updateDefaultVolumes() {
2157         for (int stream = 0; stream < mStreamStates.length; stream++) {
2158             int streamVolumeAlias = mStreamVolumeAlias[stream];
2159             if (mUseVolumeGroupAliases) {
2160                 if (AudioSystem.DEFAULT_STREAM_VOLUME[stream] != UNSET_INDEX) {
2161                     // Already initialized through default property based mecanism.
2162                     continue;
2163                 }
2164                 streamVolumeAlias = AudioSystem.STREAM_MUSIC;
2165                 int defaultAliasVolume = getUiDefaultRescaledIndex(streamVolumeAlias, stream);
2166                 if ((defaultAliasVolume >= MIN_STREAM_VOLUME[stream])
2167                         && (defaultAliasVolume <= MAX_STREAM_VOLUME[stream])) {
2168                     AudioSystem.DEFAULT_STREAM_VOLUME[stream] = defaultAliasVolume;
2169                     continue;
2170                 }
2171             }
2172             if (stream != streamVolumeAlias) {
2173                 AudioSystem.DEFAULT_STREAM_VOLUME[stream] =
2174                         getUiDefaultRescaledIndex(streamVolumeAlias, stream);
2175             }
2176         }
2177     }
2178 
getUiDefaultRescaledIndex(int srcStream, int dstStream)2179     private int getUiDefaultRescaledIndex(int srcStream, int dstStream) {
2180         return (rescaleIndex(AudioSystem.DEFAULT_STREAM_VOLUME[srcStream] * 10,
2181                 srcStream, dstStream) + 5) / 10;
2182     }
2183 
dumpStreamStates(PrintWriter pw)2184     private void dumpStreamStates(PrintWriter pw) {
2185         pw.println("\nStream volumes (device: index)");
2186         int numStreamTypes = AudioSystem.getNumStreamTypes();
2187         for (int i = 0; i < numStreamTypes; i++) {
2188             StringBuilder alias = new StringBuilder();
2189             if (mStreamVolumeAlias[i] != i) {
2190                 alias.append(" (aliased to: ")
2191                         .append(AudioSystem.STREAM_NAMES[mStreamVolumeAlias[i]])
2192                         .append(")");
2193             }
2194             pw.println("- " + AudioSystem.STREAM_NAMES[i] + alias + ":");
2195             mStreamStates[i].dump(pw);
2196             pw.println("");
2197         }
2198         pw.print("\n- mute affected streams = 0x");
2199         pw.println(Integer.toHexString(mMuteAffectedStreams));
2200     }
2201 
updateStreamVolumeAlias(boolean updateVolumes, String caller)2202     private void updateStreamVolumeAlias(boolean updateVolumes, String caller) {
2203         int dtmfStreamAlias;
2204         final int a11yStreamAlias = sIndependentA11yVolume ?
2205                 AudioSystem.STREAM_ACCESSIBILITY : AudioSystem.STREAM_MUSIC;
2206         final int assistantStreamAlias = mContext.getResources().getBoolean(
2207                 com.android.internal.R.bool.config_useAssistantVolume) ?
2208                 AudioSystem.STREAM_ASSISTANT : AudioSystem.STREAM_MUSIC;
2209 
2210         if (mIsSingleVolume) {
2211             mStreamVolumeAlias = STREAM_VOLUME_ALIAS_TELEVISION.clone();
2212             dtmfStreamAlias = AudioSystem.STREAM_MUSIC;
2213         } else if (mUseVolumeGroupAliases) {
2214             mStreamVolumeAlias = STREAM_VOLUME_ALIAS_NONE.clone();
2215             dtmfStreamAlias = AudioSystem.STREAM_DTMF;
2216         } else {
2217             switch (mPlatformType) {
2218                 case AudioSystem.PLATFORM_VOICE:
2219                     mStreamVolumeAlias = STREAM_VOLUME_ALIAS_VOICE.clone();
2220                     dtmfStreamAlias = AudioSystem.STREAM_RING;
2221                     break;
2222                 default:
2223                     mStreamVolumeAlias = STREAM_VOLUME_ALIAS_DEFAULT.clone();
2224                     dtmfStreamAlias = AudioSystem.STREAM_MUSIC;
2225             }
2226             if (!mNotifAliasRing) {
2227                 mStreamVolumeAlias[AudioSystem.STREAM_NOTIFICATION] =
2228                         AudioSystem.STREAM_NOTIFICATION;
2229             }
2230         }
2231 
2232         if (mIsSingleVolume) {
2233             mRingerModeAffectedStreams = 0;
2234         } else {
2235             if (isInCommunication()) {
2236                 dtmfStreamAlias = AudioSystem.STREAM_VOICE_CALL;
2237                 mRingerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF);
2238             } else {
2239                 mRingerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF);
2240             }
2241         }
2242 
2243         mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias;
2244         mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY] = a11yStreamAlias;
2245         mStreamVolumeAlias[AudioSystem.STREAM_ASSISTANT] = assistantStreamAlias;
2246 
2247         if (updateVolumes && mStreamStates != null) {
2248             updateDefaultVolumes();
2249 
2250             synchronized (mSettingsLock) {
2251                 synchronized (VolumeStreamState.class) {
2252                     mStreamStates[AudioSystem.STREAM_DTMF]
2253                             .setAllIndexes(mStreamStates[dtmfStreamAlias], caller);
2254                     mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setSettingName(
2255                             System.VOLUME_SETTINGS_INT[a11yStreamAlias]);
2256                     mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setAllIndexes(
2257                             mStreamStates[a11yStreamAlias], caller);
2258                 }
2259             }
2260             if (sIndependentA11yVolume) {
2261                 // restore the a11y values from the settings
2262                 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].readSettings();
2263             }
2264 
2265             // apply stream mute states according to new value of mRingerModeAffectedStreams
2266             setRingerModeInt(getRingerModeInternal(), false);
2267             sendMsg(mAudioHandler,
2268                     MSG_SET_ALL_VOLUMES,
2269                     SENDMSG_QUEUE,
2270                     0,
2271                     0,
2272                     mStreamStates[AudioSystem.STREAM_DTMF], 0);
2273             sendMsg(mAudioHandler,
2274                     MSG_SET_ALL_VOLUMES,
2275                     SENDMSG_QUEUE,
2276                     0,
2277                     0,
2278                     mStreamStates[AudioSystem.STREAM_ACCESSIBILITY], 0);
2279         }
2280     }
2281 
readDockAudioSettings(ContentResolver cr)2282     private void readDockAudioSettings(ContentResolver cr)
2283     {
2284         mDockAudioMediaEnabled = mSettings.getGlobalInt(
2285                                         cr, Settings.Global.DOCK_AUDIO_MEDIA_ENABLED, 0) == 1;
2286 
2287         sendMsg(mAudioHandler,
2288                 MSG_SET_FORCE_USE,
2289                 SENDMSG_QUEUE,
2290                 AudioSystem.FOR_DOCK,
2291                 mDockAudioMediaEnabled ?
2292                         AudioSystem.FORCE_DIGITAL_DOCK : AudioSystem.FORCE_NONE,
2293                 new String("readDockAudioSettings"),
2294                 0);
2295 
2296     }
2297 
2298 
updateMasterMono(ContentResolver cr)2299     private void updateMasterMono(ContentResolver cr)
2300     {
2301         final boolean masterMono = mSettings.getSystemIntForUser(
2302                 cr, System.MASTER_MONO, 0 /* default */, UserHandle.USER_CURRENT) == 1;
2303         if (DEBUG_VOL) {
2304             Log.d(TAG, String.format("Master mono %b", masterMono));
2305         }
2306         AudioSystem.setMasterMono(masterMono);
2307     }
2308 
updateMasterBalance(ContentResolver cr)2309     private void updateMasterBalance(ContentResolver cr) {
2310         final float masterBalance = System.getFloatForUser(
2311                 cr, System.MASTER_BALANCE, 0.f /* default */, UserHandle.USER_CURRENT);
2312         if (DEBUG_VOL) {
2313             Log.d(TAG, String.format("Master balance %f", masterBalance));
2314         }
2315         if (AudioSystem.setMasterBalance(masterBalance) != 0) {
2316             Log.e(TAG, String.format("setMasterBalance failed for %f", masterBalance));
2317         }
2318     }
2319 
sendEncodedSurroundMode(ContentResolver cr, String eventSource)2320     private void sendEncodedSurroundMode(ContentResolver cr, String eventSource)
2321     {
2322         final int encodedSurroundMode = mSettings.getGlobalInt(
2323                 cr, Settings.Global.ENCODED_SURROUND_OUTPUT,
2324                 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
2325         sendEncodedSurroundMode(encodedSurroundMode, eventSource);
2326     }
2327 
sendEncodedSurroundMode(int encodedSurroundMode, String eventSource)2328     private void sendEncodedSurroundMode(int encodedSurroundMode, String eventSource)
2329     {
2330         // initialize to guaranteed bad value
2331         int forceSetting = AudioSystem.NUM_FORCE_CONFIG;
2332         switch (encodedSurroundMode) {
2333             case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO:
2334                 forceSetting = AudioSystem.FORCE_NONE;
2335                 break;
2336             case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER:
2337                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_NEVER;
2338                 break;
2339             case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS:
2340                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_ALWAYS;
2341                 break;
2342             case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL:
2343                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_MANUAL;
2344                 break;
2345             default:
2346                 Log.e(TAG, "updateSurroundSoundSettings: illegal value "
2347                         + encodedSurroundMode);
2348                 break;
2349         }
2350         if (forceSetting != AudioSystem.NUM_FORCE_CONFIG) {
2351             mDeviceBroker.setForceUse_Async(AudioSystem.FOR_ENCODED_SURROUND, forceSetting,
2352                     eventSource);
2353         }
2354     }
2355 
2356     @Override // Binder call
onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)2357     public void onShellCommand(FileDescriptor in, FileDescriptor out,
2358             FileDescriptor err, String[] args, ShellCallback callback,
2359             ResultReceiver resultReceiver) {
2360         if (mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_AUDIO_POLICY)
2361                 != PackageManager.PERMISSION_GRANTED) {
2362             throw new SecurityException("Missing MANAGE_AUDIO_POLICY permission");
2363         }
2364         new AudioManagerShellCommand(AudioService.this).exec(this, in, out, err,
2365                 args, callback, resultReceiver);
2366     }
2367 
2368     /** @see AudioManager#getSurroundFormats() */
2369     @Override
getSurroundFormats()2370     public Map<Integer, Boolean> getSurroundFormats() {
2371         Map<Integer, Boolean> surroundFormats = new HashMap<>();
2372         int status = AudioSystem.getSurroundFormats(surroundFormats);
2373         if (status != AudioManager.SUCCESS) {
2374             // fail and bail!
2375             Log.e(TAG, "getSurroundFormats failed:" + status);
2376             return new HashMap<>(); // Always return a map.
2377         }
2378         return surroundFormats;
2379     }
2380 
2381     /** @see AudioManager#getReportedSurroundFormats() */
2382     @Override
getReportedSurroundFormats()2383     public List<Integer> getReportedSurroundFormats() {
2384         ArrayList<Integer> reportedSurroundFormats = new ArrayList<>();
2385         int status = AudioSystem.getReportedSurroundFormats(reportedSurroundFormats);
2386         if (status != AudioManager.SUCCESS) {
2387             // fail and bail!
2388             Log.e(TAG, "getReportedSurroundFormats failed:" + status);
2389             return new ArrayList<>(); // Always return a list.
2390         }
2391         return reportedSurroundFormats;
2392     }
2393 
2394     /** @see AudioManager#isSurroundFormatEnabled(int) */
2395     @Override
isSurroundFormatEnabled(int audioFormat)2396     public boolean isSurroundFormatEnabled(int audioFormat) {
2397         if (!isSurroundFormat(audioFormat)) {
2398             Log.w(TAG, "audioFormat to enable is not a surround format.");
2399             return false;
2400         }
2401         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS)
2402                 != PackageManager.PERMISSION_GRANTED) {
2403             throw new SecurityException("Missing WRITE_SETTINGS permission");
2404         }
2405 
2406         final long token = Binder.clearCallingIdentity();
2407         try {
2408             synchronized (mSettingsLock) {
2409                 HashSet<Integer> enabledFormats = getEnabledFormats();
2410                 return enabledFormats.contains(audioFormat);
2411             }
2412         } finally {
2413             Binder.restoreCallingIdentity(token);
2414         }
2415     }
2416 
2417     /** @see AudioManager#setSurroundFormatEnabled(int, boolean) */
2418     @Override
setSurroundFormatEnabled(int audioFormat, boolean enabled)2419     public boolean setSurroundFormatEnabled(int audioFormat, boolean enabled) {
2420         if (!isSurroundFormat(audioFormat)) {
2421             Log.w(TAG, "audioFormat to enable is not a surround format.");
2422             return false;
2423         }
2424         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS)
2425                 != PackageManager.PERMISSION_GRANTED) {
2426             throw new SecurityException("Missing WRITE_SETTINGS permission");
2427         }
2428 
2429         HashSet<Integer> enabledFormats = getEnabledFormats();
2430         if (enabled) {
2431             enabledFormats.add(audioFormat);
2432         } else {
2433             enabledFormats.remove(audioFormat);
2434         }
2435         final long token = Binder.clearCallingIdentity();
2436         try {
2437             synchronized (mSettingsLock) {
2438                 mSettings.putGlobalString(mContentResolver,
2439                         Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
2440                         TextUtils.join(",", enabledFormats));
2441             }
2442         } finally {
2443             Binder.restoreCallingIdentity(token);
2444         }
2445         return true;
2446     }
2447 
2448     /** @see AudioManager#setEncodedSurroundMode(int) */
2449     @Override
setEncodedSurroundMode(@udioManager.EncodedSurroundOutputMode int mode)2450     public boolean setEncodedSurroundMode(@AudioManager.EncodedSurroundOutputMode int mode) {
2451         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS)
2452                 != PackageManager.PERMISSION_GRANTED) {
2453             throw new SecurityException("Missing WRITE_SETTINGS permission");
2454         }
2455 
2456         final long token = Binder.clearCallingIdentity();
2457         try {
2458             synchronized (mSettingsLock) {
2459                 mSettings.putGlobalInt(mContentResolver,
2460                         Settings.Global.ENCODED_SURROUND_OUTPUT,
2461                         toEncodedSurroundSetting(mode));
2462             }
2463         } finally {
2464             Binder.restoreCallingIdentity(token);
2465         }
2466         return true;
2467     }
2468 
2469     /** @see AudioManager#getEncodedSurroundMode() */
2470     @Override
getEncodedSurroundMode(int targetSdkVersion)2471     public int getEncodedSurroundMode(int targetSdkVersion) {
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                 int encodedSurroundSetting = mSettings.getGlobalInt(mContentResolver,
2481                         Settings.Global.ENCODED_SURROUND_OUTPUT,
2482                         AudioManager.ENCODED_SURROUND_OUTPUT_AUTO);
2483                 return toEncodedSurroundOutputMode(encodedSurroundSetting, targetSdkVersion);
2484             }
2485         } finally {
2486             Binder.restoreCallingIdentity(token);
2487         }
2488     }
2489 
2490     /** @return the formats that are enabled in global settings */
getEnabledFormats()2491     private HashSet<Integer> getEnabledFormats() {
2492         HashSet<Integer> formats = new HashSet<>();
2493         String enabledFormats = mSettings.getGlobalString(mContentResolver,
2494                 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
2495         if (enabledFormats != null) {
2496             try {
2497                 Arrays.stream(TextUtils.split(enabledFormats, ","))
2498                         .mapToInt(Integer::parseInt)
2499                         .forEach(formats::add);
2500             } catch (NumberFormatException e) {
2501                 Log.w(TAG, "ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS misformatted.", e);
2502             }
2503         }
2504         return formats;
2505     }
2506 
2507     @SuppressWarnings("AndroidFrameworkCompatChange")
2508     @AudioManager.EncodedSurroundOutputMode
toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion)2509     private int toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion) {
2510         if (targetSdkVersion <= Build.VERSION_CODES.S
2511                 && encodedSurroundSetting > Settings.Global.ENCODED_SURROUND_SC_MAX) {
2512             return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN;
2513         }
2514         switch (encodedSurroundSetting) {
2515             case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO:
2516                 return AudioManager.ENCODED_SURROUND_OUTPUT_AUTO;
2517             case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER:
2518                 return AudioManager.ENCODED_SURROUND_OUTPUT_NEVER;
2519             case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS:
2520                 return AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS;
2521             case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL:
2522                 return AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL;
2523             default:
2524                 return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN;
2525         }
2526     }
2527 
toEncodedSurroundSetting( @udioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode)2528     private int toEncodedSurroundSetting(
2529             @AudioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode) {
2530         switch (encodedSurroundOutputMode) {
2531             case AudioManager.ENCODED_SURROUND_OUTPUT_NEVER:
2532                 return Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER;
2533             case AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS:
2534                 return Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS;
2535             case AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL:
2536                 return Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL;
2537             default:
2538                 return Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO;
2539         }
2540     }
2541 
isSurroundFormat(int audioFormat)2542     private boolean isSurroundFormat(int audioFormat) {
2543         for (int sf : AudioFormat.SURROUND_SOUND_ENCODING) {
2544             if (sf == audioFormat) {
2545                 return true;
2546             }
2547         }
2548         return false;
2549     }
2550 
sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate)2551     private void sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate) {
2552         if (mEncodedSurroundMode != Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL) {
2553             // Manually enable surround formats only when the setting is in manual mode.
2554             return;
2555         }
2556         String enabledSurroundFormats = mSettings.getGlobalString(
2557                 cr, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
2558         if (enabledSurroundFormats == null) {
2559             // Never allow enabledSurroundFormats as a null, which could happen when
2560             // ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS is not appear in settings DB.
2561             enabledSurroundFormats = "";
2562         }
2563         if (!forceUpdate && TextUtils.equals(enabledSurroundFormats, mEnabledSurroundFormats)) {
2564             // Update enabled surround formats to AudioPolicyManager only when forceUpdate
2565             // is true or enabled surround formats changed.
2566             return;
2567         }
2568 
2569         mEnabledSurroundFormats = enabledSurroundFormats;
2570         String[] surroundFormats = TextUtils.split(enabledSurroundFormats, ",");
2571         ArrayList<Integer> formats = new ArrayList<>();
2572         for (String format : surroundFormats) {
2573             try {
2574                 int audioFormat = Integer.valueOf(format);
2575                 if (isSurroundFormat(audioFormat) && !formats.contains(audioFormat)) {
2576                     formats.add(audioFormat);
2577                 }
2578             } catch (Exception e) {
2579                 Log.e(TAG, "Invalid enabled surround format:" + format);
2580             }
2581         }
2582         // Set filtered surround formats to settings DB in case
2583         // there are invalid surround formats in original settings.
2584         mSettings.putGlobalString(mContext.getContentResolver(),
2585                 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
2586                 TextUtils.join(",", formats));
2587         sendMsg(mAudioHandler, MSG_ENABLE_SURROUND_FORMATS, SENDMSG_QUEUE, 0, 0, formats, 0);
2588     }
2589 
onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats)2590     private void onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats) {
2591         // Set surround format enabled accordingly.
2592         for (int surroundFormat : AudioFormat.SURROUND_SOUND_ENCODING) {
2593             boolean enabled = enabledSurroundFormats.contains(surroundFormat);
2594             int ret = AudioSystem.setSurroundFormatEnabled(surroundFormat, enabled);
2595             Log.i(TAG, "enable surround format:" + surroundFormat + " " + enabled + " " + ret);
2596         }
2597     }
2598 
2599     @GuardedBy("mSettingsLock")
updateAssistantUIdLocked(boolean forceUpdate)2600     private void updateAssistantUIdLocked(boolean forceUpdate) {
2601         int assistantUid = INVALID_UID;
2602         // Consider assistants in the following order of priority:
2603         // 1) apk in assistant role
2604         // 2) voice interaction service
2605         // 3) assistant service
2606 
2607         String packageName = "";
2608         if (mRoleObserver != null) {
2609             packageName = mRoleObserver.getAssistantRoleHolder();
2610         }
2611         if (TextUtils.isEmpty(packageName)) {
2612             String assistantName = mSettings.getSecureStringForUser(
2613                             mContentResolver,
2614                             Settings.Secure.VOICE_INTERACTION_SERVICE, UserHandle.USER_CURRENT);
2615             if (TextUtils.isEmpty(assistantName)) {
2616                 assistantName = mSettings.getSecureStringForUser(
2617                         mContentResolver,
2618                         Settings.Secure.ASSISTANT, UserHandle.USER_CURRENT);
2619             }
2620             if (!TextUtils.isEmpty(assistantName)) {
2621                 ComponentName componentName = ComponentName.unflattenFromString(assistantName);
2622                 if (componentName == null) {
2623                     Slog.w(TAG, "Invalid service name for "
2624                             + Settings.Secure.VOICE_INTERACTION_SERVICE + ": " + assistantName);
2625                     return;
2626                 }
2627                 packageName = componentName.getPackageName();
2628             }
2629         }
2630         if (!TextUtils.isEmpty(packageName)) {
2631             PackageManager pm = mContext.getPackageManager();
2632             ActivityManager am =
2633                           (ActivityManager) mContext.getSystemService(mContext.ACTIVITY_SERVICE);
2634 
2635             if (pm.checkPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD, packageName)
2636                     == PackageManager.PERMISSION_GRANTED) {
2637                 try {
2638                     assistantUid = pm.getPackageUidAsUser(packageName, am.getCurrentUser());
2639                 } catch (PackageManager.NameNotFoundException e) {
2640                     Log.e(TAG,
2641                             "updateAssistantUId() could not find UID for package: " + packageName);
2642                 }
2643             }
2644         }
2645         if ((mPrimaryAssistantUid != assistantUid) || forceUpdate) {
2646             mAssistantUids.remove(mPrimaryAssistantUid);
2647             mPrimaryAssistantUid = assistantUid;
2648             addAssistantServiceUidsLocked(new int[]{mPrimaryAssistantUid});
2649         }
2650     }
2651 
readPersistedSettings()2652     private void readPersistedSettings() {
2653         if (!mSystemServer.isPrivileged()) {
2654             return;
2655         }
2656         final ContentResolver cr = mContentResolver;
2657 
2658         int ringerModeFromSettings =
2659                 mSettings.getGlobalInt(
2660                         cr, Settings.Global.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
2661         int ringerMode = ringerModeFromSettings;
2662         // validity check in case the settings are restored from a device with incompatible
2663         // ringer modes
2664         if (!isValidRingerMode(ringerMode)) {
2665             ringerMode = AudioManager.RINGER_MODE_NORMAL;
2666         }
2667         if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) {
2668             ringerMode = AudioManager.RINGER_MODE_SILENT;
2669         }
2670         if (ringerMode != ringerModeFromSettings) {
2671             mSettings.putGlobalInt(cr, Settings.Global.MODE_RINGER, ringerMode);
2672         }
2673         if (mUseFixedVolume || mIsSingleVolume) {
2674             ringerMode = AudioManager.RINGER_MODE_NORMAL;
2675         }
2676         synchronized(mSettingsLock) {
2677             mRingerMode = ringerMode;
2678             if (mRingerModeExternal == -1) {
2679                 mRingerModeExternal = mRingerMode;
2680             }
2681 
2682             // System.VIBRATE_ON is not used any more but defaults for mVibrateSetting
2683             // are still needed while setVibrateSetting() and getVibrateSetting() are being
2684             // deprecated.
2685             mVibrateSetting = AudioSystem.getValueForVibrateSetting(0,
2686                                             AudioManager.VIBRATE_TYPE_NOTIFICATION,
2687                                             mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT
2688                                                             : AudioManager.VIBRATE_SETTING_OFF);
2689             mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting,
2690                                             AudioManager.VIBRATE_TYPE_RINGER,
2691                                             mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT
2692                                                             : AudioManager.VIBRATE_SETTING_OFF);
2693 
2694             updateRingerAndZenModeAffectedStreams();
2695             readDockAudioSettings(cr);
2696             sendEncodedSurroundMode(cr, "readPersistedSettings");
2697             sendEnabledSurroundFormats(cr, true);
2698             updateAssistantUIdLocked(/* forceUpdate= */ true);
2699             resetActiveAssistantUidsLocked();
2700             AudioSystem.setRttEnabled(mRttEnabled);
2701         }
2702 
2703         mMuteAffectedStreams = mSettings.getSystemIntForUser(cr,
2704                 System.MUTE_STREAMS_AFFECTED, AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED,
2705                 UserHandle.USER_CURRENT);
2706 
2707         updateMasterMono(cr);
2708 
2709         updateMasterBalance(cr);
2710 
2711         // Each stream will read its own persisted settings
2712 
2713         // Broadcast the sticky intents
2714         broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, mRingerModeExternal);
2715         broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, mRingerMode);
2716 
2717         // Broadcast vibrate settings
2718         broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
2719         broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION);
2720 
2721         // Load settings for the volume controller
2722         mVolumeController.loadSettings(cr);
2723     }
2724 
2725     @GuardedBy("mSettingsLock")
resetActiveAssistantUidsLocked()2726     private void resetActiveAssistantUidsLocked() {
2727         mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS;
2728         updateActiveAssistantServiceUids();
2729     }
2730 
readUserRestrictions()2731     private void readUserRestrictions() {
2732         if (!mSystemServer.isPrivileged()) {
2733             return;
2734         }
2735         final int currentUser = getCurrentUserId();
2736 
2737         // Check the current user restriction.
2738         boolean masterMute =
2739                 mUserManagerInternal.getUserRestriction(currentUser,
2740                         UserManager.DISALLOW_UNMUTE_DEVICE)
2741                         || mUserManagerInternal.getUserRestriction(currentUser,
2742                         UserManager.DISALLOW_ADJUST_VOLUME);
2743         if (mUseFixedVolume) {
2744             masterMute = false;
2745             AudioSystem.setMasterVolume(1.0f);
2746         }
2747         if (DEBUG_VOL) {
2748             Log.d(TAG, String.format("Master mute %s, user=%d", masterMute, currentUser));
2749         }
2750         AudioSystem.setMasterMute(masterMute);
2751         broadcastMasterMuteStatus(masterMute);
2752 
2753         mMicMuteFromRestrictions = mUserManagerInternal.getUserRestriction(
2754                 currentUser, UserManager.DISALLOW_UNMUTE_MICROPHONE);
2755         if (DEBUG_VOL) {
2756             Log.d(TAG, String.format("Mic mute %b, user=%d", mMicMuteFromRestrictions,
2757                     currentUser));
2758         }
2759         setMicrophoneMuteNoCallerCheck(currentUser);
2760     }
2761 
getIndexRange(int streamType)2762     private int getIndexRange(int streamType) {
2763         return (mStreamStates[streamType].getMaxIndex() - mStreamStates[streamType].getMinIndex());
2764     }
2765 
rescaleIndex(VolumeInfo volumeInfo, int dstStream)2766     private int rescaleIndex(VolumeInfo volumeInfo, int dstStream) {
2767         if (volumeInfo.getVolumeIndex() == VolumeInfo.INDEX_NOT_SET
2768                 || volumeInfo.getMinVolumeIndex() == VolumeInfo.INDEX_NOT_SET
2769                 || volumeInfo.getMaxVolumeIndex() == VolumeInfo.INDEX_NOT_SET) {
2770             Log.e(TAG, "rescaleIndex: volumeInfo has invalid index or range");
2771             return mStreamStates[dstStream].getMinIndex();
2772         }
2773         return rescaleIndex(volumeInfo.getVolumeIndex(),
2774                 volumeInfo.getMinVolumeIndex(), volumeInfo.getMaxVolumeIndex(),
2775                 mStreamStates[dstStream].getMinIndex(), mStreamStates[dstStream].getMaxIndex());
2776     }
2777 
rescaleIndex(int index, int srcStream, VolumeInfo dstVolumeInfo)2778     private int rescaleIndex(int index, int srcStream, VolumeInfo dstVolumeInfo) {
2779         int dstMin = dstVolumeInfo.getMinVolumeIndex();
2780         int dstMax = dstVolumeInfo.getMaxVolumeIndex();
2781         // Don't rescale index if the VolumeInfo is missing a min or max index
2782         if (dstMin == VolumeInfo.INDEX_NOT_SET || dstMax == VolumeInfo.INDEX_NOT_SET) {
2783             return index;
2784         }
2785         return rescaleIndex(index,
2786                 mStreamStates[srcStream].getMinIndex(), mStreamStates[srcStream].getMaxIndex(),
2787                 dstMin, dstMax);
2788     }
2789 
rescaleIndex(int index, int srcStream, int dstStream)2790     private int rescaleIndex(int index, int srcStream, int dstStream) {
2791         return rescaleIndex(index,
2792                 mStreamStates[srcStream].getMinIndex(), mStreamStates[srcStream].getMaxIndex(),
2793                 mStreamStates[dstStream].getMinIndex(), mStreamStates[dstStream].getMaxIndex());
2794     }
2795 
rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax)2796     private int rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax) {
2797         int srcRange = srcMax - srcMin;
2798         int dstRange = dstMax - dstMin;
2799         if (srcRange == 0) {
2800             Log.e(TAG, "rescaleIndex : index range should not be zero");
2801             return dstMin;
2802         }
2803         return dstMin + ((index - srcMin) * dstRange + srcRange / 2) / srcRange;
2804     }
2805 
rescaleStep(int step, int srcStream, int dstStream)2806     private int rescaleStep(int step, int srcStream, int dstStream) {
2807         int srcRange = getIndexRange(srcStream);
2808         int dstRange = getIndexRange(dstStream);
2809         if (srcRange == 0) {
2810             Log.e(TAG, "rescaleStep : index range should not be zero");
2811             return 0;
2812         }
2813 
2814         return ((step * dstRange + srcRange / 2) / srcRange);
2815     }
2816 
2817     ///////////////////////////////////////////////////////////////////////////
2818     // IPC methods
2819     ///////////////////////////////////////////////////////////////////////////
2820     /**
2821      * @see AudioManager#setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes)
2822      * @see AudioManager#setPreferredDevicesForStrategy(AudioProductStrategy,
2823      *                                                  List<AudioDeviceAttributes>)
2824      */
setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices)2825     public int setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices) {
2826         if (devices == null) {
2827             return AudioSystem.ERROR;
2828         }
2829         enforceModifyAudioRoutingPermission();
2830         final String logString = String.format(
2831                 "setPreferredDeviceForStrategy u/pid:%d/%d strat:%d dev:%s",
2832                 Binder.getCallingUid(), Binder.getCallingPid(), strategy,
2833                 devices.stream().map(e -> e.toString()).collect(Collectors.joining(",")));
2834         sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG));
2835         if (devices.stream().anyMatch(device ->
2836                 device.getRole() == AudioDeviceAttributes.ROLE_INPUT)) {
2837             Log.e(TAG, "Unsupported input routing in " + logString);
2838             return AudioSystem.ERROR;
2839         }
2840 
2841         final int status = mDeviceBroker.setPreferredDevicesForStrategySync(strategy, devices);
2842         if (status != AudioSystem.SUCCESS) {
2843             Log.e(TAG, String.format("Error %d in %s)", status, logString));
2844         }
2845 
2846         return status;
2847     }
2848 
2849     /** @see AudioManager#removePreferredDeviceForStrategy(AudioProductStrategy) */
removePreferredDevicesForStrategy(int strategy)2850     public int removePreferredDevicesForStrategy(int strategy) {
2851         enforceModifyAudioRoutingPermission();
2852         final String logString =
2853                 String.format("removePreferredDeviceForStrategy strat:%d", strategy);
2854         sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG));
2855 
2856         final int status = mDeviceBroker.removePreferredDevicesForStrategySync(strategy);
2857         if (status != AudioSystem.SUCCESS) {
2858             Log.e(TAG, String.format("Error %d in %s)", status, logString));
2859         }
2860         return status;
2861     }
2862 
2863     /**
2864      * @see AudioManager#getPreferredDeviceForStrategy(AudioProductStrategy)
2865      * @see AudioManager#getPreferredDevicesForStrategy(AudioProductStrategy)
2866      */
getPreferredDevicesForStrategy(int strategy)2867     public List<AudioDeviceAttributes> getPreferredDevicesForStrategy(int strategy) {
2868         enforceModifyAudioRoutingPermission();
2869         List<AudioDeviceAttributes> devices = new ArrayList<>();
2870         final long identity = Binder.clearCallingIdentity();
2871         final int status = AudioSystem.getDevicesForRoleAndStrategy(
2872                 strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
2873         Binder.restoreCallingIdentity(identity);
2874         if (status != AudioSystem.SUCCESS) {
2875             Log.e(TAG, String.format("Error %d in getPreferredDeviceForStrategy(%d)",
2876                     status, strategy));
2877             return new ArrayList<AudioDeviceAttributes>();
2878         } else {
2879             return devices;
2880         }
2881     }
2882 
2883     /** @see AudioManager#addOnPreferredDevicesForStrategyChangedListener(
2884      *               Executor, AudioManager.OnPreferredDevicesForStrategyChangedListener)
2885      */
registerStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)2886     public void registerStrategyPreferredDevicesDispatcher(
2887             @Nullable IStrategyPreferredDevicesDispatcher dispatcher) {
2888         if (dispatcher == null) {
2889             return;
2890         }
2891         enforceModifyAudioRoutingPermission();
2892         mDeviceBroker.registerStrategyPreferredDevicesDispatcher(dispatcher);
2893     }
2894 
2895     /** @see AudioManager#removeOnPreferredDevicesForStrategyChangedListener(
2896      *               AudioManager.OnPreferredDevicesForStrategyChangedListener)
2897      */
unregisterStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)2898     public void unregisterStrategyPreferredDevicesDispatcher(
2899             @Nullable IStrategyPreferredDevicesDispatcher dispatcher) {
2900         if (dispatcher == null) {
2901             return;
2902         }
2903         enforceModifyAudioRoutingPermission();
2904         mDeviceBroker.unregisterStrategyPreferredDevicesDispatcher(dispatcher);
2905     }
2906 
2907     /**
2908      * @see AudioManager#setPreferredDeviceForCapturePreset(int, AudioDeviceAttributes)
2909      */
setPreferredDevicesForCapturePreset( int capturePreset, List<AudioDeviceAttributes> devices)2910     public int setPreferredDevicesForCapturePreset(
2911             int capturePreset, List<AudioDeviceAttributes> devices) {
2912         if (devices == null) {
2913             return AudioSystem.ERROR;
2914         }
2915         enforceModifyAudioRoutingPermission();
2916         final String logString = String.format(
2917                 "setPreferredDevicesForCapturePreset u/pid:%d/%d source:%d dev:%s",
2918                 Binder.getCallingUid(), Binder.getCallingPid(), capturePreset,
2919                 devices.stream().map(e -> e.toString()).collect(Collectors.joining(",")));
2920         sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG));
2921         if (devices.stream().anyMatch(device ->
2922                 device.getRole() == AudioDeviceAttributes.ROLE_OUTPUT)) {
2923             Log.e(TAG, "Unsupported output routing in " + logString);
2924             return AudioSystem.ERROR;
2925         }
2926 
2927         final int status = mDeviceBroker.setPreferredDevicesForCapturePresetSync(
2928                 capturePreset, devices);
2929         if (status != AudioSystem.SUCCESS) {
2930             Log.e(TAG, String.format("Error %d in %s)", status, logString));
2931         }
2932 
2933         return status;
2934     }
2935 
2936     /** @see AudioManager#clearPreferredDevicesForCapturePreset(int) */
clearPreferredDevicesForCapturePreset(int capturePreset)2937     public int clearPreferredDevicesForCapturePreset(int capturePreset) {
2938         enforceModifyAudioRoutingPermission();
2939         final String logString = String.format(
2940                 "removePreferredDeviceForCapturePreset source:%d", capturePreset);
2941         sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG));
2942 
2943         final int status = mDeviceBroker.clearPreferredDevicesForCapturePresetSync(capturePreset);
2944         if (status != AudioSystem.SUCCESS) {
2945             Log.e(TAG, String.format("Error %d in %s", status, logString));
2946         }
2947         return status;
2948     }
2949 
2950     /**
2951      * @see AudioManager#getPreferredDevicesForCapturePreset(int)
2952      */
getPreferredDevicesForCapturePreset(int capturePreset)2953     public List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int capturePreset) {
2954         enforceModifyAudioRoutingPermission();
2955         List<AudioDeviceAttributes> devices = new ArrayList<>();
2956         final long identity = Binder.clearCallingIdentity();
2957         final int status = AudioSystem.getDevicesForRoleAndCapturePreset(
2958                 capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
2959         Binder.restoreCallingIdentity(identity);
2960         if (status != AudioSystem.SUCCESS) {
2961             Log.e(TAG, String.format("Error %d in getPreferredDeviceForCapturePreset(%d)",
2962                     status, capturePreset));
2963             return new ArrayList<AudioDeviceAttributes>();
2964         } else {
2965             return devices;
2966         }
2967     }
2968 
2969     /**
2970      * @see AudioManager#addOnPreferredDevicesForCapturePresetChangedListener(
2971      *              Executor, OnPreferredDevicesForCapturePresetChangedListener)
2972      */
registerCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)2973     public void registerCapturePresetDevicesRoleDispatcher(
2974             @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) {
2975         if (dispatcher == null) {
2976             return;
2977         }
2978         enforceModifyAudioRoutingPermission();
2979         mDeviceBroker.registerCapturePresetDevicesRoleDispatcher(dispatcher);
2980     }
2981 
2982     /**
2983      * @see AudioManager#removeOnPreferredDevicesForCapturePresetChangedListener(
2984      *              AudioManager.OnPreferredDevicesForCapturePresetChangedListener)
2985      */
unregisterCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)2986     public void unregisterCapturePresetDevicesRoleDispatcher(
2987             @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) {
2988         if (dispatcher == null) {
2989             return;
2990         }
2991         enforceModifyAudioRoutingPermission();
2992         mDeviceBroker.unregisterCapturePresetDevicesRoleDispatcher(dispatcher);
2993     }
2994 
2995     /** @see AudioManager#getDevicesForAttributes(AudioAttributes) */
getDevicesForAttributes( @onNull AudioAttributes attributes)2996     public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes(
2997             @NonNull AudioAttributes attributes) {
2998         enforceQueryStateOrModifyRoutingPermission();
2999         return getDevicesForAttributesInt(attributes, false /* forVolume */);
3000     }
3001 
3002     /** @see AudioManager#getAudioDevicesForAttributes(AudioAttributes)
3003      * This method is similar with AudioService#getDevicesForAttributes,
3004      * only it doesn't enforce permissions because it is used by an unprivileged public API
3005      * instead of the system API.
3006      */
getDevicesForAttributesUnprotected( @onNull AudioAttributes attributes)3007     public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesUnprotected(
3008             @NonNull AudioAttributes attributes) {
3009         return getDevicesForAttributesInt(attributes, false /* forVolume */);
3010     }
3011 
3012     /**
3013      * @see AudioManager#isMusicActive()
3014      * @param remotely true if query is for remote playback (cast), false for local playback.
3015      */
isMusicActive(boolean remotely)3016     public boolean isMusicActive(boolean remotely) {
3017         // no permission required
3018         final long token = Binder.clearCallingIdentity();
3019         try {
3020             if (remotely) {
3021                 return AudioSystem.isStreamActiveRemotely(AudioSystem.STREAM_MUSIC, 0);
3022             } else {
3023                 return AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0);
3024             }
3025         } finally {
3026             Binder.restoreCallingIdentity(token);
3027         }
3028     }
3029 
getDevicesForAttributesInt( @onNull AudioAttributes attributes, boolean forVolume)3030     protected @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesInt(
3031             @NonNull AudioAttributes attributes, boolean forVolume) {
3032         Objects.requireNonNull(attributes);
3033         return mAudioSystem.getDevicesForAttributes(attributes, forVolume);
3034     }
3035 
3036     // pre-condition: event.getKeyCode() is one of KeyEvent.KEYCODE_VOLUME_UP,
3037     //                                   KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_MUTE
handleVolumeKey(@onNull KeyEvent event, boolean isOnTv, @NonNull String callingPackage, @NonNull String caller)3038     public void handleVolumeKey(@NonNull KeyEvent event, boolean isOnTv,
3039             @NonNull String callingPackage, @NonNull String caller) {
3040         int keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_NORMAL;
3041         if (isOnTv) {
3042             if (event.getAction() == KeyEvent.ACTION_DOWN) {
3043                 keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_START;
3044             } else { // may catch more than ACTION_UP, but will end vol adjustement
3045                 // the vol key is either released (ACTION_UP), or multiple keys are pressed
3046                 // (ACTION_MULTIPLE) and we don't know what to do for volume control on CEC, end
3047                 // the repeated volume adjustement
3048                 keyEventMode = AudioDeviceVolumeManager.ADJUST_MODE_END;
3049             }
3050         } else if (event.getAction() != KeyEvent.ACTION_DOWN) {
3051             return;
3052         }
3053 
3054         int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND
3055                 | AudioManager.FLAG_FROM_KEY;
3056 
3057         switch (event.getKeyCode()) {
3058             case KeyEvent.KEYCODE_VOLUME_UP:
3059                     adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE,
3060                             AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller,
3061                             Binder.getCallingUid(), Binder.getCallingPid(), true, keyEventMode);
3062                 break;
3063             case KeyEvent.KEYCODE_VOLUME_DOWN:
3064                     adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER,
3065                             AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller,
3066                             Binder.getCallingUid(), Binder.getCallingPid(), true, keyEventMode);
3067                 break;
3068             case KeyEvent.KEYCODE_VOLUME_MUTE:
3069                 if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
3070                     adjustSuggestedStreamVolume(AudioManager.ADJUST_TOGGLE_MUTE,
3071                             AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller,
3072                             Binder.getCallingUid(), Binder.getCallingPid(),
3073                             true, AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
3074                 }
3075                 break;
3076             default:
3077                 Log.e(TAG, "Invalid key code " + event.getKeyCode() + " sent by " + callingPackage);
3078                 return; // not needed but added if code gets added below this switch statement
3079         }
3080     }
3081 
setNavigationRepeatSoundEffectsEnabled(boolean enabled)3082     public void setNavigationRepeatSoundEffectsEnabled(boolean enabled) {
3083         mNavigationRepeatSoundEffectsEnabled = enabled;
3084     }
3085 
3086     /**
3087      * @return true if the fast scroll sound effects are enabled
3088      */
areNavigationRepeatSoundEffectsEnabled()3089     public boolean areNavigationRepeatSoundEffectsEnabled() {
3090         return mNavigationRepeatSoundEffectsEnabled;
3091     }
3092 
setHomeSoundEffectEnabled(boolean enabled)3093     public void setHomeSoundEffectEnabled(boolean enabled) {
3094         mHomeSoundEffectEnabled = enabled;
3095     }
3096 
3097     /**
3098      * @return true if the home sound effect is enabled
3099      */
isHomeSoundEffectEnabled()3100     public boolean isHomeSoundEffectEnabled() {
3101         return mHomeSoundEffectEnabled;
3102     }
3103 
3104     /** 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)3105     private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
3106             String callingPackage, String caller, int uid, int pid, boolean hasModifyAudioSettings,
3107             int keyEventMode) {
3108         if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream=" + suggestedStreamType
3109                 + ", flags=" + flags + ", caller=" + caller
3110                 + ", volControlStream=" + mVolumeControlStream
3111                 + ", userSelect=" + mUserSelectedVolumeControlStream);
3112         if (direction != AudioManager.ADJUST_SAME) {
3113             sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_SUGG_VOL, suggestedStreamType,
3114                     direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage)
3115                     .append("/").append(caller).append(" uid:").append(uid).toString()));
3116         }
3117 
3118         boolean hasExternalVolumeController = notifyExternalVolumeController(direction);
3119 
3120         new MediaMetrics.Item(mMetricsId + "adjustSuggestedStreamVolume")
3121                 .setUid(Binder.getCallingUid())
3122                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage)
3123                 .set(MediaMetrics.Property.CLIENT_NAME, caller)
3124                 .set(MediaMetrics.Property.DIRECTION, direction > 0
3125                         ? MediaMetrics.Value.UP : MediaMetrics.Value.DOWN)
3126                 .set(MediaMetrics.Property.EXTERNAL, hasExternalVolumeController
3127                         ? MediaMetrics.Value.YES : MediaMetrics.Value.NO)
3128                 .set(MediaMetrics.Property.FLAGS, flags)
3129                 .record();
3130 
3131         if (hasExternalVolumeController) {
3132             return;
3133         }
3134 
3135         final int streamType;
3136         synchronized (mForceControlStreamLock) {
3137             // Request lock in case mVolumeControlStream is changed by other thread.
3138             if (mUserSelectedVolumeControlStream) { // implies mVolumeControlStream != -1
3139                 streamType = mVolumeControlStream;
3140             } else {
3141                 final int maybeActiveStreamType = getActiveStreamType(suggestedStreamType);
3142                 final boolean activeForReal;
3143                 if (maybeActiveStreamType == AudioSystem.STREAM_RING
3144                         || maybeActiveStreamType == AudioSystem.STREAM_NOTIFICATION) {
3145                     activeForReal = wasStreamActiveRecently(maybeActiveStreamType, 0);
3146                 } else {
3147                     activeForReal = mAudioSystem.isStreamActive(maybeActiveStreamType, 0);
3148                 }
3149                 if (activeForReal || mVolumeControlStream == -1) {
3150                     streamType = maybeActiveStreamType;
3151                 } else {
3152                     streamType = mVolumeControlStream;
3153                 }
3154             }
3155         }
3156 
3157         final boolean isMute = isMuteAdjust(direction);
3158 
3159         ensureValidStreamType(streamType);
3160         final int resolvedStream = mStreamVolumeAlias[streamType];
3161 
3162         // Play sounds on STREAM_RING only.
3163         if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 &&
3164                 resolvedStream != AudioSystem.STREAM_RING) {
3165             flags &= ~AudioManager.FLAG_PLAY_SOUND;
3166         }
3167 
3168         // For notifications/ring, show the ui before making any adjustments
3169         // Don't suppress mute/unmute requests
3170         // Don't suppress adjustments for single volume device
3171         if (mVolumeController.suppressAdjustment(resolvedStream, flags, isMute)
3172                 && !mIsSingleVolume) {
3173             direction = 0;
3174             flags &= ~AudioManager.FLAG_PLAY_SOUND;
3175             flags &= ~AudioManager.FLAG_VIBRATE;
3176             if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment");
3177         }
3178 
3179         adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid, pid,
3180                 null, hasModifyAudioSettings, keyEventMode);
3181     }
3182 
notifyExternalVolumeController(int direction)3183     private boolean notifyExternalVolumeController(int direction) {
3184         final IAudioPolicyCallback externalVolumeController;
3185         synchronized (mExtVolumeControllerLock) {
3186             externalVolumeController = mExtVolumeController;
3187         }
3188         if (externalVolumeController == null) {
3189             return false;
3190         }
3191 
3192         sendMsg(mAudioHandler, MSG_NOTIFY_VOL_EVENT, SENDMSG_QUEUE,
3193                 direction, 0 /*ignored*/,
3194                 externalVolumeController, 0 /*delay*/);
3195         return true;
3196     }
3197 
3198     /** Retain API for unsupported app usage */
adjustStreamVolume(int streamType, int direction, int flags, String callingPackage)3199     public void adjustStreamVolume(int streamType, int direction, int flags,
3200             String callingPackage) {
3201         adjustStreamVolumeWithAttribution(streamType, direction, flags, callingPackage, null);
3202     }
3203 
3204     /** @see AudioManager#adjustStreamVolume(int, int, int)
3205      * Part of service interface, check permissions here */
adjustStreamVolumeWithAttribution(int streamType, int direction, int flags, String callingPackage, String attributionTag)3206     public void adjustStreamVolumeWithAttribution(int streamType, int direction, int flags,
3207             String callingPackage, String attributionTag) {
3208         if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {
3209             Log.w(TAG, "Trying to call adjustStreamVolume() for a11y without"
3210                     + "CHANGE_ACCESSIBILITY_VOLUME / callingPackage=" + callingPackage);
3211             return;
3212         }
3213 
3214         sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_STREAM_VOL, streamType,
3215                 direction/*val1*/, flags/*val2*/, callingPackage));
3216         adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage,
3217                 Binder.getCallingUid(), Binder.getCallingPid(), attributionTag,
3218                 callingHasAudioSettingsPermission(), AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
3219     }
3220 
adjustStreamVolume(int streamType, int direction, int flags, String callingPackage, String caller, int uid, int pid, String attributionTag, boolean hasModifyAudioSettings, int keyEventMode)3221     protected void adjustStreamVolume(int streamType, int direction, int flags,
3222             String callingPackage, String caller, int uid, int pid, String attributionTag,
3223             boolean hasModifyAudioSettings, int keyEventMode) {
3224         if (mUseFixedVolume) {
3225             return;
3226         }
3227         if (DEBUG_VOL) Log.d(TAG, "adjustStreamVolume() stream=" + streamType + ", dir=" + direction
3228                 + ", flags=" + flags + ", caller=" + caller);
3229 
3230         ensureValidDirection(direction);
3231         ensureValidStreamType(streamType);
3232 
3233         boolean isMuteAdjust = isMuteAdjust(direction);
3234 
3235         if (isMuteAdjust && !isStreamAffectedByMute(streamType)) {
3236             return;
3237         }
3238 
3239         // If adjust is mute and the stream is STREAM_VOICE_CALL or STREAM_BLUETOOTH_SCO, make sure
3240         // that the calling app have the MODIFY_PHONE_STATE permission.
3241         if (isMuteAdjust &&
3242             (streamType == AudioSystem.STREAM_VOICE_CALL ||
3243                 streamType == AudioSystem.STREAM_BLUETOOTH_SCO) &&
3244                 mContext.checkPermission(android.Manifest.permission.MODIFY_PHONE_STATE, pid, uid)
3245                     != PackageManager.PERMISSION_GRANTED) {
3246             Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: adjustStreamVolume from pid="
3247                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
3248             return;
3249         }
3250 
3251         // If the stream is STREAM_ASSISTANT,
3252         // make sure that the calling app have the MODIFY_AUDIO_ROUTING permission.
3253         if (streamType == AudioSystem.STREAM_ASSISTANT &&
3254                 mContext.checkPermission(
3255                 android.Manifest.permission.MODIFY_AUDIO_ROUTING, pid, uid)
3256                     != PackageManager.PERMISSION_GRANTED) {
3257             Log.w(TAG, "MODIFY_AUDIO_ROUTING Permission Denial: adjustStreamVolume from pid="
3258                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
3259             return;
3260         }
3261 
3262         // use stream type alias here so that streams with same alias have the same behavior,
3263         // including with regard to silent mode control (e.g the use of STREAM_RING below and in
3264         // checkForRingerModeChange() in place of STREAM_RING or STREAM_NOTIFICATION)
3265         int streamTypeAlias = mStreamVolumeAlias[streamType];
3266 
3267         VolumeStreamState streamState = mStreamStates[streamTypeAlias];
3268 
3269         final int device = getDeviceForStream(streamTypeAlias);
3270 
3271         int aliasIndex = streamState.getIndex(device);
3272         boolean adjustVolume = true;
3273         int step;
3274 
3275         // skip a2dp absolute volume control request when the device
3276         // is neither an a2dp device nor BLE device
3277         if ((!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
3278                 && !AudioSystem.DEVICE_OUT_ALL_BLE_SET.contains(device))
3279                 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) {
3280             return;
3281         }
3282 
3283         // If we are being called by the system (e.g. hardware keys) check for current user
3284         // so we handle user restrictions correctly.
3285         if (uid == android.os.Process.SYSTEM_UID) {
3286             uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid));
3287         }
3288         // validate calling package and app op
3289         if (!checkNoteAppOp(
3290                 STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage, attributionTag)) {
3291             return;
3292         }
3293 
3294         // reset any pending volume command
3295         synchronized (mSafeMediaVolumeStateLock) {
3296             mPendingVolumeCommand = null;
3297         }
3298 
3299         flags &= ~AudioManager.FLAG_FIXED_VOLUME;
3300         if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) {
3301             flags |= AudioManager.FLAG_FIXED_VOLUME;
3302 
3303             // Always toggle between max safe volume and 0 for fixed volume devices where safe
3304             // volume is enforced, and max and 0 for the others.
3305             // This is simulated by stepping by the full allowed volume range
3306             if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE &&
3307                     mSafeMediaVolumeDevices.contains(device)) {
3308                 step = safeMediaVolumeIndex(device);
3309             } else {
3310                 step = streamState.getMaxIndex();
3311             }
3312             if (aliasIndex != 0) {
3313                 aliasIndex = step;
3314             }
3315         } else {
3316             // convert one UI step (+/-1) into a number of internal units on the stream alias
3317             step = rescaleStep(10, streamType, streamTypeAlias);
3318         }
3319 
3320         // If either the client forces allowing ringer modes for this adjustment,
3321         // or the stream type is one that is affected by ringer modes
3322         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
3323                 (isUiSoundsStreamType(streamTypeAlias))) {
3324             int ringerMode = getRingerModeInternal();
3325             // do not vibrate if already in vibrate mode
3326             if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
3327                 flags &= ~AudioManager.FLAG_VIBRATE;
3328             }
3329             // Check if the ringer mode handles this adjustment. If it does we don't
3330             // need to adjust the volume further.
3331             final int result = checkForRingerModeChange(aliasIndex, direction, step,
3332                     streamState.mIsMuted, callingPackage, flags);
3333             adjustVolume = (result & FLAG_ADJUST_VOLUME) != 0;
3334             // If suppressing a volume adjustment in silent mode, display the UI hint
3335             if ((result & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) {
3336                 flags |= AudioManager.FLAG_SHOW_SILENT_HINT;
3337             }
3338             // If suppressing a volume down adjustment in vibrate mode, display the UI hint
3339             if ((result & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) {
3340                 flags |= AudioManager.FLAG_SHOW_VIBRATE_HINT;
3341             }
3342         }
3343 
3344         // If the ringer mode or zen is muting the stream, do not change stream unless
3345         // it'll cause us to exit dnd
3346         if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) {
3347             adjustVolume = false;
3348         }
3349         int oldIndex = mStreamStates[streamType].getIndex(device);
3350 
3351         // Check if the volume adjustment should be handled by an absolute volume controller instead
3352         if (isAbsoluteVolumeDevice(device)
3353                 && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) {
3354             AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device);
3355             if (info.mHandlesVolumeAdjustment) {
3356                 dispatchAbsoluteVolumeAdjusted(streamType, info, oldIndex, direction,
3357                         keyEventMode);
3358                 return;
3359             }
3360         }
3361 
3362         if (adjustVolume && (direction != AudioManager.ADJUST_SAME)
3363                 && (keyEventMode != AudioDeviceVolumeManager.ADJUST_MODE_END)) {
3364             mAudioHandler.removeMessages(MSG_UNMUTE_STREAM);
3365 
3366             if (isMuteAdjust && !mFullVolumeDevices.contains(device)) {
3367                 boolean state;
3368                 if (direction == AudioManager.ADJUST_TOGGLE_MUTE) {
3369                     state = !streamState.mIsMuted;
3370                 } else {
3371                     state = direction == AudioManager.ADJUST_MUTE;
3372                 }
3373                 muteAliasStreams(streamTypeAlias, state);
3374             } else if ((direction == AudioManager.ADJUST_RAISE) &&
3375                     !checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) {
3376                 Log.e(TAG, "adjustStreamVolume() safe volume index = " + oldIndex);
3377                 mVolumeController.postDisplaySafeVolumeWarning(flags);
3378             } else if (!isFullVolumeDevice(device)
3379                     && (streamState.adjustIndex(direction * step, device, caller,
3380                             hasModifyAudioSettings)
3381                             || streamState.mIsMuted)) {
3382                 // Post message to set system volume (it in turn will post a
3383                 // message to persist).
3384                 if (streamState.mIsMuted) {
3385                     // Unmute the stream if it was previously muted
3386                     if (direction == AudioManager.ADJUST_RAISE) {
3387                         // unmute immediately for volume up
3388                         muteAliasStreams(streamTypeAlias, false);
3389                     } else if (direction == AudioManager.ADJUST_LOWER) {
3390                         if (mIsSingleVolume) {
3391                             sendMsg(mAudioHandler, MSG_UNMUTE_STREAM, SENDMSG_QUEUE,
3392                                     streamTypeAlias, flags, null, UNMUTE_STREAM_DELAY);
3393                         }
3394                     }
3395                 }
3396                 sendMsg(mAudioHandler,
3397                         MSG_SET_DEVICE_VOLUME,
3398                         SENDMSG_QUEUE,
3399                         device,
3400                         0,
3401                         streamState,
3402                         0);
3403             }
3404 
3405             int newIndex = mStreamStates[streamType].getIndex(device);
3406 
3407             // Check if volume update should be send to AVRCP
3408             if (streamTypeAlias == AudioSystem.STREAM_MUSIC
3409                     && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
3410                     && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
3411                 if (DEBUG_VOL) {
3412                     Log.d(TAG, "adjustSreamVolume: postSetAvrcpAbsoluteVolumeIndex index="
3413                             + newIndex + "stream=" + streamType);
3414                 }
3415                 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(newIndex / 10);
3416             } else if (isAbsoluteVolumeDevice(device)
3417                     && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) {
3418                 AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device);
3419                 dispatchAbsoluteVolumeChanged(streamType, info, newIndex);
3420             }
3421 
3422             if (AudioSystem.isLeAudioDeviceType(device)
3423                     && streamType == getBluetoothContextualVolumeStream()
3424                     && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
3425                 if (DEBUG_VOL) {
3426                     Log.d(TAG, "adjustSreamVolume postSetLeAudioVolumeIndex index="
3427                             + newIndex + " stream=" + streamType);
3428                 }
3429                 mDeviceBroker.postSetLeAudioVolumeIndex(newIndex,
3430                     mStreamStates[streamType].getMaxIndex(), streamType);
3431             }
3432 
3433             // Check if volume update should be send to Hearing Aid
3434             if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
3435                 // only modify the hearing aid attenuation when the stream to modify matches
3436                 // the one expected by the hearing aid
3437                 if (streamType == getBluetoothContextualVolumeStream()) {
3438                     if (DEBUG_VOL) {
3439                         Log.d(TAG, "adjustSreamVolume postSetHearingAidVolumeIndex index="
3440                                 + newIndex + " stream=" + streamType);
3441                     }
3442                     mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType);
3443                 }
3444             }
3445         }
3446 
3447         final int newIndex = mStreamStates[streamType].getIndex(device);
3448 
3449         if (adjustVolume) {
3450             synchronized (mHdmiClientLock) {
3451                 if (mHdmiManager != null) {
3452                     // At most one of mHdmiPlaybackClient and mHdmiTvClient should be non-null
3453                     HdmiClient fullVolumeHdmiClient = mHdmiPlaybackClient;
3454                     if (mHdmiTvClient != null) {
3455                         fullVolumeHdmiClient = mHdmiTvClient;
3456                     }
3457 
3458                     if (fullVolumeHdmiClient != null
3459                             && mHdmiCecVolumeControlEnabled
3460                             && streamTypeAlias == AudioSystem.STREAM_MUSIC
3461                             // vol change on a full volume device
3462                             && isFullVolumeDevice(device)) {
3463                         int keyCode = KeyEvent.KEYCODE_UNKNOWN;
3464                         switch (direction) {
3465                             case AudioManager.ADJUST_RAISE:
3466                                 keyCode = KeyEvent.KEYCODE_VOLUME_UP;
3467                                 break;
3468                             case AudioManager.ADJUST_LOWER:
3469                                 keyCode = KeyEvent.KEYCODE_VOLUME_DOWN;
3470                                 break;
3471                             case AudioManager.ADJUST_TOGGLE_MUTE:
3472                             case AudioManager.ADJUST_MUTE:
3473                             case AudioManager.ADJUST_UNMUTE:
3474                                 // Many CEC devices only support toggle mute. Therefore, we send the
3475                                 // same keycode for all three mute options.
3476                                 keyCode = KeyEvent.KEYCODE_VOLUME_MUTE;
3477                                 break;
3478                             default:
3479                                 break;
3480                         }
3481                         if (keyCode != KeyEvent.KEYCODE_UNKNOWN) {
3482                             final long ident = Binder.clearCallingIdentity();
3483                             try {
3484                                 switch (keyEventMode) {
3485                                     case AudioDeviceVolumeManager.ADJUST_MODE_NORMAL:
3486                                         fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, true);
3487                                         fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, false);
3488                                         break;
3489                                     case AudioDeviceVolumeManager.ADJUST_MODE_START:
3490                                         fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, true);
3491                                         break;
3492                                     case AudioDeviceVolumeManager.ADJUST_MODE_END:
3493                                         fullVolumeHdmiClient.sendVolumeKeyEvent(keyCode, false);
3494                                         break;
3495                                     default:
3496                                         Log.e(TAG, "Invalid keyEventMode " + keyEventMode);
3497                                 }
3498                             } finally {
3499                                 Binder.restoreCallingIdentity(ident);
3500                             }
3501                         }
3502                     }
3503 
3504                     if (streamTypeAlias == AudioSystem.STREAM_MUSIC
3505                             && (oldIndex != newIndex || isMuteAdjust)) {
3506                         maybeSendSystemAudioStatusCommand(isMuteAdjust);
3507                     }
3508                 }
3509             }
3510         }
3511         sendVolumeUpdate(streamType, oldIndex, newIndex, flags, device);
3512     }
3513 
3514     /**
3515      * Loops on aliasted stream, update the mute cache attribute of each
3516      * {@see AudioService#VolumeStreamState}, and then apply the change.
3517      * It prevents to unnecessary {@see AudioSystem#setStreamVolume} done for each stream
3518      * and aliases before mute change changed and after.
3519      */
muteAliasStreams(int streamAlias, boolean state)3520     private void muteAliasStreams(int streamAlias, boolean state) {
3521         synchronized (VolumeStreamState.class) {
3522             List<Integer> streamsToMute = new ArrayList<>();
3523             for (int stream = 0; stream < mStreamStates.length; stream++) {
3524                 VolumeStreamState vss = mStreamStates[stream];
3525                 if (streamAlias == mStreamVolumeAlias[stream] && vss.isMutable()) {
3526                     if (!(readCameraSoundForced()
3527                             && (vss.getStreamType()
3528                                     == AudioSystem.STREAM_SYSTEM_ENFORCED))) {
3529                         boolean changed = vss.mute(state, /* apply= */ false);
3530                         if (changed) {
3531                             streamsToMute.add(stream);
3532                         }
3533                     }
3534                 }
3535             }
3536             streamsToMute.forEach(streamToMute -> {
3537                 mStreamStates[streamToMute].doMute();
3538                 broadcastMuteSetting(streamToMute, state);
3539             });
3540         }
3541     }
3542 
broadcastMuteSetting(int streamType, boolean isMuted)3543     private void broadcastMuteSetting(int streamType, boolean isMuted) {
3544         // Stream mute changed, fire the intent.
3545         Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION);
3546         intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, streamType);
3547         intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, isMuted);
3548         sendBroadcastToAll(intent);
3549     }
3550 
3551     // Called after a delay when volume down is pressed while muted
onUnmuteStream(int stream, int flags)3552     private void onUnmuteStream(int stream, int flags) {
3553         boolean wasMuted;
3554         synchronized (VolumeStreamState.class) {
3555             final VolumeStreamState streamState = mStreamStates[stream];
3556             wasMuted = streamState.mute(false); // if unmuting causes a change, it was muted
3557 
3558             final int device = getDeviceForStream(stream);
3559             final int index = streamState.getIndex(device);
3560             sendVolumeUpdate(stream, index, index, flags, device);
3561         }
3562         if (stream == AudioSystem.STREAM_MUSIC && wasMuted) {
3563             synchronized (mHdmiClientLock) {
3564                 maybeSendSystemAudioStatusCommand(true);
3565             }
3566         }
3567     }
3568 
3569     @GuardedBy("mHdmiClientLock")
maybeSendSystemAudioStatusCommand(boolean isMuteAdjust)3570     private void maybeSendSystemAudioStatusCommand(boolean isMuteAdjust) {
3571         if (mHdmiAudioSystemClient == null
3572                 || !mHdmiSystemAudioSupported
3573                 || !mHdmiCecVolumeControlEnabled) {
3574             return;
3575         }
3576 
3577         final long identity = Binder.clearCallingIdentity();
3578         mHdmiAudioSystemClient.sendReportAudioStatusCecCommand(
3579                 isMuteAdjust, getStreamVolume(AudioSystem.STREAM_MUSIC),
3580                 getStreamMaxVolume(AudioSystem.STREAM_MUSIC),
3581                 isStreamMute(AudioSystem.STREAM_MUSIC));
3582         Binder.restoreCallingIdentity(identity);
3583     }
3584 
3585     // StreamVolumeCommand contains the information needed to defer the process of
3586     // setStreamVolume() in case the user has to acknowledge the safe volume warning message.
3587     static class StreamVolumeCommand {
3588         public final int mStreamType;
3589         public final int mIndex;
3590         public final int mFlags;
3591         public final int mDevice;
3592 
StreamVolumeCommand(int streamType, int index, int flags, int device)3593         StreamVolumeCommand(int streamType, int index, int flags, int device) {
3594             mStreamType = streamType;
3595             mIndex = index;
3596             mFlags = flags;
3597             mDevice = device;
3598         }
3599 
3600         @Override
toString()3601         public String toString() {
3602             return new StringBuilder().append("{streamType=").append(mStreamType).append(",index=")
3603                     .append(mIndex).append(",flags=").append(mFlags).append(",device=")
3604                     .append(mDevice).append('}').toString();
3605         }
3606     }
3607 
getNewRingerMode(int stream, int index, int flags)3608     private int getNewRingerMode(int stream, int index, int flags) {
3609         // setRingerMode does nothing if the device is single volume,so the value would be unchanged
3610         if (mIsSingleVolume) {
3611             return getRingerModeExternal();
3612         }
3613 
3614         // setting volume on ui sounds stream type also controls silent mode
3615         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
3616                 (stream == getUiSoundsStreamType())) {
3617             int newRingerMode;
3618             if (index == 0) {
3619                 newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE
3620                         : mVolumePolicy.volumeDownToEnterSilent ? AudioManager.RINGER_MODE_SILENT
3621                                 : AudioManager.RINGER_MODE_NORMAL;
3622             } else {
3623                 newRingerMode = AudioManager.RINGER_MODE_NORMAL;
3624             }
3625             return newRingerMode;
3626         }
3627         return getRingerModeExternal();
3628     }
3629 
isAndroidNPlus(String caller)3630     private boolean isAndroidNPlus(String caller) {
3631         try {
3632             final ApplicationInfo applicationInfo =
3633                     mContext.getPackageManager().getApplicationInfoAsUser(
3634                             caller, 0, UserHandle.getUserId(Binder.getCallingUid()));
3635             if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N) {
3636                 return true;
3637             }
3638             return false;
3639         } catch (PackageManager.NameNotFoundException e) {
3640             return true;
3641         }
3642     }
3643 
wouldToggleZenMode(int newMode)3644     private boolean wouldToggleZenMode(int newMode) {
3645         if (getRingerModeExternal() == AudioManager.RINGER_MODE_SILENT
3646                 && newMode != AudioManager.RINGER_MODE_SILENT) {
3647             return true;
3648         } else if (getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT
3649                 && newMode == AudioManager.RINGER_MODE_SILENT) {
3650             return true;
3651         }
3652         return false;
3653     }
3654 
3655     /**
3656      * Update stream volume, ringer mode and mute status after a volume index change
3657      * @param streamType
3658      * @param index
3659      * @param flags
3660      * @param device the device for which the volume is changed
3661      * @param caller
3662      * @param hasModifyAudioSettings
3663      * @param canChangeMute true if the origin of this event is one where the mute state should be
3664      *                      updated following the change in volume index
3665      */
onSetStreamVolume(int streamType, int index, int flags, int device, String caller, boolean hasModifyAudioSettings, boolean canChangeMute)3666     private void onSetStreamVolume(int streamType, int index, int flags, int device,
3667             String caller, boolean hasModifyAudioSettings, boolean canChangeMute) {
3668         final int stream = mStreamVolumeAlias[streamType];
3669         setStreamVolumeInt(stream, index, device, false, caller, hasModifyAudioSettings);
3670         // setting volume on ui sounds stream type also controls silent mode
3671         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
3672                 (stream == getUiSoundsStreamType())) {
3673             setRingerMode(getNewRingerMode(stream, index, flags),
3674                     TAG + ".onSetStreamVolume", false /*external*/);
3675         }
3676         // setting non-zero volume for a muted stream unmutes the stream and vice versa
3677         // except for BT SCO stream where only explicit mute is allowed to comply to BT requirements
3678         if ((streamType != AudioSystem.STREAM_BLUETOOTH_SCO) && canChangeMute) {
3679             // As adjustStreamVolume with muteAdjust flags mute/unmutes stream and aliased streams.
3680             muteAliasStreams(stream, index == 0);
3681         }
3682     }
3683 
enforceModifyAudioRoutingPermission()3684     private void enforceModifyAudioRoutingPermission() {
3685         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
3686                 != PackageManager.PERMISSION_GRANTED) {
3687             throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission");
3688         }
3689     }
3690 
3691     // TODO enforce MODIFY_AUDIO_SYSTEM_SETTINGS when defined
enforceModifyAudioRoutingOrSystemSettingsPermission()3692     private void enforceModifyAudioRoutingOrSystemSettingsPermission() {
3693         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
3694                 != PackageManager.PERMISSION_GRANTED
3695                 /*&& mContext.checkCallingOrSelfPermission(
3696                         android.Manifest.permission.MODIFY_AUDIO_SYSTEM_SETTINGS)
3697                             != PackageManager.PERMISSION_DENIED*/) {
3698             throw new SecurityException(
3699                     "Missing MODIFY_AUDIO_ROUTING or MODIFY_AUDIO_SYSTEM_SETTINGS permission");
3700         }
3701     }
3702 
enforceAccessUltrasoundPermission()3703     private void enforceAccessUltrasoundPermission() {
3704         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.ACCESS_ULTRASOUND)
3705                 != PackageManager.PERMISSION_GRANTED) {
3706             throw new SecurityException("Missing ACCESS_ULTRASOUND permission");
3707         }
3708     }
3709 
enforceQueryStatePermission()3710     private void enforceQueryStatePermission() {
3711         if (mContext.checkCallingOrSelfPermission(Manifest.permission.QUERY_AUDIO_STATE)
3712                 != PackageManager.PERMISSION_GRANTED) {
3713             throw new SecurityException("Missing QUERY_AUDIO_STATE permissions");
3714         }
3715     }
3716 
enforceQueryStateOrModifyRoutingPermission()3717     private void enforceQueryStateOrModifyRoutingPermission() {
3718         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
3719                 != PackageManager.PERMISSION_GRANTED
3720                 && mContext.checkCallingOrSelfPermission(Manifest.permission.QUERY_AUDIO_STATE)
3721                 != PackageManager.PERMISSION_GRANTED) {
3722             throw new SecurityException(
3723                     "Missing MODIFY_AUDIO_ROUTING or QUERY_AUDIO_STATE permissions");
3724         }
3725     }
3726 
enforceCallAudioInterceptionPermission()3727     private void enforceCallAudioInterceptionPermission() {
3728         if (mContext.checkCallingOrSelfPermission(
3729                 android.Manifest.permission.CALL_AUDIO_INTERCEPTION)
3730                 != PackageManager.PERMISSION_GRANTED) {
3731             throw new SecurityException("Missing CALL_AUDIO_INTERCEPTION permission");
3732         }
3733     }
3734 
3735 
3736     /** @see AudioManager#setVolumeGroupVolumeIndex(int, int, int) */
setVolumeGroupVolumeIndex(int groupId, int index, int flags, String callingPackage, String attributionTag)3737     public void setVolumeGroupVolumeIndex(int groupId, int index, int flags,
3738             String callingPackage, String attributionTag) {
3739         enforceModifyAudioRoutingPermission();
3740         if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
3741             Log.e(TAG, ": no volume group found for id " + groupId);
3742             return;
3743         }
3744         VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
3745 
3746         sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_SET_GROUP_VOL, vgs.name(),
3747                 index, flags, callingPackage + ", user " + getCurrentUserId()));
3748 
3749         vgs.setVolumeIndex(index, flags);
3750 
3751         // For legacy reason, propagate to all streams associated to this volume group
3752         for (int groupedStream : vgs.getLegacyStreamTypes()) {
3753             try {
3754                 ensureValidStreamType(groupedStream);
3755             } catch (IllegalArgumentException e) {
3756                 Log.d(TAG, "volume group " + groupId + " has internal streams (" + groupedStream
3757                         + "), do not change associated stream volume");
3758                 continue;
3759             }
3760             setStreamVolume(groupedStream, index, flags, /*device*/ null,
3761                     callingPackage, callingPackage,
3762                     attributionTag, Binder.getCallingUid(), true /*hasModifyAudioSettings*/);
3763         }
3764     }
3765 
3766     @Nullable
getAudioVolumeGroupById(int volumeGroupId)3767     private AudioVolumeGroup getAudioVolumeGroupById(int volumeGroupId) {
3768         for (AudioVolumeGroup avg : AudioVolumeGroup.getAudioVolumeGroups()) {
3769             if (avg.getId() == volumeGroupId) {
3770                 return avg;
3771             }
3772         }
3773 
3774         Log.e(TAG, ": invalid volume group id: " + volumeGroupId + " requested");
3775         return null;
3776     }
3777 
3778     /** @see AudioManager#getVolumeGroupVolumeIndex(int) */
getVolumeGroupVolumeIndex(int groupId)3779     public int getVolumeGroupVolumeIndex(int groupId) {
3780         enforceModifyAudioRoutingPermission();
3781         synchronized (VolumeStreamState.class) {
3782             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
3783                 throw new IllegalArgumentException("No volume group for id " + groupId);
3784             }
3785             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
3786             // Return 0 when muted, not min index since for e.g. Voice Call, it has a non zero
3787             // min but it mutable on permission condition.
3788             return vgs.isMuted() ? 0 : vgs.getVolumeIndex();
3789         }
3790     }
3791 
3792     /** @see AudioManager#getVolumeGroupMaxVolumeIndex(int) */
getVolumeGroupMaxVolumeIndex(int groupId)3793     public int getVolumeGroupMaxVolumeIndex(int groupId) {
3794         enforceModifyAudioRoutingPermission();
3795         synchronized (VolumeStreamState.class) {
3796             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
3797                 throw new IllegalArgumentException("No volume group for id " + groupId);
3798             }
3799             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
3800             return vgs.getMaxIndex();
3801         }
3802     }
3803 
3804     /** @see AudioManager#getVolumeGroupMinVolumeIndex(int) */
getVolumeGroupMinVolumeIndex(int groupId)3805     public int getVolumeGroupMinVolumeIndex(int groupId) {
3806         enforceModifyAudioRoutingPermission();
3807         synchronized (VolumeStreamState.class) {
3808             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
3809                 throw new IllegalArgumentException("No volume group for id " + groupId);
3810             }
3811             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
3812             return vgs.getMinIndex();
3813         }
3814     }
3815 
3816     /** @see AudioDeviceVolumeManager#setDeviceVolume(VolumeInfo, AudioDeviceAttributes)
3817      * Part of service interface, check permissions and parameters here
3818      * Note calling package is for logging purposes only, not to be trusted
3819      */
setDeviceVolume(@onNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage)3820     public void setDeviceVolume(@NonNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada,
3821             @NonNull String callingPackage) {
3822         enforceModifyAudioRoutingOrSystemSettingsPermission();
3823         Objects.requireNonNull(vi);
3824         Objects.requireNonNull(ada);
3825         Objects.requireNonNull(callingPackage);
3826 
3827         if (!vi.hasStreamType()) {
3828             Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception());
3829             return;
3830         }
3831 
3832         int index = vi.getVolumeIndex();
3833         if (index == VolumeInfo.INDEX_NOT_SET && !vi.hasMuteCommand()) {
3834             throw new IllegalArgumentException(
3835                     "changing device volume requires a volume index or mute command");
3836         }
3837 
3838         // force a cache clear to force reevaluating stream type to audio device selection
3839         // that can interfere with the sending of the VOLUME_CHANGED_ACTION intent
3840         // TODO change cache management to not rely only on invalidation, but on "do not trust"
3841         //     moments when routing is in flux.
3842         mAudioSystem.clearRoutingCache();
3843 
3844         // log the current device that will be used when evaluating the sending of the
3845         // VOLUME_CHANGED_ACTION intent to see if the current device is the one being modified
3846         final int currDev = getDeviceForStream(vi.getStreamType());
3847 
3848         final boolean skipping = (currDev == ada.getInternalType());
3849 
3850         AudioService.sVolumeLogger.log(new DeviceVolumeEvent(vi.getStreamType(), index, ada,
3851                 currDev, callingPackage, skipping));
3852 
3853         if (skipping) {
3854             // setDeviceVolume was called on a device currently being used
3855             return;
3856         }
3857 
3858         // TODO handle unmuting of current audio device
3859         // if a stream is not muted but the VolumeInfo is for muting, set the volume index
3860         // for the device to min volume
3861         if (vi.hasMuteCommand() && vi.isMuted() && !isStreamMute(vi.getStreamType())) {
3862             setStreamVolumeWithAttributionInt(vi.getStreamType(),
3863                     mStreamStates[vi.getStreamType()].getMinIndex(),
3864                     /*flags*/ 0,
3865                     ada, callingPackage, null);
3866             return;
3867         }
3868 
3869         if (vi.getMinVolumeIndex() == VolumeInfo.INDEX_NOT_SET
3870                 || vi.getMaxVolumeIndex() == VolumeInfo.INDEX_NOT_SET) {
3871             // assume index meant to be in stream type range, validate
3872             if ((index * 10) < mStreamStates[vi.getStreamType()].getMinIndex()
3873                     || (index * 10) > mStreamStates[vi.getStreamType()].getMaxIndex()) {
3874                 throw new IllegalArgumentException("invalid volume index " + index
3875                         + " not between min/max for stream " + vi.getStreamType());
3876             }
3877         } else {
3878             // check if index needs to be rescaled
3879             final int min = (mStreamStates[vi.getStreamType()].getMinIndex() + 5) / 10;
3880             final int max = (mStreamStates[vi.getStreamType()].getMaxIndex() + 5) / 10;
3881             if (vi.getMinVolumeIndex() != min || vi.getMaxVolumeIndex() != max) {
3882                 index = rescaleIndex(index,
3883                         /*srcMin*/ vi.getMinVolumeIndex(), /*srcMax*/ vi.getMaxVolumeIndex(),
3884                         /*dstMin*/ min, /*dstMax*/ max);
3885             }
3886         }
3887         setStreamVolumeWithAttributionInt(vi.getStreamType(), index, /*flags*/ 0,
3888                 ada, callingPackage, null);
3889     }
3890 
3891     /** Retain API for unsupported app usage */
setStreamVolume(int streamType, int index, int flags, String callingPackage)3892     public void setStreamVolume(int streamType, int index, int flags, String callingPackage) {
3893         setStreamVolumeWithAttribution(streamType, index, flags,
3894                 callingPackage, /*attributionTag*/ null);
3895     }
3896 
3897     /** @see AudioManager#adjustVolumeGroupVolume(int, int, int) */
adjustVolumeGroupVolume(int groupId, int direction, int flags, String callingPackage)3898     public void adjustVolumeGroupVolume(int groupId, int direction, int flags,
3899                                         String callingPackage) {
3900         ensureValidDirection(direction);
3901         if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
3902             Log.e(TAG, ": no volume group found for id " + groupId);
3903             return;
3904         }
3905         VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
3906         // For compatibility reason, use stream API if group linked to a valid stream
3907         boolean fallbackOnStream = false;
3908         for (int stream : vgs.getLegacyStreamTypes()) {
3909             try {
3910                 ensureValidStreamType(stream);
3911             } catch (IllegalArgumentException e) {
3912                 Log.d(TAG, "volume group " + groupId + " has internal streams (" + stream
3913                         + "), do not change associated stream volume");
3914                 continue;
3915             }
3916             // Note: Group and Stream does not share same convention, 0 is mute for stream,
3917             // min index is acting as mute for Groups
3918             if (vgs.isVssMuteBijective(stream)) {
3919                 adjustStreamVolume(stream, direction, flags, callingPackage);
3920                 if (isMuteAdjust(direction)) {
3921                     // will be propagated to all aliased streams
3922                     return;
3923                 }
3924                 fallbackOnStream = true;
3925             }
3926         }
3927         if (fallbackOnStream) {
3928             // Handled by at least one stream, will be propagated to group, bailing out.
3929             return;
3930         }
3931         sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_GROUP_VOL, vgs.name(),
3932                 direction, flags, callingPackage));
3933         vgs.adjustVolume(direction, flags);
3934     }
3935 
3936     /** @see AudioManager#getLastAudibleVolumeGroupVolume(int) */
getLastAudibleVolumeGroupVolume(int groupId)3937     public int getLastAudibleVolumeGroupVolume(int groupId) {
3938         enforceQueryStatePermission();
3939         synchronized (VolumeStreamState.class) {
3940             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
3941                 Log.e(TAG, ": no volume group found for id " + groupId);
3942                 return 0;
3943             }
3944             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
3945             return vgs.getVolumeIndex();
3946         }
3947     }
3948 
3949     /** @see AudioManager#isVolumeGroupMuted(int) */
isVolumeGroupMuted(int groupId)3950     public boolean isVolumeGroupMuted(int groupId) {
3951         synchronized (VolumeStreamState.class) {
3952             if (sVolumeGroupStates.indexOfKey(groupId) < 0) {
3953                 Log.e(TAG, ": no volume group found for id " + groupId);
3954                 return false;
3955             }
3956             VolumeGroupState vgs = sVolumeGroupStates.get(groupId);
3957             return vgs.isMuted();
3958         }
3959     }
3960 
3961     /** @see AudioManager#setStreamVolume(int, int, int)
3962      * Part of service interface, check permissions here */
setStreamVolumeWithAttribution(int streamType, int index, int flags, String callingPackage, String attributionTag)3963     public void setStreamVolumeWithAttribution(int streamType, int index, int flags,
3964             String callingPackage, String attributionTag) {
3965         setStreamVolumeWithAttributionInt(streamType, index, flags, /*device*/ null,
3966                 callingPackage, attributionTag);
3967     }
3968 
3969     /**
3970      * Internal method for a stream type volume change. Can be used to change the volume on a
3971      * given device only
3972      * @param streamType the stream type whose volume is to be changed
3973      * @param index the volume index
3974      * @param flags options for volume handling
3975      * @param device null when controlling volume for the current routing, otherwise the device
3976      *               for which volume is being changed
3977      * @param callingPackage client side-provided package name of caller, not to be trusted
3978      * @param attributionTag client side-provided attribution name, not to be trusted
3979      */
setStreamVolumeWithAttributionInt(int streamType, int index, int flags, @Nullable AudioDeviceAttributes device, String callingPackage, String attributionTag)3980     protected void setStreamVolumeWithAttributionInt(int streamType, int index, int flags,
3981             @Nullable AudioDeviceAttributes device,
3982             String callingPackage, String attributionTag) {
3983         if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {
3984             Log.w(TAG, "Trying to call setStreamVolume() for a11y without"
3985                     + " CHANGE_ACCESSIBILITY_VOLUME  callingPackage=" + callingPackage);
3986             return;
3987         }
3988         if ((streamType == AudioManager.STREAM_VOICE_CALL) && (index == 0)
3989                 && (mContext.checkCallingOrSelfPermission(
3990                     android.Manifest.permission.MODIFY_PHONE_STATE)
3991                     != PackageManager.PERMISSION_GRANTED)) {
3992             Log.w(TAG, "Trying to call setStreamVolume() for STREAM_VOICE_CALL and index 0 without"
3993                     + " MODIFY_PHONE_STATE  callingPackage=" + callingPackage);
3994             return;
3995         }
3996         if ((streamType == AudioManager.STREAM_ASSISTANT)
3997             && (mContext.checkCallingOrSelfPermission(
3998                     android.Manifest.permission.MODIFY_AUDIO_ROUTING)
3999                     != PackageManager.PERMISSION_GRANTED)) {
4000             Log.w(TAG, "Trying to call setStreamVolume() for STREAM_ASSISTANT without"
4001                     + " MODIFY_AUDIO_ROUTING  callingPackage=" + callingPackage);
4002             return;
4003         }
4004 
4005         if (device == null) {
4006             // call was already logged in setDeviceVolume()
4007             sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType,
4008                     index/*val1*/, flags/*val2*/, callingPackage));
4009         }
4010         setStreamVolume(streamType, index, flags, device,
4011                 callingPackage, callingPackage, attributionTag,
4012                 Binder.getCallingUid(), callingOrSelfHasAudioSettingsPermission());
4013     }
4014 
4015     /** @see AudioManager#isUltrasoundSupported() */
isUltrasoundSupported()4016     public boolean isUltrasoundSupported() {
4017         enforceAccessUltrasoundPermission();
4018         return AudioSystem.isUltrasoundSupported();
4019     }
4020 
canChangeAccessibilityVolume()4021     private boolean canChangeAccessibilityVolume() {
4022         synchronized (mAccessibilityServiceUidsLock) {
4023             if (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
4024                     android.Manifest.permission.CHANGE_ACCESSIBILITY_VOLUME)) {
4025                 return true;
4026             }
4027             if (mAccessibilityServiceUids != null) {
4028                 int callingUid = Binder.getCallingUid();
4029                 for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
4030                     if (mAccessibilityServiceUids[i] == callingUid) {
4031                         return true;
4032                     }
4033                 }
4034             }
4035             return false;
4036         }
4037     }
4038 
getBluetoothContextualVolumeStream()4039     /*package*/ int getBluetoothContextualVolumeStream() {
4040         return getBluetoothContextualVolumeStream(mMode.get());
4041     }
4042 
getBluetoothContextualVolumeStream(int mode)4043     private int getBluetoothContextualVolumeStream(int mode) {
4044         switch (mode) {
4045             case AudioSystem.MODE_IN_COMMUNICATION:
4046             case AudioSystem.MODE_IN_CALL:
4047                 return AudioSystem.STREAM_VOICE_CALL;
4048             case AudioSystem.MODE_NORMAL:
4049             default:
4050                 // other conditions will influence the stream type choice, read on...
4051                 break;
4052         }
4053         if (mVoicePlaybackActive.get()) {
4054             return AudioSystem.STREAM_VOICE_CALL;
4055         }
4056         return AudioSystem.STREAM_MUSIC;
4057     }
4058 
4059     private AtomicBoolean mVoicePlaybackActive = new AtomicBoolean(false);
4060     private AtomicBoolean mMediaPlaybackActive = new AtomicBoolean(false);
4061 
4062     private final IPlaybackConfigDispatcher mPlaybackActivityMonitor =
4063             new IPlaybackConfigDispatcher.Stub() {
4064         @Override
4065         public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs,
4066                                                  boolean flush) {
4067             sendMsg(mAudioHandler, MSG_PLAYBACK_CONFIG_CHANGE, SENDMSG_REPLACE,
4068                     0 /*arg1 ignored*/, 0 /*arg2 ignored*/,
4069                     configs /*obj*/, 0 /*delay*/);
4070         }
4071     };
4072 
onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs)4073     private void onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) {
4074         boolean voiceActive = false;
4075         boolean mediaActive = false;
4076         for (AudioPlaybackConfiguration config : configs) {
4077             final int usage = config.getAudioAttributes().getUsage();
4078             if (!config.isActive()) {
4079                 continue;
4080             }
4081             if (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION
4082                     || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING) {
4083                 voiceActive = true;
4084             }
4085             if (usage == AudioAttributes.USAGE_MEDIA || usage == AudioAttributes.USAGE_GAME) {
4086                 mediaActive = true;
4087             }
4088         }
4089         if (mVoicePlaybackActive.getAndSet(voiceActive) != voiceActive) {
4090             updateHearingAidVolumeOnVoiceActivityUpdate();
4091         }
4092         if (mMediaPlaybackActive.getAndSet(mediaActive) != mediaActive && mediaActive) {
4093             scheduleMusicActiveCheck();
4094         }
4095         // Update playback active state for all apps in audio mode stack.
4096         // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE
4097         // and request an audio mode update immediately. Upon any other change, queue the message
4098         // and request an audio mode update after a grace period.
4099         synchronized (mDeviceBroker.mSetModeLock) {
4100             boolean updateAudioMode = false;
4101             int existingMsgPolicy = SENDMSG_QUEUE;
4102             int delay = CHECK_MODE_FOR_UID_PERIOD_MS;
4103             for (SetModeDeathHandler h : mSetModeDeathHandlers) {
4104                 boolean wasActive = h.isActive();
4105                 h.setPlaybackActive(false);
4106                 for (AudioPlaybackConfiguration config : configs) {
4107                     final int usage = config.getAudioAttributes().getUsage();
4108                     if (config.getClientUid() == h.getUid()
4109                             && (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION
4110                                 || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING)
4111                             && config.getPlayerState()
4112                                 == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
4113                         h.setPlaybackActive(true);
4114                         break;
4115                     }
4116                 }
4117                 if (wasActive != h.isActive()) {
4118                     updateAudioMode = true;
4119                     if (h.isActive() && h == getAudioModeOwnerHandler()) {
4120                         existingMsgPolicy = SENDMSG_REPLACE;
4121                         delay = 0;
4122                     }
4123                 }
4124             }
4125             if (updateAudioMode) {
4126                 sendMsg(mAudioHandler,
4127                         MSG_UPDATE_AUDIO_MODE,
4128                         existingMsgPolicy,
4129                         AudioSystem.MODE_CURRENT,
4130                         android.os.Process.myPid(),
4131                         mContext.getPackageName(),
4132                         delay);
4133             }
4134         }
4135     }
4136 
4137     private final IRecordingConfigDispatcher mVoiceRecordingActivityMonitor =
4138             new IRecordingConfigDispatcher.Stub() {
4139         @Override
4140         public void dispatchRecordingConfigChange(List<AudioRecordingConfiguration> configs) {
4141             sendMsg(mAudioHandler, MSG_RECORDING_CONFIG_CHANGE, SENDMSG_REPLACE,
4142                     0 /*arg1 ignored*/, 0 /*arg2 ignored*/,
4143                     configs /*obj*/, 0 /*delay*/);
4144         }
4145     };
4146 
onRecordingConfigChange(List<AudioRecordingConfiguration> configs)4147     private void onRecordingConfigChange(List<AudioRecordingConfiguration> configs) {
4148         // Update recording active state for all apps in audio mode stack.
4149         // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE
4150         // and request an audio mode update immediately. Upon any other change, queue the message
4151         // and request an audio mode update after a grace period.
4152         synchronized (mDeviceBroker.mSetModeLock) {
4153             boolean updateAudioMode = false;
4154             int existingMsgPolicy = SENDMSG_QUEUE;
4155             int delay = CHECK_MODE_FOR_UID_PERIOD_MS;
4156             for (SetModeDeathHandler h : mSetModeDeathHandlers) {
4157                 boolean wasActive = h.isActive();
4158                 h.setRecordingActive(false);
4159                 for (AudioRecordingConfiguration config : configs) {
4160                     if (config.getClientUid() == h.getUid()
4161                             && config.getAudioSource() == AudioSource.VOICE_COMMUNICATION) {
4162                         h.setRecordingActive(true);
4163                         break;
4164                     }
4165                 }
4166                 if (wasActive != h.isActive()) {
4167                     updateAudioMode = true;
4168                     if (h.isActive() && h == getAudioModeOwnerHandler()) {
4169                         existingMsgPolicy = SENDMSG_REPLACE;
4170                         delay = 0;
4171                     }
4172                 }
4173             }
4174             if (updateAudioMode) {
4175                 sendMsg(mAudioHandler,
4176                         MSG_UPDATE_AUDIO_MODE,
4177                         existingMsgPolicy,
4178                         AudioSystem.MODE_CURRENT,
4179                         android.os.Process.myPid(),
4180                         mContext.getPackageName(),
4181                         delay);
4182             }
4183         }
4184     }
4185 
dumpAudioMode(PrintWriter pw)4186     private void dumpAudioMode(PrintWriter pw) {
4187         pw.println("\nAudio mode: ");
4188         pw.println("- Requested mode = " + AudioSystem.modeToString(getMode()));
4189         pw.println("- Actual mode = " + AudioSystem.modeToString(mMode.get()));
4190         pw.println("- Mode owner: ");
4191         SetModeDeathHandler hdlr = getAudioModeOwnerHandler();
4192         if (hdlr != null) {
4193             hdlr.dump(pw, -1);
4194         } else {
4195             pw.println("   None");
4196         }
4197         pw.println("- Mode owner stack: ");
4198         if (mSetModeDeathHandlers.isEmpty()) {
4199             pw.println("   Empty");
4200         } else {
4201             for (int i = 0; i < mSetModeDeathHandlers.size(); i++) {
4202                 mSetModeDeathHandlers.get(i).dump(pw, i);
4203             }
4204         }
4205     }
4206 
updateHearingAidVolumeOnVoiceActivityUpdate()4207     private void updateHearingAidVolumeOnVoiceActivityUpdate() {
4208         final int streamType = getBluetoothContextualVolumeStream();
4209         final int index = getStreamVolume(streamType);
4210         sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_HEARING_AID,
4211                 mVoicePlaybackActive.get(), streamType, index));
4212         mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
4213 
4214     }
4215 
4216     /**
4217      * Manage an audio mode change for audio devices that use an "absolute volume" model,
4218      * i.e. the framework sends the full scale signal, and the actual volume for the use case
4219      * is communicated separately.
4220      */
updateAbsVolumeMultiModeDevices(int oldMode, int newMode)4221     void updateAbsVolumeMultiModeDevices(int oldMode, int newMode) {
4222         if (oldMode == newMode) {
4223             return;
4224         }
4225         switch (newMode) {
4226             case AudioSystem.MODE_IN_COMMUNICATION:
4227             case AudioSystem.MODE_IN_CALL:
4228             case AudioSystem.MODE_NORMAL:
4229             case AudioSystem.MODE_CALL_SCREENING:
4230             case AudioSystem.MODE_CALL_REDIRECT:
4231             case AudioSystem.MODE_COMMUNICATION_REDIRECT:
4232                 break;
4233             default:
4234                 // no-op is enough for all other values
4235                 return;
4236         }
4237 
4238         int streamType = getBluetoothContextualVolumeStream(newMode);
4239 
4240         final Set<Integer> deviceTypes = getDeviceSetForStreamDirect(streamType);
4241         final Set<Integer> absVolumeMultiModeCaseDevices = AudioSystem.intersectionAudioDeviceTypes(
4242                 mAbsVolumeMultiModeCaseDevices, deviceTypes);
4243         if (absVolumeMultiModeCaseDevices.isEmpty()) {
4244             return;
4245         }
4246 
4247         // handling of specific interfaces goes here:
4248         if (AudioSystem.isSingleAudioDeviceType(
4249                 absVolumeMultiModeCaseDevices, AudioSystem.DEVICE_OUT_HEARING_AID)) {
4250             final int index = getStreamVolume(streamType);
4251             sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_MODE_CHANGE_HEARING_AID,
4252                     newMode, streamType, index));
4253             mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
4254         }
4255     }
4256 
setLeAudioVolumeOnModeUpdate(int mode, int device)4257     private void setLeAudioVolumeOnModeUpdate(int mode, int device) {
4258         switch (mode) {
4259             case AudioSystem.MODE_IN_COMMUNICATION:
4260             case AudioSystem.MODE_IN_CALL:
4261             case AudioSystem.MODE_NORMAL:
4262             case AudioSystem.MODE_CALL_SCREENING:
4263             case AudioSystem.MODE_CALL_REDIRECT:
4264             case AudioSystem.MODE_COMMUNICATION_REDIRECT:
4265                 break;
4266             default:
4267                 // no-op is enough for all other values
4268                 return;
4269         }
4270 
4271         // Forcefully set LE audio volume as a workaround, since in some cases
4272         // (like the outgoing call) the value of 'device' is not DEVICE_OUT_BLE_*
4273         // even when BLE is connected.
4274         if (!AudioSystem.isLeAudioDeviceType(device)) {
4275             device = AudioSystem.DEVICE_OUT_BLE_HEADSET;
4276         }
4277 
4278         final int streamType = getBluetoothContextualVolumeStream(mode);
4279         final int index = mStreamStates[streamType].getIndex(device);
4280         final int maxIndex = mStreamStates[streamType].getMaxIndex();
4281 
4282         if (DEBUG_VOL) {
4283             Log.d(TAG, "setLeAudioVolumeOnModeUpdate postSetLeAudioVolumeIndex index="
4284                     + index + " maxIndex=" + maxIndex + " streamType=" + streamType);
4285         }
4286         mDeviceBroker.postSetLeAudioVolumeIndex(index, maxIndex, streamType);
4287         mDeviceBroker.postApplyVolumeOnDevice(streamType, device, "setLeAudioVolumeOnModeUpdate");
4288     }
4289 
setStreamVolume(int streamType, int index, int flags, @Nullable AudioDeviceAttributes ada, String callingPackage, String caller, String attributionTag, int uid, boolean hasModifyAudioSettings)4290     private void setStreamVolume(int streamType, int index, int flags,
4291             @Nullable AudioDeviceAttributes ada,
4292             String callingPackage, String caller, String attributionTag, int uid,
4293             boolean hasModifyAudioSettings) {
4294         if (DEBUG_VOL) {
4295             Log.d(TAG, "setStreamVolume(stream=" + streamType+", index=" + index
4296                     + ", dev=" + ada
4297                     + ", calling=" + callingPackage + ")");
4298         }
4299         if (mUseFixedVolume) {
4300             return;
4301         }
4302 
4303         ensureValidStreamType(streamType);
4304         int streamTypeAlias = mStreamVolumeAlias[streamType];
4305         VolumeStreamState streamState = mStreamStates[streamTypeAlias];
4306 
4307         final int device = (ada == null)
4308                 ? getDeviceForStream(streamType)
4309                 : ada.getInternalType();
4310         int oldIndex;
4311 
4312         // skip a2dp absolute volume control request when the device
4313         // is neither an a2dp device nor BLE device
4314         if ((!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
4315                 && !AudioSystem.DEVICE_OUT_ALL_BLE_SET.contains(device))
4316                 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) {
4317             return;
4318         }
4319         // If we are being called by the system (e.g. hardware keys) check for current user
4320         // so we handle user restrictions correctly.
4321         if (uid == android.os.Process.SYSTEM_UID) {
4322             uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid));
4323         }
4324         if (!checkNoteAppOp(
4325                 STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage, attributionTag)) {
4326             return;
4327         }
4328 
4329         if (isAndroidNPlus(callingPackage)
4330                 && wouldToggleZenMode(getNewRingerMode(streamTypeAlias, index, flags))
4331                 && !mNm.isNotificationPolicyAccessGrantedForPackage(callingPackage)) {
4332             throw new SecurityException("Not allowed to change Do Not Disturb state");
4333         }
4334 
4335         if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) {
4336             return;
4337         }
4338 
4339         synchronized (mSafeMediaVolumeStateLock) {
4340             // reset any pending volume command
4341             mPendingVolumeCommand = null;
4342 
4343             oldIndex = streamState.getIndex(device);
4344 
4345             index = rescaleIndex(index * 10, streamType, streamTypeAlias);
4346 
4347             if (streamTypeAlias == AudioSystem.STREAM_MUSIC
4348                     && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
4349                     && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
4350                 if (DEBUG_VOL) {
4351                     Log.d(TAG, "setStreamVolume postSetAvrcpAbsoluteVolumeIndex index=" + index
4352                             + "stream=" + streamType);
4353                 }
4354                 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index / 10);
4355             } else if (isAbsoluteVolumeDevice(device)
4356                     && ((flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0)) {
4357                 AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device);
4358 
4359                 dispatchAbsoluteVolumeChanged(streamType, info, index);
4360             }
4361 
4362             if (AudioSystem.isLeAudioDeviceType(device)
4363                     && streamType == getBluetoothContextualVolumeStream()
4364                     && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
4365                 if (DEBUG_VOL) {
4366                     Log.d(TAG, "adjustSreamVolume postSetLeAudioVolumeIndex index="
4367                             + index + " stream=" + streamType);
4368                 }
4369                 mDeviceBroker.postSetLeAudioVolumeIndex(index,
4370                     mStreamStates[streamType].getMaxIndex(), streamType);
4371             }
4372 
4373             if (device == AudioSystem.DEVICE_OUT_HEARING_AID
4374                     && streamType == getBluetoothContextualVolumeStream()) {
4375                 Log.i(TAG, "setStreamVolume postSetHearingAidVolumeIndex index=" + index
4376                         + " stream=" + streamType);
4377                 mDeviceBroker.postSetHearingAidVolumeIndex(index, streamType);
4378             }
4379 
4380             flags &= ~AudioManager.FLAG_FIXED_VOLUME;
4381             if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) {
4382                 flags |= AudioManager.FLAG_FIXED_VOLUME;
4383 
4384                 // volume is either 0 or max allowed for fixed volume devices
4385                 if (index != 0) {
4386                     if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE &&
4387                             mSafeMediaVolumeDevices.contains(device)) {
4388                         index = safeMediaVolumeIndex(device);
4389                     } else {
4390                         index = streamState.getMaxIndex();
4391                     }
4392                 }
4393             }
4394 
4395             if (!checkSafeMediaVolume(streamTypeAlias, index, device)) {
4396                 mVolumeController.postDisplaySafeVolumeWarning(flags);
4397                 mPendingVolumeCommand = new StreamVolumeCommand(
4398                                                     streamType, index, flags, device);
4399             } else {
4400                 onSetStreamVolume(streamType, index, flags, device, caller, hasModifyAudioSettings,
4401                         // ada is non-null when called from setDeviceVolume,
4402                         // which shouldn't update the mute state
4403                         ada == null /*canChangeMute*/);
4404                 index = mStreamStates[streamType].getIndex(device);
4405             }
4406         }
4407         synchronized (mHdmiClientLock) {
4408             if (streamTypeAlias == AudioSystem.STREAM_MUSIC
4409                     && (oldIndex != index)) {
4410                 maybeSendSystemAudioStatusCommand(false);
4411             }
4412         }
4413         if (ada == null) {
4414             // only non-null when coming here from setDeviceVolume
4415             // TODO change test to check early if device is current device or not
4416             sendVolumeUpdate(streamType, oldIndex, index, flags, device);
4417         }
4418     }
4419 
dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, int index)4420     private void dispatchAbsoluteVolumeChanged(int streamType, AbsoluteVolumeDeviceInfo deviceInfo,
4421             int index) {
4422         VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType);
4423         if (volumeInfo != null) {
4424             try {
4425                 deviceInfo.mCallback.dispatchDeviceVolumeChanged(deviceInfo.mDevice,
4426                         new VolumeInfo.Builder(volumeInfo)
4427                                 .setVolumeIndex(rescaleIndex(index, streamType, volumeInfo))
4428                                 .build());
4429             } catch (RemoteException e) {
4430                 Log.w(TAG, "Couldn't dispatch absolute volume behavior volume change");
4431             }
4432         }
4433     }
4434 
dispatchAbsoluteVolumeAdjusted(int streamType, AbsoluteVolumeDeviceInfo deviceInfo, int index, int direction, int mode)4435     private void dispatchAbsoluteVolumeAdjusted(int streamType,
4436             AbsoluteVolumeDeviceInfo deviceInfo, int index, int direction, int mode) {
4437         VolumeInfo volumeInfo = deviceInfo.getMatchingVolumeInfoForStream(streamType);
4438         if (volumeInfo != null) {
4439             try {
4440                 deviceInfo.mCallback.dispatchDeviceVolumeAdjusted(deviceInfo.mDevice,
4441                         new VolumeInfo.Builder(volumeInfo)
4442                                 .setVolumeIndex(rescaleIndex(index, streamType, volumeInfo))
4443                                 .build(),
4444                         direction,
4445                         mode);
4446             } catch (RemoteException e) {
4447                 Log.w(TAG, "Couldn't dispatch absolute volume behavior volume adjustment");
4448             }
4449         }
4450     }
4451 
4452     // No ringer or zen muted stream volumes can be changed unless it'll exit dnd
volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags)4453     private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) {
4454         switch (mNm.getZenMode()) {
4455             case Settings.Global.ZEN_MODE_OFF:
4456                 return true;
4457             case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
4458             case Settings.Global.ZEN_MODE_ALARMS:
4459             case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
4460                 return !isStreamMutedByRingerOrZenMode(streamTypeAlias)
4461                         || isUiSoundsStreamType(streamTypeAlias)
4462                         || (flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0;
4463         }
4464 
4465         return true;
4466     }
4467 
4468     /** @see AudioManager#forceVolumeControlStream(int) */
forceVolumeControlStream(int streamType, IBinder cb)4469     public void forceVolumeControlStream(int streamType, IBinder cb) {
4470         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
4471                 != PackageManager.PERMISSION_GRANTED) {
4472             return;
4473         }
4474         if (DEBUG_VOL) { Log.d(TAG, String.format("forceVolumeControlStream(%d)", streamType)); }
4475         synchronized(mForceControlStreamLock) {
4476             if (mVolumeControlStream != -1 && streamType != -1) {
4477                 mUserSelectedVolumeControlStream = true;
4478             }
4479             mVolumeControlStream = streamType;
4480             if (mVolumeControlStream == -1) {
4481                 if (mForceControlStreamClient != null) {
4482                     mForceControlStreamClient.release();
4483                     mForceControlStreamClient = null;
4484                 }
4485                 mUserSelectedVolumeControlStream = false;
4486             } else {
4487                 if (null == mForceControlStreamClient) {
4488                     mForceControlStreamClient = new ForceControlStreamClient(cb);
4489                 } else {
4490                     if (mForceControlStreamClient.getBinder() == cb) {
4491                         Log.d(TAG, "forceVolumeControlStream cb:" + cb + " is already linked.");
4492                     } else {
4493                         mForceControlStreamClient.release();
4494                         mForceControlStreamClient = new ForceControlStreamClient(cb);
4495                     }
4496                 }
4497             }
4498         }
4499     }
4500 
4501     private class ForceControlStreamClient implements IBinder.DeathRecipient {
4502         private IBinder mCb; // To be notified of client's death
4503 
ForceControlStreamClient(IBinder cb)4504         ForceControlStreamClient(IBinder cb) {
4505             if (cb != null) {
4506                 try {
4507                     cb.linkToDeath(this, 0);
4508                 } catch (RemoteException e) {
4509                     // Client has died!
4510                     Log.w(TAG, "ForceControlStreamClient() could not link to "+cb+" binder death");
4511                     cb = null;
4512                 }
4513             }
4514             mCb = cb;
4515         }
4516 
binderDied()4517         public void binderDied() {
4518             synchronized(mForceControlStreamLock) {
4519                 Log.w(TAG, "SCO client died");
4520                 if (mForceControlStreamClient != this) {
4521                     Log.w(TAG, "unregistered control stream client died");
4522                 } else {
4523                     mForceControlStreamClient = null;
4524                     mVolumeControlStream = -1;
4525                     mUserSelectedVolumeControlStream = false;
4526                 }
4527             }
4528         }
4529 
release()4530         public void release() {
4531             if (mCb != null) {
4532                 mCb.unlinkToDeath(this, 0);
4533                 mCb = null;
4534             }
4535         }
4536 
getBinder()4537         public IBinder getBinder() {
4538             return mCb;
4539         }
4540     }
4541 
sendBroadcastToAll(Intent intent)4542     private void sendBroadcastToAll(Intent intent) {
4543         if (!mSystemServer.isPrivileged()) {
4544             return;
4545         }
4546         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
4547         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
4548         final long ident = Binder.clearCallingIdentity();
4549         try {
4550             mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
4551         } finally {
4552             Binder.restoreCallingIdentity(ident);
4553         }
4554     }
4555 
sendStickyBroadcastToAll(Intent intent)4556     private void sendStickyBroadcastToAll(Intent intent) {
4557         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
4558         final long ident = Binder.clearCallingIdentity();
4559         try {
4560             mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
4561         } finally {
4562             Binder.restoreCallingIdentity(ident);
4563         }
4564     }
4565 
getCurrentUserId()4566     private int getCurrentUserId() {
4567         final long ident = Binder.clearCallingIdentity();
4568         try {
4569             UserInfo currentUser = ActivityManager.getService().getCurrentUser();
4570             return currentUser.id;
4571         } catch (RemoteException e) {
4572             // Activity manager not running, nothing we can do assume user 0.
4573         } finally {
4574             Binder.restoreCallingIdentity(ident);
4575         }
4576         return UserHandle.USER_SYSTEM;
4577     }
4578 
4579     // UI update and Broadcast Intent
sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device)4580     protected void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device)
4581     {
4582         streamType = mStreamVolumeAlias[streamType];
4583 
4584         if (streamType == AudioSystem.STREAM_MUSIC && isFullVolumeDevice(device)) {
4585             flags &= ~AudioManager.FLAG_SHOW_UI;
4586         }
4587         mVolumeController.postVolumeChanged(streamType, flags);
4588     }
4589 
4590     // Don't show volume UI when:
4591     //  - Hdmi-CEC system audio mode is on and we are a TV panel
updateFlagsForTvPlatform(int flags)4592     private int updateFlagsForTvPlatform(int flags) {
4593         synchronized (mHdmiClientLock) {
4594             if (mHdmiTvClient != null && mHdmiSystemAudioSupported
4595                     && mHdmiCecVolumeControlEnabled) {
4596                 flags &= ~AudioManager.FLAG_SHOW_UI;
4597             }
4598         }
4599         return flags;
4600     }
4601     // UI update and Broadcast Intent
sendMasterMuteUpdate(boolean muted, int flags)4602     private void sendMasterMuteUpdate(boolean muted, int flags) {
4603         mVolumeController.postMasterMuteChanged(updateFlagsForTvPlatform(flags));
4604         broadcastMasterMuteStatus(muted);
4605     }
4606 
broadcastMasterMuteStatus(boolean muted)4607     private void broadcastMasterMuteStatus(boolean muted) {
4608         Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION);
4609         intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, muted);
4610         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
4611                 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
4612         sendStickyBroadcastToAll(intent);
4613     }
4614 
4615     /**
4616      * Sets the stream state's index, and posts a message to set system volume.
4617      * This will not call out to the UI. Assumes a valid stream type.
4618      *
4619      * @param streamType Type of the stream
4620      * @param index Desired volume index of the stream
4621      * @param device the device whose volume must be changed
4622      * @param force If true, set the volume even if the desired volume is same
4623      * @param caller
4624      * @param hasModifyAudioSettings true if the caller is granted MODIFY_AUDIO_SETTINGS or
4625      *                              MODIFY_AUDIO_ROUTING permission
4626      * as the current volume.
4627      */
setStreamVolumeInt(int streamType, int index, int device, boolean force, String caller, boolean hasModifyAudioSettings)4628     private void setStreamVolumeInt(int streamType,
4629                                     int index,
4630                                     int device,
4631                                     boolean force,
4632                                     String caller, boolean hasModifyAudioSettings) {
4633         if (isFullVolumeDevice(device)) {
4634             return;
4635         }
4636         VolumeStreamState streamState = mStreamStates[streamType];
4637 
4638         if (streamState.setIndex(index, device, caller, hasModifyAudioSettings) || force) {
4639             // Post message to set system volume (it in turn will post a message
4640             // to persist).
4641             sendMsg(mAudioHandler,
4642                     MSG_SET_DEVICE_VOLUME,
4643                     SENDMSG_QUEUE,
4644                     device,
4645                     0,
4646                     streamState,
4647                     0);
4648         }
4649     }
4650 
4651     /** get stream mute state. */
isStreamMute(int streamType)4652     public boolean isStreamMute(int streamType) {
4653         if (streamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
4654             streamType = getActiveStreamType(streamType);
4655         }
4656         synchronized (VolumeStreamState.class) {
4657             ensureValidStreamType(streamType);
4658             return mStreamStates[streamType].mIsMuted;
4659         }
4660     }
4661 
4662     private class RmtSbmxFullVolDeathHandler implements IBinder.DeathRecipient {
4663         private IBinder mICallback; // To be notified of client's death
4664 
RmtSbmxFullVolDeathHandler(IBinder cb)4665         RmtSbmxFullVolDeathHandler(IBinder cb) {
4666             mICallback = cb;
4667             try {
4668                 cb.linkToDeath(this, 0/*flags*/);
4669             } catch (RemoteException e) {
4670                 Log.e(TAG, "can't link to death", e);
4671             }
4672         }
4673 
isHandlerFor(IBinder cb)4674         boolean isHandlerFor(IBinder cb) {
4675             return mICallback.equals(cb);
4676         }
4677 
forget()4678         void forget() {
4679             try {
4680                 mICallback.unlinkToDeath(this, 0/*flags*/);
4681             } catch (NoSuchElementException e) {
4682                 Log.e(TAG, "error unlinking to death", e);
4683             }
4684         }
4685 
binderDied()4686         public void binderDied() {
4687             Log.w(TAG, "Recorder with remote submix at full volume died " + mICallback);
4688             forceRemoteSubmixFullVolume(false, mICallback);
4689         }
4690     }
4691 
4692     /**
4693      * call must be synchronized on mRmtSbmxFullVolDeathHandlers
4694      * @return true if there is a registered death handler, false otherwise */
discardRmtSbmxFullVolDeathHandlerFor(IBinder cb)4695     private boolean discardRmtSbmxFullVolDeathHandlerFor(IBinder cb) {
4696         Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator();
4697         while (it.hasNext()) {
4698             final RmtSbmxFullVolDeathHandler handler = it.next();
4699             if (handler.isHandlerFor(cb)) {
4700                 handler.forget();
4701                 mRmtSbmxFullVolDeathHandlers.remove(handler);
4702                 return true;
4703             }
4704         }
4705         return false;
4706     }
4707 
4708     /** call synchronized on mRmtSbmxFullVolDeathHandlers */
hasRmtSbmxFullVolDeathHandlerFor(IBinder cb)4709     private boolean hasRmtSbmxFullVolDeathHandlerFor(IBinder cb) {
4710         Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator();
4711         while (it.hasNext()) {
4712             if (it.next().isHandlerFor(cb)) {
4713                 return true;
4714             }
4715         }
4716         return false;
4717     }
4718 
4719     private int mRmtSbmxFullVolRefCount = 0;
4720     private final ArrayList<RmtSbmxFullVolDeathHandler> mRmtSbmxFullVolDeathHandlers =
4721             new ArrayList<RmtSbmxFullVolDeathHandler>();
4722 
forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb)4723     public void forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb) {
4724         if (cb == null) {
4725             return;
4726         }
4727         if ((PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
4728                         android.Manifest.permission.CAPTURE_AUDIO_OUTPUT))) {
4729             Log.w(TAG, "Trying to call forceRemoteSubmixFullVolume() without CAPTURE_AUDIO_OUTPUT");
4730             return;
4731         }
4732         synchronized(mRmtSbmxFullVolDeathHandlers) {
4733             boolean applyRequired = false;
4734             if (startForcing) {
4735                 if (!hasRmtSbmxFullVolDeathHandlerFor(cb)) {
4736                     mRmtSbmxFullVolDeathHandlers.add(new RmtSbmxFullVolDeathHandler(cb));
4737                     if (mRmtSbmxFullVolRefCount == 0) {
4738                         mFullVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
4739                         mFixedVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
4740                         applyRequired = true;
4741                     }
4742                     mRmtSbmxFullVolRefCount++;
4743                 }
4744             } else {
4745                 if (discardRmtSbmxFullVolDeathHandlerFor(cb) && (mRmtSbmxFullVolRefCount > 0)) {
4746                     mRmtSbmxFullVolRefCount--;
4747                     if (mRmtSbmxFullVolRefCount == 0) {
4748                         mFullVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
4749                         mFixedVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
4750                         applyRequired = true;
4751                     }
4752                 }
4753             }
4754             if (applyRequired) {
4755                 // Assumes only STREAM_MUSIC going through DEVICE_OUT_REMOTE_SUBMIX
4756                 checkAllFixedVolumeDevices(AudioSystem.STREAM_MUSIC);
4757                 mStreamStates[AudioSystem.STREAM_MUSIC].applyAllVolumes();
4758             }
4759         }
4760     }
4761 
setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, int userId, int pid, String attributionTag)4762     private void setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid,
4763             int userId, int pid, String attributionTag) {
4764         // If we are being called by the system check for user we are going to change
4765         // so we handle user restrictions correctly.
4766         if (uid == android.os.Process.SYSTEM_UID) {
4767             uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4768         }
4769         // If OP_AUDIO_MASTER_VOLUME is set, disallow unmuting.
4770         if (!mute && !checkNoteAppOp(
4771                 AppOpsManager.OP_AUDIO_MASTER_VOLUME, uid, callingPackage, attributionTag)) {
4772             return;
4773         }
4774         if (userId != UserHandle.getCallingUserId() &&
4775                 mContext.checkPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4776                         pid, uid)
4777                 != PackageManager.PERMISSION_GRANTED) {
4778             return;
4779         }
4780         setMasterMuteInternalNoCallerCheck(mute, flags, userId);
4781     }
4782 
setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId)4783     private void setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId) {
4784         if (DEBUG_VOL) {
4785             Log.d(TAG, String.format("Master mute %s, %d, user=%d", mute, flags, userId));
4786         }
4787         if (!isPlatformAutomotive() && mUseFixedVolume) {
4788             // If using fixed volume, we don't mute.
4789             // TODO: remove the isPlatformAutomotive check here.
4790             // The isPlatformAutomotive check is added for safety but may not be necessary.
4791             return;
4792         }
4793         // For automotive,
4794         // - the car service is always running as system user
4795         // - foreground users are non-system users
4796         // Car service is in charge of dispatching the key event include global mute to Android.
4797         // Therefore, the getCurrentUser() is always different to the foreground user.
4798         if ((isPlatformAutomotive() && userId == UserHandle.USER_SYSTEM)
4799                 || (getCurrentUserId() == userId)) {
4800             if (mute != AudioSystem.getMasterMute()) {
4801                 AudioSystem.setMasterMute(mute);
4802                 sendMasterMuteUpdate(mute, flags);
4803             }
4804         }
4805     }
4806 
4807     /** get global mute state. */
isMasterMute()4808     public boolean isMasterMute() {
4809         return AudioSystem.getMasterMute();
4810     }
4811 
4812     /** @see AudioManager#setMasterMute(boolean, int) */
setMasterMute(boolean mute, int flags, String callingPackage, int userId, String attributionTag)4813     public void setMasterMute(boolean mute, int flags, String callingPackage, int userId,
4814             String attributionTag) {
4815         enforceModifyAudioRoutingPermission();
4816         setMasterMuteInternal(mute, flags, callingPackage,
4817                 Binder.getCallingUid(), userId, Binder.getCallingPid(), attributionTag);
4818     }
4819 
4820     /** @see AudioManager#getStreamVolume(int) */
getStreamVolume(int streamType)4821     public int getStreamVolume(int streamType) {
4822         ensureValidStreamType(streamType);
4823         int device = getDeviceForStream(streamType);
4824         synchronized (VolumeStreamState.class) {
4825             int index = mStreamStates[streamType].getIndex(device);
4826 
4827             // by convention getStreamVolume() returns 0 when a stream is muted.
4828             if (mStreamStates[streamType].mIsMuted) {
4829                 index = 0;
4830             }
4831             if (index != 0 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
4832                     isFixedVolumeDevice(device)) {
4833                 index = mStreamStates[streamType].getMaxIndex();
4834             }
4835             return (index + 5) / 10;
4836         }
4837     }
4838 
4839     /**
4840      * @see AudioDeviceVolumeManager#getDeviceVolume(VolumeInfo, AudioDeviceAttributes)
4841      */
getDeviceVolume(@onNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage)4842     public @NonNull VolumeInfo getDeviceVolume(@NonNull VolumeInfo vi,
4843             @NonNull AudioDeviceAttributes ada, @NonNull String callingPackage) {
4844         enforceModifyAudioRoutingOrSystemSettingsPermission();
4845         Objects.requireNonNull(vi);
4846         Objects.requireNonNull(ada);
4847         Objects.requireNonNull(callingPackage);
4848         if (!vi.hasStreamType()) {
4849             Log.e(TAG, "Unsupported non-stream type based VolumeInfo", new Exception());
4850             return getDefaultVolumeInfo();
4851         }
4852 
4853         int streamType = vi.getStreamType();
4854         final VolumeInfo.Builder vib = new VolumeInfo.Builder(vi);
4855         vib.setMinVolumeIndex((mStreamStates[streamType].mIndexMin + 5) / 10);
4856         vib.setMaxVolumeIndex((mStreamStates[streamType].mIndexMax + 5) / 10);
4857         synchronized (VolumeStreamState.class) {
4858             final int index;
4859             if (isFixedVolumeDevice(ada.getInternalType())) {
4860                 index = (mStreamStates[streamType].mIndexMax + 5) / 10;
4861             } else {
4862                 index = (mStreamStates[streamType].getIndex(ada.getInternalType()) + 5) / 10;
4863             }
4864             vib.setVolumeIndex(index);
4865             // only set as a mute command if stream muted
4866             if (mStreamStates[streamType].mIsMuted) {
4867                 vib.setMuted(true);
4868             }
4869             return vib.build();
4870         }
4871     }
4872 
4873     /** @see AudioManager#getStreamMaxVolume(int) */
getStreamMaxVolume(int streamType)4874     public int getStreamMaxVolume(int streamType) {
4875         ensureValidStreamType(streamType);
4876         return (mStreamStates[streamType].getMaxIndex() + 5) / 10;
4877     }
4878 
4879     /** @see AudioManager#getStreamMinVolumeInt(int)
4880      * Part of service interface, check permissions here */
getStreamMinVolume(int streamType)4881     public int getStreamMinVolume(int streamType) {
4882         ensureValidStreamType(streamType);
4883         final boolean isPrivileged =
4884                 Binder.getCallingUid() == Process.SYSTEM_UID
4885                  || callingHasAudioSettingsPermission()
4886                  || (mContext.checkCallingPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)
4887                         == PackageManager.PERMISSION_GRANTED);
4888         return (mStreamStates[streamType].getMinIndex(isPrivileged) + 5) / 10;
4889     }
4890 
4891     /** Get last audible volume before stream was muted. */
getLastAudibleStreamVolume(int streamType)4892     public int getLastAudibleStreamVolume(int streamType) {
4893         enforceQueryStatePermission();
4894         ensureValidStreamType(streamType);
4895         int device = getDeviceForStream(streamType);
4896         return (mStreamStates[streamType].getIndex(device) + 5) / 10;
4897     }
4898 
4899     /**
4900      * Default VolumeInfo returned by {@link VolumeInfo#getDefaultVolumeInfo()}
4901      * Lazily initialized in {@link #getDefaultVolumeInfo()}
4902      */
4903     static VolumeInfo sDefaultVolumeInfo;
4904 
4905     /** @see VolumeInfo#getDefaultVolumeInfo() */
getDefaultVolumeInfo()4906     public VolumeInfo getDefaultVolumeInfo() {
4907         if (sDefaultVolumeInfo == null) {
4908             sDefaultVolumeInfo = new VolumeInfo.Builder(AudioSystem.STREAM_MUSIC)
4909                     .setMinVolumeIndex(getStreamMinVolume(AudioSystem.STREAM_MUSIC))
4910                     .setMaxVolumeIndex(getStreamMaxVolume(AudioSystem.STREAM_MUSIC))
4911                     .build();
4912         }
4913         return sDefaultVolumeInfo;
4914     }
4915 
4916     /** @see AudioManager#getUiSoundsStreamType()
4917      * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for
4918      * UI Sounds identification.
4919      * Fallback on Voice configuration to ensure correct behavior of DnD feature.
4920      */
getUiSoundsStreamType()4921     public int getUiSoundsStreamType() {
4922         return mUseVolumeGroupAliases ? STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM]
4923                 : mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM];
4924     }
4925 
4926     /**
4927      * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for
4928      * UI Sounds identification.
4929      * Fallback on Voice configuration to ensure correct behavior of DnD feature.
4930      */
isUiSoundsStreamType(int aliasStreamType)4931     private boolean isUiSoundsStreamType(int aliasStreamType) {
4932         return mUseVolumeGroupAliases
4933                 ? STREAM_VOLUME_ALIAS_VOICE[aliasStreamType]
4934                         == STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM]
4935                 : aliasStreamType == mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM];
4936     }
4937 
4938     /** @see AudioManager#setMicrophoneMute(boolean) */
4939     @Override
setMicrophoneMute(boolean on, String callingPackage, int userId, String attributionTag)4940     public void setMicrophoneMute(boolean on, String callingPackage, int userId,
4941             String attributionTag) {
4942         // If we are being called by the system check for user we are going to change
4943         // so we handle user restrictions correctly.
4944         int uid = Binder.getCallingUid();
4945         if (uid == android.os.Process.SYSTEM_UID) {
4946             uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4947         }
4948         MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
4949                 .setUid(uid)
4950                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage)
4951                 .set(MediaMetrics.Property.EVENT, "setMicrophoneMute")
4952                 .set(MediaMetrics.Property.REQUEST, on
4953                         ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE);
4954 
4955         // If OP_MUTE_MICROPHONE is set, disallow unmuting.
4956         if (!on && !checkNoteAppOp(
4957                 AppOpsManager.OP_MUTE_MICROPHONE, uid, callingPackage, attributionTag)) {
4958             mmi.set(MediaMetrics.Property.EARLY_RETURN, "disallow unmuting").record();
4959             return;
4960         }
4961         if (!checkAudioSettingsPermission("setMicrophoneMute()")) {
4962             mmi.set(MediaMetrics.Property.EARLY_RETURN, "!checkAudioSettingsPermission").record();
4963             return;
4964         }
4965         if (userId != UserHandle.getCallingUserId() &&
4966                 mContext.checkCallingOrSelfPermission(
4967                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
4968                 != PackageManager.PERMISSION_GRANTED) {
4969             mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission").record();
4970             return;
4971         }
4972         mMicMuteFromApi = on;
4973         mmi.record(); // record now, the no caller check will set the mute state.
4974         setMicrophoneMuteNoCallerCheck(userId);
4975     }
4976 
4977     /** @see AudioManager#setMicrophoneMuteFromSwitch(boolean) */
setMicrophoneMuteFromSwitch(boolean on)4978     public void setMicrophoneMuteFromSwitch(boolean on) {
4979         int userId = Binder.getCallingUid();
4980         if (userId != android.os.Process.SYSTEM_UID) {
4981             Log.e(TAG, "setMicrophoneMuteFromSwitch() called from non system user!");
4982             return;
4983         }
4984         mMicMuteFromSwitch = on;
4985         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
4986                 .setUid(userId)
4987                 .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteFromSwitch")
4988                 .set(MediaMetrics.Property.REQUEST, on
4989                         ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE)
4990                 .record();
4991         setMicrophoneMuteNoCallerCheck(userId);
4992     }
4993 
setMicMuteFromSwitchInput()4994     private void setMicMuteFromSwitchInput() {
4995         InputManager im = mContext.getSystemService(InputManager.class);
4996         final int isMicMuted = im.isMicMuted();
4997         if (isMicMuted != InputManager.SWITCH_STATE_UNKNOWN) {
4998             setMicrophoneMuteFromSwitch(im.isMicMuted() != InputManager.SWITCH_STATE_OFF);
4999         }
5000     }
5001 
5002     /**
5003      * Returns the microphone mute state as seen from the native audio system
5004      * @return true if microphone is reported as muted by primary HAL
5005      */
isMicrophoneMuted()5006     public boolean isMicrophoneMuted() {
5007         return mMicMuteFromSystemCached
5008                 && (!mMicMuteFromPrivacyToggle
5009                         || mMicMuteFromApi || mMicMuteFromRestrictions || mMicMuteFromSwitch);
5010     }
5011 
isMicrophoneSupposedToBeMuted()5012     private boolean isMicrophoneSupposedToBeMuted() {
5013         return mMicMuteFromSwitch || mMicMuteFromRestrictions || mMicMuteFromApi
5014                 || mMicMuteFromPrivacyToggle;
5015     }
5016 
setMicrophoneMuteNoCallerCheck(int userId)5017     private void setMicrophoneMuteNoCallerCheck(int userId) {
5018         final boolean muted = isMicrophoneSupposedToBeMuted();
5019         if (DEBUG_VOL) {
5020             Log.d(TAG, String.format("Mic mute %b, user=%d", muted, userId));
5021         }
5022         // only mute for the current user
5023         if (getCurrentUserId() == userId || userId == android.os.Process.SYSTEM_UID) {
5024             final boolean currentMute = mAudioSystem.isMicrophoneMuted();
5025             final long identity = Binder.clearCallingIdentity();
5026             final int ret = mAudioSystem.muteMicrophone(muted);
5027 
5028             // update cache with the real state independently from what was set
5029             mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted();
5030             if (ret != AudioSystem.AUDIO_STATUS_OK) {
5031                 Log.e(TAG, "Error changing mic mute state to " + muted + " current:"
5032                         + mMicMuteFromSystemCached);
5033             }
5034 
5035             new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
5036                     .setUid(userId)
5037                     .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteNoCallerCheck")
5038                     .set(MediaMetrics.Property.MUTE, mMicMuteFromSystemCached
5039                             ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
5040                     .set(MediaMetrics.Property.REQUEST, muted
5041                             ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE)
5042                     .set(MediaMetrics.Property.STATUS, ret)
5043                     .record();
5044 
5045             try {
5046                 // send the intent even if there was a failure to change the actual mute state:
5047                 // the AudioManager.setMicrophoneMute API doesn't have a return value to
5048                 // indicate if the call failed to successfully change the mute state, and receiving
5049                 // the intent may be the only time an application can resynchronize its mic mute
5050                 // state with the actual system mic mute state
5051                 if (muted != currentMute) {
5052                     sendMsg(mAudioHandler, MSG_BROADCAST_MICROPHONE_MUTE,
5053                                 SENDMSG_NOOP, 0, 0, null, 0);
5054                 }
5055             } finally {
5056                 Binder.restoreCallingIdentity(identity);
5057             }
5058         }
5059     }
5060 
5061     @Override
getRingerModeExternal()5062     public int getRingerModeExternal() {
5063         synchronized(mSettingsLock) {
5064             return mRingerModeExternal;
5065         }
5066     }
5067 
5068     @Override
getRingerModeInternal()5069     public int getRingerModeInternal() {
5070         synchronized(mSettingsLock) {
5071             return mRingerMode;
5072         }
5073     }
5074 
ensureValidRingerMode(int ringerMode)5075     private void ensureValidRingerMode(int ringerMode) {
5076         if (!isValidRingerMode(ringerMode)) {
5077             throw new IllegalArgumentException("Bad ringer mode " + ringerMode);
5078         }
5079     }
5080 
5081     /** @see AudioManager#isValidRingerMode(int) */
isValidRingerMode(int ringerMode)5082     public boolean isValidRingerMode(int ringerMode) {
5083         return ringerMode >= 0 && ringerMode <= AudioManager.RINGER_MODE_MAX;
5084     }
5085 
setRingerModeExternal(int ringerMode, String caller)5086     public void setRingerModeExternal(int ringerMode, String caller) {
5087         if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode)
5088                 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)) {
5089             throw new SecurityException("Not allowed to change Do Not Disturb state");
5090         }
5091 
5092         setRingerMode(ringerMode, caller, true /*external*/);
5093     }
5094 
setRingerModeInternal(int ringerMode, String caller)5095     public void setRingerModeInternal(int ringerMode, String caller) {
5096         enforceVolumeController("setRingerModeInternal");
5097         setRingerMode(ringerMode, caller, false /*external*/);
5098     }
5099 
silenceRingerModeInternal(String reason)5100     public void silenceRingerModeInternal(String reason) {
5101         VibrationEffect effect = null;
5102         int ringerMode = AudioManager.RINGER_MODE_SILENT;
5103         int toastText = 0;
5104 
5105         int silenceRingerSetting = Settings.Secure.VOLUME_HUSH_OFF;
5106         if (mContext.getResources()
5107                 .getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled)) {
5108             silenceRingerSetting = mSettings.getSecureIntForUser(mContentResolver,
5109                     Settings.Secure.VOLUME_HUSH_GESTURE, VOLUME_HUSH_OFF,
5110                     UserHandle.USER_CURRENT);
5111         }
5112 
5113         switch(silenceRingerSetting) {
5114             case VOLUME_HUSH_MUTE:
5115                 effect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK);
5116                 ringerMode = AudioManager.RINGER_MODE_SILENT;
5117                 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_silent;
5118                 break;
5119             case VOLUME_HUSH_VIBRATE:
5120                 effect = VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK);
5121                 ringerMode = AudioManager.RINGER_MODE_VIBRATE;
5122                 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_vibrate;
5123                 break;
5124         }
5125         maybeVibrate(effect, reason);
5126         setRingerModeInternal(ringerMode, reason);
5127         Toast.makeText(mContext, toastText, Toast.LENGTH_SHORT).show();
5128     }
5129 
maybeVibrate(VibrationEffect effect, String reason)5130     private boolean maybeVibrate(VibrationEffect effect, String reason) {
5131         if (!mHasVibrator) {
5132             return false;
5133         }
5134         if (effect == null) {
5135             return false;
5136         }
5137         mVibrator.vibrate(Binder.getCallingUid(), mContext.getOpPackageName(), effect,
5138                 reason, TOUCH_VIBRATION_ATTRIBUTES);
5139         return true;
5140     }
5141 
setRingerMode(int ringerMode, String caller, boolean external)5142     private void setRingerMode(int ringerMode, String caller, boolean external) {
5143         if (mUseFixedVolume || mIsSingleVolume || mUseVolumeGroupAliases) {
5144             return;
5145         }
5146         if (caller == null || caller.length() == 0) {
5147             throw new IllegalArgumentException("Bad caller: " + caller);
5148         }
5149         ensureValidRingerMode(ringerMode);
5150         if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) {
5151             ringerMode = AudioManager.RINGER_MODE_SILENT;
5152         }
5153         final long identity = Binder.clearCallingIdentity();
5154         try {
5155             synchronized (mSettingsLock) {
5156                 final int ringerModeInternal = getRingerModeInternal();
5157                 final int ringerModeExternal = getRingerModeExternal();
5158                 if (external) {
5159                     setRingerModeExt(ringerMode);
5160                     if (mRingerModeDelegate != null) {
5161                         ringerMode = mRingerModeDelegate.onSetRingerModeExternal(ringerModeExternal,
5162                                 ringerMode, caller, ringerModeInternal, mVolumePolicy);
5163                     }
5164                     if (ringerMode != ringerModeInternal) {
5165                         setRingerModeInt(ringerMode, true /*persist*/);
5166                     }
5167                 } else /*internal*/ {
5168                     if (ringerMode != ringerModeInternal) {
5169                         setRingerModeInt(ringerMode, true /*persist*/);
5170                     }
5171                     if (mRingerModeDelegate != null) {
5172                         ringerMode = mRingerModeDelegate.onSetRingerModeInternal(ringerModeInternal,
5173                                 ringerMode, caller, ringerModeExternal, mVolumePolicy);
5174                     }
5175                     setRingerModeExt(ringerMode);
5176                 }
5177             }
5178         } finally {
5179             Binder.restoreCallingIdentity(identity);
5180         }
5181     }
5182 
setRingerModeExt(int ringerMode)5183     private void setRingerModeExt(int ringerMode) {
5184         synchronized(mSettingsLock) {
5185             if (ringerMode == mRingerModeExternal) return;
5186             mRingerModeExternal = ringerMode;
5187         }
5188         // Send sticky broadcast
5189         broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, ringerMode);
5190     }
5191 
5192     @GuardedBy("mSettingsLock")
muteRingerModeStreams()5193     private void muteRingerModeStreams() {
5194         // Mute stream if not previously muted by ringer mode and (ringer mode
5195         // is not RINGER_MODE_NORMAL OR stream is zen muted) and stream is affected by ringer mode.
5196         // Unmute stream if previously muted by ringer/zen mode and ringer mode
5197         // is RINGER_MODE_NORMAL or stream is not affected by ringer mode.
5198         int numStreamTypes = AudioSystem.getNumStreamTypes();
5199 
5200         if (mNm == null) {
5201             mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
5202         }
5203 
5204         final int ringerMode = mRingerMode; // Read ringer mode as reading primitives is atomic
5205         final boolean ringerModeMute = ringerMode == AudioManager.RINGER_MODE_VIBRATE
5206                 || ringerMode == AudioManager.RINGER_MODE_SILENT;
5207         final boolean shouldRingSco = ringerMode == AudioManager.RINGER_MODE_VIBRATE
5208                 && mDeviceBroker.isBluetoothScoActive();
5209         // Ask audio policy engine to force use Bluetooth SCO channel if needed
5210         final String eventSource = "muteRingerModeStreams() from u/pid:" + Binder.getCallingUid()
5211                 + "/" + Binder.getCallingPid();
5212         sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, AudioSystem.FOR_VIBRATE_RINGING,
5213                 shouldRingSco ? AudioSystem.FORCE_BT_SCO : AudioSystem.FORCE_NONE, eventSource, 0);
5214 
5215         for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
5216             final boolean isMuted = isStreamMutedByRingerOrZenMode(streamType);
5217             final boolean muteAllowedBySco =
5218                     !(shouldRingSco && streamType == AudioSystem.STREAM_RING);
5219             final boolean shouldZenMute = shouldZenMuteStream(streamType);
5220             final boolean shouldMute = shouldZenMute || (ringerModeMute
5221                     && isStreamAffectedByRingerMode(streamType) && muteAllowedBySco);
5222             if (isMuted == shouldMute) continue;
5223             if (!shouldMute) {
5224                 // unmute
5225                 // ring and notifications volume should never be 0 when not silenced
5226                 if (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING
5227                         || mStreamVolumeAlias[streamType] == AudioSystem.STREAM_NOTIFICATION) {
5228                     synchronized (VolumeStreamState.class) {
5229                         final VolumeStreamState vss = mStreamStates[streamType];
5230                         for (int i = 0; i < vss.mIndexMap.size(); i++) {
5231                             int device = vss.mIndexMap.keyAt(i);
5232                             int value = vss.mIndexMap.valueAt(i);
5233                             if (value == 0) {
5234                                 vss.setIndex(10, device, TAG, true /*hasModifyAudioSettings*/);
5235                             }
5236                         }
5237                         // Persist volume for stream ring when it is changed here
5238                       final int device = getDeviceForStream(streamType);
5239                       sendMsg(mAudioHandler,
5240                               MSG_PERSIST_VOLUME,
5241                               SENDMSG_QUEUE,
5242                               device,
5243                               0,
5244                               mStreamStates[streamType],
5245                               PERSIST_DELAY);
5246                     }
5247                 }
5248                 mStreamStates[streamType].mute(false);
5249                 mRingerAndZenModeMutedStreams &= ~(1 << streamType);
5250             } else {
5251                 // mute
5252                 mStreamStates[streamType].mute(true);
5253                 mRingerAndZenModeMutedStreams |= (1 << streamType);
5254             }
5255         }
5256     }
5257 
isAlarm(int streamType)5258     private boolean isAlarm(int streamType) {
5259         return streamType == AudioSystem.STREAM_ALARM;
5260     }
5261 
isNotificationOrRinger(int streamType)5262     private boolean isNotificationOrRinger(int streamType) {
5263         return streamType == AudioSystem.STREAM_NOTIFICATION
5264                 || streamType == AudioSystem.STREAM_RING;
5265     }
5266 
isMedia(int streamType)5267     private boolean isMedia(int streamType) {
5268         return streamType == AudioSystem.STREAM_MUSIC;
5269     }
5270 
5271 
isSystem(int streamType)5272     private boolean isSystem(int streamType) {
5273         return streamType == AudioSystem.STREAM_SYSTEM;
5274     }
5275 
setRingerModeInt(int ringerMode, boolean persist)5276     private void setRingerModeInt(int ringerMode, boolean persist) {
5277         final boolean change;
5278         synchronized(mSettingsLock) {
5279             change = mRingerMode != ringerMode;
5280             mRingerMode = ringerMode;
5281             muteRingerModeStreams();
5282         }
5283 
5284         // Post a persist ringer mode msg
5285         if (persist) {
5286             sendMsg(mAudioHandler, MSG_PERSIST_RINGER_MODE,
5287                     SENDMSG_REPLACE, 0, 0, null, PERSIST_DELAY);
5288         }
5289         if (change) {
5290             // Send sticky broadcast
5291             broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, ringerMode);
5292         }
5293     }
5294 
postUpdateRingerModeServiceInt()5295     /*package*/ void postUpdateRingerModeServiceInt() {
5296         sendMsg(mAudioHandler, MSG_UPDATE_RINGER_MODE, SENDMSG_QUEUE, 0, 0, null, 0);
5297     }
5298 
onUpdateRingerModeServiceInt()5299     private void onUpdateRingerModeServiceInt() {
5300         setRingerModeInt(getRingerModeInternal(), false);
5301     }
5302 
5303     /** @see AudioManager#shouldVibrate(int) */
shouldVibrate(int vibrateType)5304     public boolean shouldVibrate(int vibrateType) {
5305         if (!mHasVibrator) return false;
5306 
5307         switch (getVibrateSetting(vibrateType)) {
5308 
5309             case AudioManager.VIBRATE_SETTING_ON:
5310                 return getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT;
5311 
5312             case AudioManager.VIBRATE_SETTING_ONLY_SILENT:
5313                 return getRingerModeExternal() == AudioManager.RINGER_MODE_VIBRATE;
5314 
5315             case AudioManager.VIBRATE_SETTING_OFF:
5316                 // return false, even for incoming calls
5317                 return false;
5318 
5319             default:
5320                 return false;
5321         }
5322     }
5323 
5324     /** @see AudioManager#getVibrateSetting(int) */
getVibrateSetting(int vibrateType)5325     public int getVibrateSetting(int vibrateType) {
5326         if (!mHasVibrator) return AudioManager.VIBRATE_SETTING_OFF;
5327         return (mVibrateSetting >> (vibrateType * 2)) & 3;
5328     }
5329 
5330     /** @see AudioManager#setVibrateSetting(int, int) */
setVibrateSetting(int vibrateType, int vibrateSetting)5331     public void setVibrateSetting(int vibrateType, int vibrateSetting) {
5332 
5333         if (!mHasVibrator) return;
5334 
5335         mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, vibrateType,
5336                 vibrateSetting);
5337 
5338         // Broadcast change
5339         broadcastVibrateSetting(vibrateType);
5340 
5341     }
5342 
5343     private class SetModeDeathHandler implements IBinder.DeathRecipient {
5344         private final IBinder mCb; // To be notified of client's death
5345         private final int mPid;
5346         private final int mUid;
5347         private final boolean mIsPrivileged;
5348         private final String mPackage;
5349         private int mMode;
5350         private long mUpdateTime;
5351         private boolean mPlaybackActive = false;
5352         private boolean mRecordingActive = false;
5353 
SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged, String caller, int mode)5354         SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged,
5355                             String caller, int mode) {
5356             mMode = mode;
5357             mCb = cb;
5358             mPid = pid;
5359             mUid = uid;
5360             mPackage = caller;
5361             mIsPrivileged = isPrivileged;
5362             mUpdateTime = java.lang.System.currentTimeMillis();
5363         }
5364 
binderDied()5365         public void binderDied() {
5366             synchronized (mDeviceBroker.mSetModeLock) {
5367                 Log.w(TAG, "SetModeDeathHandler client died");
5368                 int index = mSetModeDeathHandlers.indexOf(this);
5369                 if (index < 0) {
5370                     Log.w(TAG, "unregistered SetModeDeathHandler client died");
5371                 } else {
5372                     SetModeDeathHandler h = mSetModeDeathHandlers.get(index);
5373                     mSetModeDeathHandlers.remove(index);
5374                     sendMsg(mAudioHandler,
5375                             MSG_UPDATE_AUDIO_MODE,
5376                             SENDMSG_QUEUE,
5377                             AudioSystem.MODE_CURRENT,
5378                             android.os.Process.myPid(),
5379                             mContext.getPackageName(),
5380                             0);
5381                 }
5382             }
5383         }
5384 
getPid()5385         public int getPid() {
5386             return mPid;
5387         }
5388 
setMode(int mode)5389         public void setMode(int mode) {
5390             mMode = mode;
5391             mUpdateTime = java.lang.System.currentTimeMillis();
5392         }
5393 
getMode()5394         public int getMode() {
5395             return mMode;
5396         }
5397 
getBinder()5398         public IBinder getBinder() {
5399             return mCb;
5400         }
5401 
getUid()5402         public int getUid() {
5403             return mUid;
5404         }
5405 
getPackage()5406         public String getPackage() {
5407             return mPackage;
5408         }
5409 
isPrivileged()5410         public boolean isPrivileged() {
5411             return mIsPrivileged;
5412         }
5413 
getUpdateTime()5414         public long getUpdateTime() {
5415             return mUpdateTime;
5416         }
5417 
setPlaybackActive(boolean active)5418         public void setPlaybackActive(boolean active) {
5419             mPlaybackActive = active;
5420         }
5421 
setRecordingActive(boolean active)5422         public void setRecordingActive(boolean active) {
5423             mRecordingActive = active;
5424         }
5425 
5426         /**
5427          * An app is considered active if:
5428          * - It is privileged (has MODIFY_PHONE_STATE permission)
5429          *  or
5430          * - It requests mode MODE_IN_COMMUNICATION, and it is either playing
5431          * or recording for VOICE_COMMUNICATION.
5432          *   or
5433          * - It requests a mode different from MODE_IN_COMMUNICATION or MODE_NORMAL
5434          * Note: only privileged apps can request MODE_IN_CALL, MODE_CALL_REDIRECT
5435          * or MODE_COMMUNICATION_REDIRECT.
5436          */
isActive()5437         public boolean isActive() {
5438             return mIsPrivileged
5439                     || ((mMode == AudioSystem.MODE_IN_COMMUNICATION)
5440                         && (mRecordingActive || mPlaybackActive))
5441                     || mMode == AudioSystem.MODE_RINGTONE
5442                     || mMode == AudioSystem.MODE_CALL_SCREENING;
5443         }
5444 
dump(PrintWriter pw, int index)5445         public void dump(PrintWriter pw, int index) {
5446             SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm:ss:SSS");
5447 
5448             if (index >= 0) {
5449                 pw.println("  Requester # " + (index + 1) + ":");
5450             }
5451             pw.println("  - Mode: " + AudioSystem.modeToString(mMode));
5452             pw.println("  - Binder: " + mCb);
5453             pw.println("  - Pid: " + mPid);
5454             pw.println("  - Uid: " + mUid);
5455             pw.println("  - Package: " + mPackage);
5456             pw.println("  - Privileged: " + mIsPrivileged);
5457             pw.println("  - Active: " + isActive());
5458             pw.println("    Playback active: " + mPlaybackActive);
5459             pw.println("    Recording active: " + mRecordingActive);
5460             pw.println("  - update time: " + format.format(new Date(mUpdateTime)));
5461         }
5462     }
5463 
5464     @GuardedBy("mDeviceBroker.mSetModeLock")
getAudioModeOwnerHandler()5465     private SetModeDeathHandler getAudioModeOwnerHandler() {
5466         // The Audio mode owner is:
5467         // 1) the most recent privileged app in the stack
5468         // 2) the most recent active app in the tack
5469         SetModeDeathHandler modeOwner = null;
5470         SetModeDeathHandler privilegedModeOwner = null;
5471         for (SetModeDeathHandler h : mSetModeDeathHandlers) {
5472             if (h.isActive()) {
5473                 // privileged apps are always active
5474                 if (h.isPrivileged()) {
5475                     if (privilegedModeOwner == null
5476                             || h.getUpdateTime() > privilegedModeOwner.getUpdateTime()) {
5477                         privilegedModeOwner = h;
5478                     }
5479                 } else {
5480                     if (modeOwner == null
5481                             || h.getUpdateTime() > modeOwner.getUpdateTime()) {
5482                         modeOwner = h;
5483                     }
5484                 }
5485             }
5486         }
5487         return privilegedModeOwner != null ? privilegedModeOwner :  modeOwner;
5488     }
5489 
5490     /**
5491      * Return information on the current audio mode owner
5492      * @return 0 if nobody owns the mode
5493      */
5494     @GuardedBy("mDeviceBroker.mSetModeLock")
getAudioModeOwner()5495     /*package*/ AudioDeviceBroker.AudioModeInfo getAudioModeOwner() {
5496         SetModeDeathHandler hdlr = getAudioModeOwnerHandler();
5497         if (hdlr != null) {
5498             return new AudioDeviceBroker.AudioModeInfo(
5499                     hdlr.getMode(), hdlr.getPid(), hdlr.getUid());
5500         }
5501         return new AudioDeviceBroker.AudioModeInfo(AudioSystem.MODE_NORMAL, 0 , 0);
5502     }
5503 
5504     /**
5505      * Return the uid of the current audio mode owner
5506      * @return 0 if nobody owns the mode
5507      */
5508     @GuardedBy("mDeviceBroker.mSetModeLock")
getModeOwnerUid()5509     /*package*/ int getModeOwnerUid() {
5510         SetModeDeathHandler hdlr = getAudioModeOwnerHandler();
5511         if (hdlr != null) {
5512             return hdlr.getUid();
5513         }
5514         return 0;
5515     }
5516 
5517     /** @see AudioManager#setMode(int) */
setMode(int mode, IBinder cb, String callingPackage)5518     public void setMode(int mode, IBinder cb, String callingPackage) {
5519         int pid = Binder.getCallingPid();
5520         int uid = Binder.getCallingUid();
5521         if (DEBUG_MODE) {
5522             Log.v(TAG, "setMode(mode=" + mode + ", pid=" + pid
5523                     + ", uid=" + uid + ", caller=" + callingPackage + ")");
5524         }
5525         if (!checkAudioSettingsPermission("setMode()")) {
5526             return;
5527         }
5528         if (cb == null) {
5529             Log.e(TAG, "setMode() called with null binder");
5530             return;
5531         }
5532         if (mode < AudioSystem.MODE_CURRENT || mode >= AudioSystem.NUM_MODES) {
5533             Log.w(TAG, "setMode() invalid mode: " + mode);
5534             return;
5535         }
5536 
5537         if (mode == AudioSystem.MODE_CURRENT) {
5538             mode = getMode();
5539         }
5540 
5541         if (mode == AudioSystem.MODE_CALL_SCREENING && !mIsCallScreeningModeSupported) {
5542             Log.w(TAG, "setMode(MODE_CALL_SCREENING) not permitted "
5543                     + "when call screening is not supported");
5544             return;
5545         }
5546 
5547         final boolean hasModifyPhoneStatePermission = mContext.checkCallingOrSelfPermission(
5548                 android.Manifest.permission.MODIFY_PHONE_STATE)
5549                 == PackageManager.PERMISSION_GRANTED;
5550         if ((mode == AudioSystem.MODE_IN_CALL
5551                 || mode == AudioSystem.MODE_CALL_REDIRECT
5552                 || mode == AudioSystem.MODE_COMMUNICATION_REDIRECT)
5553                 && !hasModifyPhoneStatePermission) {
5554             Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setMode("
5555                     + AudioSystem.modeToString(mode) + ") from pid=" + pid
5556                     + ", uid=" + Binder.getCallingUid());
5557             return;
5558         }
5559 
5560         SetModeDeathHandler currentModeHandler = null;
5561         synchronized (mDeviceBroker.mSetModeLock) {
5562             for (SetModeDeathHandler h : mSetModeDeathHandlers) {
5563                 if (h.getPid() == pid) {
5564                     currentModeHandler = h;
5565                     break;
5566                 }
5567             }
5568 
5569             if (mode == AudioSystem.MODE_NORMAL) {
5570                 if (currentModeHandler != null) {
5571                     if (!currentModeHandler.isPrivileged()
5572                             && currentModeHandler.getMode() == AudioSystem.MODE_IN_COMMUNICATION) {
5573                         mAudioHandler.removeEqualMessages(
5574                                 MSG_CHECK_MODE_FOR_UID, currentModeHandler);
5575                     }
5576                     mSetModeDeathHandlers.remove(currentModeHandler);
5577                     if (DEBUG_MODE) {
5578                         Log.v(TAG, "setMode(" + mode + ") removing hldr for pid: " + pid);
5579                     }
5580                     try {
5581                         currentModeHandler.getBinder().unlinkToDeath(currentModeHandler, 0);
5582                     } catch (NoSuchElementException e) {
5583                         Log.w(TAG, "setMode link does not exist ...");
5584                     }
5585                 }
5586             } else {
5587                 if (currentModeHandler != null) {
5588                     currentModeHandler.setMode(mode);
5589                     if (DEBUG_MODE) {
5590                         Log.v(TAG, "setMode(" + mode + ") updating hldr for pid: " + pid);
5591                     }
5592                 } else {
5593                     currentModeHandler = new SetModeDeathHandler(cb, pid, uid,
5594                             hasModifyPhoneStatePermission, callingPackage, mode);
5595                     // Register for client death notification
5596                     try {
5597                         cb.linkToDeath(currentModeHandler, 0);
5598                     } catch (RemoteException e) {
5599                         // Client has died!
5600                         Log.w(TAG, "setMode() could not link to " + cb + " binder death");
5601                         return;
5602                     }
5603                     mSetModeDeathHandlers.add(currentModeHandler);
5604                     if (DEBUG_MODE) {
5605                         Log.v(TAG, "setMode(" + mode + ") adding handler for pid=" + pid);
5606                     }
5607                 }
5608                 if (mode == AudioSystem.MODE_IN_COMMUNICATION) {
5609                     // Force active state when entering/updating the stack to avoid glitches when
5610                     // an app starts playing/recording after settng the audio mode,
5611                     // and send a reminder to check activity after a grace period.
5612                     if (!currentModeHandler.isPrivileged()) {
5613                         currentModeHandler.setPlaybackActive(true);
5614                         currentModeHandler.setRecordingActive(true);
5615                         sendMsg(mAudioHandler,
5616                                 MSG_CHECK_MODE_FOR_UID,
5617                                 SENDMSG_QUEUE,
5618                                 0,
5619                                 0,
5620                                 currentModeHandler,
5621                                 CHECK_MODE_FOR_UID_PERIOD_MS);
5622                     }
5623                 }
5624             }
5625 
5626             sendMsg(mAudioHandler,
5627                     MSG_UPDATE_AUDIO_MODE,
5628                     SENDMSG_REPLACE,
5629                     mode,
5630                     pid,
5631                     callingPackage,
5632                     0);
5633         }
5634     }
5635 
5636     @GuardedBy("mDeviceBroker.mSetModeLock")
onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage, boolean force)5637     void onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage,
5638                            boolean force) {
5639         if (requestedMode == AudioSystem.MODE_CURRENT) {
5640             requestedMode = getMode();
5641         }
5642         int mode = AudioSystem.MODE_NORMAL;
5643         int uid = 0;
5644         int pid = 0;
5645         SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler();
5646         if (currentModeHandler != null) {
5647             mode = currentModeHandler.getMode();
5648             uid = currentModeHandler.getUid();
5649             pid = currentModeHandler.getPid();
5650         }
5651         if (DEBUG_MODE) {
5652             Log.v(TAG, "onUpdateAudioMode() new mode: " + mode + ", current mode: "
5653                     + mMode.get() + " requested mode: " + requestedMode);
5654         }
5655         if (mode != mMode.get() || force) {
5656             final long identity = Binder.clearCallingIdentity();
5657             int status = mAudioSystem.setPhoneState(mode, uid);
5658             Binder.restoreCallingIdentity(identity);
5659             if (status == AudioSystem.AUDIO_STATUS_OK) {
5660                 if (DEBUG_MODE) {
5661                     Log.v(TAG, "onUpdateAudioMode: mode successfully set to " + mode);
5662                 }
5663                 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_MODE, SENDMSG_REPLACE, mode, 0,
5664                         /*obj*/ null, /*delay*/ 0);
5665                 int previousMode = mMode.getAndSet(mode);
5666                 // Note: newModeOwnerPid is always 0 when actualMode is MODE_NORMAL
5667                 mModeLogger.log(new PhoneStateEvent(requesterPackage, requesterPid,
5668                         requestedMode, pid, mode));
5669 
5670                 int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
5671                 int device = getDeviceForStream(streamType);
5672                 int index = mStreamStates[mStreamVolumeAlias[streamType]].getIndex(device);
5673                 setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, true,
5674                         requesterPackage, true /*hasModifyAudioSettings*/);
5675 
5676                 updateStreamVolumeAlias(true /*updateVolumes*/, requesterPackage);
5677 
5678                 // change of mode may require volume to be re-applied on some devices
5679                 updateAbsVolumeMultiModeDevices(previousMode, mode);
5680 
5681                 setLeAudioVolumeOnModeUpdate(mode, device);
5682 
5683                 // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all SCO
5684                 // connections not started by the application changing the mode when pid changes
5685                 mDeviceBroker.postSetModeOwner(mode, pid, uid);
5686             } else {
5687                 Log.w(TAG, "onUpdateAudioMode: failed to set audio mode to: " + mode);
5688             }
5689         }
5690     }
5691 
5692     /** @see AudioManager#getMode() */
getMode()5693     public int getMode() {
5694         synchronized (mDeviceBroker.mSetModeLock) {
5695             SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler();
5696             if (currentModeHandler != null) {
5697                 return currentModeHandler.getMode();
5698             }
5699             return AudioSystem.MODE_NORMAL;
5700         }
5701     }
5702 
5703     /** cached value read from audiopolicy manager after initialization. */
5704     private boolean mIsCallScreeningModeSupported = false;
5705 
5706     /** @see AudioManager#isCallScreeningModeSupported() */
isCallScreeningModeSupported()5707     public boolean isCallScreeningModeSupported() {
5708         return mIsCallScreeningModeSupported;
5709     }
5710 
dispatchMode(int mode)5711     protected void dispatchMode(int mode) {
5712         final int nbDispatchers = mModeDispatchers.beginBroadcast();
5713         for (int i = 0; i < nbDispatchers; i++) {
5714             try {
5715                 mModeDispatchers.getBroadcastItem(i).dispatchAudioModeChanged(mode);
5716             } catch (RemoteException e) {
5717             }
5718         }
5719         mModeDispatchers.finishBroadcast();
5720     }
5721 
5722     final RemoteCallbackList<IAudioModeDispatcher> mModeDispatchers =
5723             new RemoteCallbackList<IAudioModeDispatcher>();
5724 
5725     /**
5726      * @see {@link AudioManager#addOnModeChangedListener(Executor, AudioManager.OnModeChangedListener)}
5727      * @param dispatcher
5728      */
registerModeDispatcher( @onNull IAudioModeDispatcher dispatcher)5729     public void registerModeDispatcher(
5730             @NonNull IAudioModeDispatcher dispatcher) {
5731         mModeDispatchers.register(dispatcher);
5732     }
5733 
5734     /**
5735      * @see {@link AudioManager#removeOnModeChangedListener(AudioManager.OnModeChangedListener)}
5736      * @param dispatcher
5737      */
unregisterModeDispatcher( @onNull IAudioModeDispatcher dispatcher)5738     public void unregisterModeDispatcher(
5739             @NonNull IAudioModeDispatcher dispatcher) {
5740         mModeDispatchers.unregister(dispatcher);
5741     }
5742 
5743     /** @see AudioManager#isPstnCallAudioInterceptable() */
isPstnCallAudioInterceptable()5744     public boolean isPstnCallAudioInterceptable() {
5745         enforceCallAudioInterceptionPermission();
5746 
5747         boolean uplinkDeviceFound = false;
5748         boolean downlinkDeviceFound = false;
5749         AudioDeviceInfo[] devices = AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_ALL);
5750         for (AudioDeviceInfo device : devices) {
5751             if (device.getInternalType() == AudioSystem.DEVICE_OUT_TELEPHONY_TX) {
5752                 uplinkDeviceFound = true;
5753             } else if (device.getInternalType() == AudioSystem.DEVICE_IN_TELEPHONY_RX) {
5754                 downlinkDeviceFound = true;
5755             }
5756             if (uplinkDeviceFound && downlinkDeviceFound) {
5757                 return true;
5758             }
5759         }
5760         return false;
5761     }
5762 
5763     /** @see AudioManager#setRttEnabled() */
5764     @Override
setRttEnabled(boolean rttEnabled)5765     public void setRttEnabled(boolean rttEnabled) {
5766         if (mContext.checkCallingOrSelfPermission(
5767                 android.Manifest.permission.MODIFY_PHONE_STATE)
5768                 != PackageManager.PERMISSION_GRANTED) {
5769             Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setRttEnabled from pid="
5770                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
5771             return;
5772         }
5773         synchronized (mSettingsLock) {
5774             mRttEnabled = rttEnabled;
5775             final long identity = Binder.clearCallingIdentity();
5776             try {
5777                 AudioSystem.setRttEnabled(rttEnabled);
5778             } finally {
5779                 Binder.restoreCallingIdentity(identity);
5780             }
5781         }
5782     }
5783 
5784     /** @see AudioManager#adjustSuggestedStreamVolumeForUid(int, int, int, String, int, int, int) */
5785     @Override
adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)5786     public void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags,
5787             @NonNull String packageName, int uid, int pid, UserHandle userHandle,
5788             int targetSdkVersion) {
5789         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
5790             throw new SecurityException("Should only be called from system process");
5791         }
5792 
5793         // direction and stream type swap here because the public
5794         // adjustSuggested has a different order than the other methods.
5795         adjustSuggestedStreamVolume(direction, streamType, flags, packageName, packageName,
5796                 uid, pid, hasAudioSettingsPermission(uid, pid),
5797                 AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
5798     }
5799 
5800     /** @see AudioManager#adjustStreamVolumeForUid(int, int, int, String, int, int, int) */
5801     @Override
adjustStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)5802     public void adjustStreamVolumeForUid(int streamType, int direction, int flags,
5803             @NonNull String packageName, int uid, int pid, UserHandle userHandle,
5804             int targetSdkVersion) {
5805         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
5806             throw new SecurityException("Should only be called from system process");
5807         }
5808 
5809         if (direction != AudioManager.ADJUST_SAME) {
5810             sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_VOL_UID, streamType,
5811                     direction/*val1*/, flags/*val2*/,
5812                     new StringBuilder(packageName).append(" uid:").append(uid)
5813                     .toString()));
5814         }
5815 
5816         adjustStreamVolume(streamType, direction, flags, packageName, packageName, uid, pid,
5817                 null, hasAudioSettingsPermission(uid, pid),
5818                 AudioDeviceVolumeManager.ADJUST_MODE_NORMAL);
5819     }
5820 
5821     /** @see AudioManager#setStreamVolumeForUid(int, int, int, String, int, int, int) */
5822     @Override
setStreamVolumeForUid(int streamType, int index, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)5823     public void setStreamVolumeForUid(int streamType, int index, int flags,
5824             @NonNull String packageName, int uid, int pid, UserHandle userHandle,
5825             int targetSdkVersion) {
5826         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
5827             throw new SecurityException("Should only be called from system process");
5828         }
5829 
5830         setStreamVolume(streamType, index, flags, /*device*/ null,
5831                 packageName, packageName, null, uid,
5832                 hasAudioSettingsPermission(uid, pid));
5833     }
5834 
5835     //==========================================================================================
5836     // Sound Effects
5837     //==========================================================================================
5838     private static final class LoadSoundEffectReply
5839             implements SoundEffectsHelper.OnEffectsLoadCompleteHandler {
5840         private static final int SOUND_EFFECTS_LOADING = 1;
5841         private static final int SOUND_EFFECTS_LOADED = 0;
5842         private static final int SOUND_EFFECTS_ERROR = -1;
5843         private static final int SOUND_EFFECTS_LOAD_TIMEOUT_MS = 5000;
5844 
5845         private int mStatus = SOUND_EFFECTS_LOADING;
5846 
5847         @Override
run(boolean success)5848         public synchronized void run(boolean success) {
5849             mStatus = success ? SOUND_EFFECTS_LOADED : SOUND_EFFECTS_ERROR;
5850             notify();
5851         }
5852 
waitForLoaded(int attempts)5853         public synchronized boolean waitForLoaded(int attempts) {
5854             while ((mStatus == SOUND_EFFECTS_LOADING) && (attempts-- > 0)) {
5855                 try {
5856                     wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS);
5857                 } catch (InterruptedException e) {
5858                     Log.w(TAG, "Interrupted while waiting sound pool loaded.");
5859                 }
5860             }
5861             return mStatus == SOUND_EFFECTS_LOADED;
5862         }
5863     }
5864 
5865     /** @see AudioManager#playSoundEffect(int, int) */
playSoundEffect(int effectType, int userId)5866     public void playSoundEffect(int effectType, int userId) {
5867         if (querySoundEffectsEnabled(userId)) {
5868             playSoundEffectVolume(effectType, -1.0f);
5869         }
5870     }
5871 
5872     /**
5873      * Settings has an in memory cache, so this is fast.
5874      */
querySoundEffectsEnabled(int user)5875     private boolean querySoundEffectsEnabled(int user) {
5876         return mSettings.getSystemIntForUser(getContentResolver(),
5877                 Settings.System.SOUND_EFFECTS_ENABLED, 0, user) != 0;
5878     }
5879 
5880     /** @see AudioManager#playSoundEffect(int, float) */
playSoundEffectVolume(int effectType, float volume)5881     public void playSoundEffectVolume(int effectType, float volume) {
5882         // do not try to play the sound effect if the system stream is muted
5883         if (isStreamMute(STREAM_SYSTEM)) {
5884             return;
5885         }
5886 
5887         if (effectType >= AudioManager.NUM_SOUND_EFFECTS || effectType < 0) {
5888             Log.w(TAG, "AudioService effectType value " + effectType + " out of range");
5889             return;
5890         }
5891 
5892         sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SENDMSG_QUEUE,
5893                 effectType, (int) (volume * 1000), null, 0);
5894     }
5895 
5896     /**
5897      * Loads samples into the soundpool.
5898      * This method must be called at first when sound effects are enabled
5899      */
loadSoundEffects()5900     public boolean loadSoundEffects() {
5901         LoadSoundEffectReply reply = new LoadSoundEffectReply();
5902         sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, reply, 0);
5903         return reply.waitForLoaded(3 /*attempts*/);
5904     }
5905 
5906     /**
5907      * Schedule loading samples into the soundpool.
5908      * This method can be overridden to schedule loading at a later time.
5909      */
scheduleLoadSoundEffects()5910     protected void scheduleLoadSoundEffects() {
5911         sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0);
5912     }
5913 
5914     /**
5915      *  Unloads samples from the sound pool.
5916      *  This method can be called to free some memory when
5917      *  sound effects are disabled.
5918      */
unloadSoundEffects()5919     public void unloadSoundEffects() {
5920         sendMsg(mAudioHandler, MSG_UNLOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0);
5921     }
5922 
5923     /** @see AudioManager#reloadAudioSettings() */
reloadAudioSettings()5924     public void reloadAudioSettings() {
5925         readAudioSettings(false /*userSwitch*/);
5926     }
5927 
readAudioSettings(boolean userSwitch)5928     private void readAudioSettings(boolean userSwitch) {
5929         // restore ringer mode, ringer mode affected streams, mute affected streams and vibrate settings
5930         readPersistedSettings();
5931         readUserRestrictions();
5932 
5933         // restore volume settings
5934         int numStreamTypes = AudioSystem.getNumStreamTypes();
5935         for (int streamType = 0; streamType < numStreamTypes; streamType++) {
5936             VolumeStreamState streamState = mStreamStates[streamType];
5937 
5938             if (userSwitch && mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) {
5939                 continue;
5940             }
5941 
5942             streamState.readSettings();
5943             synchronized (VolumeStreamState.class) {
5944                 // unmute stream that was muted but is not affect by mute anymore
5945                 if (streamState.mIsMuted && ((!isStreamAffectedByMute(streamType) &&
5946                         !isStreamMutedByRingerOrZenMode(streamType)) || mUseFixedVolume)) {
5947                     streamState.mIsMuted = false;
5948                 }
5949             }
5950         }
5951 
5952         readVolumeGroupsSettings(userSwitch);
5953 
5954         // apply new ringer mode before checking volume for alias streams so that streams
5955         // muted by ringer mode have the correct volume
5956         setRingerModeInt(getRingerModeInternal(), false);
5957 
5958         checkAllFixedVolumeDevices();
5959         checkAllAliasStreamVolumes();
5960         checkMuteAffectedStreams();
5961 
5962         synchronized (mSafeMediaVolumeStateLock) {
5963             mMusicActiveMs = MathUtils.constrain(mSettings.getSecureIntForUser(mContentResolver,
5964                     Settings.Secure.UNSAFE_VOLUME_MUSIC_ACTIVE_MS, 0, UserHandle.USER_CURRENT),
5965                     0, UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX);
5966             if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) {
5967                 enforceSafeMediaVolume(TAG);
5968             }
5969         }
5970 
5971         if (DEBUG_VOL) {
5972             Log.d(TAG, "Restoring device volume behavior");
5973         }
5974         restoreDeviceVolumeBehavior();
5975     }
5976 
5977     /** @see AudioManager#getAvailableCommunicationDevices(int) */
getAvailableCommunicationDeviceIds()5978     public int[] getAvailableCommunicationDeviceIds() {
5979         List<AudioDeviceInfo> commDevices = AudioDeviceBroker.getAvailableCommunicationDevices();
5980         return commDevices.stream().mapToInt(AudioDeviceInfo::getId).toArray();
5981     }
5982 
5983     /**
5984      * @see AudioManager#setCommunicationDevice(int)
5985      * @see AudioManager#clearCommunicationDevice()
5986      */
setCommunicationDevice(IBinder cb, int portId)5987     public boolean setCommunicationDevice(IBinder cb, int portId) {
5988         final int uid = Binder.getCallingUid();
5989         final int pid = Binder.getCallingPid();
5990 
5991         AudioDeviceInfo device = null;
5992         if (portId != 0) {
5993             device = AudioManager.getDeviceForPortId(portId, AudioManager.GET_DEVICES_OUTPUTS);
5994             if (device == null) {
5995                 Log.w(TAG, "setCommunicationDevice: invalid portID " + portId);
5996                 return false;
5997             }
5998             if (!AudioDeviceBroker.isValidCommunicationDevice(device)) {
5999                 throw new IllegalArgumentException("invalid device type " + device.getType());
6000             }
6001         }
6002         final String eventSource = new StringBuilder()
6003                 .append(device == null ? "clearCommunicationDevice(" : "setCommunicationDevice(")
6004                 .append(") from u/pid:").append(uid).append("/")
6005                 .append(pid).toString();
6006 
6007         int deviceType = AudioSystem.DEVICE_OUT_DEFAULT;
6008         String deviceAddress = null;
6009         if (device != null) {
6010             deviceType = device.getPort().type();
6011             deviceAddress = device.getAddress();
6012         } else {
6013             AudioDeviceInfo curDevice = mDeviceBroker.getCommunicationDevice();
6014             if (curDevice != null) {
6015                 deviceType = curDevice.getPort().type();
6016                 deviceAddress = curDevice.getAddress();
6017             }
6018         }
6019         // do not log metrics if clearing communication device while no communication device
6020         // was selected
6021         if (deviceType != AudioSystem.DEVICE_OUT_DEFAULT) {
6022             new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
6023                     + MediaMetrics.SEPARATOR + "setCommunicationDevice")
6024                     .set(MediaMetrics.Property.DEVICE,
6025                             AudioSystem.getDeviceName(deviceType))
6026                     .set(MediaMetrics.Property.ADDRESS, deviceAddress)
6027                     .set(MediaMetrics.Property.STATE, device != null
6028                             ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED)
6029                     .record();
6030         }
6031 
6032         final long ident = Binder.clearCallingIdentity();
6033         boolean status =
6034                 mDeviceBroker.setCommunicationDevice(cb, pid, device, eventSource);
6035         Binder.restoreCallingIdentity(ident);
6036         return status;
6037     }
6038 
6039     /** @see AudioManager#getCommunicationDevice() */
getCommunicationDevice()6040     public int getCommunicationDevice() {
6041         int deviceId = 0;
6042         final long ident = Binder.clearCallingIdentity();
6043         try {
6044             AudioDeviceInfo device = mDeviceBroker.getCommunicationDevice();
6045             deviceId = device != null ? device.getId() : 0;
6046         } finally {
6047             Binder.restoreCallingIdentity(ident);
6048         }
6049         return deviceId;
6050     }
6051 
6052     /** @see AudioManager#addOnCommunicationDeviceChangedListener(
6053      *               Executor, AudioManager.OnCommunicationDeviceChangedListener)
6054      */
registerCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)6055     public void registerCommunicationDeviceDispatcher(
6056             @Nullable ICommunicationDeviceDispatcher dispatcher) {
6057         if (dispatcher == null) {
6058             return;
6059         }
6060         mDeviceBroker.registerCommunicationDeviceDispatcher(dispatcher);
6061     }
6062 
6063     /** @see AudioManager#removeOnCommunicationDeviceChangedListener(
6064      *               AudioManager.OnCommunicationDeviceChangedListener)
6065      */
unregisterCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)6066     public void unregisterCommunicationDeviceDispatcher(
6067             @Nullable ICommunicationDeviceDispatcher dispatcher) {
6068         if (dispatcher == null) {
6069             return;
6070         }
6071         mDeviceBroker.unregisterCommunicationDeviceDispatcher(dispatcher);
6072     }
6073 
6074     /** @see AudioManager#setSpeakerphoneOn(boolean) */
setSpeakerphoneOn(IBinder cb, boolean on)6075     public void setSpeakerphoneOn(IBinder cb, boolean on) {
6076         if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) {
6077             return;
6078         }
6079 
6080         // for logging only
6081         final int uid = Binder.getCallingUid();
6082         final int pid = Binder.getCallingPid();
6083 
6084         final String eventSource = new StringBuilder("setSpeakerphoneOn(").append(on)
6085                 .append(") from u/pid:").append(uid).append("/")
6086                 .append(pid).toString();
6087         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
6088                 + MediaMetrics.SEPARATOR + "setSpeakerphoneOn")
6089                 .setUid(uid)
6090                 .setPid(pid)
6091                 .set(MediaMetrics.Property.STATE, on
6092                         ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
6093                 .record();
6094         final long ident = Binder.clearCallingIdentity();
6095         mDeviceBroker.setSpeakerphoneOn(cb, pid, on, eventSource);
6096         Binder.restoreCallingIdentity(ident);
6097     }
6098 
6099     /** @see AudioManager#isSpeakerphoneOn() */
isSpeakerphoneOn()6100     public boolean isSpeakerphoneOn() {
6101         return mDeviceBroker.isSpeakerphoneOn();
6102     }
6103 
6104 
6105     /** BT SCO audio state seen by apps using the deprecated API setBluetoothScoOn().
6106      * @see isBluetoothScoOn() */
6107     private boolean mBtScoOnByApp;
6108 
6109     /** @see AudioManager#setBluetoothScoOn(boolean) */
setBluetoothScoOn(boolean on)6110     public void setBluetoothScoOn(boolean on) {
6111         if (!checkAudioSettingsPermission("setBluetoothScoOn()")) {
6112             return;
6113         }
6114 
6115         // Only enable calls from system components
6116         if (UserHandle.getCallingAppId() >= FIRST_APPLICATION_UID) {
6117             mBtScoOnByApp = on;
6118             return;
6119         }
6120 
6121         // for logging only
6122         final int uid = Binder.getCallingUid();
6123         final int pid = Binder.getCallingPid();
6124         final String eventSource = new StringBuilder("setBluetoothScoOn(").append(on)
6125                 .append(") from u/pid:").append(uid).append("/").append(pid).toString();
6126 
6127         //bt sco
6128         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
6129                 + MediaMetrics.SEPARATOR + "setBluetoothScoOn")
6130                 .setUid(uid)
6131                 .setPid(pid)
6132                 .set(MediaMetrics.Property.STATE, on
6133                         ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
6134                 .record();
6135 
6136         mDeviceBroker.setBluetoothScoOn(on, eventSource);
6137     }
6138 
6139     /** @see AudioManager#isBluetoothScoOn()
6140      * Note that it doesn't report internal state, but state seen by apps (which may have
6141      * called setBluetoothScoOn() */
isBluetoothScoOn()6142     public boolean isBluetoothScoOn() {
6143         return mBtScoOnByApp || mDeviceBroker.isBluetoothScoOn();
6144     }
6145 
6146     // TODO investigate internal users due to deprecation of SDK API
6147     /** @see AudioManager#setBluetoothA2dpOn(boolean) */
setBluetoothA2dpOn(boolean on)6148     public void setBluetoothA2dpOn(boolean on) {
6149         if (!checkAudioSettingsPermission("setBluetoothA2dpOn()")) {
6150             return;
6151         }
6152 
6153         // for logging only
6154         final int uid = Binder.getCallingUid();
6155         final int pid = Binder.getCallingPid();
6156         final String eventSource = new StringBuilder("setBluetoothA2dpOn(").append(on)
6157                 .append(") from u/pid:").append(uid).append("/")
6158                 .append(pid).toString();
6159 
6160         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
6161                 + MediaMetrics.SEPARATOR + "setBluetoothA2dpOn")
6162                 .setUid(uid)
6163                 .setPid(pid)
6164                 .set(MediaMetrics.Property.STATE, on
6165                         ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
6166                 .record();
6167 
6168         mDeviceBroker.setBluetoothA2dpOn_Async(on, eventSource);
6169     }
6170 
6171     /** @see AudioManager#isBluetoothA2dpOn() */
isBluetoothA2dpOn()6172     public boolean isBluetoothA2dpOn() {
6173         return mDeviceBroker.isBluetoothA2dpOn();
6174     }
6175 
6176     /** @see AudioManager#startBluetoothSco() */
startBluetoothSco(IBinder cb, int targetSdkVersion)6177     public void startBluetoothSco(IBinder cb, int targetSdkVersion) {
6178         if (!checkAudioSettingsPermission("startBluetoothSco()")) {
6179             return;
6180         }
6181 
6182         final int uid = Binder.getCallingUid();
6183         final int pid = Binder.getCallingPid();
6184         final int scoAudioMode =
6185                 (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ?
6186                         BtHelper.SCO_MODE_VIRTUAL_CALL : BtHelper.SCO_MODE_UNDEFINED;
6187         final String eventSource = new StringBuilder("startBluetoothSco()")
6188                 .append(") from u/pid:").append(uid).append("/")
6189                 .append(pid).toString();
6190 
6191         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
6192                 .setUid(uid)
6193                 .setPid(pid)
6194                 .set(MediaMetrics.Property.EVENT, "startBluetoothSco")
6195                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
6196                         BtHelper.scoAudioModeToString(scoAudioMode))
6197                 .record();
6198         startBluetoothScoInt(cb, pid, scoAudioMode, eventSource);
6199 
6200     }
6201 
6202     /** @see AudioManager#startBluetoothScoVirtualCall() */
startBluetoothScoVirtualCall(IBinder cb)6203     public void startBluetoothScoVirtualCall(IBinder cb) {
6204         if (!checkAudioSettingsPermission("startBluetoothScoVirtualCall()")) {
6205             return;
6206         }
6207 
6208         final int uid = Binder.getCallingUid();
6209         final int pid = Binder.getCallingPid();
6210         final String eventSource = new StringBuilder("startBluetoothScoVirtualCall()")
6211                 .append(") from u/pid:").append(uid).append("/")
6212                 .append(pid).toString();
6213 
6214         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
6215                 .setUid(uid)
6216                 .setPid(pid)
6217                 .set(MediaMetrics.Property.EVENT, "startBluetoothScoVirtualCall")
6218                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
6219                         BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_VIRTUAL_CALL))
6220                 .record();
6221         startBluetoothScoInt(cb, pid, BtHelper.SCO_MODE_VIRTUAL_CALL, eventSource);
6222     }
6223 
startBluetoothScoInt(IBinder cb, int pid, int scoAudioMode, @NonNull String eventSource)6224     void startBluetoothScoInt(IBinder cb, int pid, int scoAudioMode, @NonNull String eventSource) {
6225         MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
6226                 .set(MediaMetrics.Property.EVENT, "startBluetoothScoInt")
6227                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
6228                         BtHelper.scoAudioModeToString(scoAudioMode));
6229 
6230         if (!checkAudioSettingsPermission("startBluetoothSco()") ||
6231                 !mSystemReady) {
6232             mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission or systemReady").record();
6233             return;
6234         }
6235         final long ident = Binder.clearCallingIdentity();
6236         mDeviceBroker.startBluetoothScoForClient(cb, pid, scoAudioMode, eventSource);
6237         Binder.restoreCallingIdentity(ident);
6238         mmi.record();
6239     }
6240 
6241     /** @see AudioManager#stopBluetoothSco() */
stopBluetoothSco(IBinder cb)6242     public void stopBluetoothSco(IBinder cb){
6243         if (!checkAudioSettingsPermission("stopBluetoothSco()") ||
6244                 !mSystemReady) {
6245             return;
6246         }
6247         final int uid = Binder.getCallingUid();
6248         final int pid = Binder.getCallingPid();
6249         final String eventSource =  new StringBuilder("stopBluetoothSco()")
6250                 .append(") from u/pid:").append(uid).append("/")
6251                 .append(pid).toString();
6252         final long ident = Binder.clearCallingIdentity();
6253         mDeviceBroker.stopBluetoothScoForClient(cb, pid, eventSource);
6254         Binder.restoreCallingIdentity(ident);
6255         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
6256                 .setUid(uid)
6257                 .setPid(pid)
6258                 .set(MediaMetrics.Property.EVENT, "stopBluetoothSco")
6259                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
6260                         BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_UNDEFINED))
6261                 .record();
6262     }
6263 
6264 
getContentResolver()6265     /*package*/ ContentResolver getContentResolver() {
6266         return mContentResolver;
6267     }
6268 
scheduleMusicActiveCheck()6269     private void scheduleMusicActiveCheck() {
6270         synchronized (mSafeMediaVolumeStateLock) {
6271             cancelMusicActiveCheck();
6272             mMusicActiveIntent = PendingIntent.getBroadcast(mContext,
6273                 REQUEST_CODE_CHECK_MUSIC_ACTIVE,
6274                 new Intent(ACTION_CHECK_MUSIC_ACTIVE),
6275                 PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
6276             mAlarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP,
6277                     SystemClock.elapsedRealtime()
6278                     + MUSIC_ACTIVE_POLL_PERIOD_MS, mMusicActiveIntent);
6279         }
6280     }
6281 
cancelMusicActiveCheck()6282     private void cancelMusicActiveCheck() {
6283         synchronized (mSafeMediaVolumeStateLock) {
6284             if (mMusicActiveIntent != null) {
6285                 mAlarmManager.cancel(mMusicActiveIntent);
6286                 mMusicActiveIntent = null;
6287             }
6288         }
6289     }
onCheckMusicActive(String caller)6290     private void onCheckMusicActive(String caller) {
6291         synchronized (mSafeMediaVolumeStateLock) {
6292             if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE) {
6293                 int device = getDeviceForStream(AudioSystem.STREAM_MUSIC);
6294                 if (mSafeMediaVolumeDevices.contains(device)
6295                         && mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)) {
6296                     scheduleMusicActiveCheck();
6297                     int index = mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(device);
6298                     if (index > safeMediaVolumeIndex(device)) {
6299                         // Approximate cumulative active music time
6300                         long curTimeMs = SystemClock.elapsedRealtime();
6301                         if (mLastMusicActiveTimeMs != 0) {
6302                             mMusicActiveMs += (int) (curTimeMs - mLastMusicActiveTimeMs);
6303                         }
6304                         mLastMusicActiveTimeMs = curTimeMs;
6305                         Log.i(TAG, "onCheckMusicActive() mMusicActiveMs: " + mMusicActiveMs);
6306                         if (mMusicActiveMs > UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX) {
6307                             setSafeMediaVolumeEnabled(true, caller);
6308                             mMusicActiveMs = 0;
6309                         }
6310                         saveMusicActiveMs();
6311                     }
6312                 } else {
6313                     cancelMusicActiveCheck();
6314                     mLastMusicActiveTimeMs = 0;
6315                 }
6316             }
6317         }
6318     }
6319 
saveMusicActiveMs()6320     private void saveMusicActiveMs() {
6321         mAudioHandler.obtainMessage(MSG_PERSIST_MUSIC_ACTIVE_MS, mMusicActiveMs, 0).sendToTarget();
6322     }
6323 
getSafeUsbMediaVolumeIndex()6324     private int getSafeUsbMediaVolumeIndex() {
6325         // determine UI volume index corresponding to the wanted safe gain in dBFS
6326         int min = MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC];
6327         int max = MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC];
6328 
6329         mSafeUsbMediaVolumeDbfs = mContext.getResources().getInteger(
6330                 com.android.internal.R.integer.config_safe_media_volume_usb_mB) / 100.0f;
6331 
6332         while (Math.abs(max - min) > 1) {
6333             int index = (max + min) / 2;
6334             float gainDB = AudioSystem.getStreamVolumeDB(
6335                     AudioSystem.STREAM_MUSIC, index, AudioSystem.DEVICE_OUT_USB_HEADSET);
6336             if (Float.isNaN(gainDB)) {
6337                 //keep last min in case of read error
6338                 break;
6339             } else if (gainDB == mSafeUsbMediaVolumeDbfs) {
6340                 min = index;
6341                 break;
6342             } else if (gainDB < mSafeUsbMediaVolumeDbfs) {
6343                 min = index;
6344             } else {
6345                 max = index;
6346             }
6347         }
6348         return min * 10;
6349     }
6350 
onConfigureSafeVolume(boolean force, String caller)6351     private void onConfigureSafeVolume(boolean force, String caller) {
6352         synchronized (mSafeMediaVolumeStateLock) {
6353             int mcc = mContext.getResources().getConfiguration().mcc;
6354             if ((mMcc != mcc) || ((mMcc == 0) && force)) {
6355                 mSafeMediaVolumeIndex = mContext.getResources().getInteger(
6356                         com.android.internal.R.integer.config_safe_media_volume_index) * 10;
6357 
6358                 mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex();
6359 
6360                 boolean safeMediaVolumeEnabled =
6361                         SystemProperties.getBoolean("audio.safemedia.force", false)
6362                         || mContext.getResources().getBoolean(
6363                                 com.android.internal.R.bool.config_safe_media_volume_enabled);
6364 
6365                 boolean safeMediaVolumeBypass =
6366                         SystemProperties.getBoolean("audio.safemedia.bypass", false);
6367 
6368                 // The persisted state is either "disabled" or "active": this is the state applied
6369                 // next time we boot and cannot be "inactive"
6370                 int persistedState;
6371                 if (safeMediaVolumeEnabled && !safeMediaVolumeBypass) {
6372                     persistedState = SAFE_MEDIA_VOLUME_ACTIVE;
6373                     // The state can already be "inactive" here if the user has forced it before
6374                     // the 30 seconds timeout for forced configuration. In this case we don't reset
6375                     // it to "active".
6376                     if (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_INACTIVE) {
6377                         if (mMusicActiveMs == 0) {
6378                             mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE;
6379                             enforceSafeMediaVolume(caller);
6380                         } else {
6381                             // We have existing playback time recorded, already confirmed.
6382                             mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_INACTIVE;
6383                             mLastMusicActiveTimeMs = 0;
6384                         }
6385                     }
6386                 } else {
6387                     persistedState = SAFE_MEDIA_VOLUME_DISABLED;
6388                     mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_DISABLED;
6389                 }
6390                 mMcc = mcc;
6391                 sendMsg(mAudioHandler,
6392                         MSG_PERSIST_SAFE_VOLUME_STATE,
6393                         SENDMSG_QUEUE,
6394                         persistedState,
6395                         0,
6396                         null,
6397                         0);
6398             }
6399         }
6400     }
6401 
6402     ///////////////////////////////////////////////////////////////////////////
6403     // Internal methods
6404     ///////////////////////////////////////////////////////////////////////////
6405 
6406     /**
6407      * Checks if the adjustment should change ringer mode instead of just
6408      * adjusting volume. If so, this will set the proper ringer mode and volume
6409      * indices on the stream states.
6410      */
checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted, String caller, int flags)6411     private int checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted,
6412             String caller, int flags) {
6413         int result = FLAG_ADJUST_VOLUME;
6414         if (isPlatformTelevision() || mIsSingleVolume) {
6415             return result;
6416         }
6417 
6418         int ringerMode = getRingerModeInternal();
6419 
6420         switch (ringerMode) {
6421         case RINGER_MODE_NORMAL:
6422             if (direction == AudioManager.ADJUST_LOWER) {
6423                 if (mHasVibrator) {
6424                     // "step" is the delta in internal index units corresponding to a
6425                     // change of 1 in UI index units.
6426                     // Because of rounding when rescaling from one stream index range to its alias
6427                     // index range, we cannot simply test oldIndex == step:
6428                     //   (step <= oldIndex < 2 * step) is equivalent to: (old UI index == 1)
6429                     if (step <= oldIndex && oldIndex < 2 * step) {
6430                         ringerMode = RINGER_MODE_VIBRATE;
6431                         mLoweredFromNormalToVibrateTime = SystemClock.uptimeMillis();
6432                     }
6433                 } else {
6434                     if (oldIndex == step && mVolumePolicy.volumeDownToEnterSilent) {
6435                         ringerMode = RINGER_MODE_SILENT;
6436                     }
6437                 }
6438             } else if (mIsSingleVolume && (direction == AudioManager.ADJUST_TOGGLE_MUTE
6439                     || direction == AudioManager.ADJUST_MUTE)) {
6440                 if (mHasVibrator) {
6441                     ringerMode = RINGER_MODE_VIBRATE;
6442                 } else {
6443                     ringerMode = RINGER_MODE_SILENT;
6444                 }
6445                 // Setting the ringer mode will toggle mute
6446                 result &= ~FLAG_ADJUST_VOLUME;
6447             }
6448             break;
6449         case RINGER_MODE_VIBRATE:
6450             if (!mHasVibrator) {
6451                 Log.e(TAG, "checkForRingerModeChange() current ringer mode is vibrate" +
6452                         "but no vibrator is present");
6453                 break;
6454             }
6455             if ((direction == AudioManager.ADJUST_LOWER)) {
6456                 // This is the case we were muted with the volume turned up
6457                 if (mIsSingleVolume && oldIndex >= 2 * step && isMuted) {
6458                     ringerMode = RINGER_MODE_NORMAL;
6459                 } else if (mPrevVolDirection != AudioManager.ADJUST_LOWER) {
6460                     if (mVolumePolicy.volumeDownToEnterSilent) {
6461                         final long diff = SystemClock.uptimeMillis()
6462                                 - mLoweredFromNormalToVibrateTime;
6463                         if (diff > mVolumePolicy.vibrateToSilentDebounce
6464                                 && mRingerModeDelegate.canVolumeDownEnterSilent()) {
6465                             ringerMode = RINGER_MODE_SILENT;
6466                         }
6467                     } else {
6468                         result |= AudioManager.FLAG_SHOW_VIBRATE_HINT;
6469                     }
6470                 }
6471             } else if (direction == AudioManager.ADJUST_RAISE
6472                     || direction == AudioManager.ADJUST_TOGGLE_MUTE
6473                     || direction == AudioManager.ADJUST_UNMUTE) {
6474                 ringerMode = RINGER_MODE_NORMAL;
6475             }
6476             result &= ~FLAG_ADJUST_VOLUME;
6477             break;
6478         case RINGER_MODE_SILENT:
6479             if (mIsSingleVolume && direction == AudioManager.ADJUST_LOWER && oldIndex >= 2 * step && isMuted) {
6480                 // This is the case we were muted with the volume turned up
6481                 ringerMode = RINGER_MODE_NORMAL;
6482             } else if (direction == AudioManager.ADJUST_RAISE
6483                     || direction == AudioManager.ADJUST_TOGGLE_MUTE
6484                     || direction == AudioManager.ADJUST_UNMUTE) {
6485                 if (!mVolumePolicy.volumeUpToExitSilent) {
6486                     result |= AudioManager.FLAG_SHOW_SILENT_HINT;
6487                 } else {
6488                   if (mHasVibrator && direction == AudioManager.ADJUST_RAISE) {
6489                       ringerMode = RINGER_MODE_VIBRATE;
6490                   } else {
6491                       // If we don't have a vibrator or they were toggling mute
6492                       // go straight back to normal.
6493                       ringerMode = RINGER_MODE_NORMAL;
6494                   }
6495                 }
6496             }
6497             result &= ~FLAG_ADJUST_VOLUME;
6498             break;
6499         default:
6500             Log.e(TAG, "checkForRingerModeChange() wrong ringer mode: "+ringerMode);
6501             break;
6502         }
6503 
6504         if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode)
6505                 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)
6506                 && (flags & AudioManager.FLAG_FROM_KEY) == 0) {
6507             throw new SecurityException("Not allowed to change Do Not Disturb state");
6508         }
6509 
6510         setRingerMode(ringerMode, TAG + ".checkForRingerModeChange", false /*external*/);
6511 
6512         mPrevVolDirection = direction;
6513 
6514         return result;
6515     }
6516 
6517     @Override
isStreamAffectedByRingerMode(int streamType)6518     public boolean isStreamAffectedByRingerMode(int streamType) {
6519         return (mRingerModeAffectedStreams & (1 << streamType)) != 0;
6520     }
6521 
shouldZenMuteStream(int streamType)6522     private boolean shouldZenMuteStream(int streamType) {
6523         if (mNm.getZenMode() != Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
6524             return false;
6525         }
6526 
6527         NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy();
6528         final boolean muteAlarms = (zenPolicy.priorityCategories
6529                 & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0;
6530         final boolean muteMedia = (zenPolicy.priorityCategories
6531                 & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0;
6532         final boolean muteSystem = (zenPolicy.priorityCategories
6533                 & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0;
6534         final boolean muteNotificationAndRing = ZenModeConfig
6535                 .areAllPriorityOnlyRingerSoundsMuted(zenPolicy);
6536         return muteAlarms && isAlarm(streamType)
6537                 || muteMedia && isMedia(streamType)
6538                 || muteSystem && isSystem(streamType)
6539                 || muteNotificationAndRing && isNotificationOrRinger(streamType);
6540     }
6541 
isStreamMutedByRingerOrZenMode(int streamType)6542     private boolean isStreamMutedByRingerOrZenMode(int streamType) {
6543         return (mRingerAndZenModeMutedStreams & (1 << streamType)) != 0;
6544     }
6545 
6546     /**
6547      * Notifications, ringer and system sounds are controlled by the ringer:
6548      * {@link ZenModeHelper.RingerModeDelegate#getRingerModeAffectedStreams(int)} but can
6549      * also be muted by DND based on the DND mode:
6550      * DND total silence: media and alarms streams can be muted by DND
6551      * DND alarms only: no streams additionally controlled by DND
6552      * DND priority only: alarms, media, system, ringer and notification streams can be muted by
6553      * DND.  The current applied zenPolicy determines which streams will be muted by DND.
6554      * @return true if changed, else false
6555      */
updateZenModeAffectedStreams()6556     private boolean updateZenModeAffectedStreams() {
6557         if (!mSystemReady) {
6558             return false;
6559         }
6560 
6561         int zenModeAffectedStreams = 0;
6562         final int zenMode = mNm.getZenMode();
6563 
6564         if (zenMode == Settings.Global.ZEN_MODE_NO_INTERRUPTIONS) {
6565             zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM;
6566             zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC;
6567         } else if (zenMode == Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
6568             NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy();
6569             if ((zenPolicy.priorityCategories
6570                     & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0) {
6571                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM;
6572             }
6573 
6574             if ((zenPolicy.priorityCategories
6575                     & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0) {
6576                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC;
6577             }
6578 
6579             // even if zen isn't muting the system stream, the ringer mode can still mute
6580             // the system stream
6581             if ((zenPolicy.priorityCategories
6582                     & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0) {
6583                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM;
6584             }
6585 
6586             if (ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(zenPolicy)) {
6587                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION;
6588                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING;
6589             }
6590         }
6591 
6592         if (mZenModeAffectedStreams != zenModeAffectedStreams) {
6593             mZenModeAffectedStreams = zenModeAffectedStreams;
6594             return true;
6595         }
6596 
6597         return false;
6598     }
6599 
6600     @GuardedBy("mSettingsLock")
updateRingerAndZenModeAffectedStreams()6601     private boolean updateRingerAndZenModeAffectedStreams() {
6602         boolean updatedZenModeAffectedStreams = updateZenModeAffectedStreams();
6603         int ringerModeAffectedStreams = mSettings.getSystemIntForUser(mContentResolver,
6604                 Settings.System.MODE_RINGER_STREAMS_AFFECTED,
6605                 ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
6606                  (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)),
6607                  UserHandle.USER_CURRENT);
6608 
6609         if (mIsSingleVolume) {
6610             ringerModeAffectedStreams = 0;
6611         } else if (mRingerModeDelegate != null) {
6612             ringerModeAffectedStreams = mRingerModeDelegate
6613                     .getRingerModeAffectedStreams(ringerModeAffectedStreams);
6614         }
6615         if (mCameraSoundForced) {
6616             ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
6617         } else {
6618             ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
6619         }
6620         if (mStreamVolumeAlias[AudioSystem.STREAM_DTMF] == AudioSystem.STREAM_RING) {
6621             ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF);
6622         } else {
6623             ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF);
6624         }
6625 
6626         if (ringerModeAffectedStreams != mRingerModeAffectedStreams) {
6627             mSettings.putSystemIntForUser(mContentResolver,
6628                     Settings.System.MODE_RINGER_STREAMS_AFFECTED,
6629                     ringerModeAffectedStreams,
6630                     UserHandle.USER_CURRENT);
6631             mRingerModeAffectedStreams = ringerModeAffectedStreams;
6632             return true;
6633         }
6634         return updatedZenModeAffectedStreams;
6635     }
6636 
6637     @Override
isStreamAffectedByMute(int streamType)6638     public boolean isStreamAffectedByMute(int streamType) {
6639         return (mMuteAffectedStreams & (1 << streamType)) != 0;
6640     }
6641 
ensureValidDirection(int direction)6642     private void ensureValidDirection(int direction) {
6643         switch (direction) {
6644             case AudioManager.ADJUST_LOWER:
6645             case AudioManager.ADJUST_RAISE:
6646             case AudioManager.ADJUST_SAME:
6647             case AudioManager.ADJUST_MUTE:
6648             case AudioManager.ADJUST_UNMUTE:
6649             case AudioManager.ADJUST_TOGGLE_MUTE:
6650                 break;
6651             default:
6652                 throw new IllegalArgumentException("Bad direction " + direction);
6653         }
6654     }
6655 
ensureValidStreamType(int streamType)6656     private void ensureValidStreamType(int streamType) {
6657         if (streamType < 0 || streamType >= mStreamStates.length) {
6658             throw new IllegalArgumentException("Bad stream type " + streamType);
6659         }
6660     }
6661 
isMuteAdjust(int adjust)6662     private boolean isMuteAdjust(int adjust) {
6663         return adjust == AudioManager.ADJUST_MUTE || adjust == AudioManager.ADJUST_UNMUTE
6664                 || adjust == AudioManager.ADJUST_TOGGLE_MUTE;
6665     }
6666 
6667     /** only public for mocking/spying, do not call outside of AudioService */
6668     @VisibleForTesting
isInCommunication()6669     public boolean isInCommunication() {
6670         boolean IsInCall = false;
6671 
6672         TelecomManager telecomManager =
6673                 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
6674 
6675         final long ident = Binder.clearCallingIdentity();
6676         IsInCall = telecomManager.isInCall();
6677         Binder.restoreCallingIdentity(ident);
6678 
6679         int mode = mMode.get();
6680         return (IsInCall
6681                 || mode == AudioManager.MODE_IN_COMMUNICATION
6682                 || mode == AudioManager.MODE_IN_CALL);
6683     }
6684 
6685     /**
6686      * For code clarity for getActiveStreamType(int)
6687      * @param delay_ms max time since last stream activity to consider
6688      * @return true if stream is active in streams handled by AudioFlinger now or
6689      *     in the last "delay_ms" ms.
6690      */
wasStreamActiveRecently(int stream, int delay_ms)6691     private boolean wasStreamActiveRecently(int stream, int delay_ms) {
6692         return mAudioSystem.isStreamActive(stream, delay_ms)
6693                 || mAudioSystem.isStreamActiveRemotely(stream, delay_ms);
6694     }
6695 
getActiveStreamType(int suggestedStreamType)6696     private int getActiveStreamType(int suggestedStreamType) {
6697         if (mIsSingleVolume
6698                 && suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
6699             return AudioSystem.STREAM_MUSIC;
6700         }
6701 
6702         switch (mPlatformType) {
6703         case AudioSystem.PLATFORM_VOICE:
6704             if (isInCommunication()) {
6705                 if (mDeviceBroker.isBluetoothScoActive()) {
6706                     // Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO...");
6707                     return AudioSystem.STREAM_BLUETOOTH_SCO;
6708                 } else {
6709                     // Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL...");
6710                     return AudioSystem.STREAM_VOICE_CALL;
6711                 }
6712             } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
6713                 if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
6714                     if (DEBUG_VOL)
6715                         Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active");
6716                     return AudioSystem.STREAM_RING;
6717                 } else if (wasStreamActiveRecently(
6718                         AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
6719                     if (DEBUG_VOL)
6720                         Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION stream active");
6721                     return AudioSystem.STREAM_NOTIFICATION;
6722                 } else {
6723                     if (DEBUG_VOL) {
6724                         Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK("
6725                                 + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default");
6726                     }
6727                     return DEFAULT_VOL_STREAM_NO_PLAYBACK;
6728                 }
6729             } else if (
6730                     wasStreamActiveRecently(AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
6731                 if (DEBUG_VOL)
6732                     Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION stream active");
6733                 return AudioSystem.STREAM_NOTIFICATION;
6734             } else if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
6735                 if (DEBUG_VOL)
6736                     Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active");
6737                 return AudioSystem.STREAM_RING;
6738             }
6739         default:
6740             if (isInCommunication()) {
6741                 if (mDeviceBroker.isBluetoothScoActive()) {
6742                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO");
6743                     return AudioSystem.STREAM_BLUETOOTH_SCO;
6744                 } else {
6745                     if (DEBUG_VOL)  Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL");
6746                     return AudioSystem.STREAM_VOICE_CALL;
6747                 }
6748             } else if (mAudioSystem.isStreamActive(
6749                     AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
6750                 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION");
6751                 return AudioSystem.STREAM_NOTIFICATION;
6752             } else if (mAudioSystem.isStreamActive(
6753                     AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
6754                 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING");
6755                 return AudioSystem.STREAM_RING;
6756             } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
6757                 if (mAudioSystem.isStreamActive(
6758                         AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
6759                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION");
6760                     return AudioSystem.STREAM_NOTIFICATION;
6761                 }
6762                 if (mAudioSystem.isStreamActive(
6763                         AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
6764                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING");
6765                     return AudioSystem.STREAM_RING;
6766                 }
6767                 if (DEBUG_VOL) {
6768                     Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK("
6769                             + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default");
6770                 }
6771                 return DEFAULT_VOL_STREAM_NO_PLAYBACK;
6772             }
6773             break;
6774         }
6775         if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Returning suggested type "
6776                 + suggestedStreamType);
6777         return suggestedStreamType;
6778     }
6779 
broadcastRingerMode(String action, int ringerMode)6780     private void broadcastRingerMode(String action, int ringerMode) {
6781         if (!mSystemServer.isPrivileged()) {
6782             return;
6783         }
6784         // Send sticky broadcast
6785         Intent broadcast = new Intent(action);
6786         broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, ringerMode);
6787         broadcast.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
6788                 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
6789         sendStickyBroadcastToAll(broadcast);
6790     }
6791 
broadcastVibrateSetting(int vibrateType)6792     private void broadcastVibrateSetting(int vibrateType) {
6793         if (!mSystemServer.isPrivileged()) {
6794             return;
6795         }
6796         // Send broadcast
6797         if (mActivityManagerInternal.isSystemReady()) {
6798             Intent broadcast = new Intent(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
6799             broadcast.putExtra(AudioManager.EXTRA_VIBRATE_TYPE, vibrateType);
6800             broadcast.putExtra(AudioManager.EXTRA_VIBRATE_SETTING, getVibrateSetting(vibrateType));
6801             sendBroadcastToAll(broadcast);
6802         }
6803     }
6804 
6805     // Message helper methods
6806     /**
6807      * Queue a message on the given handler's message queue, after acquiring the service wake lock.
6808      * Note that the wake lock needs to be released after the message has been handled.
6809      */
queueMsgUnderWakeLock(Handler handler, int msg, int arg1, int arg2, Object obj, int delay)6810     private void queueMsgUnderWakeLock(Handler handler, int msg,
6811             int arg1, int arg2, Object obj, int delay) {
6812         final long ident = Binder.clearCallingIdentity();
6813         // Always acquire the wake lock as AudioService because it is released by the
6814         // message handler.
6815         mAudioEventWakeLock.acquire();
6816         Binder.restoreCallingIdentity(ident);
6817         sendMsg(handler, msg, SENDMSG_QUEUE, arg1, arg2, obj, delay);
6818     }
6819 
sendMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, int delay)6820     private static void sendMsg(Handler handler, int msg,
6821             int existingMsgPolicy, int arg1, int arg2, Object obj, int delay) {
6822         if (existingMsgPolicy == SENDMSG_REPLACE) {
6823             handler.removeMessages(msg);
6824         } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) {
6825             return;
6826         }
6827 
6828         final long time = SystemClock.uptimeMillis() + delay;
6829         handler.sendMessageAtTime(handler.obtainMessage(msg, arg1, arg2, obj), time);
6830     }
6831 
checkAudioSettingsPermission(String method)6832     boolean checkAudioSettingsPermission(String method) {
6833         if (callingOrSelfHasAudioSettingsPermission()) {
6834             return true;
6835         }
6836         String msg = "Audio Settings Permission Denial: " + method + " from pid="
6837                 + Binder.getCallingPid()
6838                 + ", uid=" + Binder.getCallingUid();
6839         Log.w(TAG, msg);
6840         return false;
6841     }
6842 
callingOrSelfHasAudioSettingsPermission()6843     private boolean callingOrSelfHasAudioSettingsPermission() {
6844         return mContext.checkCallingOrSelfPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS)
6845                 == PackageManager.PERMISSION_GRANTED;
6846     }
6847 
callingHasAudioSettingsPermission()6848     private boolean callingHasAudioSettingsPermission() {
6849         return mContext.checkCallingPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS)
6850                 == PackageManager.PERMISSION_GRANTED;
6851     }
6852 
hasAudioSettingsPermission(int uid, int pid)6853     private boolean hasAudioSettingsPermission(int uid, int pid) {
6854         return mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid)
6855                 == PackageManager.PERMISSION_GRANTED;
6856     }
6857 
6858     /**
6859      * Minimum attenuation that can be set for alarms over speaker by an application that
6860      * doesn't have the MODIFY_AUDIO_SETTINGS permission.
6861      */
6862     protected static final float MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB = -36.0f;
6863 
6864     /**
6865      * Configures the VolumeStreamState instances for minimum stream index that can be accessed
6866      * without MODIFY_AUDIO_SETTINGS permission.
6867      * Can only be done successfully once audio policy has finished reading its configuration files
6868      * for the volume curves. If not, getStreamVolumeDB will return NaN, and the min value will
6869      * remain at the stream min index value.
6870      */
initMinStreamVolumeWithoutModifyAudioSettings()6871     protected void initMinStreamVolumeWithoutModifyAudioSettings() {
6872         int idx;
6873         int deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER_SAFE;
6874         if (Float.isNaN(AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM,
6875                 MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM], deviceForAlarm))) {
6876             deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER;
6877         }
6878         for (idx = MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM];
6879                 idx >= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]; idx--) {
6880             if (AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM, idx, deviceForAlarm)
6881                     < MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB) {
6882                 break;
6883             }
6884         }
6885         final int safeIndex = idx <= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]
6886                 ? MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]
6887                 : Math.min(idx + 1, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]);
6888         // update the VolumeStreamState for STREAM_ALARM and its aliases
6889         for (int stream : mStreamVolumeAlias) {
6890             if (mStreamVolumeAlias[stream] == AudioSystem.STREAM_ALARM) {
6891                 mStreamStates[stream].updateNoPermMinIndex(safeIndex);
6892             }
6893         }
6894     }
6895 
6896     /**
6897      * Returns device associated with the stream volume.
6898      *
6899      * Only public for mocking/spying, do not call outside of AudioService.
6900      * Device volume aliasing means DEVICE_OUT_SPEAKER may be returned for
6901      * DEVICE_OUT_SPEAKER_SAFE.
6902      */
6903     @VisibleForTesting
getDeviceForStream(int stream)6904     public int getDeviceForStream(int stream) {
6905         return selectOneAudioDevice(getDeviceSetForStream(stream));
6906     }
6907 
6908     /*
6909      * Must match native apm_extract_one_audio_device() used in getDeviceForVolume()
6910      * or the wrong device volume may be adjusted.
6911      */
selectOneAudioDevice(Set<Integer> deviceSet)6912     private int selectOneAudioDevice(Set<Integer> deviceSet) {
6913         if (deviceSet.isEmpty()) {
6914             return AudioSystem.DEVICE_NONE;
6915         } else if (deviceSet.size() == 1) {
6916             return deviceSet.iterator().next();
6917         } else {
6918             // Multiple device selection is either:
6919             //  - speaker + one other device: give priority to speaker in this case.
6920             //  - one A2DP device + another device: happens with duplicated output. In this case
6921             // retain the device on the A2DP output as the other must not correspond to an active
6922             // selection if not the speaker.
6923             //  - HDMI-CEC system audio mode only output: give priority to available item in order.
6924 
6925             if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPEAKER)) {
6926                 return AudioSystem.DEVICE_OUT_SPEAKER;
6927             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPEAKER_SAFE)) {
6928                 // Note: DEVICE_OUT_SPEAKER_SAFE not present in getDeviceSetForStreamDirect
6929                 return AudioSystem.DEVICE_OUT_SPEAKER_SAFE;
6930             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_HDMI_ARC)) {
6931                 return AudioSystem.DEVICE_OUT_HDMI_ARC;
6932             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_HDMI_EARC)) {
6933                 return AudioSystem.DEVICE_OUT_HDMI_EARC;
6934             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_AUX_LINE)) {
6935                 return AudioSystem.DEVICE_OUT_AUX_LINE;
6936             } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPDIF)) {
6937                 return AudioSystem.DEVICE_OUT_SPDIF;
6938             } else {
6939                 // At this point, deviceSet should contain exactly one A2DP device;
6940                 // regardless, return the first A2DP device in numeric order.
6941                 // If there is no A2DP device, this falls through to log an error.
6942                 for (int deviceType : deviceSet) {
6943                     if (AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(deviceType)) {
6944                         return deviceType;
6945                     }
6946                 }
6947             }
6948         }
6949         Log.w(TAG, "selectOneAudioDevice returning DEVICE_NONE from invalid device combination "
6950                 + AudioSystem.deviceSetToString(deviceSet));
6951         return AudioSystem.DEVICE_NONE;
6952     }
6953 
6954     /**
6955      * @see AudioManager#getDevicesForStream(int)
6956      * @deprecated on {@link android.os.Build.VERSION_CODES#T} as new devices
6957      *              will have multi-bit device types since S.
6958      *              Use {@link #getDevicesForAttributes()} instead.
6959      */
6960     @Override
6961     @Deprecated
getDeviceMaskForStream(int streamType)6962     public int getDeviceMaskForStream(int streamType) {
6963         ensureValidStreamType(streamType);
6964         // no permission required
6965         final long token = Binder.clearCallingIdentity();
6966         try {
6967             return AudioSystem.getDeviceMaskFromSet(
6968                     getDeviceSetForStreamDirect(streamType));
6969         } finally {
6970             Binder.restoreCallingIdentity(token);
6971         }
6972     }
6973 
6974     /**
6975      * Returns the devices associated with a stream type.
6976      *
6977      * SPEAKER_SAFE will alias to SPEAKER.
6978      */
6979     @NonNull
getDeviceSetForStreamDirect(int stream)6980     private Set<Integer> getDeviceSetForStreamDirect(int stream) {
6981         final AudioAttributes attr =
6982                 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream);
6983         Set<Integer> deviceSet =
6984                 AudioSystem.generateAudioDeviceTypesSet(
6985                         getDevicesForAttributesInt(attr, true /* forVolume */));
6986         return deviceSet;
6987     }
6988 
6989     /**
6990      * Returns a reference to the list of devices for the stream, do not modify.
6991      *
6992      * The device returned may be aliased to the actual device whose volume curve
6993      * will be used.  For example DEVICE_OUT_SPEAKER_SAFE aliases to DEVICE_OUT_SPEAKER.
6994      */
6995     @NonNull
getDeviceSetForStream(int stream)6996     public Set<Integer> getDeviceSetForStream(int stream) {
6997         ensureValidStreamType(stream);
6998         synchronized (VolumeStreamState.class) {
6999             return mStreamStates[stream].observeDevicesForStream_syncVSS(true);
7000         }
7001     }
7002 
onObserveDevicesForAllStreams(int skipStream)7003     private void onObserveDevicesForAllStreams(int skipStream) {
7004         synchronized (mSettingsLock) {
7005             synchronized (VolumeStreamState.class) {
7006                 for (int stream = 0; stream < mStreamStates.length; stream++) {
7007                     if (stream != skipStream) {
7008                         Set<Integer> deviceSet =
7009                                 mStreamStates[stream].observeDevicesForStream_syncVSS(
7010                                         false /*checkOthers*/);
7011                         for (Integer device : deviceSet) {
7012                             // Update volume states for devices routed for the stream
7013                             updateVolumeStates(device, stream,
7014                                     "AudioService#onObserveDevicesForAllStreams");
7015                         }
7016                     }
7017                 }
7018             }
7019         }
7020     }
7021 
7022     /** only public for mocking/spying, do not call outside of AudioService */
7023     @VisibleForTesting
postObserveDevicesForAllStreams()7024     public void postObserveDevicesForAllStreams() {
7025         postObserveDevicesForAllStreams(-1);
7026     }
7027 
7028     /** only public for mocking/spying, do not call outside of AudioService */
7029     @VisibleForTesting
postObserveDevicesForAllStreams(int skipStream)7030     public void postObserveDevicesForAllStreams(int skipStream) {
7031         sendMsg(mAudioHandler,
7032                 MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS,
7033                 SENDMSG_QUEUE, skipStream /*arg1*/, 0 /*arg2*/, null /*obj*/,
7034                 0 /*delay*/);
7035     }
7036 
7037     /**
7038      * @see AudioDeviceVolumeManager#setDeviceAbsoluteMultiVolumeBehavior
7039      *
7040      * @param register Whether the listener is to be registered or unregistered. If false, the
7041      *                 device adopts variable volume behavior.
7042      */
7043     @RequiresPermission(anyOf = { android.Manifest.permission.MODIFY_AUDIO_ROUTING,
7044             android.Manifest.permission.BLUETOOTH_PRIVILEGED })
registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register, IAudioDeviceVolumeDispatcher cb, String packageName, AudioDeviceAttributes device, List<VolumeInfo> volumes, boolean handlesVolumeAdjustment)7045     public void registerDeviceVolumeDispatcherForAbsoluteVolume(boolean register,
7046             IAudioDeviceVolumeDispatcher cb, String packageName,
7047             AudioDeviceAttributes device, List<VolumeInfo> volumes,
7048             boolean handlesVolumeAdjustment) {
7049         // verify permissions
7050         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
7051                 != PackageManager.PERMISSION_GRANTED
7052                 && mContext.checkCallingOrSelfPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
7053                 != PackageManager.PERMISSION_GRANTED) {
7054             throw new SecurityException(
7055                     "Missing MODIFY_AUDIO_ROUTING or BLUETOOTH_PRIVILEGED permissions");
7056         }
7057         // verify arguments
7058         Objects.requireNonNull(device);
7059         Objects.requireNonNull(volumes);
7060 
7061         int deviceOut = device.getInternalType();
7062         if (register) {
7063             AbsoluteVolumeDeviceInfo info = new AbsoluteVolumeDeviceInfo(
7064                     device, volumes, cb, handlesVolumeAdjustment);
7065             boolean volumeBehaviorChanged =
7066                     removeAudioSystemDeviceOutFromFullVolumeDevices(deviceOut)
7067                     | removeAudioSystemDeviceOutFromFixedVolumeDevices(deviceOut)
7068                     | (addAudioSystemDeviceOutToAbsVolumeDevices(deviceOut, info) == null);
7069             if (volumeBehaviorChanged) {
7070                 dispatchDeviceVolumeBehavior(device, AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
7071             }
7072             // Update stream volumes to the given device, if specified in a VolumeInfo.
7073             // Mute state is not updated because it is stream-wide - the only way to mute a
7074             // stream's output to a particular device is to set the volume index to zero.
7075             for (VolumeInfo volumeInfo : volumes) {
7076                 if (volumeInfo.getVolumeIndex() != VolumeInfo.INDEX_NOT_SET
7077                         && volumeInfo.getMinVolumeIndex() != VolumeInfo.INDEX_NOT_SET
7078                         && volumeInfo.getMaxVolumeIndex() != VolumeInfo.INDEX_NOT_SET) {
7079                     if (volumeInfo.hasStreamType()) {
7080                         setStreamVolumeInt(volumeInfo.getStreamType(),
7081                                 rescaleIndex(volumeInfo, volumeInfo.getStreamType()),
7082                                 deviceOut, false /*force*/, packageName,
7083                                 true /*hasModifyAudioSettings*/);
7084                     } else {
7085                         for (int streamType : volumeInfo.getVolumeGroup().getLegacyStreamTypes()) {
7086                             setStreamVolumeInt(streamType, rescaleIndex(volumeInfo, streamType),
7087                                     deviceOut, false /*force*/, packageName,
7088                                     true /*hasModifyAudioSettings*/);
7089                         }
7090                     }
7091                 }
7092             }
7093         } else {
7094             boolean wasAbsVol = removeAudioSystemDeviceOutFromAbsVolumeDevices(deviceOut) != null;
7095             if (wasAbsVol) {
7096                 dispatchDeviceVolumeBehavior(device, AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE);
7097             }
7098         }
7099     }
7100 
7101     /**
7102      * @see AudioManager#setDeviceVolumeBehavior(AudioDeviceAttributes, int)
7103      * @param device the audio device to be affected
7104      * @param deviceVolumeBehavior one of the device behaviors
7105      */
setDeviceVolumeBehavior(@onNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName)7106     public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
7107             @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName) {
7108         // verify permissions
7109         enforceModifyAudioRoutingPermission();
7110         // verify arguments
7111         Objects.requireNonNull(device);
7112         AudioManager.enforceValidVolumeBehavior(deviceVolumeBehavior);
7113         sVolumeLogger.log(new AudioEventLogger.StringEvent("setDeviceVolumeBehavior: dev:"
7114                 + AudioSystem.getOutputDeviceName(device.getInternalType()) + " addr:"
7115                 + device.getAddress() + " behavior:"
7116                 + AudioDeviceVolumeManager.volumeBehaviorName(deviceVolumeBehavior)
7117                 + " pack:" + pkgName).printLog(TAG));
7118         if (pkgName == null) {
7119             pkgName = "";
7120         }
7121         if (device.getType() == AudioDeviceInfo.TYPE_BLUETOOTH_A2DP) {
7122             avrcpSupportsAbsoluteVolume(device.getAddress(),
7123                     deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
7124             return;
7125         }
7126 
7127         setDeviceVolumeBehaviorInternal(device, deviceVolumeBehavior, pkgName);
7128         persistDeviceVolumeBehavior(device.getInternalType(), deviceVolumeBehavior);
7129     }
7130 
setDeviceVolumeBehaviorInternal(@onNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller)7131     private void setDeviceVolumeBehaviorInternal(@NonNull AudioDeviceAttributes device,
7132             @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller) {
7133         int audioSystemDeviceOut = device.getInternalType();
7134         boolean volumeBehaviorChanged = false;
7135         // update device masks based on volume behavior
7136         switch (deviceVolumeBehavior) {
7137             case AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE:
7138                 volumeBehaviorChanged |=
7139                         removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut)
7140                         | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut)
7141                         | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut)
7142                                 != null);
7143                 break;
7144             case AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED:
7145                 volumeBehaviorChanged |=
7146                         removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut)
7147                         | addAudioSystemDeviceOutToFixedVolumeDevices(audioSystemDeviceOut)
7148                         | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut)
7149                                 != null);
7150                 break;
7151             case AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL:
7152                 volumeBehaviorChanged |=
7153                         addAudioSystemDeviceOutToFullVolumeDevices(audioSystemDeviceOut)
7154                         | removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut)
7155                         | (removeAudioSystemDeviceOutFromAbsVolumeDevices(audioSystemDeviceOut)
7156                                 != null);
7157                 break;
7158             case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE:
7159             case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE:
7160                 throw new IllegalArgumentException("Absolute volume unsupported for now");
7161         }
7162 
7163         if (volumeBehaviorChanged) {
7164             sendMsg(mAudioHandler, MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR, SENDMSG_QUEUE,
7165                     deviceVolumeBehavior, 0, device, /*delay*/ 0);
7166         }
7167 
7168         // log event and caller
7169         sDeviceLogger.log(new AudioEventLogger.StringEvent(
7170                 "Volume behavior " + deviceVolumeBehavior + " for dev=0x"
7171                       + Integer.toHexString(audioSystemDeviceOut) + " from:" + caller));
7172         // make sure we have a volume entry for this device, and that volume is updated according
7173         // to volume behavior
7174         postUpdateVolumeStatesForAudioDevice(audioSystemDeviceOut,
7175                 "setDeviceVolumeBehavior:" + caller);
7176     }
7177 
7178     /**
7179      * @see AudioManager#getDeviceVolumeBehavior(AudioDeviceAttributes)
7180      * @param device the audio output device type
7181      * @return the volume behavior for the device
7182      */
7183     public @AudioManager.DeviceVolumeBehavior
getDeviceVolumeBehavior(@onNull AudioDeviceAttributes device)7184     int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
7185         Objects.requireNonNull(device);
7186         // verify permissions
7187         enforceQueryStateOrModifyRoutingPermission();
7188 
7189         return getDeviceVolumeBehaviorInt(device);
7190     }
7191 
7192     private @AudioManager.DeviceVolumeBehavior
getDeviceVolumeBehaviorInt(@onNull AudioDeviceAttributes device)7193             int getDeviceVolumeBehaviorInt(@NonNull AudioDeviceAttributes device) {
7194         // Get the internal type set by the AudioDeviceAttributes constructor which is always more
7195         // exact (avoids double conversions) than a conversion from SDK type via
7196         // AudioDeviceInfo.convertDeviceTypeToInternalDevice()
7197         final int audioSystemDeviceOut = device.getInternalType();
7198 
7199         int setDeviceVolumeBehavior = retrieveStoredDeviceVolumeBehavior(audioSystemDeviceOut);
7200         if (setDeviceVolumeBehavior != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET) {
7201             return setDeviceVolumeBehavior;
7202         }
7203 
7204         // setDeviceVolumeBehavior has not been explicitly called for the device type. Deduce the
7205         // current volume behavior.
7206         if (mFullVolumeDevices.contains(audioSystemDeviceOut)) {
7207             return AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL;
7208         }
7209         if (mFixedVolumeDevices.contains(audioSystemDeviceOut)) {
7210             return AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED;
7211         }
7212         if (mAbsVolumeMultiModeCaseDevices.contains(audioSystemDeviceOut)) {
7213             return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE;
7214         }
7215         if (isAbsoluteVolumeDevice(audioSystemDeviceOut)
7216                 || isA2dpAbsoluteVolumeDevice(audioSystemDeviceOut)
7217                 || AudioSystem.isLeAudioDeviceType(audioSystemDeviceOut)) {
7218             return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE;
7219         }
7220         return AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE;
7221     }
7222 
7223     /**
7224      * @see AudioManager#isVolumeFixed()
7225      * Note there are no permission checks on this operation, as this is part of API 21
7226      * @return true if the current device's volume behavior for media is
7227      *         DEVICE_VOLUME_BEHAVIOR_FIXED
7228      */
isVolumeFixed()7229     public boolean isVolumeFixed() {
7230         if (mUseFixedVolume) {
7231             return true;
7232         }
7233         final AudioAttributes attributes = new AudioAttributes.Builder()
7234                 .setUsage(AudioAttributes.USAGE_MEDIA)
7235                 .build();
7236         // calling getDevice*Int to bypass permission check
7237         final List<AudioDeviceAttributes> devices =
7238                 getDevicesForAttributesInt(attributes, true /* forVolume */);
7239         for (AudioDeviceAttributes device : devices) {
7240             if (getDeviceVolumeBehaviorInt(device) == AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED) {
7241                 return true;
7242             }
7243         }
7244         return false;
7245     }
7246 
7247     /*package*/ static final int CONNECTION_STATE_DISCONNECTED = 0;
7248     /*package*/ static final int CONNECTION_STATE_CONNECTED = 1;
7249     /**
7250      * The states that can be used with AudioService.setWiredDeviceConnectionState()
7251      * Attention: those values differ from those in BluetoothProfile, follow annotations to
7252      * distinguish between @ConnectionState and @BtProfileConnectionState
7253      */
7254     @IntDef({
7255             CONNECTION_STATE_DISCONNECTED,
7256             CONNECTION_STATE_CONNECTED,
7257     })
7258     @Retention(RetentionPolicy.SOURCE)
7259     public @interface ConnectionState {}
7260 
7261     /**
7262      * see AudioManager.setWiredDeviceConnectionState()
7263      */
setWiredDeviceConnectionState(AudioDeviceAttributes attributes, @ConnectionState int state, String caller)7264     public void setWiredDeviceConnectionState(AudioDeviceAttributes attributes,
7265             @ConnectionState int state, String caller) {
7266         enforceModifyAudioRoutingPermission();
7267         if (state != CONNECTION_STATE_CONNECTED
7268                 && state != CONNECTION_STATE_DISCONNECTED) {
7269             throw new IllegalArgumentException("Invalid state " + state);
7270         }
7271         new MediaMetrics.Item(mMetricsId + "setWiredDeviceConnectionState")
7272                 .set(MediaMetrics.Property.ADDRESS, attributes.getAddress())
7273                 .set(MediaMetrics.Property.CLIENT_NAME, caller)
7274                 .set(MediaMetrics.Property.DEVICE,
7275                         AudioSystem.getDeviceName(attributes.getInternalType()))
7276                 .set(MediaMetrics.Property.NAME, attributes.getName())
7277                 .set(MediaMetrics.Property.STATE,
7278                         state == CONNECTION_STATE_CONNECTED ? "connected" : "disconnected")
7279                 .record();
7280         mDeviceBroker.setWiredDeviceConnectionState(attributes, state, caller);
7281     }
7282 
7283     /** @see AudioManager#setTestDeviceConnectionState(AudioDeviceAttributes, boolean) */
setTestDeviceConnectionState(@onNull AudioDeviceAttributes device, boolean connected)7284     public void setTestDeviceConnectionState(@NonNull AudioDeviceAttributes device,
7285             boolean connected) {
7286         Objects.requireNonNull(device);
7287         enforceModifyAudioRoutingPermission();
7288         mDeviceBroker.setTestDeviceConnectionState(device,
7289                 connected ? CONNECTION_STATE_CONNECTED : CONNECTION_STATE_DISCONNECTED);
7290         // simulate a routing update from native
7291         sendMsg(mAudioHandler,
7292                 MSG_ROUTING_UPDATED,
7293                 SENDMSG_REPLACE, 0, 0, null,
7294                 /*delay*/ 0);
7295     }
7296 
7297     /**
7298      * @hide
7299      * The states that can be used with AudioService.setBluetoothHearingAidDeviceConnectionState()
7300      * and AudioService.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent()
7301      */
7302     @IntDef({
7303             BluetoothProfile.STATE_DISCONNECTED,
7304             BluetoothProfile.STATE_CONNECTED,
7305     })
7306     @Retention(RetentionPolicy.SOURCE)
7307     public @interface BtProfileConnectionState {}
7308 
7309     /**
7310      * @hide
7311      * The profiles that can be used with AudioService.handleBluetoothActiveDeviceChanged()
7312      */
7313     @IntDef({
7314             BluetoothProfile.HEARING_AID,
7315             BluetoothProfile.A2DP,
7316             BluetoothProfile.A2DP_SINK,
7317             BluetoothProfile.LE_AUDIO,
7318             BluetoothProfile.LE_AUDIO_BROADCAST,
7319     })
7320     @Retention(RetentionPolicy.SOURCE)
7321     public @interface BtProfile {}
7322 
7323 
7324     /**
7325      * See AudioManager.handleBluetoothActiveDeviceChanged(...)
7326      */
handleBluetoothActiveDeviceChanged(BluetoothDevice newDevice, BluetoothDevice previousDevice, @NonNull BluetoothProfileConnectionInfo info)7327     public void handleBluetoothActiveDeviceChanged(BluetoothDevice newDevice,
7328             BluetoothDevice previousDevice, @NonNull BluetoothProfileConnectionInfo info) {
7329         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.BLUETOOTH_STACK)
7330                 != PackageManager.PERMISSION_GRANTED) {
7331             throw new SecurityException("Bluetooth is the only caller allowed");
7332         }
7333         if (info == null) {
7334             throw new IllegalArgumentException("Illegal null BluetoothProfileConnectionInfo for"
7335                     + " device " + previousDevice + " -> " + newDevice);
7336         }
7337         final int profile = info.getProfile();
7338         if (profile != BluetoothProfile.A2DP && profile != BluetoothProfile.A2DP_SINK
7339                 && profile != BluetoothProfile.LE_AUDIO
7340                 && profile != BluetoothProfile.LE_AUDIO_BROADCAST
7341                 && profile != BluetoothProfile.HEARING_AID) {
7342             throw new IllegalArgumentException("Illegal BluetoothProfile profile for device "
7343                     + previousDevice + " -> " + newDevice + ". Got: " + profile);
7344         }
7345         AudioDeviceBroker.BtDeviceChangedData data =
7346                 new AudioDeviceBroker.BtDeviceChangedData(newDevice, previousDevice, info,
7347                         "AudioService");
7348         sendMsg(mAudioHandler, MSG_BT_DEV_CHANGED, SENDMSG_QUEUE, 0, 0,
7349                 /*obj*/ data, /*delay*/ 0);
7350     }
7351 
7352     /** only public for mocking/spying, do not call outside of AudioService */
7353     @VisibleForTesting
setMusicMute(boolean mute)7354     public void setMusicMute(boolean mute) {
7355         mStreamStates[AudioSystem.STREAM_MUSIC].muteInternally(mute);
7356     }
7357 
7358     private static final Set<Integer> DEVICE_MEDIA_UNMUTED_ON_PLUG_SET;
7359     static {
7360         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET = new HashSet<>();
7361         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADSET);
7362         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE);
7363         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_LINE);
7364         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_A2DP_SET);
7365         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_USB_SET);
7366         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_HDMI);
7367     }
7368 
7369     /** only public for mocking/spying, do not call outside of AudioService */
7370     @VisibleForTesting
postAccessoryPlugMediaUnmute(int newDevice)7371     public void postAccessoryPlugMediaUnmute(int newDevice) {
7372         sendMsg(mAudioHandler, MSG_ACCESSORY_PLUG_MEDIA_UNMUTE, SENDMSG_QUEUE,
7373                 newDevice, 0, null, 0);
7374     }
7375 
onAccessoryPlugMediaUnmute(int newDevice)7376     private void onAccessoryPlugMediaUnmute(int newDevice) {
7377         if (DEBUG_VOL) {
7378             Log.i(TAG, String.format("onAccessoryPlugMediaUnmute newDevice=%d [%s]",
7379                     newDevice, AudioSystem.getOutputDeviceName(newDevice)));
7380         }
7381 
7382         if (mNm.getZenMode() != Settings.Global.ZEN_MODE_NO_INTERRUPTIONS
7383                 && !isStreamMutedByRingerOrZenMode(AudioSystem.STREAM_MUSIC)
7384                 && DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.contains(newDevice)
7385                 && mStreamStates[AudioSystem.STREAM_MUSIC].mIsMuted
7386                 && mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(newDevice) != 0
7387                 && getDeviceSetForStreamDirect(AudioSystem.STREAM_MUSIC).contains(newDevice)) {
7388             if (DEBUG_VOL) {
7389                 Log.i(TAG, String.format("onAccessoryPlugMediaUnmute unmuting device=%d [%s]",
7390                         newDevice, AudioSystem.getOutputDeviceName(newDevice)));
7391             }
7392             mStreamStates[AudioSystem.STREAM_MUSIC].mute(false);
7393         }
7394     }
7395 
7396     /**
7397      * See AudioManager.hasHapticChannels(Context, Uri).
7398      */
hasHapticChannels(Uri uri)7399     public boolean hasHapticChannels(Uri uri) {
7400         return AudioManager.hasHapticChannelsImpl(mContext, uri);
7401     }
7402 
7403     ///////////////////////////////////////////////////////////////////////////
7404     // Inner classes
7405     ///////////////////////////////////////////////////////////////////////////
7406     /**
7407      * Key is the AudioManager VolumeGroupId
7408      * Value is the VolumeGroupState
7409      */
7410     private static final SparseArray<VolumeGroupState> sVolumeGroupStates = new SparseArray<>();
7411 
initVolumeGroupStates()7412     private void initVolumeGroupStates() {
7413         for (final AudioVolumeGroup avg : getAudioVolumeGroups()) {
7414             try {
7415                 // if no valid attributes, this volume group is not controllable, throw exception
7416                 ensureValidAttributes(avg);
7417                 sVolumeGroupStates.append(avg.getId(), new VolumeGroupState(avg));
7418             } catch (IllegalArgumentException e) {
7419                 // Volume Groups without attributes are not controllable through set/get volume
7420                 // using attributes. Do not append them.
7421                 if (DEBUG_VOL) {
7422                     Log.d(TAG, "volume group " + avg.name() + " for internal policy needs");
7423                 }
7424                 continue;
7425             }
7426         }
7427         for (int i = 0; i < sVolumeGroupStates.size(); i++) {
7428             final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
7429             vgs.applyAllVolumes(/* userSwitch= */ false);
7430         }
7431     }
7432 
ensureValidAttributes(AudioVolumeGroup avg)7433     private void ensureValidAttributes(AudioVolumeGroup avg) {
7434         boolean hasAtLeastOneValidAudioAttributes = avg.getAudioAttributes().stream()
7435                 .anyMatch(aa -> !aa.equals(AudioProductStrategy.getDefaultAttributes()));
7436         if (!hasAtLeastOneValidAudioAttributes) {
7437             throw new IllegalArgumentException("Volume Group " + avg.name()
7438                     + " has no valid audio attributes");
7439         }
7440     }
7441 
readVolumeGroupsSettings(boolean userSwitch)7442     private void readVolumeGroupsSettings(boolean userSwitch) {
7443         synchronized (mSettingsLock) {
7444             synchronized (VolumeStreamState.class) {
7445                 if (DEBUG_VOL) {
7446                     Log.d(TAG, "readVolumeGroupsSettings userSwitch=" + userSwitch);
7447                 }
7448                 for (int i = 0; i < sVolumeGroupStates.size(); i++) {
7449                     VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
7450                     // as for STREAM_MUSIC, preserve volume from one user to the next.
7451                     if (!(userSwitch && vgs.isMusic())) {
7452                         vgs.clearIndexCache();
7453                         vgs.readSettings();
7454                     }
7455                     vgs.applyAllVolumes(userSwitch);
7456                 }
7457             }
7458         }
7459     }
7460 
7461     // Called upon crash of AudioServer
restoreVolumeGroups()7462     private void restoreVolumeGroups() {
7463         if (DEBUG_VOL) {
7464             Log.v(TAG, "restoreVolumeGroups");
7465         }
7466         for (int i = 0; i < sVolumeGroupStates.size(); i++) {
7467             final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
7468             vgs.applyAllVolumes(false/*userSwitch*/);
7469         }
7470     }
7471 
dumpVolumeGroups(PrintWriter pw)7472     private void dumpVolumeGroups(PrintWriter pw) {
7473         pw.println("\nVolume Groups (device: index)");
7474         for (int i = 0; i < sVolumeGroupStates.size(); i++) {
7475             final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
7476             vgs.dump(pw);
7477             pw.println("");
7478         }
7479     }
7480 
isCallStream(int stream)7481     private static boolean isCallStream(int stream) {
7482         return stream == AudioSystem.STREAM_VOICE_CALL
7483                 || stream == AudioSystem.STREAM_BLUETOOTH_SCO;
7484     }
7485 
getVolumeGroupForStreamType(int stream)7486     private static int getVolumeGroupForStreamType(int stream) {
7487         AudioAttributes attributes =
7488                 AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream);
7489         if (attributes.equals(new AudioAttributes.Builder().build())) {
7490             return AudioVolumeGroup.DEFAULT_VOLUME_GROUP;
7491         }
7492         return AudioProductStrategy.getVolumeGroupIdForAudioAttributes(
7493                 attributes, /* fallbackOnDefault= */ false);
7494     }
7495 
7496     // NOTE: Locking order for synchronized objects related to volume management:
7497     //  1     mSettingsLock
7498     //  2       VolumeStreamState.class
7499     private class VolumeGroupState {
7500         private final AudioVolumeGroup mAudioVolumeGroup;
7501         private final SparseIntArray mIndexMap = new SparseIntArray(8);
7502         private int mIndexMin;
7503         private int mIndexMax;
7504         private boolean mHasValidStreamType = false;
7505         private int mPublicStreamType = AudioSystem.STREAM_MUSIC;
7506         private AudioAttributes mAudioAttributes = AudioProductStrategy.getDefaultAttributes();
7507         private boolean mIsMuted = false;
7508         private String mSettingName;
7509 
7510         // No API in AudioSystem to get a device from strategy or from attributes.
7511         // Need a valid public stream type to use current API getDeviceForStream
getDeviceForVolume()7512         private int getDeviceForVolume() {
7513             return getDeviceForStream(mPublicStreamType);
7514         }
7515 
VolumeGroupState(AudioVolumeGroup avg)7516         private VolumeGroupState(AudioVolumeGroup avg) {
7517             mAudioVolumeGroup = avg;
7518             if (DEBUG_VOL) {
7519                 Log.v(TAG, "VolumeGroupState for " + avg.toString());
7520             }
7521             // mAudioAttributes is the default at this point
7522             for (AudioAttributes aa : avg.getAudioAttributes()) {
7523                 if (!aa.equals(mAudioAttributes)) {
7524                     mAudioAttributes = aa;
7525                     break;
7526                 }
7527             }
7528             int[] streamTypes = mAudioVolumeGroup.getLegacyStreamTypes();
7529             String streamSettingName = "";
7530             if (streamTypes.length != 0) {
7531                 // Uses already initialized MIN / MAX if a stream type is attached to group
7532                 for (int streamType : streamTypes) {
7533                     if (streamType != AudioSystem.STREAM_DEFAULT
7534                             && streamType < AudioSystem.getNumStreamTypes()) {
7535                         mPublicStreamType = streamType;
7536                         mHasValidStreamType = true;
7537                         streamSettingName = System.VOLUME_SETTINGS_INT[mPublicStreamType];
7538                         break;
7539                     }
7540                 }
7541                 mIndexMin = MIN_STREAM_VOLUME[mPublicStreamType];
7542                 mIndexMax = MAX_STREAM_VOLUME[mPublicStreamType];
7543             } else if (!avg.getAudioAttributes().isEmpty()) {
7544                 mIndexMin = AudioSystem.getMinVolumeIndexForAttributes(mAudioAttributes);
7545                 mIndexMax = AudioSystem.getMaxVolumeIndexForAttributes(mAudioAttributes);
7546             } else {
7547                 throw new IllegalArgumentException("volume group: " + mAudioVolumeGroup.name()
7548                         + " has neither valid attributes nor valid stream types assigned");
7549             }
7550             mSettingName = !streamSettingName.isEmpty() ? streamSettingName : ("volume_" + name());
7551             // Load volume indexes from data base
7552             readSettings();
7553         }
7554 
getLegacyStreamTypes()7555         public @NonNull int[] getLegacyStreamTypes() {
7556             return mAudioVolumeGroup.getLegacyStreamTypes();
7557         }
7558 
name()7559         public String name() {
7560             return mAudioVolumeGroup.name();
7561         }
7562 
7563         /**
7564          * Volume group with non null minimum index are considered as non mutable, thus
7565          * bijectivity is broken with potential associated stream type.
7566          * VOICE_CALL stream has minVolumeIndex > 0  but can be muted directly by an
7567          * app that has MODIFY_PHONE_STATE permission.
7568          */
isVssMuteBijective(int stream)7569         private boolean isVssMuteBijective(int stream) {
7570             return isStreamAffectedByMute(stream)
7571                     && (getMinIndex() == (mStreamStates[stream].mIndexMin + 5) / 10)
7572                     && (getMinIndex() == 0 || isCallStream(stream));
7573         }
7574 
isMutable()7575         private boolean isMutable() {
7576             return mIndexMin == 0 || (mHasValidStreamType && isVssMuteBijective(mPublicStreamType));
7577         }
7578         /**
7579          * Mute/unmute the volume group
7580          * @param muted the new mute state
7581          */
7582         @GuardedBy("AudioService.VolumeStreamState.class")
mute(boolean muted)7583         public boolean mute(boolean muted) {
7584             if (!isMutable()) {
7585                 // Non mutable volume group
7586                 if (DEBUG_VOL) {
7587                     Log.d(TAG, "invalid mute on unmutable volume group " + name());
7588                 }
7589                 return false;
7590             }
7591             boolean changed = (mIsMuted != muted);
7592             // As for VSS, mute shall apply minIndex to all devices found in IndexMap and default.
7593             if (changed) {
7594                 mIsMuted = muted;
7595                 applyAllVolumes(false /*userSwitch*/);
7596             }
7597             return changed;
7598         }
7599 
isMuted()7600         public boolean isMuted() {
7601             return mIsMuted;
7602         }
7603 
adjustVolume(int direction, int flags)7604         public void adjustVolume(int direction, int flags) {
7605             synchronized (VolumeStreamState.class) {
7606                 int device = getDeviceForVolume();
7607                 int previousIndex = getIndex(device);
7608                 if (isMuteAdjust(direction) && !isMutable()) {
7609                     // Non mutable volume group
7610                     if (DEBUG_VOL) {
7611                         Log.d(TAG, "invalid mute on unmutable volume group " + name());
7612                     }
7613                     return;
7614                 }
7615                 switch (direction) {
7616                     case AudioManager.ADJUST_TOGGLE_MUTE: {
7617                         // Note: If muted by volume 0, unmute will restore volume 0.
7618                         mute(!mIsMuted);
7619                         break;
7620                     }
7621                     case AudioManager.ADJUST_UNMUTE:
7622                         // Note: If muted by volume 0, unmute will restore volume 0.
7623                         mute(false);
7624                         break;
7625                     case AudioManager.ADJUST_MUTE:
7626                         // May be already muted by setvolume 0, prevent from setting same value
7627                         if (previousIndex != 0) {
7628                             // bypass persist
7629                             mute(true);
7630                         }
7631                         mIsMuted = true;
7632                         break;
7633                     case AudioManager.ADJUST_RAISE:
7634                         // As for stream, RAISE during mute will increment the index
7635                         setVolumeIndex(Math.min(previousIndex + 1, mIndexMax),  device, flags);
7636                         break;
7637                     case AudioManager.ADJUST_LOWER:
7638                         // For stream, ADJUST_LOWER on a muted VSS is a no-op
7639                         // If we decide to unmute on ADJUST_LOWER, cannot fallback on
7640                         // adjustStreamVolume for group associated to legacy stream type
7641                         if (isMuted() && previousIndex != 0) {
7642                             mute(false);
7643                         } else {
7644                             int newIndex = Math.max(previousIndex - 1, mIndexMin);
7645                             setVolumeIndex(newIndex, device, flags);
7646                         }
7647                         break;
7648                 }
7649             }
7650         }
7651 
getVolumeIndex()7652         public int getVolumeIndex() {
7653             synchronized (VolumeStreamState.class) {
7654                 return getIndex(getDeviceForVolume());
7655             }
7656         }
7657 
setVolumeIndex(int index, int flags)7658         public void setVolumeIndex(int index, int flags) {
7659             synchronized (VolumeStreamState.class) {
7660                 if (mUseFixedVolume) {
7661                     return;
7662                 }
7663                 setVolumeIndex(index, getDeviceForVolume(), flags);
7664             }
7665         }
7666 
7667         @GuardedBy("AudioService.VolumeStreamState.class")
setVolumeIndex(int index, int device, int flags)7668         private void setVolumeIndex(int index, int device, int flags) {
7669             // Update cache & persist (muted by volume 0 shall be persisted)
7670             updateVolumeIndex(index, device);
7671             // setting non-zero volume for a muted stream unmutes the stream and vice versa,
7672             boolean changed = mute(index == 0);
7673             if (!changed) {
7674                 // Set the volume index only if mute operation is a no-op
7675                 index = getValidIndex(index);
7676                 setVolumeIndexInt(index, device, flags);
7677             }
7678         }
7679 
7680         @GuardedBy("AudioService.VolumeStreamState.class")
updateVolumeIndex(int index, int device)7681         public void updateVolumeIndex(int index, int device) {
7682             // Filter persistency if already exist and the index has not changed
7683             if (mIndexMap.indexOfKey(device) < 0 || mIndexMap.get(device) != index) {
7684                 // Update local cache
7685                 mIndexMap.put(device, getValidIndex(index));
7686 
7687                 // update data base - post a persist volume group msg
7688                 sendMsg(mAudioHandler,
7689                         MSG_PERSIST_VOLUME_GROUP,
7690                         SENDMSG_QUEUE,
7691                         device,
7692                         0,
7693                         this,
7694                         PERSIST_DELAY);
7695             }
7696         }
7697 
7698         @GuardedBy("AudioService.VolumeStreamState.class")
setVolumeIndexInt(int index, int device, int flags)7699         private void setVolumeIndexInt(int index, int device, int flags) {
7700             // Reflect mute state of corresponding stream by forcing index to 0 if muted
7701             // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted.
7702             // This allows RX path muting by the audio HAL only when explicitly muted but not when
7703             // index is just set to 0 to repect BT requirements
7704             if (mHasValidStreamType && isVssMuteBijective(mPublicStreamType)
7705                     && mStreamStates[mPublicStreamType].isFullyMuted()) {
7706                 index = 0;
7707             } else if (mPublicStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0) {
7708                 index = 1;
7709             }
7710             // Set the volume index
7711             AudioSystem.setVolumeIndexForAttributes(mAudioAttributes, index, device);
7712         }
7713 
7714         @GuardedBy("AudioService.VolumeStreamState.class")
getIndex(int device)7715         private int getIndex(int device) {
7716             int index = mIndexMap.get(device, -1);
7717             // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
7718             return (index != -1) ? index : mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT);
7719         }
7720 
7721         @GuardedBy("AudioService.VolumeStreamState.class")
hasIndexForDevice(int device)7722         private boolean hasIndexForDevice(int device) {
7723             return (mIndexMap.get(device, -1) != -1);
7724         }
7725 
getMaxIndex()7726         public int getMaxIndex() {
7727             return mIndexMax;
7728         }
7729 
getMinIndex()7730         public int getMinIndex() {
7731             return mIndexMin;
7732         }
7733 
isValidStream(int stream)7734         private boolean isValidStream(int stream) {
7735             return (stream != AudioSystem.STREAM_DEFAULT) && (stream < mStreamStates.length);
7736         }
7737 
isMusic()7738         public boolean isMusic() {
7739             return mHasValidStreamType && mPublicStreamType == AudioSystem.STREAM_MUSIC;
7740         }
7741 
applyAllVolumes(boolean userSwitch)7742         public void applyAllVolumes(boolean userSwitch) {
7743             String caller = "from vgs";
7744             synchronized (VolumeStreamState.class) {
7745                 // apply device specific volumes first
7746                 for (int i = 0; i < mIndexMap.size(); i++) {
7747                     int device = mIndexMap.keyAt(i);
7748                     int index = mIndexMap.valueAt(i);
7749                     boolean synced = false;
7750                     if (device != AudioSystem.DEVICE_OUT_DEFAULT) {
7751                         for (int stream : getLegacyStreamTypes()) {
7752                             if (isValidStream(stream)) {
7753                                 boolean streamMuted = mStreamStates[stream].mIsMuted;
7754                                 int deviceForStream = getDeviceForStream(stream);
7755                                 int indexForStream =
7756                                         (mStreamStates[stream].getIndex(deviceForStream) + 5) / 10;
7757                                 if (device == deviceForStream) {
7758                                     if (indexForStream == index && (isMuted() == streamMuted)
7759                                             && isVssMuteBijective(stream)) {
7760                                         synced = true;
7761                                         continue;
7762                                     }
7763                                     if (indexForStream != index) {
7764                                         mStreamStates[stream].setIndex(index * 10, device, caller,
7765                                                 true /*hasModifyAudioSettings*/);
7766                                     }
7767                                     if ((isMuted() != streamMuted) && isVssMuteBijective(stream)) {
7768                                         mStreamStates[stream].mute(isMuted());
7769                                     }
7770                                 }
7771                             }
7772                         }
7773                         if (!synced) {
7774                             if (DEBUG_VOL) {
7775                                 Log.d(TAG, "applyAllVolumes: apply index " + index + ", group "
7776                                         + mAudioVolumeGroup.name() + " and device "
7777                                         + AudioSystem.getOutputDeviceName(device));
7778                             }
7779                             setVolumeIndexInt(isMuted() ? 0 : index, device, 0 /*flags*/);
7780                         }
7781                     }
7782                 }
7783                 // apply default volume last: by convention , default device volume will be used
7784                 // by audio policy manager if no explicit volume is present for a given device type
7785                 int index = getIndex(AudioSystem.DEVICE_OUT_DEFAULT);
7786                 boolean synced = false;
7787                 int deviceForVolume = getDeviceForVolume();
7788                 boolean forceDeviceSync = userSwitch && (mIndexMap.indexOfKey(deviceForVolume) < 0);
7789                 for (int stream : getLegacyStreamTypes()) {
7790                     if (isValidStream(stream)) {
7791                         boolean streamMuted = mStreamStates[stream].mIsMuted;
7792                         int defaultStreamIndex = (mStreamStates[stream].getIndex(
7793                                         AudioSystem.DEVICE_OUT_DEFAULT) + 5) / 10;
7794                         if (forceDeviceSync) {
7795                             mStreamStates[stream].setIndex(index * 10, deviceForVolume, caller,
7796                                     true /*hasModifyAudioSettings*/);
7797                         }
7798                         if (defaultStreamIndex == index && (isMuted() == streamMuted)
7799                                 && isVssMuteBijective(stream)) {
7800                             synced = true;
7801                             continue;
7802                         }
7803                         if (defaultStreamIndex != index) {
7804                             mStreamStates[stream].setIndex(
7805                                     index * 10, AudioSystem.DEVICE_OUT_DEFAULT, caller,
7806                                     true /*hasModifyAudioSettings*/);
7807                         }
7808                         if ((isMuted() != streamMuted) && isVssMuteBijective(stream)) {
7809                             mStreamStates[stream].mute(isMuted());
7810                         }
7811                     }
7812                 }
7813                 if (!synced) {
7814                     if (DEBUG_VOL) {
7815                         Log.d(TAG, "applyAllVolumes: apply default device index " + index
7816                                 + ", group " + mAudioVolumeGroup.name());
7817                     }
7818                     setVolumeIndexInt(
7819                             isMuted() ? 0 : index, AudioSystem.DEVICE_OUT_DEFAULT, 0 /*flags*/);
7820                 }
7821                 if (forceDeviceSync) {
7822                     if (DEBUG_VOL) {
7823                         Log.d(TAG, "applyAllVolumes: forceDeviceSync index " + index
7824                                 + ", device " + AudioSystem.getOutputDeviceName(deviceForVolume)
7825                                 + ", group " + mAudioVolumeGroup.name());
7826                     }
7827                     setVolumeIndexInt(isMuted() ? 0 : index, deviceForVolume, 0);
7828                 }
7829             }
7830         }
7831 
clearIndexCache()7832         public void clearIndexCache() {
7833             mIndexMap.clear();
7834         }
7835 
persistVolumeGroup(int device)7836         private void persistVolumeGroup(int device) {
7837             // No need to persist the index if the volume group is backed up
7838             // by a public stream type as this is redundant
7839             if (mUseFixedVolume || mHasValidStreamType) {
7840                 return;
7841             }
7842             if (DEBUG_VOL) {
7843                 Log.v(TAG, "persistVolumeGroup: storing index " + getIndex(device) + " for group "
7844                         + mAudioVolumeGroup.name()
7845                         + ", device " + AudioSystem.getOutputDeviceName(device)
7846                         + " and User=" + getCurrentUserId()
7847                         + " mSettingName: " + mSettingName);
7848             }
7849 
7850             boolean success = mSettings.putSystemIntForUser(mContentResolver,
7851                     getSettingNameForDevice(device),
7852                     getIndex(device),
7853                     isMusic() ? UserHandle.USER_SYSTEM : UserHandle.USER_CURRENT);
7854             if (!success) {
7855                 Log.e(TAG, "persistVolumeGroup failed for group " +  mAudioVolumeGroup.name());
7856             }
7857         }
7858 
readSettings()7859         public void readSettings() {
7860             synchronized (VolumeStreamState.class) {
7861                 // force maximum volume on all streams if fixed volume property is set
7862                 if (mUseFixedVolume) {
7863                     mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
7864                     return;
7865                 }
7866                 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
7867                     // retrieve current volume for device
7868                     // if no volume stored for current volume group and device, use default volume
7869                     // if default device, continue otherwise
7870                     int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT)
7871                             ? AudioSystem.DEFAULT_STREAM_VOLUME[mPublicStreamType] : -1;
7872                     int index;
7873                     String name = getSettingNameForDevice(device);
7874                     index = mSettings.getSystemIntForUser(
7875                             mContentResolver, name, defaultIndex,
7876                             isMusic() ? UserHandle.USER_SYSTEM : UserHandle.USER_CURRENT);
7877                     if (index == -1) {
7878                         continue;
7879                     }
7880                     if (mPublicStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED
7881                             && mCameraSoundForced) {
7882                         index = mIndexMax;
7883                     }
7884                     if (DEBUG_VOL) {
7885                         Log.v(TAG, "readSettings: found stored index " + getValidIndex(index)
7886                                  + " for group " + mAudioVolumeGroup.name() + ", device: " + name
7887                                  + ", User=" + getCurrentUserId());
7888                     }
7889                     mIndexMap.put(device, getValidIndex(index));
7890                 }
7891             }
7892         }
7893 
7894         @GuardedBy("AudioService.VolumeStreamState.class")
getValidIndex(int index)7895         private int getValidIndex(int index) {
7896             if (index < mIndexMin) {
7897                 return mIndexMin;
7898             } else if (mUseFixedVolume || index > mIndexMax) {
7899                 return mIndexMax;
7900             }
7901             return index;
7902         }
7903 
getSettingNameForDevice(int device)7904         public @NonNull String getSettingNameForDevice(int device) {
7905             String suffix = AudioSystem.getOutputDeviceName(device);
7906             if (suffix.isEmpty()) {
7907                 return mSettingName;
7908             }
7909             return mSettingName + "_" + AudioSystem.getOutputDeviceName(device);
7910         }
7911 
setSettingName(String settingName)7912         void setSettingName(String settingName) {
7913             mSettingName = settingName;
7914         }
7915 
getSettingName()7916         String getSettingName() {
7917             return mSettingName;
7918         }
7919 
dump(PrintWriter pw)7920         private void dump(PrintWriter pw) {
7921             pw.println("- VOLUME GROUP " + mAudioVolumeGroup.name() + ":");
7922             pw.print("   Muted: ");
7923             pw.println(mIsMuted);
7924             pw.print("   Min: ");
7925             pw.println(mIndexMin);
7926             pw.print("   Max: ");
7927             pw.println(mIndexMax);
7928             pw.print("   Current: ");
7929             for (int i = 0; i < mIndexMap.size(); i++) {
7930                 if (i > 0) {
7931                     pw.print(", ");
7932                 }
7933                 int device = mIndexMap.keyAt(i);
7934                 pw.print(Integer.toHexString(device));
7935                 String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
7936                         : AudioSystem.getOutputDeviceName(device);
7937                 if (!deviceName.isEmpty()) {
7938                     pw.print(" (");
7939                     pw.print(deviceName);
7940                     pw.print(")");
7941                 }
7942                 pw.print(": ");
7943                 pw.print(mIndexMap.valueAt(i));
7944             }
7945             pw.println();
7946             pw.print("   Devices: ");
7947             int n = 0;
7948             int devices = getDeviceForVolume();
7949             for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
7950                 if ((devices & device) == device) {
7951                     if (n++ > 0) {
7952                         pw.print(", ");
7953                     }
7954                     pw.print(AudioSystem.getOutputDeviceName(device));
7955                 }
7956             }
7957             pw.println();
7958             pw.print("   Streams: ");
7959             Arrays.stream(getLegacyStreamTypes())
7960                     .forEach(stream -> pw.print(AudioSystem.streamToString(stream) + " "));
7961         }
7962     }
7963 
7964 
7965     // NOTE: Locking order for synchronized objects related to volume or ringer mode management:
7966     //  1 mScoclient OR mSafeMediaVolumeState
7967     //  2   mSetModeLock
7968     //  3     mSettingsLock
7969     //  4       VolumeStreamState.class
7970     private class VolumeStreamState {
7971         private final int mStreamType;
7972         private VolumeGroupState mVolumeGroupState = null;
7973         private int mIndexMin;
7974         // min index when user doesn't have permission to change audio settings
7975         private int mIndexMinNoPerm;
7976         private int mIndexMax;
7977 
7978         private boolean mIsMuted = false;
7979         private boolean mIsMutedInternally = false;
7980         private String mVolumeIndexSettingName;
7981         @NonNull private Set<Integer> mObservedDeviceSet = new TreeSet<>();
7982 
7983         private final SparseIntArray mIndexMap = new SparseIntArray(8) {
7984             @Override
7985             public void put(int key, int value) {
7986                 super.put(key, value);
7987                 record("put", key, value);
7988             }
7989             @Override
7990             public void setValueAt(int index, int value) {
7991                 super.setValueAt(index, value);
7992                 record("setValueAt", keyAt(index), value);
7993             }
7994 
7995             // Record all changes in the VolumeStreamState
7996             private void record(String event, int key, int value) {
7997                 final String device = key == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
7998                         : AudioSystem.getOutputDeviceName(key);
7999                 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_VOLUME + MediaMetrics.SEPARATOR
8000                         + AudioSystem.streamToString(mStreamType)
8001                         + "." + device)
8002                         .set(MediaMetrics.Property.EVENT, event)
8003                         .set(MediaMetrics.Property.INDEX, value)
8004                         .set(MediaMetrics.Property.MIN_INDEX, mIndexMin)
8005                         .set(MediaMetrics.Property.MAX_INDEX, mIndexMax)
8006                         .record();
8007             }
8008         };
8009         private final Intent mVolumeChanged;
8010         private final Intent mStreamDevicesChanged;
8011 
VolumeStreamState(String settingName, int streamType)8012         private VolumeStreamState(String settingName, int streamType) {
8013             mVolumeIndexSettingName = settingName;
8014 
8015             mStreamType = streamType;
8016             mIndexMin = MIN_STREAM_VOLUME[streamType] * 10;
8017             mIndexMinNoPerm = mIndexMin; // may be overwritten later in updateNoPermMinIndex()
8018             mIndexMax = MAX_STREAM_VOLUME[streamType] * 10;
8019             final int status = AudioSystem.initStreamVolume(
8020                     streamType, mIndexMin / 10, mIndexMax / 10);
8021             if (status != AudioSystem.AUDIO_STATUS_OK) {
8022                 sLifecycleLogger.log(new AudioEventLogger.StringEvent(
8023                          "VSS() stream:" + streamType + " initStreamVolume=" + status)
8024                         .printLog(ALOGE, TAG));
8025                 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0,
8026                         "VSS()" /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
8027             }
8028 
8029             readSettings();
8030             mVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION);
8031             mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
8032             mStreamDevicesChanged = new Intent(AudioManager.STREAM_DEVICES_CHANGED_ACTION);
8033             mStreamDevicesChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
8034         }
8035 
8036         /**
8037          * Associate a {@link volumeGroupState} on the {@link VolumeStreamState}.
8038          * <p> It helps to synchronize the index, mute attributes on the maching
8039          * {@link volumeGroupState}
8040          * @param volumeGroupState matching the {@link VolumeStreamState}
8041          */
setVolumeGroupState(VolumeGroupState volumeGroupState)8042         public void setVolumeGroupState(VolumeGroupState volumeGroupState) {
8043             mVolumeGroupState = volumeGroupState;
8044             if (mVolumeGroupState != null) {
8045                 mVolumeGroupState.setSettingName(mVolumeIndexSettingName);
8046             }
8047         }
8048         /**
8049          * Update the minimum index that can be used without MODIFY_AUDIO_SETTINGS permission
8050          * @param index minimum index expressed in "UI units", i.e. no 10x factor
8051          */
updateNoPermMinIndex(int index)8052         public void updateNoPermMinIndex(int index) {
8053             mIndexMinNoPerm = index * 10;
8054             if (mIndexMinNoPerm < mIndexMin) {
8055                 Log.e(TAG, "Invalid mIndexMinNoPerm for stream " + mStreamType);
8056                 mIndexMinNoPerm = mIndexMin;
8057             }
8058         }
8059 
8060         /**
8061          * Returns a list of devices associated with the stream type.
8062          *
8063          * This is a reference to the local list, do not modify.
8064          */
8065         @GuardedBy("VolumeStreamState.class")
8066         @NonNull
observeDevicesForStream_syncVSS( boolean checkOthers)8067         public Set<Integer> observeDevicesForStream_syncVSS(
8068                 boolean checkOthers) {
8069             if (!mSystemServer.isPrivileged()) {
8070                 return new TreeSet<Integer>();
8071             }
8072             final Set<Integer> deviceSet =
8073                     getDeviceSetForStreamDirect(mStreamType);
8074             if (deviceSet.equals(mObservedDeviceSet)) {
8075                 return mObservedDeviceSet;
8076             }
8077 
8078             // Use legacy bit masks for message signalling.
8079             // TODO(b/185386781): message needs update since it uses devices bit-mask.
8080             final int devices = AudioSystem.getDeviceMaskFromSet(deviceSet);
8081             final int prevDevices = AudioSystem.getDeviceMaskFromSet(mObservedDeviceSet);
8082 
8083             mObservedDeviceSet = deviceSet;
8084             if (checkOthers) {
8085                 // one stream's devices have changed, check the others
8086                 postObserveDevicesForAllStreams(mStreamType);
8087             }
8088             // log base stream changes to the event log
8089             if (mStreamVolumeAlias[mStreamType] == mStreamType) {
8090                 EventLogTags.writeStreamDevicesChanged(mStreamType, prevDevices, devices);
8091             }
8092             // send STREAM_DEVICES_CHANGED_ACTION on the message handler so it is scheduled after
8093             // the postObserveDevicesForStreams is handled
8094             sendMsg(mAudioHandler,
8095                     MSG_STREAM_DEVICES_CHANGED,
8096                     SENDMSG_QUEUE, prevDevices /*arg1*/, devices /*arg2*/,
8097                     // ok to send reference to this object, it is final
8098                     mStreamDevicesChanged /*obj*/, 0 /*delay*/);
8099             return mObservedDeviceSet;
8100         }
8101 
getSettingNameForDevice(int device)8102         public @Nullable String getSettingNameForDevice(int device) {
8103             if (!hasValidSettingsName()) {
8104                 return null;
8105             }
8106             final String suffix = AudioSystem.getOutputDeviceName(device);
8107             if (suffix.isEmpty()) {
8108                 return mVolumeIndexSettingName;
8109             }
8110             return mVolumeIndexSettingName + "_" + suffix;
8111         }
8112 
hasValidSettingsName()8113         private boolean hasValidSettingsName() {
8114             return (mVolumeIndexSettingName != null && !mVolumeIndexSettingName.isEmpty());
8115         }
8116 
setSettingName(String settingName)8117         void setSettingName(String settingName) {
8118             mVolumeIndexSettingName = settingName;
8119             if (mVolumeGroupState != null) {
8120                 mVolumeGroupState.setSettingName(mVolumeIndexSettingName);
8121             }
8122         }
8123 
getSettingName()8124         String getSettingName() {
8125             return mVolumeIndexSettingName;
8126         }
8127 
readSettings()8128         public void readSettings() {
8129             synchronized (mSettingsLock) {
8130                 synchronized (VolumeStreamState.class) {
8131                     // force maximum volume on all streams if fixed volume property is set
8132                     if (mUseFixedVolume) {
8133                         mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
8134                         return;
8135                     }
8136                     // do not read system stream volume from settings: this stream is always aliased
8137                     // to another stream type and its volume is never persisted. Values in settings can
8138                     // only be stale values
8139                     if ((mStreamType == AudioSystem.STREAM_SYSTEM) ||
8140                             (mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED)) {
8141                         int index = 10 * AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType];
8142                         if (mCameraSoundForced) {
8143                             index = mIndexMax;
8144                         }
8145                         mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, index);
8146                         return;
8147                     }
8148                 }
8149             }
8150             synchronized (VolumeStreamState.class) {
8151                 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
8152 
8153                     // retrieve current volume for device
8154                     // if no volume stored for current stream and device, use default volume if default
8155                     // device, continue otherwise
8156                     int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) ?
8157                             AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType] : -1;
8158                     int index;
8159                     if (!hasValidSettingsName()) {
8160                         index = defaultIndex;
8161                     } else {
8162                         String name = getSettingNameForDevice(device);
8163                         index = mSettings.getSystemIntForUser(
8164                                 mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT);
8165                     }
8166                     if (index == -1) {
8167                         continue;
8168                     }
8169 
8170                     mIndexMap.put(device, getValidIndex(10 * index,
8171                             true /*hasModifyAudioSettings*/));
8172                 }
8173             }
8174         }
8175 
getAbsoluteVolumeIndex(int index)8176         private int getAbsoluteVolumeIndex(int index) {
8177             /* Special handling for Bluetooth Absolute Volume scenario
8178              * If we send full audio gain, some accessories are too loud even at its lowest
8179              * volume. We are not able to enumerate all such accessories, so here is the
8180              * workaround from phone side.
8181              * Pre-scale volume at lowest volume steps 1 2 and 3.
8182              * For volume step 0, set audio gain to 0 as some accessories won't mute on their end.
8183              */
8184             if (index == 0) {
8185                 // 0% for volume 0
8186                 index = 0;
8187             } else if (index > 0 && index <= 3) {
8188                 // Pre-scale for volume steps 1 2 and 3
8189                 index = (int) (mIndexMax * mPrescaleAbsoluteVolume[index - 1]) / 10;
8190             } else {
8191                 // otherwise, full gain
8192                 index = (mIndexMax + 5) / 10;
8193             }
8194             return index;
8195         }
8196 
setStreamVolumeIndex(int index, int device)8197         private void setStreamVolumeIndex(int index, int device) {
8198             // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted.
8199             // This allows RX path muting by the audio HAL only when explicitly muted but not when
8200             // index is just set to 0 to repect BT requirements
8201             if (mStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0
8202                     && !isFullyMuted()) {
8203                 index = 1;
8204             }
8205             mAudioSystem.setStreamVolumeIndexAS(mStreamType, index, device);
8206         }
8207 
8208         // must be called while synchronized VolumeStreamState.class
applyDeviceVolume_syncVSS(int device)8209         /*package*/ void applyDeviceVolume_syncVSS(int device) {
8210             int index;
8211             if (isFullyMuted()) {
8212                 index = 0;
8213             } else if (isAbsoluteVolumeDevice(device)
8214                     || isA2dpAbsoluteVolumeDevice(device)
8215                     || AudioSystem.isLeAudioDeviceType(device)) {
8216                 index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10);
8217             } else if (isFullVolumeDevice(device)) {
8218                 index = (mIndexMax + 5)/10;
8219             } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
8220                 index = (mIndexMax + 5)/10;
8221             } else {
8222                 index = (getIndex(device) + 5)/10;
8223             }
8224             setStreamVolumeIndex(index, device);
8225         }
8226 
applyAllVolumes()8227         public void applyAllVolumes() {
8228             synchronized (VolumeStreamState.class) {
8229                 // apply device specific volumes first
8230                 int index;
8231                 for (int i = 0; i < mIndexMap.size(); i++) {
8232                     final int device = mIndexMap.keyAt(i);
8233                     if (device != AudioSystem.DEVICE_OUT_DEFAULT) {
8234                         if (isFullyMuted()) {
8235                             index = 0;
8236                         } else if (isAbsoluteVolumeDevice(device)
8237                                 || isA2dpAbsoluteVolumeDevice(device)
8238                                 || AudioSystem.isLeAudioDeviceType(device)) {
8239                             index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10);
8240                         } else if (isFullVolumeDevice(device)) {
8241                             index = (mIndexMax + 5)/10;
8242                         } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
8243                             index = (mIndexMax + 5)/10;
8244                         } else {
8245                             index = (mIndexMap.valueAt(i) + 5)/10;
8246                         }
8247                         setStreamVolumeIndex(index, device);
8248                     }
8249                 }
8250                 // apply default volume last: by convention , default device volume will be used
8251                 // by audio policy manager if no explicit volume is present for a given device type
8252                 if (isFullyMuted()) {
8253                     index = 0;
8254                 } else {
8255                     index = (getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)/10;
8256                 }
8257                 setStreamVolumeIndex(index, AudioSystem.DEVICE_OUT_DEFAULT);
8258             }
8259         }
8260 
adjustIndex(int deltaIndex, int device, String caller, boolean hasModifyAudioSettings)8261         public boolean adjustIndex(int deltaIndex, int device, String caller,
8262                 boolean hasModifyAudioSettings) {
8263             return setIndex(getIndex(device) + deltaIndex, device, caller,
8264                     hasModifyAudioSettings);
8265         }
8266 
setIndex(int index, int device, String caller, boolean hasModifyAudioSettings)8267         public boolean setIndex(int index, int device, String caller,
8268                 boolean hasModifyAudioSettings) {
8269             boolean changed;
8270             int oldIndex;
8271             final boolean isCurrentDevice;
8272             synchronized (mSettingsLock) {
8273                 synchronized (VolumeStreamState.class) {
8274                     oldIndex = getIndex(device);
8275                     index = getValidIndex(index, hasModifyAudioSettings);
8276                     if ((mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED) && mCameraSoundForced) {
8277                         index = mIndexMax;
8278                     }
8279                     mIndexMap.put(device, index);
8280 
8281                     changed = oldIndex != index;
8282                     // Apply change to all streams using this one as alias if:
8283                     // - the index actually changed OR
8284                     // - there is no volume index stored for this device on alias stream.
8285                     // If changing volume of current device, also change volume of current
8286                     // device on aliased stream
8287                     isCurrentDevice = (device == getDeviceForStream(mStreamType));
8288                     final int numStreamTypes = AudioSystem.getNumStreamTypes();
8289                     for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
8290                         final VolumeStreamState aliasStreamState = mStreamStates[streamType];
8291                         if (streamType != mStreamType &&
8292                                 mStreamVolumeAlias[streamType] == mStreamType &&
8293                                 (changed || !aliasStreamState.hasIndexForDevice(device))) {
8294                             final int scaledIndex = rescaleIndex(index, mStreamType, streamType);
8295                             aliasStreamState.setIndex(scaledIndex, device, caller,
8296                                     hasModifyAudioSettings);
8297                             if (isCurrentDevice) {
8298                                 aliasStreamState.setIndex(scaledIndex,
8299                                         getDeviceForStream(streamType), caller,
8300                                         hasModifyAudioSettings);
8301                             }
8302                         }
8303                     }
8304                     // Mirror changes in SPEAKER ringtone volume on SCO when
8305                     if (changed && mStreamType == AudioSystem.STREAM_RING
8306                             && device == AudioSystem.DEVICE_OUT_SPEAKER) {
8307                         for (int i = 0; i < mIndexMap.size(); i++) {
8308                             int otherDevice = mIndexMap.keyAt(i);
8309                             if (AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(otherDevice)) {
8310                                 mIndexMap.put(otherDevice, index);
8311                             }
8312                         }
8313                     }
8314                 }
8315             }
8316             if (changed) {
8317                 // If associated to volume group, update group cache
8318                 updateVolumeGroupIndex(device, /* forceMuteState= */ false);
8319 
8320                 oldIndex = (oldIndex + 5) / 10;
8321                 index = (index + 5) / 10;
8322                 // log base stream changes to the event log
8323                 if (mStreamVolumeAlias[mStreamType] == mStreamType) {
8324                     if (caller == null) {
8325                         Log.w(TAG, "No caller for volume_changed event", new Throwable());
8326                     }
8327                     EventLogTags.writeVolumeChanged(mStreamType, oldIndex, index, mIndexMax / 10,
8328                             caller);
8329                 }
8330                 // fire changed intents for all streams, but only when the device it changed on
8331                 // is the current device
8332                 if ((index != oldIndex) && isCurrentDevice) {
8333                     mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index);
8334                     mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex);
8335                     mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS,
8336                             mStreamVolumeAlias[mStreamType]);
8337                     AudioService.sVolumeLogger.log(new VolChangedBroadcastEvent(
8338                             mStreamType, mStreamVolumeAlias[mStreamType], index));
8339                     sendBroadcastToAll(mVolumeChanged);
8340                 }
8341             }
8342             return changed;
8343         }
8344 
getIndex(int device)8345         public int getIndex(int device) {
8346             synchronized (VolumeStreamState.class) {
8347                 int index = mIndexMap.get(device, -1);
8348                 if (index == -1) {
8349                     // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
8350                     index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT);
8351                 }
8352                 return index;
8353             }
8354         }
8355 
hasIndexForDevice(int device)8356         public boolean hasIndexForDevice(int device) {
8357             synchronized (VolumeStreamState.class) {
8358                 return (mIndexMap.get(device, -1) != -1);
8359             }
8360         }
8361 
getMaxIndex()8362         public int getMaxIndex() {
8363             return mIndexMax;
8364         }
8365 
8366         /**
8367          * @return the lowest index regardless of permissions
8368          */
getMinIndex()8369         public int getMinIndex() {
8370             return mIndexMin;
8371         }
8372 
8373         /**
8374          * @param isPrivileged true if the caller is privileged and not subject to minimum
8375          *                     volume index thresholds
8376          * @return the lowest index that this caller can set or adjust to
8377          */
getMinIndex(boolean isPrivileged)8378         public int getMinIndex(boolean isPrivileged) {
8379             return isPrivileged ? mIndexMin : mIndexMinNoPerm;
8380         }
8381 
8382         /**
8383          * Copies all device/index pairs from the given VolumeStreamState after initializing
8384          * them with the volume for DEVICE_OUT_DEFAULT. No-op if the source VolumeStreamState
8385          * has the same stream type as this instance.
8386          * @param srcStream
8387          * @param caller
8388          */
8389         // must be sync'd on mSettingsLock before VolumeStreamState.class
8390         @GuardedBy("VolumeStreamState.class")
setAllIndexes(VolumeStreamState srcStream, String caller)8391         public void setAllIndexes(VolumeStreamState srcStream, String caller) {
8392             if (mStreamType == srcStream.mStreamType) {
8393                 return;
8394             }
8395             int srcStreamType = srcStream.getStreamType();
8396             // apply default device volume from source stream to all devices first in case
8397             // some devices are present in this stream state but not in source stream state
8398             int index = srcStream.getIndex(AudioSystem.DEVICE_OUT_DEFAULT);
8399             index = rescaleIndex(index, srcStreamType, mStreamType);
8400             for (int i = 0; i < mIndexMap.size(); i++) {
8401                 mIndexMap.put(mIndexMap.keyAt(i), index);
8402             }
8403             // Now apply actual volume for devices in source stream state
8404             SparseIntArray srcMap = srcStream.mIndexMap;
8405             for (int i = 0; i < srcMap.size(); i++) {
8406                 int device = srcMap.keyAt(i);
8407                 index = srcMap.valueAt(i);
8408                 index = rescaleIndex(index, srcStreamType, mStreamType);
8409 
8410                 setIndex(index, device, caller, true /*hasModifyAudioSettings*/);
8411             }
8412         }
8413 
8414         // must be sync'd on mSettingsLock before VolumeStreamState.class
8415         @GuardedBy("VolumeStreamState.class")
setAllIndexesToMax()8416         public void setAllIndexesToMax() {
8417             for (int i = 0; i < mIndexMap.size(); i++) {
8418                 mIndexMap.put(mIndexMap.keyAt(i), mIndexMax);
8419             }
8420         }
8421 
8422         // If associated to volume group, update group cache
updateVolumeGroupIndex(int device, boolean forceMuteState)8423         private void updateVolumeGroupIndex(int device, boolean forceMuteState) {
8424             synchronized (VolumeStreamState.class) {
8425                 if (mVolumeGroupState != null) {
8426                     int groupIndex = (getIndex(device) + 5) / 10;
8427                     if (DEBUG_VOL) {
8428                         Log.d(TAG, "updateVolumeGroupIndex for stream " + mStreamType
8429                                 + ", muted=" + mIsMuted + ", device=" + device + ", index="
8430                                 + getIndex(device) + ", group " + mVolumeGroupState.name()
8431                                 + " Muted=" + mVolumeGroupState.isMuted() + ", Index=" + groupIndex
8432                                 + ", forceMuteState=" + forceMuteState);
8433                     }
8434                     mVolumeGroupState.updateVolumeIndex(groupIndex, device);
8435                     // Only propage mute of stream when applicable
8436                     if (isMutable()) {
8437                         // For call stream, align mute only when muted, not when index is set to 0
8438                         mVolumeGroupState.mute(
8439                                 forceMuteState ? mIsMuted :
8440                                         (groupIndex == 0 && !isCallStream(mStreamType))
8441                                                 || mIsMuted);
8442                     }
8443                 }
8444             }
8445         }
8446 
8447         /**
8448          * Mute/unmute the stream
8449          * @param state the new mute state
8450          * @return true if the mute state was changed
8451          */
mute(boolean state)8452         public boolean mute(boolean state) {
8453             boolean changed = false;
8454             synchronized (VolumeStreamState.class) {
8455                 changed = mute(state, true);
8456             }
8457             if (changed) {
8458                 broadcastMuteSetting(mStreamType, state);
8459             }
8460             return changed;
8461         }
8462 
8463         /**
8464          * Mute/unmute the stream by AudioService
8465          * @param state the new mute state
8466          * @return true if the mute state was changed
8467          */
muteInternally(boolean state)8468         public boolean muteInternally(boolean state) {
8469             boolean changed = false;
8470             synchronized (VolumeStreamState.class) {
8471                 if (state != mIsMutedInternally) {
8472                     changed = true;
8473                     mIsMutedInternally = state;
8474                     // mute immediately to avoid delay and preemption when using a message.
8475                     applyAllVolumes();
8476                 }
8477             }
8478             if (changed) {
8479                 sVolumeLogger.log(new VolumeEvent(
8480                         VolumeEvent.VOL_MUTE_STREAM_INT, mStreamType, state));
8481             }
8482             return changed;
8483         }
8484 
8485         @GuardedBy("VolumeStreamState.class")
isFullyMuted()8486         public boolean isFullyMuted() {
8487             return mIsMuted || mIsMutedInternally;
8488         }
8489 
8490 
isMutable()8491         private boolean isMutable() {
8492             return isStreamAffectedByMute(mStreamType)
8493                     && (mIndexMin == 0 || isCallStream(mStreamType));
8494         }
8495 
8496         /**
8497          * Mute/unmute the stream
8498          * @param state the new mute state
8499          * @param apply true to propagate to HW, or false just to update the cache. May be needed
8500          * to mute a stream and its aliases as applyAllVolume will force settings to aliases.
8501          * It prevents unnecessary calls to {@see AudioSystem#setStreamVolume}
8502          * @return true if the mute state was changed
8503          */
mute(boolean state, boolean apply)8504         public boolean mute(boolean state, boolean apply) {
8505             synchronized (VolumeStreamState.class) {
8506                 boolean changed = state != mIsMuted;
8507                 if (changed) {
8508                     mIsMuted = state;
8509                     if (apply) {
8510                         doMute();
8511                     }
8512                 }
8513                 return changed;
8514             }
8515         }
8516 
doMute()8517         public void doMute() {
8518             synchronized (VolumeStreamState.class) {
8519                 // If associated to volume group, update group cache
8520                 updateVolumeGroupIndex(getDeviceForStream(mStreamType), /* forceMuteState= */ true);
8521 
8522                 // Set the new mute volume. This propagates the values to
8523                 // the audio system, otherwise the volume won't be changed
8524                 // at the lower level.
8525                 sendMsg(mAudioHandler,
8526                         MSG_SET_ALL_VOLUMES,
8527                         SENDMSG_QUEUE,
8528                         0,
8529                         0,
8530                         this, 0);
8531             }
8532         }
8533 
getStreamType()8534         public int getStreamType() {
8535             return mStreamType;
8536         }
8537 
checkFixedVolumeDevices()8538         public void checkFixedVolumeDevices() {
8539             synchronized (VolumeStreamState.class) {
8540                 // ignore settings for fixed volume devices: volume should always be at max or 0
8541                 if (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_MUSIC) {
8542                     for (int i = 0; i < mIndexMap.size(); i++) {
8543                         int device = mIndexMap.keyAt(i);
8544                         int index = mIndexMap.valueAt(i);
8545                         if (isFullVolumeDevice(device)
8546                                 || (isFixedVolumeDevice(device) && index != 0)) {
8547                             mIndexMap.put(device, mIndexMax);
8548                         }
8549                         applyDeviceVolume_syncVSS(device);
8550                     }
8551                 }
8552             }
8553         }
8554 
getValidIndex(int index, boolean hasModifyAudioSettings)8555         private int getValidIndex(int index, boolean hasModifyAudioSettings) {
8556             final int indexMin = hasModifyAudioSettings ? mIndexMin : mIndexMinNoPerm;
8557             if (index < indexMin) {
8558                 return indexMin;
8559             } else if (mUseFixedVolume || index > mIndexMax) {
8560                 return mIndexMax;
8561             }
8562 
8563             return index;
8564         }
8565 
dump(PrintWriter pw)8566         private void dump(PrintWriter pw) {
8567             pw.print("   Muted: ");
8568             pw.println(mIsMuted);
8569             pw.print("   Muted Internally: ");
8570             pw.println(mIsMutedInternally);
8571             pw.print("   Min: ");
8572             pw.print((mIndexMin + 5) / 10);
8573             if (mIndexMin != mIndexMinNoPerm) {
8574                 pw.print(" w/o perm:");
8575                 pw.println((mIndexMinNoPerm + 5) / 10);
8576             } else {
8577                 pw.println();
8578             }
8579             pw.print("   Max: ");
8580             pw.println((mIndexMax + 5) / 10);
8581             pw.print("   streamVolume:"); pw.println(getStreamVolume(mStreamType));
8582             pw.print("   Current: ");
8583             for (int i = 0; i < mIndexMap.size(); i++) {
8584                 if (i > 0) {
8585                     pw.print(", ");
8586                 }
8587                 final int device = mIndexMap.keyAt(i);
8588                 pw.print(Integer.toHexString(device));
8589                 final String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
8590                         : AudioSystem.getOutputDeviceName(device);
8591                 if (!deviceName.isEmpty()) {
8592                     pw.print(" (");
8593                     pw.print(deviceName);
8594                     pw.print(")");
8595                 }
8596                 pw.print(": ");
8597                 final int index = (mIndexMap.valueAt(i) + 5) / 10;
8598                 pw.print(index);
8599             }
8600             pw.println();
8601             pw.print("   Devices: ");
8602             pw.print(AudioSystem.deviceSetToString(getDeviceSetForStream(mStreamType)));
8603             pw.println();
8604             pw.print("   Volume Group: ");
8605             pw.println(mVolumeGroupState != null ? mVolumeGroupState.name() : "n/a");
8606         }
8607     }
8608 
8609     /** Thread that handles native AudioSystem control. */
8610     private class AudioSystemThread extends Thread {
AudioSystemThread()8611         AudioSystemThread() {
8612             super("AudioService");
8613         }
8614 
8615         @Override
run()8616         public void run() {
8617             // Set this thread up so the handler will work on it
8618             Looper.prepare();
8619 
8620             synchronized(AudioService.this) {
8621                 mAudioHandler = new AudioHandler();
8622 
8623                 // Notify that the handler has been created
8624                 AudioService.this.notify();
8625             }
8626 
8627             // Listen for volume change requests that are set by VolumePanel
8628             Looper.loop();
8629         }
8630     }
8631 
8632     private static final class DeviceVolumeUpdate {
8633         final int mStreamType;
8634         final int mDevice;
8635         final @NonNull String mCaller;
8636         private static final int NO_NEW_INDEX = -2049;
8637         private final int mVssVolIndex;
8638 
8639         // Constructor with volume index, meant to cause this volume to be set and applied for the
8640         // given stream type on the given device
DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller)8641         DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller) {
8642             mStreamType = streamType;
8643             mVssVolIndex = vssVolIndex;
8644             mDevice = device;
8645             mCaller = caller;
8646         }
8647 
8648         // Constructor with no volume index, meant to cause re-apply of volume for the given
8649         // stream type on the given device
DeviceVolumeUpdate(int streamType, int device, @NonNull String caller)8650         DeviceVolumeUpdate(int streamType, int device, @NonNull String caller) {
8651             mStreamType = streamType;
8652             mVssVolIndex = NO_NEW_INDEX;
8653             mDevice = device;
8654             mCaller = caller;
8655         }
8656 
hasVolumeIndex()8657         boolean hasVolumeIndex() {
8658             return mVssVolIndex != NO_NEW_INDEX;
8659         }
8660 
getVolumeIndex()8661         int getVolumeIndex() throws IllegalStateException {
8662             Preconditions.checkState(mVssVolIndex != NO_NEW_INDEX);
8663             return mVssVolIndex;
8664         }
8665     }
8666 
8667     /** only public for mocking/spying, do not call outside of AudioService */
8668     @VisibleForTesting
postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device, String caller)8669     public void postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device,
8670                                                 String caller) {
8671         sendMsg(mAudioHandler,
8672                 MSG_SET_DEVICE_STREAM_VOLUME,
8673                 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/,
8674                 new DeviceVolumeUpdate(streamType, vssVolIndex, device, caller),
8675                 0 /*delay*/);
8676     }
8677 
postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller)8678     /*package*/ void postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller) {
8679         sendMsg(mAudioHandler,
8680                 MSG_SET_DEVICE_STREAM_VOLUME,
8681                 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/,
8682                 new DeviceVolumeUpdate(streamType, device, caller),
8683                 0 /*delay*/);
8684     }
8685 
onSetVolumeIndexOnDevice(@onNull DeviceVolumeUpdate update)8686     private void onSetVolumeIndexOnDevice(@NonNull DeviceVolumeUpdate update) {
8687         final VolumeStreamState streamState = mStreamStates[update.mStreamType];
8688         if (update.hasVolumeIndex()) {
8689             int index = update.getVolumeIndex();
8690             if (!checkSafeMediaVolume(update.mStreamType, index, update.mDevice)) {
8691                 index = safeMediaVolumeIndex(update.mDevice);
8692             }
8693             streamState.setIndex(index, update.mDevice, update.mCaller,
8694                     // trusted as index is always validated before message is posted
8695                     true /*hasModifyAudioSettings*/);
8696             sVolumeLogger.log(new AudioEventLogger.StringEvent(update.mCaller + " dev:0x"
8697                     + Integer.toHexString(update.mDevice) + " volIdx:" + index));
8698         } else {
8699             sVolumeLogger.log(new AudioEventLogger.StringEvent(update.mCaller
8700                     + " update vol on dev:0x" + Integer.toHexString(update.mDevice)));
8701         }
8702         setDeviceVolume(streamState, update.mDevice);
8703     }
8704 
setDeviceVolume(VolumeStreamState streamState, int device)8705     /*package*/ void setDeviceVolume(VolumeStreamState streamState, int device) {
8706 
8707         synchronized (VolumeStreamState.class) {
8708             // Apply volume
8709             streamState.applyDeviceVolume_syncVSS(device);
8710 
8711             // Apply change to all streams using this one as alias
8712             int numStreamTypes = AudioSystem.getNumStreamTypes();
8713             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
8714                 if (streamType != streamState.mStreamType &&
8715                         mStreamVolumeAlias[streamType] == streamState.mStreamType) {
8716                     // Make sure volume is also maxed out on A2DP device for aliased stream
8717                     // that may have a different device selected
8718                     int streamDevice = getDeviceForStream(streamType);
8719                     if ((device != streamDevice)
8720                             && (isAbsoluteVolumeDevice(device)
8721                                 || isA2dpAbsoluteVolumeDevice(device)
8722                                 || AudioSystem.isLeAudioDeviceType(device))) {
8723                         mStreamStates[streamType].applyDeviceVolume_syncVSS(device);
8724                     }
8725                     mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice);
8726                 }
8727             }
8728         }
8729         // Post a persist volume msg
8730         sendMsg(mAudioHandler,
8731                 MSG_PERSIST_VOLUME,
8732                 SENDMSG_QUEUE,
8733                 device,
8734                 0,
8735                 streamState,
8736                 PERSIST_DELAY);
8737 
8738     }
8739 
8740     /** Handles internal volume messages in separate volume thread. */
8741     private class AudioHandler extends Handler {
8742 
AudioHandler()8743         AudioHandler() {
8744             super();
8745         }
8746 
AudioHandler(Looper looper)8747         AudioHandler(Looper looper) {
8748             super(looper);
8749         }
8750 
setAllVolumes(VolumeStreamState streamState)8751         private void setAllVolumes(VolumeStreamState streamState) {
8752 
8753             // Apply volume
8754             streamState.applyAllVolumes();
8755 
8756             // Apply change to all streams using this one as alias
8757             int numStreamTypes = AudioSystem.getNumStreamTypes();
8758             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
8759                 if (streamType != streamState.mStreamType &&
8760                         mStreamVolumeAlias[streamType] == streamState.mStreamType) {
8761                     mStreamStates[streamType].applyAllVolumes();
8762                 }
8763             }
8764         }
8765 
persistVolume(VolumeStreamState streamState, int device)8766         private void persistVolume(VolumeStreamState streamState, int device) {
8767             if (mUseFixedVolume) {
8768                 return;
8769             }
8770             if (mIsSingleVolume && (streamState.mStreamType != AudioSystem.STREAM_MUSIC)) {
8771                 return;
8772             }
8773             if (streamState.hasValidSettingsName()) {
8774                 mSettings.putSystemIntForUser(mContentResolver,
8775                         streamState.getSettingNameForDevice(device),
8776                         (streamState.getIndex(device) + 5) / 10,
8777                         UserHandle.USER_CURRENT);
8778             }
8779         }
8780 
persistRingerMode(int ringerMode)8781         private void persistRingerMode(int ringerMode) {
8782             if (mUseFixedVolume) {
8783                 return;
8784             }
8785             mSettings.putGlobalInt(mContentResolver, Settings.Global.MODE_RINGER, ringerMode);
8786         }
8787 
onPersistSafeVolumeState(int state)8788         private void onPersistSafeVolumeState(int state) {
8789             mSettings.putGlobalInt(mContentResolver,
8790                     Settings.Global.AUDIO_SAFE_VOLUME_STATE,
8791                     state);
8792         }
8793 
onNotifyVolumeEvent(@onNull IAudioPolicyCallback apc, @AudioManager.VolumeAdjustment int direction)8794         private void onNotifyVolumeEvent(@NonNull IAudioPolicyCallback apc,
8795                 @AudioManager.VolumeAdjustment int direction) {
8796             try {
8797                 apc.notifyVolumeAdjust(direction);
8798             } catch(Exception e) {
8799                 // nothing we can do about this. Do not log error, too much potential for spam
8800             }
8801         }
8802 
8803         @Override
handleMessage(Message msg)8804         public void handleMessage(Message msg) {
8805             switch (msg.what) {
8806 
8807                 case MSG_SET_DEVICE_VOLUME:
8808                     setDeviceVolume((VolumeStreamState) msg.obj, msg.arg1);
8809                     break;
8810 
8811                 case MSG_SET_ALL_VOLUMES:
8812                     setAllVolumes((VolumeStreamState) msg.obj);
8813                     break;
8814 
8815                 case MSG_PERSIST_VOLUME:
8816                     persistVolume((VolumeStreamState) msg.obj, msg.arg1);
8817                     break;
8818 
8819                 case MSG_PERSIST_VOLUME_GROUP:
8820                     final VolumeGroupState vgs = (VolumeGroupState) msg.obj;
8821                     vgs.persistVolumeGroup(msg.arg1);
8822                     break;
8823 
8824                 case MSG_PERSIST_RINGER_MODE:
8825                     // note that the value persisted is the current ringer mode, not the
8826                     // value of ringer mode as of the time the request was made to persist
8827                     persistRingerMode(getRingerModeInternal());
8828                     break;
8829 
8830                 case MSG_AUDIO_SERVER_DIED:
8831                     onAudioServerDied();
8832                     break;
8833 
8834                 case MSG_DISPATCH_AUDIO_SERVER_STATE:
8835                     onDispatchAudioServerStateChange(msg.arg1 == 1);
8836                     break;
8837 
8838                 case MSG_UNLOAD_SOUND_EFFECTS:
8839                     mSfxHelper.unloadSoundEffects();
8840                     break;
8841 
8842                 case MSG_LOAD_SOUND_EFFECTS:
8843                 {
8844                     LoadSoundEffectReply reply = (LoadSoundEffectReply) msg.obj;
8845                     if (mSystemReady) {
8846                         mSfxHelper.loadSoundEffects(reply);
8847                     } else {
8848                         Log.w(TAG, "[schedule]loadSoundEffects() called before boot complete");
8849                         if (reply != null) {
8850                             reply.run(false);
8851                         }
8852                     }
8853                 }
8854                     break;
8855 
8856                 case MSG_PLAY_SOUND_EFFECT:
8857                     mSfxHelper.playSoundEffect(msg.arg1, msg.arg2);
8858                     break;
8859 
8860                 case MSG_SET_FORCE_USE:
8861                 {
8862                     final String eventSource = (String) msg.obj;
8863                     final int useCase = msg.arg1;
8864                     final int config = msg.arg2;
8865                     if (useCase == AudioSystem.FOR_MEDIA) {
8866                         Log.wtf(TAG, "Invalid force use FOR_MEDIA in AudioService from "
8867                                 + eventSource);
8868                         break;
8869                     }
8870                     new MediaMetrics.Item(MediaMetrics.Name.AUDIO_FORCE_USE
8871                             + MediaMetrics.SEPARATOR + AudioSystem.forceUseUsageToString(useCase))
8872                             .set(MediaMetrics.Property.EVENT, "setForceUse")
8873                             .set(MediaMetrics.Property.FORCE_USE_DUE_TO, eventSource)
8874                             .set(MediaMetrics.Property.FORCE_USE_MODE,
8875                                     AudioSystem.forceUseConfigToString(config))
8876                             .record();
8877                     sForceUseLogger.log(
8878                             new AudioServiceEvents.ForceUseEvent(useCase, config, eventSource));
8879                     mAudioSystem.setForceUse(useCase, config);
8880                 }
8881                     break;
8882 
8883                 case MSG_DISABLE_AUDIO_FOR_UID:
8884                     mPlaybackMonitor.disableAudioForUid( msg.arg1 == 1 /* disable */,
8885                             msg.arg2 /* uid */);
8886                     mAudioEventWakeLock.release();
8887                     break;
8888 
8889                 case MSG_INIT_STREAMS_VOLUMES:
8890                     onInitStreamsAndVolumes();
8891                     mAudioEventWakeLock.release();
8892                     break;
8893 
8894                 case MSG_INIT_SPATIALIZER:
8895                     onInitSpatializer();
8896                     mAudioEventWakeLock.release();
8897                     break;
8898 
8899                 case MSG_INIT_HEADTRACKING_SENSORS:
8900                     mSpatializerHelper.onInitSensors();
8901                     break;
8902 
8903                 case MSG_PERSIST_SPATIAL_AUDIO_DEVICE_SETTINGS:
8904                     onPersistSpatialAudioDeviceSettings();
8905                     break;
8906 
8907                 case MSG_RESET_SPATIALIZER:
8908                     mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect);
8909                     break;
8910 
8911                 case MSG_CHECK_MUSIC_ACTIVE:
8912                     onCheckMusicActive((String) msg.obj);
8913                     break;
8914 
8915                 case MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED:
8916                 case MSG_CONFIGURE_SAFE_MEDIA_VOLUME:
8917                     onConfigureSafeVolume((msg.what == MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED),
8918                             (String) msg.obj);
8919                     break;
8920                 case MSG_PERSIST_SAFE_VOLUME_STATE:
8921                     onPersistSafeVolumeState(msg.arg1);
8922                     break;
8923 
8924                 case MSG_SYSTEM_READY:
8925                     onSystemReady();
8926                     break;
8927 
8928                 case MSG_INDICATE_SYSTEM_READY:
8929                     onIndicateSystemReady();
8930                     break;
8931 
8932                 case MSG_ACCESSORY_PLUG_MEDIA_UNMUTE:
8933                     onAccessoryPlugMediaUnmute(msg.arg1);
8934                     break;
8935 
8936                 case MSG_PERSIST_MUSIC_ACTIVE_MS:
8937                     final int musicActiveMs = msg.arg1;
8938                     mSettings.putSecureIntForUser(mContentResolver,
8939                             Settings.Secure.UNSAFE_VOLUME_MUSIC_ACTIVE_MS, musicActiveMs,
8940                             UserHandle.USER_CURRENT);
8941                     break;
8942 
8943                 case MSG_UNMUTE_STREAM:
8944                     onUnmuteStream(msg.arg1, msg.arg2);
8945                     break;
8946 
8947                 case MSG_DYN_POLICY_MIX_STATE_UPDATE:
8948                     onDynPolicyMixStateUpdate((String) msg.obj, msg.arg1);
8949                     break;
8950 
8951                 case MSG_NOTIFY_VOL_EVENT:
8952                     onNotifyVolumeEvent((IAudioPolicyCallback) msg.obj, msg.arg1);
8953                     break;
8954 
8955                 case MSG_ENABLE_SURROUND_FORMATS:
8956                     onEnableSurroundFormats((ArrayList<Integer>) msg.obj);
8957                     break;
8958 
8959                 case MSG_UPDATE_RINGER_MODE:
8960                     onUpdateRingerModeServiceInt();
8961                     break;
8962 
8963                 case MSG_SET_DEVICE_STREAM_VOLUME:
8964                     onSetVolumeIndexOnDevice((DeviceVolumeUpdate) msg.obj);
8965                     break;
8966 
8967                 case MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS:
8968                     onObserveDevicesForAllStreams(/*skipStream*/ msg.arg1);
8969                     break;
8970 
8971                 case MSG_HDMI_VOLUME_CHECK:
8972                     onCheckVolumeCecOnHdmiConnection(msg.arg1, (String) msg.obj);
8973                     break;
8974 
8975                 case MSG_PLAYBACK_CONFIG_CHANGE:
8976                     onPlaybackConfigChange((List<AudioPlaybackConfiguration>) msg.obj);
8977                     break;
8978                 case MSG_RECORDING_CONFIG_CHANGE:
8979                     onRecordingConfigChange((List<AudioRecordingConfiguration>) msg.obj);
8980                     break;
8981 
8982                 case MSG_BROADCAST_MICROPHONE_MUTE:
8983                     mSystemServer.sendMicrophoneMuteChangedIntent();
8984                     break;
8985 
8986                 case MSG_CHECK_MODE_FOR_UID:
8987                     synchronized (mDeviceBroker.mSetModeLock) {
8988                         if (msg.obj == null) {
8989                             break;
8990                         }
8991                         // Update active playback/recording for apps requesting IN_COMMUNICATION
8992                         // mode after a grace period following the mode change
8993                         SetModeDeathHandler h = (SetModeDeathHandler) msg.obj;
8994                         if (mSetModeDeathHandlers.indexOf(h) < 0) {
8995                             break;
8996                         }
8997                         boolean wasActive = h.isActive();
8998                         h.setPlaybackActive(mPlaybackMonitor.isPlaybackActiveForUid(h.getUid()));
8999                         h.setRecordingActive(mRecordMonitor.isRecordingActiveForUid(h.getUid()));
9000                         if (wasActive != h.isActive()) {
9001                             onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(),
9002                                     mContext.getPackageName(), false /*force*/);
9003                         }
9004                     }
9005                     break;
9006 
9007                 case MSG_STREAM_DEVICES_CHANGED:
9008                     sendBroadcastToAll(((Intent) msg.obj)
9009                             .putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_DEVICES, msg.arg1)
9010                             .putExtra(AudioManager.EXTRA_VOLUME_STREAM_DEVICES, msg.arg2));
9011                     break;
9012 
9013                 case MSG_UPDATE_VOLUME_STATES_FOR_DEVICE:
9014                     onUpdateVolumeStatesForAudioDevice(msg.arg1, (String) msg.obj);
9015                     break;
9016 
9017                 case MSG_REINIT_VOLUMES:
9018                     onReinitVolumes((String) msg.obj);
9019                     break;
9020 
9021                 case MSG_UPDATE_A11Y_SERVICE_UIDS:
9022                     onUpdateAccessibilityServiceUids();
9023                     break;
9024 
9025                 case MSG_UPDATE_AUDIO_MODE:
9026                     synchronized (mDeviceBroker.mSetModeLock) {
9027                         onUpdateAudioMode(msg.arg1, msg.arg2, (String) msg.obj, false /*force*/);
9028                     }
9029                     break;
9030 
9031                 case MSG_BT_DEV_CHANGED:
9032                     mDeviceBroker.queueOnBluetoothActiveDeviceChanged(
9033                             (AudioDeviceBroker.BtDeviceChangedData) msg.obj);
9034                     break;
9035 
9036                 case MSG_DISPATCH_AUDIO_MODE:
9037                     dispatchMode(msg.arg1);
9038                     break;
9039 
9040                 case MSG_ROUTING_UPDATED:
9041                     onRoutingUpdatedFromAudioThread();
9042                     break;
9043 
9044                 case MSG_ADD_ASSISTANT_SERVICE_UID:
9045                     onAddAssistantServiceUids(new int[]{msg.arg1});
9046                     break;
9047 
9048                 case MSG_REMOVE_ASSISTANT_SERVICE_UID:
9049                     onRemoveAssistantServiceUids(new int[]{msg.arg1});
9050                     break;
9051                 case MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID:
9052                     updateActiveAssistantServiceUids();
9053                     break;
9054 
9055                 case MSG_DISPATCH_DEVICE_VOLUME_BEHAVIOR:
9056                     dispatchDeviceVolumeBehavior((AudioDeviceAttributes) msg.obj, msg.arg1);
9057                     break;
9058 
9059                 case MSG_ROTATION_UPDATE:
9060                     // rotation parameter format: "rotation=x" where x is one of 0, 90, 180, 270
9061                     mAudioSystem.setParameters((String) msg.obj);
9062                     break;
9063 
9064                 case MSG_FOLD_UPDATE:
9065                     // fold parameter format: "device_folded=x" where x is one of on, off
9066                     mAudioSystem.setParameters((String) msg.obj);
9067                     break;
9068 
9069                 case MSG_NO_LOG_FOR_PLAYER_I:
9070                     mPlaybackMonitor.ignorePlayerIId(msg.arg1);
9071                     break;
9072             }
9073         }
9074     }
9075 
9076     private class SettingsObserver extends ContentObserver {
9077 
SettingsObserver()9078         SettingsObserver() {
9079             super(new Handler());
9080             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
9081                     Settings.Global.ZEN_MODE), false, this);
9082             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
9083                     Settings.Global.ZEN_MODE_CONFIG_ETAG), false, this);
9084             mContentResolver.registerContentObserver(Settings.System.getUriFor(
9085                 Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this);
9086             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
9087                 Settings.Global.DOCK_AUDIO_MEDIA_ENABLED), false, this);
9088             mContentResolver.registerContentObserver(Settings.System.getUriFor(
9089                     Settings.System.MASTER_MONO), false, this);
9090             mContentResolver.registerContentObserver(Settings.System.getUriFor(
9091                     Settings.System.MASTER_BALANCE), false, this);
9092 
9093             mEncodedSurroundMode = mSettings.getGlobalInt(
9094                     mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT,
9095                     Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
9096             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
9097                     Settings.Global.ENCODED_SURROUND_OUTPUT), false, this);
9098             mEnabledSurroundFormats = mSettings.getGlobalString(
9099                     mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
9100             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
9101                     Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS), false, this);
9102 
9103             mContentResolver.registerContentObserver(Settings.Secure.getUriFor(
9104                     Settings.Secure.VOICE_INTERACTION_SERVICE), false, this);
9105         }
9106 
9107         @Override
onChange(boolean selfChange)9108         public void onChange(boolean selfChange) {
9109             super.onChange(selfChange);
9110             // FIXME This synchronized is not necessary if mSettingsLock only protects mRingerMode.
9111             //       However there appear to be some missing locks around mRingerAndZenModeMutedStreams
9112             //       and mRingerModeAffectedStreams, so will leave this synchronized for now.
9113             //       mRingerAndZenModeMutedStreams and mMuteAffectedStreams are safe (only accessed once).
9114             synchronized (mSettingsLock) {
9115                 if (updateRingerAndZenModeAffectedStreams()) {
9116                     /*
9117                      * Ensure all stream types that should be affected by ringer mode
9118                      * are in the proper state.
9119                      */
9120                     setRingerModeInt(getRingerModeInternal(), false);
9121                 }
9122                 readDockAudioSettings(mContentResolver);
9123                 updateMasterMono(mContentResolver);
9124                 updateMasterBalance(mContentResolver);
9125                 updateEncodedSurroundOutput();
9126                 sendEnabledSurroundFormats(mContentResolver, mSurroundModeChanged);
9127                 updateAssistantUIdLocked(/* forceUpdate= */ false);
9128             }
9129         }
9130 
updateEncodedSurroundOutput()9131         private void updateEncodedSurroundOutput() {
9132             int newSurroundMode = mSettings.getGlobalInt(
9133                 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT,
9134                 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
9135             // Did it change?
9136             if (mEncodedSurroundMode != newSurroundMode) {
9137                 // Send to AudioPolicyManager
9138                 sendEncodedSurroundMode(newSurroundMode, "SettingsObserver");
9139                 mDeviceBroker.toggleHdmiIfConnected_Async();
9140                 mEncodedSurroundMode = newSurroundMode;
9141                 mSurroundModeChanged = true;
9142             } else {
9143                 mSurroundModeChanged = false;
9144             }
9145         }
9146     }
9147 
avrcpSupportsAbsoluteVolume(String address, boolean support)9148     private void avrcpSupportsAbsoluteVolume(String address, boolean support) {
9149         // address is not used for now, but may be used when multiple a2dp devices are supported
9150         sVolumeLogger.log(new AudioEventLogger.StringEvent("avrcpSupportsAbsoluteVolume addr="
9151                 + address + " support=" + support).printLog(TAG));
9152         mDeviceBroker.setAvrcpAbsoluteVolumeSupported(support);
9153         setAvrcpAbsoluteVolumeSupported(support);
9154     }
9155 
setAvrcpAbsoluteVolumeSupported(boolean support)9156     /*package*/ void setAvrcpAbsoluteVolumeSupported(boolean support) {
9157         mAvrcpAbsVolSupported = support;
9158         sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE,
9159                     AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0,
9160                     mStreamStates[AudioSystem.STREAM_MUSIC], 0);
9161     }
9162 
9163     /**
9164      * @return true if there is currently a registered dynamic mixing policy that affects media
9165      * and is not a render + loopback policy
9166      */
9167     // only public for mocking/spying
9168     @VisibleForTesting
hasMediaDynamicPolicy()9169     public boolean hasMediaDynamicPolicy() {
9170         synchronized (mAudioPolicies) {
9171             if (mAudioPolicies.isEmpty()) {
9172                 return false;
9173             }
9174             final Collection<AudioPolicyProxy> appColl = mAudioPolicies.values();
9175             for (AudioPolicyProxy app : appColl) {
9176                 if (app.hasMixAffectingUsage(AudioAttributes.USAGE_MEDIA,
9177                         AudioMix.ROUTE_FLAG_LOOP_BACK_RENDER)) {
9178                     return true;
9179                 }
9180             }
9181             return false;
9182         }
9183     }
9184 
9185     /** only public for mocking/spying, do not call outside of AudioService */
9186     @VisibleForTesting
checkMusicActive(int deviceType, String caller)9187     public void checkMusicActive(int deviceType, String caller) {
9188         if (mSafeMediaVolumeDevices.contains(deviceType)) {
9189             scheduleMusicActiveCheck();
9190         }
9191     }
9192 
9193     /**
9194      * Receiver for misc intent broadcasts the Phone app cares about.
9195      */
9196     private class AudioServiceBroadcastReceiver extends BroadcastReceiver {
9197         @Override
onReceive(Context context, Intent intent)9198         public void onReceive(Context context, Intent intent) {
9199             final String action = intent.getAction();
9200             int outDevice;
9201             int inDevice;
9202             int state;
9203 
9204             if (action.equals(Intent.ACTION_DOCK_EVENT)) {
9205                 int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
9206                         Intent.EXTRA_DOCK_STATE_UNDOCKED);
9207                 int config;
9208                 switch (dockState) {
9209                     case Intent.EXTRA_DOCK_STATE_DESK:
9210                         config = AudioSystem.FORCE_BT_DESK_DOCK;
9211                         break;
9212                     case Intent.EXTRA_DOCK_STATE_CAR:
9213                         config = AudioSystem.FORCE_BT_CAR_DOCK;
9214                         break;
9215                     case Intent.EXTRA_DOCK_STATE_LE_DESK:
9216                         config = AudioSystem.FORCE_ANALOG_DOCK;
9217                         break;
9218                     case Intent.EXTRA_DOCK_STATE_HE_DESK:
9219                         config = AudioSystem.FORCE_DIGITAL_DOCK;
9220                         break;
9221                     case Intent.EXTRA_DOCK_STATE_UNDOCKED:
9222                     default:
9223                         config = AudioSystem.FORCE_NONE;
9224                 }
9225                 // Low end docks have a menu to enable or disable audio
9226                 // (see mDockAudioMediaEnabled)
9227                 if (!((dockState == Intent.EXTRA_DOCK_STATE_LE_DESK)
9228                         || ((dockState == Intent.EXTRA_DOCK_STATE_UNDOCKED)
9229                                 && (mDockState == Intent.EXTRA_DOCK_STATE_LE_DESK)))) {
9230                     mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, config,
9231                             "ACTION_DOCK_EVENT intent");
9232                 }
9233                 mDockState = dockState;
9234             } else if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED)
9235                     || action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
9236                 mDeviceBroker.receiveBtEvent(intent);
9237             } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
9238                 if (mMonitorRotation) {
9239                     RotationHelper.enable();
9240                 }
9241                 AudioSystem.setParameters("screen_state=on");
9242             } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
9243                 if (mMonitorRotation) {
9244                     //reduce wakeups (save current) by only listening when display is on
9245                     RotationHelper.disable();
9246                 }
9247                 AudioSystem.setParameters("screen_state=off");
9248             } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
9249                 handleConfigurationChanged(context);
9250             } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
9251                 if (mUserSwitchedReceived) {
9252                     // attempt to stop music playback for background user except on first user
9253                     // switch (i.e. first boot)
9254                     mDeviceBroker.postBroadcastBecomingNoisy();
9255                 }
9256                 mUserSwitchedReceived = true;
9257                 // the current audio focus owner is no longer valid
9258                 mMediaFocusControl.discardAudioFocusOwner();
9259 
9260                 if (mSupportsMicPrivacyToggle) {
9261                     mMicMuteFromPrivacyToggle = mSensorPrivacyManagerInternal
9262                             .isSensorPrivacyEnabled(getCurrentUserId(),
9263                                     SensorPrivacyManager.Sensors.MICROPHONE);
9264                     setMicrophoneMuteNoCallerCheck(getCurrentUserId());
9265                 }
9266 
9267                 // load volume settings for new user
9268                 readAudioSettings(true /*userSwitch*/);
9269                 // preserve STREAM_MUSIC volume from one user to the next.
9270                 sendMsg(mAudioHandler,
9271                         MSG_SET_ALL_VOLUMES,
9272                         SENDMSG_QUEUE,
9273                         0,
9274                         0,
9275                         mStreamStates[AudioSystem.STREAM_MUSIC], 0);
9276             } else if (action.equals(Intent.ACTION_USER_BACKGROUND)) {
9277                 // Disable audio recording for the background user/profile
9278                 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
9279                 if (userId >= 0) {
9280                     // TODO Kill recording streams instead of killing processes holding permission
9281                     UserInfo userInfo = UserManagerService.getInstance().getUserInfo(userId);
9282                     killBackgroundUserProcessesWithRecordAudioPermission(userInfo);
9283                 }
9284                 UserManagerService.getInstance().setUserRestriction(
9285                         UserManager.DISALLOW_RECORD_AUDIO, true, userId);
9286             } else if (action.equals(Intent.ACTION_USER_FOREGROUND)) {
9287                 // Enable audio recording for foreground user/profile
9288                 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
9289                 UserManagerService.getInstance().setUserRestriction(
9290                         UserManager.DISALLOW_RECORD_AUDIO, false, userId);
9291             } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
9292                 state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
9293                 if (state == BluetoothAdapter.STATE_OFF ||
9294                         state == BluetoothAdapter.STATE_TURNING_OFF) {
9295                     mDeviceBroker.disconnectAllBluetoothProfiles();
9296                 }
9297             } else if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION) ||
9298                     action.equals(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION)) {
9299                 handleAudioEffectBroadcast(context, intent);
9300             } else if (action.equals(Intent.ACTION_PACKAGES_SUSPENDED)) {
9301                 final int[] suspendedUids = intent.getIntArrayExtra(Intent.EXTRA_CHANGED_UID_LIST);
9302                 final String[] suspendedPackages =
9303                         intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
9304                 if (suspendedPackages == null || suspendedUids == null
9305                         || suspendedPackages.length != suspendedUids.length) {
9306                     return;
9307                 }
9308                 for (int i = 0; i < suspendedUids.length; i++) {
9309                     if (!TextUtils.isEmpty(suspendedPackages[i])) {
9310                         mMediaFocusControl.noFocusForSuspendedApp(
9311                                 suspendedPackages[i], suspendedUids[i]);
9312                     }
9313                 }
9314             } else if (action.equals(ACTION_CHECK_MUSIC_ACTIVE)) {
9315                 onCheckMusicActive(ACTION_CHECK_MUSIC_ACTIVE);
9316             }
9317         }
9318     } // end class AudioServiceBroadcastReceiver
9319 
9320     private class AudioServiceUserRestrictionsListener implements UserRestrictionsListener {
9321 
9322         @Override
onUserRestrictionsChanged(int userId, Bundle newRestrictions, Bundle prevRestrictions)9323         public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
9324                 Bundle prevRestrictions) {
9325             // Update mic mute state.
9326             {
9327                 final boolean wasRestricted =
9328                         prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE);
9329                 final boolean isRestricted =
9330                         newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE);
9331                 if (wasRestricted != isRestricted) {
9332                     mMicMuteFromRestrictions = isRestricted;
9333                     setMicrophoneMuteNoCallerCheck(userId);
9334                 }
9335             }
9336 
9337             // Update speaker mute state.
9338             {
9339                 final boolean wasRestricted =
9340                         prevRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME)
9341                                 || prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE);
9342                 final boolean isRestricted =
9343                         newRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME)
9344                                 || newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE);
9345                 if (wasRestricted != isRestricted) {
9346                     setMasterMuteInternalNoCallerCheck(isRestricted, /* flags =*/ 0, userId);
9347                 }
9348             }
9349         }
9350     } // end class AudioServiceUserRestrictionsListener
9351 
handleAudioEffectBroadcast(Context context, Intent intent)9352     private void handleAudioEffectBroadcast(Context context, Intent intent) {
9353         String target = intent.getPackage();
9354         if (target != null) {
9355             Log.w(TAG, "effect broadcast already targeted to " + target);
9356             return;
9357         }
9358         intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
9359         // TODO this should target a user-selected panel
9360         List<ResolveInfo> ril = context.getPackageManager().queryBroadcastReceivers(
9361                 intent, 0 /* flags */);
9362         if (ril != null && ril.size() != 0) {
9363             ResolveInfo ri = ril.get(0);
9364             if (ri != null && ri.activityInfo != null && ri.activityInfo.packageName != null) {
9365                 intent.setPackage(ri.activityInfo.packageName);
9366                 context.sendBroadcastAsUser(intent, UserHandle.ALL);
9367                 return;
9368             }
9369         }
9370         Log.w(TAG, "couldn't find receiver package for effect intent");
9371     }
9372 
killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser)9373     private void killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser) {
9374         PackageManager pm = mContext.getPackageManager();
9375         // Find the home activity of the user. It should not be killed to avoid expensive restart,
9376         // when the user switches back. For managed profiles, we should kill all recording apps
9377         ComponentName homeActivityName = null;
9378         if (!oldUser.isManagedProfile()) {
9379             homeActivityName = LocalServices.getService(
9380                     ActivityTaskManagerInternal.class).getHomeActivityForUser(oldUser.id);
9381         }
9382         final String[] permissions = { Manifest.permission.RECORD_AUDIO };
9383         List<PackageInfo> packages;
9384         try {
9385             packages = AppGlobals.getPackageManager()
9386                     .getPackagesHoldingPermissions(permissions, 0, oldUser.id).getList();
9387         } catch (RemoteException e) {
9388             throw new AndroidRuntimeException(e);
9389         }
9390         for (int j = packages.size() - 1; j >= 0; j--) {
9391             PackageInfo pkg = packages.get(j);
9392             // Skip system processes
9393             if (UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID) {
9394                 continue;
9395             }
9396             // Skip packages that have permission to interact across users
9397             if (pm.checkPermission(Manifest.permission.INTERACT_ACROSS_USERS, pkg.packageName)
9398                     == PackageManager.PERMISSION_GRANTED) {
9399                 continue;
9400             }
9401             if (homeActivityName != null
9402                     && pkg.packageName.equals(homeActivityName.getPackageName())
9403                     && pkg.applicationInfo.isSystemApp()) {
9404                 continue;
9405             }
9406             try {
9407                 final int uid = pkg.applicationInfo.uid;
9408                 ActivityManager.getService().killUid(UserHandle.getAppId(uid),
9409                         UserHandle.getUserId(uid),
9410                         "killBackgroundUserProcessesWithAudioRecordPermission");
9411             } catch (RemoteException e) {
9412                 Log.w(TAG, "Error calling killUid", e);
9413             }
9414         }
9415     }
9416 
9417 
9418     //==========================================================================================
9419     // Audio Focus
9420     //==========================================================================================
9421     /**
9422      * Returns whether a focus request is eligible to force ducking.
9423      * Will return true if:
9424      * - the AudioAttributes have a usage of USAGE_ASSISTANCE_ACCESSIBILITY,
9425      * - the focus request is AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK,
9426      * - the associated Bundle has KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING set to true,
9427      * - the uid of the requester is a known accessibility service or root.
9428      * @param aa AudioAttributes of the focus request
9429      * @param uid uid of the focus requester
9430      * @return true if ducking is to be forced
9431      */
forceFocusDuckingForAccessibility(@ullable AudioAttributes aa, int request, int uid)9432     private boolean forceFocusDuckingForAccessibility(@Nullable AudioAttributes aa,
9433             int request, int uid) {
9434         if (aa == null || aa.getUsage() != AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY
9435                 || request != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) {
9436             return false;
9437         }
9438         final Bundle extraInfo = aa.getBundle();
9439         if (extraInfo == null ||
9440                 !extraInfo.getBoolean(AudioFocusRequest.KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING)) {
9441             return false;
9442         }
9443         if (uid == 0) {
9444             return true;
9445         }
9446         synchronized (mAccessibilityServiceUidsLock) {
9447             if (mAccessibilityServiceUids != null) {
9448                 int callingUid = Binder.getCallingUid();
9449                 for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
9450                     if (mAccessibilityServiceUids[i] == callingUid) {
9451                         return true;
9452                     }
9453                 }
9454             }
9455         }
9456         return false;
9457     }
9458 
isSupportedSystemUsage(@udioAttributes.AttributeUsage int usage)9459     private boolean isSupportedSystemUsage(@AudioAttributes.AttributeUsage int usage) {
9460         synchronized (mSupportedSystemUsagesLock) {
9461             for (int i = 0; i < mSupportedSystemUsages.length; i++) {
9462                 if (mSupportedSystemUsages[i] == usage) {
9463                     return true;
9464                 }
9465             }
9466             return false;
9467         }
9468     }
9469 
validateAudioAttributesUsage(@onNull AudioAttributes audioAttributes)9470     private void validateAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) {
9471         @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage();
9472         if (AudioAttributes.isSystemUsage(usage)) {
9473             if ((usage == AudioAttributes.USAGE_CALL_ASSISTANT
9474                     && (audioAttributes.getAllFlags() & AudioAttributes.FLAG_CALL_REDIRECTION) != 0
9475                     && callerHasPermission(Manifest.permission.CALL_AUDIO_INTERCEPTION))
9476                     || callerHasPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)) {
9477                 if (!isSupportedSystemUsage(usage)) {
9478                     throw new IllegalArgumentException(
9479                             "Unsupported usage " + AudioAttributes.usageToString(usage));
9480                 }
9481             } else {
9482                 throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission");
9483             }
9484         }
9485     }
9486 
isValidAudioAttributesUsage(@onNull AudioAttributes audioAttributes)9487     private boolean isValidAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) {
9488         @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage();
9489         if (AudioAttributes.isSystemUsage(usage)) {
9490             return isSupportedSystemUsage(usage)
9491                     && ((usage == AudioAttributes.USAGE_CALL_ASSISTANT
9492                         && (audioAttributes.getAllFlags()
9493                             & AudioAttributes.FLAG_CALL_REDIRECTION) != 0
9494                         && callerHasPermission(Manifest.permission.CALL_AUDIO_INTERCEPTION))
9495                         || callerHasPermission(Manifest.permission.MODIFY_AUDIO_ROUTING));
9496         }
9497         return true;
9498     }
9499 
requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb, IAudioFocusDispatcher fd, String clientId, String callingPackageName, String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk)9500     public int requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb,
9501             IAudioFocusDispatcher fd, String clientId, String callingPackageName,
9502             String attributionTag, int flags, IAudioPolicyCallback pcb, int sdk) {
9503         if ((flags & AudioManager.AUDIOFOCUS_FLAG_TEST) != 0) {
9504             throw new IllegalArgumentException("Invalid test flag");
9505         }
9506         final int uid = Binder.getCallingUid();
9507         MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus")
9508                 .setUid(uid)
9509                 //.putInt("durationHint", durationHint)
9510                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName)
9511                 .set(MediaMetrics.Property.CLIENT_NAME, clientId)
9512                 .set(MediaMetrics.Property.EVENT, "requestAudioFocus")
9513                 .set(MediaMetrics.Property.FLAGS, flags);
9514 
9515         // permission checks
9516         if (aa != null && !isValidAudioAttributesUsage(aa)) {
9517             final String reason = "Request using unsupported usage";
9518             Log.w(TAG, reason);
9519             mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
9520                     .record();
9521             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9522         }
9523         if ((flags & AudioManager.AUDIOFOCUS_FLAG_LOCK) == AudioManager.AUDIOFOCUS_FLAG_LOCK) {
9524             if (AudioSystem.IN_VOICE_COMM_FOCUS_ID.equals(clientId)) {
9525                 if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
9526                             android.Manifest.permission.MODIFY_PHONE_STATE)) {
9527                     final String reason = "Invalid permission to (un)lock audio focus";
9528                     Log.e(TAG, reason, new Exception());
9529                     mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
9530                             .record();
9531                     return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9532                 }
9533             } else {
9534                 // only a registered audio policy can be used to lock focus
9535                 synchronized (mAudioPolicies) {
9536                     if (!mAudioPolicies.containsKey(pcb.asBinder())) {
9537                         final String reason =
9538                                 "Invalid unregistered AudioPolicy to (un)lock audio focus";
9539                         Log.e(TAG, reason);
9540                         mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
9541                                 .record();
9542                         return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9543                     }
9544                 }
9545             }
9546         }
9547 
9548         if (callingPackageName == null || clientId == null || aa == null) {
9549             final String reason = "Invalid null parameter to request audio focus";
9550             Log.e(TAG, reason);
9551             mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
9552                     .record();
9553             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9554         }
9555         mmi.record();
9556         return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd,
9557                 clientId, callingPackageName, attributionTag, flags, sdk,
9558                 forceFocusDuckingForAccessibility(aa, durationHint, uid), -1 /*testUid, ignored*/);
9559     }
9560 
9561     /** 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)9562     public int requestAudioFocusForTest(AudioAttributes aa, int durationHint, IBinder cb,
9563             IAudioFocusDispatcher fd, String clientId, String callingPackageName,
9564             int flags, int fakeUid, int sdk) {
9565         if (!enforceQueryAudioStateForTest("focus request")) {
9566             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9567         }
9568         if (callingPackageName == null || clientId == null || aa == null) {
9569             final String reason = "Invalid null parameter to request audio focus";
9570             Log.e(TAG, reason);
9571             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9572         }
9573         return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd,
9574                 clientId, callingPackageName, null, flags,
9575                 sdk, false /*forceDuck*/, fakeUid);
9576     }
9577 
abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)9578     public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa,
9579             String callingPackageName) {
9580         MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus")
9581                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName)
9582                 .set(MediaMetrics.Property.CLIENT_NAME, clientId)
9583                 .set(MediaMetrics.Property.EVENT, "abandonAudioFocus");
9584 
9585         if (aa != null && !isValidAudioAttributesUsage(aa)) {
9586             Log.w(TAG, "Request using unsupported usage.");
9587             mmi.set(MediaMetrics.Property.EARLY_RETURN, "unsupported usage").record();
9588 
9589             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9590         }
9591         mmi.record();
9592         return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName);
9593     }
9594 
9595     /** see {@link AudioManager#abandonAudioFocusForTest(AudioFocusRequest, String)} */
abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)9596     public int abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId,
9597             AudioAttributes aa, String callingPackageName) {
9598         if (!enforceQueryAudioStateForTest("focus abandon")) {
9599             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
9600         }
9601         return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName);
9602     }
9603 
unregisterAudioFocusClient(String clientId)9604     public void unregisterAudioFocusClient(String clientId) {
9605         new MediaMetrics.Item(mMetricsId + "focus")
9606                 .set(MediaMetrics.Property.CLIENT_NAME, clientId)
9607                 .set(MediaMetrics.Property.EVENT, "unregisterAudioFocusClient")
9608                 .record();
9609         mMediaFocusControl.unregisterAudioFocusClient(clientId);
9610     }
9611 
getCurrentAudioFocus()9612     public int getCurrentAudioFocus() {
9613         return mMediaFocusControl.getCurrentAudioFocus();
9614     }
9615 
getFocusRampTimeMs(int focusGain, AudioAttributes attr)9616     public int getFocusRampTimeMs(int focusGain, AudioAttributes attr) {
9617         return mMediaFocusControl.getFocusRampTimeMs(focusGain, attr);
9618     }
9619 
9620     /** only public for mocking/spying, do not call outside of AudioService */
9621     @VisibleForTesting
hasAudioFocusUsers()9622     public boolean hasAudioFocusUsers() {
9623         return mMediaFocusControl.hasAudioFocusUsers();
9624     }
9625 
9626     /** see {@link AudioManager#getFadeOutDurationOnFocusLossMillis(AudioAttributes)} */
getFadeOutDurationOnFocusLossMillis(AudioAttributes aa)9627     public long getFadeOutDurationOnFocusLossMillis(AudioAttributes aa) {
9628         if (!enforceQueryAudioStateForTest("fade out duration")) {
9629             return 0;
9630         }
9631         return mMediaFocusControl.getFadeOutDurationOnFocusLossMillis(aa);
9632     }
9633 
enforceQueryAudioStateForTest(String mssg)9634     private boolean enforceQueryAudioStateForTest(String mssg) {
9635         if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
9636                 Manifest.permission.QUERY_AUDIO_STATE)) {
9637             final String reason = "Doesn't have QUERY_AUDIO_STATE permission for "
9638                     + mssg + " test API";
9639             Log.e(TAG, reason, new Exception());
9640             return false;
9641         }
9642         return true;
9643     }
9644 
9645     //==========================================================================================
9646     private final @NonNull SpatializerHelper mSpatializerHelper;
9647     /**
9648      * Initialized from property ro.audio.spatializer_enabled
9649      * Should only be 1 when the device ships with a Spatializer effect
9650      */
9651     private final boolean mHasSpatializerEffect;
9652     /**
9653      * Default value for the spatial audio feature
9654      */
9655     private static final boolean SPATIAL_AUDIO_ENABLED_DEFAULT = true;
9656 
enforceModifyDefaultAudioEffectsPermission()9657     private void enforceModifyDefaultAudioEffectsPermission() {
9658         if (mContext.checkCallingOrSelfPermission(
9659                 android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
9660                 != PackageManager.PERMISSION_GRANTED) {
9661             throw new SecurityException("Missing MODIFY_DEFAULT_AUDIO_EFFECTS permission");
9662         }
9663     }
9664 
9665     /**
9666      * Returns the immersive audio level that the platform is capable of
9667      * @see Spatializer#getImmersiveAudioLevel()
9668      */
getSpatializerImmersiveAudioLevel()9669     public int getSpatializerImmersiveAudioLevel() {
9670         return mSpatializerHelper.getCapableImmersiveAudioLevel();
9671     }
9672 
9673     /** @see Spatializer#isEnabled() */
isSpatializerEnabled()9674     public boolean isSpatializerEnabled() {
9675         return mSpatializerHelper.isEnabled();
9676     }
9677 
9678     /** @see Spatializer#isAvailable() */
isSpatializerAvailable()9679     public boolean isSpatializerAvailable() {
9680         return mSpatializerHelper.isAvailable();
9681     }
9682 
9683     /** @see Spatializer#isAvailableForDevice(AudioDeviceAttributes) */
isSpatializerAvailableForDevice(@onNull AudioDeviceAttributes device)9684     public boolean isSpatializerAvailableForDevice(@NonNull AudioDeviceAttributes device)  {
9685         enforceModifyDefaultAudioEffectsPermission();
9686         return mSpatializerHelper.isAvailableForDevice(Objects.requireNonNull(device));
9687     }
9688 
9689     /** @see Spatializer#hasHeadTracker(AudioDeviceAttributes) */
hasHeadTracker(@onNull AudioDeviceAttributes device)9690     public boolean hasHeadTracker(@NonNull AudioDeviceAttributes device) {
9691         enforceModifyDefaultAudioEffectsPermission();
9692         return mSpatializerHelper.hasHeadTracker(Objects.requireNonNull(device));
9693     }
9694 
9695     /** @see Spatializer#setHeadTrackerEnabled(boolean, AudioDeviceAttributes) */
setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device)9696     public void setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device) {
9697         enforceModifyDefaultAudioEffectsPermission();
9698         mSpatializerHelper.setHeadTrackerEnabled(enabled, Objects.requireNonNull(device));
9699     }
9700 
9701     /** @see Spatializer#isHeadTrackerEnabled(AudioDeviceAttributes) */
isHeadTrackerEnabled(@onNull AudioDeviceAttributes device)9702     public boolean isHeadTrackerEnabled(@NonNull AudioDeviceAttributes device) {
9703         enforceModifyDefaultAudioEffectsPermission();
9704         return mSpatializerHelper.isHeadTrackerEnabled(Objects.requireNonNull(device));
9705     }
9706 
9707     /** @see Spatializer#isHeadTrackerAvailable() */
isHeadTrackerAvailable()9708     public boolean isHeadTrackerAvailable() {
9709         return mSpatializerHelper.isHeadTrackerAvailable();
9710     }
9711 
9712     /** @see Spatializer#setSpatializerEnabled(boolean) */
setSpatializerEnabled(boolean enabled)9713     public void setSpatializerEnabled(boolean enabled) {
9714         enforceModifyDefaultAudioEffectsPermission();
9715         mSpatializerHelper.setFeatureEnabled(enabled);
9716     }
9717 
9718     /** @see Spatializer#canBeSpatialized() */
canBeSpatialized( @onNull AudioAttributes attributes, @NonNull AudioFormat format)9719     public boolean canBeSpatialized(
9720             @NonNull AudioAttributes attributes, @NonNull AudioFormat format) {
9721         Objects.requireNonNull(attributes);
9722         Objects.requireNonNull(format);
9723         return mSpatializerHelper.canBeSpatialized(attributes, format);
9724     }
9725 
9726     /** @see Spatializer.SpatializerInfoDispatcherStub */
registerSpatializerCallback( @onNull ISpatializerCallback cb)9727     public void registerSpatializerCallback(
9728             @NonNull ISpatializerCallback cb) {
9729         Objects.requireNonNull(cb);
9730         mSpatializerHelper.registerStateCallback(cb);
9731     }
9732 
9733     /** @see Spatializer.SpatializerInfoDispatcherStub */
unregisterSpatializerCallback( @onNull ISpatializerCallback cb)9734     public void unregisterSpatializerCallback(
9735             @NonNull ISpatializerCallback cb) {
9736         Objects.requireNonNull(cb);
9737         mSpatializerHelper.unregisterStateCallback(cb);
9738     }
9739 
9740     /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */
registerSpatializerHeadTrackingCallback( @onNull ISpatializerHeadTrackingModeCallback cb)9741     public void registerSpatializerHeadTrackingCallback(
9742             @NonNull ISpatializerHeadTrackingModeCallback cb) {
9743         enforceModifyDefaultAudioEffectsPermission();
9744         Objects.requireNonNull(cb);
9745         mSpatializerHelper.registerHeadTrackingModeCallback(cb);
9746     }
9747 
9748     /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */
unregisterSpatializerHeadTrackingCallback( @onNull ISpatializerHeadTrackingModeCallback cb)9749     public void unregisterSpatializerHeadTrackingCallback(
9750             @NonNull ISpatializerHeadTrackingModeCallback cb) {
9751         enforceModifyDefaultAudioEffectsPermission();
9752         Objects.requireNonNull(cb);
9753         mSpatializerHelper.unregisterHeadTrackingModeCallback(cb);
9754     }
9755 
9756     /** @see Spatializer.SpatializerHeadTrackerAvailableDispatcherStub */
registerSpatializerHeadTrackerAvailableCallback( @onNull ISpatializerHeadTrackerAvailableCallback cb, boolean register)9757     public void registerSpatializerHeadTrackerAvailableCallback(
9758             @NonNull ISpatializerHeadTrackerAvailableCallback cb, boolean register) {
9759         Objects.requireNonNull(cb);
9760         mSpatializerHelper.registerHeadTrackerAvailableCallback(cb, register);
9761     }
9762 
9763     /** @see Spatializer#setOnHeadToSoundstagePoseUpdatedListener */
registerHeadToSoundstagePoseCallback( @onNull ISpatializerHeadToSoundStagePoseCallback cb)9764     public void registerHeadToSoundstagePoseCallback(
9765             @NonNull ISpatializerHeadToSoundStagePoseCallback cb) {
9766         enforceModifyDefaultAudioEffectsPermission();
9767         Objects.requireNonNull(cb);
9768         mSpatializerHelper.registerHeadToSoundstagePoseCallback(cb);
9769     }
9770 
9771     /** @see Spatializer#clearOnHeadToSoundstagePoseUpdatedListener */
unregisterHeadToSoundstagePoseCallback( @onNull ISpatializerHeadToSoundStagePoseCallback cb)9772     public void unregisterHeadToSoundstagePoseCallback(
9773             @NonNull ISpatializerHeadToSoundStagePoseCallback cb) {
9774         enforceModifyDefaultAudioEffectsPermission();
9775         Objects.requireNonNull(cb);
9776         mSpatializerHelper.unregisterHeadToSoundstagePoseCallback(cb);
9777     }
9778 
9779     /** @see Spatializer#getSpatializerCompatibleAudioDevices() */
getSpatializerCompatibleAudioDevices()9780     public @NonNull List<AudioDeviceAttributes> getSpatializerCompatibleAudioDevices() {
9781         enforceModifyDefaultAudioEffectsPermission();
9782         return mSpatializerHelper.getCompatibleAudioDevices();
9783     }
9784 
9785     /** @see Spatializer#addSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */
addSpatializerCompatibleAudioDevice(@onNull AudioDeviceAttributes ada)9786     public void addSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
9787         enforceModifyDefaultAudioEffectsPermission();
9788         Objects.requireNonNull(ada);
9789         mSpatializerHelper.addCompatibleAudioDevice(ada);
9790     }
9791 
9792     /** @see Spatializer#removeSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */
removeSpatializerCompatibleAudioDevice(@onNull AudioDeviceAttributes ada)9793     public void removeSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
9794         enforceModifyDefaultAudioEffectsPermission();
9795         Objects.requireNonNull(ada);
9796         mSpatializerHelper.removeCompatibleAudioDevice(ada);
9797     }
9798 
9799     /** @see Spatializer#getSupportedHeadTrackingModes() */
getSupportedHeadTrackingModes()9800     public int[] getSupportedHeadTrackingModes() {
9801         enforceModifyDefaultAudioEffectsPermission();
9802         return mSpatializerHelper.getSupportedHeadTrackingModes();
9803     }
9804 
9805     /** @see Spatializer#getHeadTrackingMode() */
getActualHeadTrackingMode()9806     public int getActualHeadTrackingMode() {
9807         enforceModifyDefaultAudioEffectsPermission();
9808         return mSpatializerHelper.getActualHeadTrackingMode();
9809     }
9810 
9811     /** @see Spatializer#getDesiredHeadTrackingMode() */
getDesiredHeadTrackingMode()9812     public int getDesiredHeadTrackingMode() {
9813         enforceModifyDefaultAudioEffectsPermission();
9814         return mSpatializerHelper.getDesiredHeadTrackingMode();
9815     }
9816 
9817     /** @see Spatializer#setGlobalTransform */
setSpatializerGlobalTransform(@onNull float[] transform)9818     public void setSpatializerGlobalTransform(@NonNull float[] transform) {
9819         enforceModifyDefaultAudioEffectsPermission();
9820         Objects.requireNonNull(transform);
9821         mSpatializerHelper.setGlobalTransform(transform);
9822     }
9823 
9824     /** @see Spatializer#recenterHeadTracker() */
recenterHeadTracker()9825     public void recenterHeadTracker() {
9826         enforceModifyDefaultAudioEffectsPermission();
9827         mSpatializerHelper.recenterHeadTracker();
9828     }
9829 
9830     /** @see Spatializer#setDesiredHeadTrackingMode */
setDesiredHeadTrackingMode(@patializer.HeadTrackingModeSet int mode)9831     public void setDesiredHeadTrackingMode(@Spatializer.HeadTrackingModeSet int mode) {
9832         enforceModifyDefaultAudioEffectsPermission();
9833         switch(mode) {
9834             case Spatializer.HEAD_TRACKING_MODE_DISABLED:
9835             case Spatializer.HEAD_TRACKING_MODE_RELATIVE_WORLD:
9836             case Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE:
9837                 break;
9838             default:
9839                 return;
9840         }
9841         mSpatializerHelper.setDesiredHeadTrackingMode(mode);
9842     }
9843 
9844     /** @see Spatializer#setEffectParameter */
setSpatializerParameter(int key, @NonNull byte[] value)9845     public void setSpatializerParameter(int key, @NonNull byte[] value) {
9846         enforceModifyDefaultAudioEffectsPermission();
9847         Objects.requireNonNull(value);
9848         mSpatializerHelper.setEffectParameter(key, value);
9849     }
9850 
9851     /** @see Spatializer#getEffectParameter */
getSpatializerParameter(int key, @NonNull byte[] value)9852     public void getSpatializerParameter(int key, @NonNull byte[] value) {
9853         enforceModifyDefaultAudioEffectsPermission();
9854         Objects.requireNonNull(value);
9855         mSpatializerHelper.getEffectParameter(key, value);
9856     }
9857 
9858     /** @see Spatializer#getOutput */
getSpatializerOutput()9859     public int getSpatializerOutput() {
9860         enforceModifyDefaultAudioEffectsPermission();
9861         return mSpatializerHelper.getOutput();
9862     }
9863 
9864     /** @see Spatializer#setOnSpatializerOutputChangedListener */
registerSpatializerOutputCallback(ISpatializerOutputCallback cb)9865     public void registerSpatializerOutputCallback(ISpatializerOutputCallback cb) {
9866         enforceModifyDefaultAudioEffectsPermission();
9867         Objects.requireNonNull(cb);
9868         mSpatializerHelper.registerSpatializerOutputCallback(cb);
9869     }
9870 
9871     /** @see Spatializer#clearOnSpatializerOutputChangedListener */
unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb)9872     public void unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb) {
9873         enforceModifyDefaultAudioEffectsPermission();
9874         Objects.requireNonNull(cb);
9875         mSpatializerHelper.unregisterSpatializerOutputCallback(cb);
9876     }
9877 
9878     /**
9879      * post a message to schedule init/release of head tracking sensors
9880      * whether to initialize or release sensors is based on the state of spatializer
9881      */
postInitSpatializerHeadTrackingSensors()9882     void postInitSpatializerHeadTrackingSensors() {
9883         sendMsg(mAudioHandler,
9884                 MSG_INIT_HEADTRACKING_SENSORS,
9885                 SENDMSG_REPLACE,
9886                 /*arg1*/ 0, /*arg2*/ 0, TAG, /*delay*/ 0);
9887     }
9888 
9889     /**
9890      * post a message to schedule a reset of the spatializer state
9891      */
postResetSpatializer()9892     void postResetSpatializer() {
9893         sendMsg(mAudioHandler,
9894                 MSG_RESET_SPATIALIZER,
9895                 SENDMSG_REPLACE,
9896                 /*arg1*/ 0, /*arg2*/ 0, TAG, /*delay*/ 0);
9897     }
9898 
onInitSpatializer()9899     void onInitSpatializer() {
9900         final String settings = mSettings.getSecureStringForUser(mContentResolver,
9901                 Settings.Secure.SPATIAL_AUDIO_ENABLED, UserHandle.USER_CURRENT);
9902         if (settings == null) {
9903             Log.e(TAG, "error reading spatial audio device settings");
9904         }
9905         mSpatializerHelper.init(/*effectExpected*/ mHasSpatializerEffect, settings);
9906         mSpatializerHelper.setFeatureEnabled(mHasSpatializerEffect);
9907     }
9908 
9909     /**
9910      * post a message to persist the spatial audio device settings.
9911      * Message is delayed by 1s on purpose in case of successive changes in quick succession (at
9912      * init time for instance)
9913      * Note this method is made public to work around a Mockito bug where it needs to be public
9914      * in order to be mocked by a test a the same package
9915      * (see https://code.google.com/archive/p/mockito/issues/127)
9916      */
persistSpatialAudioDeviceSettings()9917     public void persistSpatialAudioDeviceSettings() {
9918         sendMsg(mAudioHandler,
9919                 MSG_PERSIST_SPATIAL_AUDIO_DEVICE_SETTINGS,
9920                 SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0, TAG,
9921                 /*delay*/ 1000);
9922     }
9923 
onPersistSpatialAudioDeviceSettings()9924     void onPersistSpatialAudioDeviceSettings() {
9925         final String settings = mSpatializerHelper.getSADeviceSettings();
9926         Log.v(TAG, "saving spatial audio device settings: " + settings);
9927         boolean res = mSettings.putSecureStringForUser(mContentResolver,
9928                 Settings.Secure.SPATIAL_AUDIO_ENABLED,
9929                 settings, UserHandle.USER_CURRENT);
9930         if (!res) {
9931             Log.e(TAG, "error saving spatial audio device settings: " + settings);
9932         }
9933     }
9934 
9935     //==========================================================================================
readCameraSoundForced()9936     private boolean readCameraSoundForced() {
9937         return SystemProperties.getBoolean("audio.camerasound.force", false) ||
9938                 mContext.getResources().getBoolean(
9939                         com.android.internal.R.bool.config_camera_sound_forced);
9940     }
9941 
9942     //==========================================================================================
9943     private final Object mMuteAwaitConnectionLock = new Object();
9944 
9945     /**
9946      * The device that is expected to be connected soon, and causes players to be muted until
9947      * its connection, or it times out.
9948      * Null when no active muting command, or it has timed out.
9949      */
9950     @GuardedBy("mMuteAwaitConnectionLock")
9951     private AudioDeviceAttributes mMutingExpectedDevice;
9952     @GuardedBy("mMuteAwaitConnectionLock")
9953     private @Nullable int[] mMutedUsagesAwaitingConnection;
9954 
9955     /** @see AudioManager#muteAwaitConnection */
9956     @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection
muteAwaitConnection(@onNull int[] usages, @NonNull AudioDeviceAttributes device, long timeOutMs)9957     public void muteAwaitConnection(@NonNull int[] usages,
9958             @NonNull AudioDeviceAttributes device, long timeOutMs) {
9959         Objects.requireNonNull(usages);
9960         Objects.requireNonNull(device);
9961         enforceModifyAudioRoutingPermission();
9962         if (timeOutMs <= 0 || usages.length == 0) {
9963             throw new IllegalArgumentException("Invalid timeOutMs/usagesToMute");
9964         }
9965         Log.i(TAG, "muteAwaitConnection dev:" + device + " timeOutMs:" + timeOutMs
9966                 + " usages:" + Arrays.toString(usages));
9967 
9968         if (mDeviceBroker.isDeviceConnected(device)) {
9969             // not throwing an exception as there could be a race between a connection (server-side,
9970             // notification of connection in flight) and a mute operation (client-side)
9971             Log.i(TAG, "muteAwaitConnection ignored, device (" + device + ") already connected");
9972             return;
9973         }
9974         synchronized (mMuteAwaitConnectionLock) {
9975             if (mMutingExpectedDevice != null) {
9976                 Log.e(TAG, "muteAwaitConnection ignored, another in progress for device:"
9977                         + mMutingExpectedDevice);
9978                 throw new IllegalStateException("muteAwaitConnection already in progress");
9979             }
9980             mMutingExpectedDevice = device;
9981             mMutedUsagesAwaitingConnection = usages;
9982             mPlaybackMonitor.muteAwaitConnection(usages, device, timeOutMs);
9983         }
9984         dispatchMuteAwaitConnection(cb -> { try {
9985             cb.dispatchOnMutedUntilConnection(device, usages); } catch (RemoteException e) { } });
9986     }
9987 
9988     /** @see AudioManager#getMutingExpectedDevice */
getMutingExpectedDevice()9989     public @Nullable AudioDeviceAttributes getMutingExpectedDevice() {
9990         enforceModifyAudioRoutingPermission();
9991         synchronized (mMuteAwaitConnectionLock) {
9992             return mMutingExpectedDevice;
9993         }
9994     }
9995 
9996     /** @see AudioManager#cancelMuteAwaitConnection */
9997     @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection
cancelMuteAwaitConnection(@onNull AudioDeviceAttributes device)9998     public void cancelMuteAwaitConnection(@NonNull AudioDeviceAttributes device) {
9999         Objects.requireNonNull(device);
10000         enforceModifyAudioRoutingPermission();
10001         Log.i(TAG, "cancelMuteAwaitConnection for device:" + device);
10002         final int[] mutedUsages;
10003         synchronized (mMuteAwaitConnectionLock) {
10004             if (mMutingExpectedDevice == null) {
10005                 // not throwing an exception as there could be a race between a timeout
10006                 // (server-side) and a cancel operation (client-side)
10007                 Log.i(TAG, "cancelMuteAwaitConnection ignored, no expected device");
10008                 return;
10009             }
10010             if (!device.equalTypeAddress(mMutingExpectedDevice)) {
10011                 Log.e(TAG, "cancelMuteAwaitConnection ignored, got " + device
10012                         + "] but expected device is" + mMutingExpectedDevice);
10013                 throw new IllegalStateException("cancelMuteAwaitConnection for wrong device");
10014             }
10015             mutedUsages = mMutedUsagesAwaitingConnection;
10016             mMutingExpectedDevice = null;
10017             mMutedUsagesAwaitingConnection = null;
10018             mPlaybackMonitor.cancelMuteAwaitConnection("cancelMuteAwaitConnection dev:" + device);
10019         }
10020         dispatchMuteAwaitConnection(cb -> { try { cb.dispatchOnUnmutedEvent(
10021                     AudioManager.MuteAwaitConnectionCallback.EVENT_CANCEL, device, mutedUsages);
10022             } catch (RemoteException e) { } });
10023     }
10024 
10025     final RemoteCallbackList<IMuteAwaitConnectionCallback> mMuteAwaitConnectionDispatchers =
10026             new RemoteCallbackList<IMuteAwaitConnectionCallback>();
10027 
10028     /** @see AudioManager#registerMuteAwaitConnectionCallback */
registerMuteAwaitConnectionDispatcher(@onNull IMuteAwaitConnectionCallback cb, boolean register)10029     public void registerMuteAwaitConnectionDispatcher(@NonNull IMuteAwaitConnectionCallback cb,
10030             boolean register) {
10031         enforceModifyAudioRoutingPermission();
10032         if (register) {
10033             mMuteAwaitConnectionDispatchers.register(cb);
10034         } else {
10035             mMuteAwaitConnectionDispatchers.unregister(cb);
10036         }
10037     }
10038 
10039     @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection
checkMuteAwaitConnection()10040     void checkMuteAwaitConnection() {
10041         final AudioDeviceAttributes device;
10042         final int[] mutedUsages;
10043         synchronized (mMuteAwaitConnectionLock) {
10044             if (mMutingExpectedDevice == null) {
10045                 return;
10046             }
10047             device = mMutingExpectedDevice;
10048             mutedUsages = mMutedUsagesAwaitingConnection;
10049             if (!mDeviceBroker.isDeviceConnected(device)) {
10050                 return;
10051             }
10052             mMutingExpectedDevice = null;
10053             mMutedUsagesAwaitingConnection = null;
10054             mPlaybackMonitor.cancelMuteAwaitConnection(
10055                     "checkMuteAwaitConnection device " + device + " connected, unmuting");
10056         }
10057         dispatchMuteAwaitConnection(cb -> { try { cb.dispatchOnUnmutedEvent(
10058                 AudioManager.MuteAwaitConnectionCallback.EVENT_CONNECTION, device, mutedUsages);
10059             } catch (RemoteException e) { } });
10060     }
10061 
10062     /**
10063      * Called by PlaybackActivityMonitor when the timeout hit for the mute on device connection
10064      */
10065     @SuppressLint("EmptyCatch") // callback exception caught inside dispatchMuteAwaitConnection
onMuteAwaitConnectionTimeout(@onNull AudioDeviceAttributes timedOutDevice)10066     void onMuteAwaitConnectionTimeout(@NonNull AudioDeviceAttributes timedOutDevice) {
10067         final int[] mutedUsages;
10068         synchronized (mMuteAwaitConnectionLock) {
10069             if (!timedOutDevice.equals(mMutingExpectedDevice)) {
10070                 return;
10071             }
10072             Log.i(TAG, "muteAwaitConnection timeout, clearing expected device "
10073                     + mMutingExpectedDevice);
10074             mutedUsages = mMutedUsagesAwaitingConnection;
10075             mMutingExpectedDevice = null;
10076             mMutedUsagesAwaitingConnection = null;
10077         }
10078         dispatchMuteAwaitConnection(cb -> { try {
10079                 cb.dispatchOnUnmutedEvent(
10080                         AudioManager.MuteAwaitConnectionCallback.EVENT_TIMEOUT,
10081                         timedOutDevice, mutedUsages);
10082             } catch (RemoteException e) { } });
10083     }
10084 
dispatchMuteAwaitConnection( java.util.function.Consumer<IMuteAwaitConnectionCallback> callback)10085     private void dispatchMuteAwaitConnection(
10086             java.util.function.Consumer<IMuteAwaitConnectionCallback> callback) {
10087         final int nbDispatchers = mMuteAwaitConnectionDispatchers.beginBroadcast();
10088         // lazy initialization as errors unlikely
10089         ArrayList<IMuteAwaitConnectionCallback> errorList = null;
10090         for (int i = 0; i < nbDispatchers; i++) {
10091             try {
10092                 callback.accept(mMuteAwaitConnectionDispatchers.getBroadcastItem(i));
10093             } catch (Exception e) {
10094                 if (errorList == null) {
10095                     errorList = new ArrayList<>(1);
10096                 }
10097                 errorList.add(mMuteAwaitConnectionDispatchers.getBroadcastItem(i));
10098             }
10099         }
10100         if (errorList != null) {
10101             for (IMuteAwaitConnectionCallback errorItem : errorList) {
10102                 mMuteAwaitConnectionDispatchers.unregister(errorItem);
10103             }
10104         }
10105         mMuteAwaitConnectionDispatchers.finishBroadcast();
10106     }
10107 
10108     final RemoteCallbackList<IDeviceVolumeBehaviorDispatcher> mDeviceVolumeBehaviorDispatchers =
10109             new RemoteCallbackList<IDeviceVolumeBehaviorDispatcher>();
10110 
10111     /**
10112      *  @see AudioDeviceVolumeManager#addOnDeviceVolumeBehaviorChangedListener and
10113      *  AudioDeviceVolumeManager#removeOnDeviceVolumeBehaviorChangedListener
10114      */
registerDeviceVolumeBehaviorDispatcher(boolean register, @NonNull IDeviceVolumeBehaviorDispatcher dispatcher)10115     public void registerDeviceVolumeBehaviorDispatcher(boolean register,
10116             @NonNull IDeviceVolumeBehaviorDispatcher dispatcher) {
10117         enforceQueryStateOrModifyRoutingPermission();
10118         Objects.requireNonNull(dispatcher);
10119         if (register) {
10120             mDeviceVolumeBehaviorDispatchers.register(dispatcher);
10121         } else {
10122             mDeviceVolumeBehaviorDispatchers.unregister(dispatcher);
10123         }
10124     }
10125 
dispatchDeviceVolumeBehavior(AudioDeviceAttributes device, int volumeBehavior)10126     private void dispatchDeviceVolumeBehavior(AudioDeviceAttributes device, int volumeBehavior) {
10127         final int dispatchers = mDeviceVolumeBehaviorDispatchers.beginBroadcast();
10128         for (int i = 0; i < dispatchers; i++) {
10129             try {
10130                 mDeviceVolumeBehaviorDispatchers.getBroadcastItem(i)
10131                         .dispatchDeviceVolumeBehaviorChanged(device, volumeBehavior);
10132             } catch (RemoteException e) {
10133             }
10134         }
10135         mDeviceVolumeBehaviorDispatchers.finishBroadcast();
10136     }
10137 
10138     //==========================================================================================
10139     // Device orientation
10140     //==========================================================================================
10141     /**
10142      * Handles device configuration changes that may map to a change in rotation.
10143      * Monitoring rotation is optional, and is defined by the definition and value
10144      * of the "ro.audio.monitorRotation" system property.
10145      */
handleConfigurationChanged(Context context)10146     private void handleConfigurationChanged(Context context) {
10147         try {
10148             // reading new configuration "safely" (i.e. under try catch) in case anything
10149             // goes wrong.
10150             Configuration config = context.getResources().getConfiguration();
10151             sendMsg(mAudioHandler,
10152                     MSG_CONFIGURE_SAFE_MEDIA_VOLUME,
10153                     SENDMSG_REPLACE,
10154                     0,
10155                     0,
10156                     TAG,
10157                     0);
10158 
10159             boolean cameraSoundForced = readCameraSoundForced();
10160             synchronized (mSettingsLock) {
10161                 final boolean cameraSoundForcedChanged = (cameraSoundForced != mCameraSoundForced);
10162                 mCameraSoundForced = cameraSoundForced;
10163                 if (cameraSoundForcedChanged) {
10164                     if (!mIsSingleVolume) {
10165                         synchronized (VolumeStreamState.class) {
10166                             VolumeStreamState s = mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED];
10167                             if (cameraSoundForced) {
10168                                 s.setAllIndexesToMax();
10169                                 mRingerModeAffectedStreams &=
10170                                         ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
10171                             } else {
10172                                 s.setAllIndexes(mStreamStates[AudioSystem.STREAM_SYSTEM], TAG);
10173                                 mRingerModeAffectedStreams |=
10174                                         (1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
10175                             }
10176                         }
10177                         // take new state into account for streams muted by ringer mode
10178                         setRingerModeInt(getRingerModeInternal(), false);
10179                     }
10180                     mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM,
10181                             cameraSoundForced ?
10182                                     AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE,
10183                             "handleConfigurationChanged");
10184                     sendMsg(mAudioHandler,
10185                             MSG_SET_ALL_VOLUMES,
10186                             SENDMSG_QUEUE,
10187                             0,
10188                             0,
10189                             mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED], 0);
10190 
10191                 }
10192             }
10193             mVolumeController.setLayoutDirection(config.getLayoutDirection());
10194         } catch (Exception e) {
10195             Log.e(TAG, "Error handling configuration change: ", e);
10196         }
10197     }
10198 
10199     @Override
setRingtonePlayer(IRingtonePlayer player)10200     public void setRingtonePlayer(IRingtonePlayer player) {
10201         mContext.enforceCallingOrSelfPermission(REMOTE_AUDIO_PLAYBACK, null);
10202         mRingtonePlayer = player;
10203     }
10204 
10205     @Override
getRingtonePlayer()10206     public IRingtonePlayer getRingtonePlayer() {
10207         return mRingtonePlayer;
10208     }
10209 
10210     @Override
startWatchingRoutes(IAudioRoutesObserver observer)10211     public AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) {
10212         return mDeviceBroker.startWatchingRoutes(observer);
10213     }
10214 
10215 
10216     //==========================================================================================
10217     // Safe media volume management.
10218     // MUSIC stream volume level is limited when headphones are connected according to safety
10219     // regulation. When the user attempts to raise the volume above the limit, a warning is
10220     // displayed and the user has to acknowlegde before the volume is actually changed.
10221     // The volume index corresponding to the limit is stored in config_safe_media_volume_index
10222     // property. Platforms with a different limit must set this property accordingly in their
10223     // overlay.
10224     //==========================================================================================
10225 
10226     // mSafeMediaVolumeState indicates whether the media volume is limited over headphones.
10227     // It is SAFE_MEDIA_VOLUME_NOT_CONFIGURED at boot time until a network service is connected
10228     // or the configure time is elapsed. It is then set to SAFE_MEDIA_VOLUME_ACTIVE or
10229     // SAFE_MEDIA_VOLUME_DISABLED according to country option. If not SAFE_MEDIA_VOLUME_DISABLED, it
10230     // can be set to SAFE_MEDIA_VOLUME_INACTIVE by calling AudioService.disableSafeMediaVolume()
10231     // (when user opts out).
10232     private static final int SAFE_MEDIA_VOLUME_NOT_CONFIGURED = 0;
10233     private static final int SAFE_MEDIA_VOLUME_DISABLED = 1;
10234     private static final int SAFE_MEDIA_VOLUME_INACTIVE = 2;  // confirmed
10235     private static final int SAFE_MEDIA_VOLUME_ACTIVE = 3;  // unconfirmed
10236     private int mSafeMediaVolumeState;
10237     private final Object mSafeMediaVolumeStateLock = new Object();
10238 
10239     private int mMcc = 0;
10240     // mSafeMediaVolumeIndex is the cached value of config_safe_media_volume_index property
10241     private int mSafeMediaVolumeIndex;
10242     // mSafeUsbMediaVolumeDbfs is the cached value of the config_safe_media_volume_usb_mB
10243     // property, divided by 100.0.
10244     private float mSafeUsbMediaVolumeDbfs;
10245     // mSafeUsbMediaVolumeIndex is used for USB Headsets and is the music volume UI index
10246     // corresponding to a gain of mSafeUsbMediaVolumeDbfs (defaulting to -37dB) in audio
10247     // flinger mixer.
10248     // We remove -22 dBs from the theoretical -15dB to account for the EQ + bass boost
10249     // amplification when both effects are on with all band gains at maximum.
10250     // This level corresponds to a loudness of 85 dB SPL for the warning to be displayed when
10251     // the headset is compliant to EN 60950 with a max loudness of 100dB SPL.
10252     private int mSafeUsbMediaVolumeIndex;
10253     // mSafeMediaVolumeDevices lists the devices for which safe media volume is enforced,
10254     /*package*/ final Set<Integer> mSafeMediaVolumeDevices = new HashSet<>(
10255             Arrays.asList(AudioSystem.DEVICE_OUT_WIRED_HEADSET,
10256                     AudioSystem.DEVICE_OUT_WIRED_HEADPHONE, AudioSystem.DEVICE_OUT_USB_HEADSET));
10257     // mMusicActiveMs is the cumulative time of music activity since safe volume was disabled.
10258     // When this time reaches UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX, the safe media volume is re-enabled
10259     // automatically. mMusicActiveMs is rounded to a multiple of MUSIC_ACTIVE_POLL_PERIOD_MS.
10260     private int mMusicActiveMs;
10261     private long mLastMusicActiveTimeMs = 0;
10262     private PendingIntent mMusicActiveIntent = null;
10263     private AlarmManager mAlarmManager;
10264 
10265     private static final int UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX = (20 * 3600 * 1000); // 20 hours
10266     private static final int MUSIC_ACTIVE_POLL_PERIOD_MS = 60000;  // 1 minute polling interval
10267     private static final int SAFE_VOLUME_CONFIGURE_TIMEOUT_MS = 30000;  // 30s after boot completed
10268     // check playback or record activity every 6 seconds for UIDs owning mode IN_COMMUNICATION
10269     private static final int CHECK_MODE_FOR_UID_PERIOD_MS = 6000;
10270 
10271     private static final String ACTION_CHECK_MUSIC_ACTIVE =
10272             "com.android.server.audio.action.CHECK_MUSIC_ACTIVE";
10273     private static final int REQUEST_CODE_CHECK_MUSIC_ACTIVE = 1;
10274 
safeMediaVolumeIndex(int device)10275     private int safeMediaVolumeIndex(int device) {
10276         if (!mSafeMediaVolumeDevices.contains(device)) {
10277             return MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC];
10278         }
10279         if (device == AudioSystem.DEVICE_OUT_USB_HEADSET) {
10280             return mSafeUsbMediaVolumeIndex;
10281         } else {
10282             return mSafeMediaVolumeIndex;
10283         }
10284     }
10285 
setSafeMediaVolumeEnabled(boolean on, String caller)10286     private void setSafeMediaVolumeEnabled(boolean on, String caller) {
10287         synchronized (mSafeMediaVolumeStateLock) {
10288             if ((mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_NOT_CONFIGURED) &&
10289                     (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_DISABLED)) {
10290                 if (on && (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE)) {
10291                     mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE;
10292                     enforceSafeMediaVolume(caller);
10293                 } else if (!on && (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE)) {
10294                     mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_INACTIVE;
10295                     mMusicActiveMs = 1;  // nonzero = confirmed
10296                     mLastMusicActiveTimeMs = 0;
10297                     saveMusicActiveMs();
10298                     scheduleMusicActiveCheck();
10299                 }
10300             }
10301         }
10302     }
10303 
enforceSafeMediaVolume(String caller)10304     private void enforceSafeMediaVolume(String caller) {
10305         VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC];
10306         Set<Integer> devices = mSafeMediaVolumeDevices;
10307 
10308         for (int device : devices) {
10309             int index = streamState.getIndex(device);
10310             if (index > safeMediaVolumeIndex(device)) {
10311                 streamState.setIndex(safeMediaVolumeIndex(device), device, caller,
10312                             true /*hasModifyAudioSettings*/);
10313                 sendMsg(mAudioHandler,
10314                         MSG_SET_DEVICE_VOLUME,
10315                         SENDMSG_QUEUE,
10316                         device,
10317                         0,
10318                         streamState,
10319                         0);
10320             }
10321         }
10322     }
10323 
checkSafeMediaVolume(int streamType, int index, int device)10324     private boolean checkSafeMediaVolume(int streamType, int index, int device) {
10325         synchronized (mSafeMediaVolumeStateLock) {
10326             if ((mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE)
10327                     && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC)
10328                     && (mSafeMediaVolumeDevices.contains(device))
10329                     && (index > safeMediaVolumeIndex(device))) {
10330                 return false;
10331             }
10332             return true;
10333         }
10334     }
10335 
10336     @Override
disableSafeMediaVolume(String callingPackage)10337     public void disableSafeMediaVolume(String callingPackage) {
10338         enforceVolumeController("disable the safe media volume");
10339         synchronized (mSafeMediaVolumeStateLock) {
10340             final long identity = Binder.clearCallingIdentity();
10341             setSafeMediaVolumeEnabled(false, callingPackage);
10342             Binder.restoreCallingIdentity(identity);
10343             if (mPendingVolumeCommand != null) {
10344                 onSetStreamVolume(mPendingVolumeCommand.mStreamType,
10345                                   mPendingVolumeCommand.mIndex,
10346                                   mPendingVolumeCommand.mFlags,
10347                                   mPendingVolumeCommand.mDevice,
10348                                   callingPackage, true /*hasModifyAudioSettings*/,
10349                                   true /*canChangeMute*/);
10350                 mPendingVolumeCommand = null;
10351             }
10352         }
10353     }
10354 
10355     //==========================================================================================
10356     // Hdmi CEC:
10357     // - System audio mode:
10358     //     If Hdmi Cec's system audio mode is on, audio service should send the volume change
10359     //     to HdmiControlService so that the audio receiver can handle it.
10360     // - CEC sink:
10361     //     OUT_HDMI becomes a "full volume device", i.e. output is always at maximum level
10362     //     and volume changes won't be taken into account on this device. Volume adjustments
10363     //     are transformed into key events for the HDMI playback client.
10364     //==========================================================================================
10365 
10366     @GuardedBy("mHdmiClientLock")
updateHdmiCecSinkLocked(boolean hdmiCecSink)10367     private void updateHdmiCecSinkLocked(boolean hdmiCecSink) {
10368         if (!hasDeviceVolumeBehavior(AudioSystem.DEVICE_OUT_HDMI)) {
10369             if (hdmiCecSink) {
10370                 if (DEBUG_VOL) {
10371                     Log.d(TAG, "CEC sink: setting HDMI as full vol device");
10372                 }
10373                 setDeviceVolumeBehaviorInternal(
10374                         new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""),
10375                         AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL,
10376                         "AudioService.updateHdmiCecSinkLocked()");
10377             } else {
10378                 if (DEBUG_VOL) {
10379                     Log.d(TAG, "TV, no CEC: setting HDMI as regular vol device");
10380                 }
10381                 // Android TV devices without CEC service apply software volume on
10382                 // HDMI output
10383                 setDeviceVolumeBehaviorInternal(
10384                         new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""),
10385                         AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE,
10386                         "AudioService.updateHdmiCecSinkLocked()");
10387             }
10388             postUpdateVolumeStatesForAudioDevice(AudioSystem.DEVICE_OUT_HDMI,
10389                     "HdmiPlaybackClient.DisplayStatusCallback");
10390         }
10391     }
10392 
10393     private class MyHdmiControlStatusChangeListenerCallback
10394             implements HdmiControlManager.HdmiControlStatusChangeListener {
onStatusChange(@dmiControlManager.HdmiCecControl int isCecEnabled, boolean isCecAvailable)10395         public void onStatusChange(@HdmiControlManager.HdmiCecControl int isCecEnabled,
10396                 boolean isCecAvailable) {
10397             synchronized (mHdmiClientLock) {
10398                 if (mHdmiManager == null) return;
10399                 boolean cecEnabled = isCecEnabled == HdmiControlManager.HDMI_CEC_CONTROL_ENABLED;
10400                 updateHdmiCecSinkLocked(cecEnabled ? isCecAvailable : false);
10401             }
10402         }
10403     };
10404 
10405     private class MyHdmiCecVolumeControlFeatureListener
10406             implements HdmiControlManager.HdmiCecVolumeControlFeatureListener {
onHdmiCecVolumeControlFeature( @dmiControlManager.VolumeControl int hdmiCecVolumeControl)10407         public void onHdmiCecVolumeControlFeature(
10408                 @HdmiControlManager.VolumeControl int hdmiCecVolumeControl) {
10409             synchronized (mHdmiClientLock) {
10410                 if (mHdmiManager == null) return;
10411                 mHdmiCecVolumeControlEnabled =
10412                         hdmiCecVolumeControl == HdmiControlManager.VOLUME_CONTROL_ENABLED;
10413             }
10414         }
10415     };
10416 
10417     private final Object mHdmiClientLock = new Object();
10418 
10419     // If HDMI-CEC system audio is supported
10420     // Note that for CEC volume commands mHdmiCecVolumeControlEnabled will play a role on volume
10421     // commands
10422     private boolean mHdmiSystemAudioSupported = false;
10423     // Set only when device is tv.
10424     @GuardedBy("mHdmiClientLock")
10425     private HdmiTvClient mHdmiTvClient;
10426     // true if the device has system feature PackageManager.FEATURE_LEANBACK.
10427     // cached HdmiControlManager interface
10428     @GuardedBy("mHdmiClientLock")
10429     private HdmiControlManager mHdmiManager;
10430     // Set only when device is a set-top box.
10431     @GuardedBy("mHdmiClientLock")
10432     private HdmiPlaybackClient mHdmiPlaybackClient;
10433     // Set only when device is an audio system.
10434     @GuardedBy("mHdmiClientLock")
10435     private HdmiAudioSystemClient mHdmiAudioSystemClient;
10436     // True when volume control over HDMI CEC is used when CEC is enabled (meaningless otherwise)
10437     @GuardedBy("mHdmiClientLock")
10438     private boolean mHdmiCecVolumeControlEnabled;
10439 
10440     private MyHdmiControlStatusChangeListenerCallback mHdmiControlStatusChangeListenerCallback =
10441             new MyHdmiControlStatusChangeListenerCallback();
10442 
10443     private MyHdmiCecVolumeControlFeatureListener mMyHdmiCecVolumeControlFeatureListener =
10444             new MyHdmiCecVolumeControlFeatureListener();
10445 
10446     @Override
setHdmiSystemAudioSupported(boolean on)10447     public int setHdmiSystemAudioSupported(boolean on) {
10448         int device = AudioSystem.DEVICE_NONE;
10449         synchronized (mHdmiClientLock) {
10450             if (mHdmiManager != null) {
10451                 if (mHdmiTvClient == null && mHdmiAudioSystemClient == null) {
10452                     Log.w(TAG, "Only Hdmi-Cec enabled TV or audio system device supports"
10453                             + "system audio mode.");
10454                     return device;
10455                 }
10456                 if (mHdmiSystemAudioSupported != on) {
10457                     mHdmiSystemAudioSupported = on;
10458                     final int config = on ? AudioSystem.FORCE_HDMI_SYSTEM_AUDIO_ENFORCED :
10459                         AudioSystem.FORCE_NONE;
10460                     mDeviceBroker.setForceUse_Async(AudioSystem.FOR_HDMI_SYSTEM_AUDIO, config,
10461                             "setHdmiSystemAudioSupported");
10462                 }
10463                 // TODO(b/185386781): Update AudioManager API to use device list.
10464                 // So far, this value appears to be advisory for debug log.
10465                 device = getDeviceMaskForStream(AudioSystem.STREAM_MUSIC);
10466             }
10467         }
10468         return device;
10469     }
10470 
10471     @Override
isHdmiSystemAudioSupported()10472     public boolean isHdmiSystemAudioSupported() {
10473         return mHdmiSystemAudioSupported;
10474     }
10475 
10476     //==========================================================================================
10477     // Accessibility
10478 
initA11yMonitoring()10479     private void initA11yMonitoring() {
10480         final AccessibilityManager accessibilityManager =
10481                 (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
10482         updateDefaultStreamOverrideDelay(accessibilityManager.isTouchExplorationEnabled());
10483         updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive());
10484         accessibilityManager.addTouchExplorationStateChangeListener(this, null);
10485         accessibilityManager.addAccessibilityServicesStateChangeListener(this);
10486     }
10487 
10488     //---------------------------------------------------------------------------------
10489     // A11y: taking touch exploration into account for selecting the default
10490     //   stream override timeout when adjusting volume
10491     //---------------------------------------------------------------------------------
10492 
10493     // - STREAM_NOTIFICATION on tablets during this period after a notification stopped
10494     // - STREAM_RING on phones during this period after a notification stopped
10495     // - STREAM_MUSIC otherwise
10496 
10497     private static final int DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS = 0;
10498     private static final int TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS = 1000;
10499 
10500     private static int sStreamOverrideDelayMs;
10501 
10502     @Override
onTouchExplorationStateChanged(boolean enabled)10503     public void onTouchExplorationStateChanged(boolean enabled) {
10504         updateDefaultStreamOverrideDelay(enabled);
10505     }
10506 
updateDefaultStreamOverrideDelay(boolean touchExploreEnabled)10507     private void updateDefaultStreamOverrideDelay(boolean touchExploreEnabled) {
10508         if (touchExploreEnabled) {
10509             sStreamOverrideDelayMs = TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS;
10510         } else {
10511             sStreamOverrideDelayMs = DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS;
10512         }
10513         if (DEBUG_VOL) Log.d(TAG, "Touch exploration enabled=" + touchExploreEnabled
10514                 + " stream override delay is now " + sStreamOverrideDelayMs + " ms");
10515     }
10516 
10517     //---------------------------------------------------------------------------------
10518     // A11y: taking a11y state into account for the handling of a11y prompts volume
10519     //---------------------------------------------------------------------------------
10520 
10521     private static boolean sIndependentA11yVolume = false;
10522 
10523     // implementation of AccessibilityServicesStateChangeListener
10524     @Override
onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager)10525     public void onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager) {
10526         updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive());
10527     }
10528 
updateA11yVolumeAlias(boolean a11VolEnabled)10529     private void updateA11yVolumeAlias(boolean a11VolEnabled) {
10530         if (DEBUG_VOL) Log.d(TAG, "Accessibility volume enabled = " + a11VolEnabled);
10531         if (sIndependentA11yVolume != a11VolEnabled) {
10532             sIndependentA11yVolume = a11VolEnabled;
10533             // update the volume mapping scheme
10534             updateStreamVolumeAlias(true /*updateVolumes*/, TAG);
10535             // update the volume controller behavior
10536             mVolumeController.setA11yMode(sIndependentA11yVolume ?
10537                     VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME :
10538                         VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME);
10539             mVolumeController.postVolumeChanged(AudioManager.STREAM_ACCESSIBILITY, 0);
10540         }
10541     }
10542 
10543     //==========================================================================================
10544     // Camera shutter sound policy.
10545     // config_camera_sound_forced configuration option in config.xml defines if the camera shutter
10546     // sound is forced (sound even if the device is in silent mode) or not. This option is false by
10547     // default and can be overridden by country specific overlay in values-mccXXX/config.xml.
10548     //==========================================================================================
10549 
10550     // cached value of com.android.internal.R.bool.config_camera_sound_forced
10551     @GuardedBy("mSettingsLock")
10552     private boolean mCameraSoundForced;
10553 
10554     // called by android.hardware.Camera to populate CameraInfo.canDisableShutterSound
isCameraSoundForced()10555     public boolean isCameraSoundForced() {
10556         synchronized (mSettingsLock) {
10557             return mCameraSoundForced;
10558         }
10559     }
10560 
10561     //==========================================================================================
10562     // AudioService logging and dumpsys
10563     //==========================================================================================
10564     static final int LOG_NB_EVENTS_LIFECYCLE = 20;
10565     static final int LOG_NB_EVENTS_PHONE_STATE = 20;
10566     static final int LOG_NB_EVENTS_DEVICE_CONNECTION = 50;
10567     static final int LOG_NB_EVENTS_FORCE_USE = 20;
10568     static final int LOG_NB_EVENTS_VOLUME = 100;
10569     static final int LOG_NB_EVENTS_DYN_POLICY = 10;
10570     static final int LOG_NB_EVENTS_SPATIAL = 30;
10571 
10572     static final AudioEventLogger sLifecycleLogger = new AudioEventLogger(LOG_NB_EVENTS_LIFECYCLE,
10573             "audio services lifecycle");
10574 
10575     final private AudioEventLogger mModeLogger = new AudioEventLogger(LOG_NB_EVENTS_PHONE_STATE,
10576             "phone state (logged after successful call to AudioSystem.setPhoneState(int, int))");
10577 
10578     // logs for wired + A2DP device connections:
10579     // - wired: logged before onSetWiredDeviceConnectionState() is executed
10580     // - A2DP: logged at reception of method call
10581     /*package*/ static final AudioEventLogger sDeviceLogger = new AudioEventLogger(
10582             LOG_NB_EVENTS_DEVICE_CONNECTION, "wired/A2DP/hearing aid device connection");
10583 
10584     static final AudioEventLogger sForceUseLogger = new AudioEventLogger(
10585             LOG_NB_EVENTS_FORCE_USE,
10586             "force use (logged before setForceUse() is executed)");
10587 
10588     static final AudioEventLogger sVolumeLogger = new AudioEventLogger(LOG_NB_EVENTS_VOLUME,
10589             "volume changes (logged when command received by AudioService)");
10590 
10591     static final AudioEventLogger sSpatialLogger = new AudioEventLogger(LOG_NB_EVENTS_SPATIAL,
10592             "spatial audio");
10593 
10594     final private AudioEventLogger mDynPolicyLogger = new AudioEventLogger(LOG_NB_EVENTS_DYN_POLICY,
10595             "dynamic policy events (logged when command received by AudioService)");
10596 
10597     private static final String[] RINGER_MODE_NAMES = new String[] {
10598             "SILENT",
10599             "VIBRATE",
10600             "NORMAL"
10601     };
10602 
dumpRingerMode(PrintWriter pw)10603     private void dumpRingerMode(PrintWriter pw) {
10604         pw.println("\nRinger mode: ");
10605         pw.println("- mode (internal) = " + RINGER_MODE_NAMES[mRingerMode]);
10606         pw.println("- mode (external) = " + RINGER_MODE_NAMES[mRingerModeExternal]);
10607         pw.println("- zen mode:" + Settings.Global.zenModeToString(mNm.getZenMode()));
10608         dumpRingerModeStreams(pw, "affected", mRingerModeAffectedStreams);
10609         dumpRingerModeStreams(pw, "muted", mRingerAndZenModeMutedStreams);
10610         pw.print("- delegate = "); pw.println(mRingerModeDelegate);
10611     }
10612 
dumpRingerModeStreams(PrintWriter pw, String type, int streams)10613     private void dumpRingerModeStreams(PrintWriter pw, String type, int streams) {
10614         pw.print("- ringer mode "); pw.print(type); pw.print(" streams = 0x");
10615         pw.print(Integer.toHexString(streams));
10616         if (streams != 0) {
10617             pw.print(" (");
10618             boolean first = true;
10619             for (int i = 0; i < AudioSystem.STREAM_NAMES.length; i++) {
10620                 final int stream = (1 << i);
10621                 if ((streams & stream) != 0) {
10622                     if (!first) pw.print(',');
10623                     pw.print(AudioSystem.STREAM_NAMES[i]);
10624                     streams &= ~stream;
10625                     first = false;
10626                 }
10627             }
10628             if (streams != 0) {
10629                 if (!first) pw.print(',');
10630                 pw.print(streams);
10631             }
10632             pw.print(')');
10633         }
10634         pw.println();
10635     }
10636 
dumpDeviceTypes(@onNull Set<Integer> deviceTypes)10637     private String dumpDeviceTypes(@NonNull Set<Integer> deviceTypes) {
10638         Iterator<Integer> it = deviceTypes.iterator();
10639         if (!it.hasNext()) {
10640             return "";
10641         }
10642         final StringBuilder sb = new StringBuilder();
10643         sb.append("0x" + Integer.toHexString(it.next()));
10644         while (it.hasNext()) {
10645             sb.append("," + "0x" + Integer.toHexString(it.next()));
10646         }
10647         return sb.toString();
10648     }
10649 
10650     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)10651     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10652         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
10653 
10654         sLifecycleLogger.dump(pw);
10655         if (mAudioHandler != null) {
10656             pw.println("\nMessage handler (watch for unhandled messages):");
10657             mAudioHandler.dump(new PrintWriterPrinter(pw), "  ");
10658         } else {
10659             pw.println("\nMessage handler is null");
10660         }
10661         mMediaFocusControl.dump(pw);
10662         dumpStreamStates(pw);
10663         dumpVolumeGroups(pw);
10664         dumpRingerMode(pw);
10665         dumpAudioMode(pw);
10666         pw.println("\nAudio routes:");
10667         pw.print("  mMainType=0x"); pw.println(Integer.toHexString(
10668                 mDeviceBroker.getCurAudioRoutes().mainType));
10669         pw.print("  mBluetoothName="); pw.println(mDeviceBroker.getCurAudioRoutes().bluetoothName);
10670 
10671         pw.println("\nOther state:");
10672         pw.print("  mVolumeController="); pw.println(mVolumeController);
10673         pw.print("  mSafeMediaVolumeState=");
10674         pw.println(safeMediaVolumeStateToString(mSafeMediaVolumeState));
10675         pw.print("  mSafeMediaVolumeIndex="); pw.println(mSafeMediaVolumeIndex);
10676         pw.print("  mSafeUsbMediaVolumeIndex="); pw.println(mSafeUsbMediaVolumeIndex);
10677         pw.print("  mSafeUsbMediaVolumeDbfs="); pw.println(mSafeUsbMediaVolumeDbfs);
10678         pw.print("  sIndependentA11yVolume="); pw.println(sIndependentA11yVolume);
10679         pw.print("  mPendingVolumeCommand="); pw.println(mPendingVolumeCommand);
10680         pw.print("  mMusicActiveMs="); pw.println(mMusicActiveMs);
10681         pw.print("  mMcc="); pw.println(mMcc);
10682         pw.print("  mCameraSoundForced="); pw.println(isCameraSoundForced());
10683         pw.print("  mHasVibrator="); pw.println(mHasVibrator);
10684         pw.print("  mVolumePolicy="); pw.println(mVolumePolicy);
10685         pw.print("  mAvrcpAbsVolSupported="); pw.println(mAvrcpAbsVolSupported);
10686         pw.print("  mBtScoOnByApp="); pw.println(mBtScoOnByApp);
10687         pw.print("  mIsSingleVolume="); pw.println(mIsSingleVolume);
10688         pw.print("  mUseFixedVolume="); pw.println(mUseFixedVolume);
10689         pw.print("  mNotifAliasRing="); pw.println(mNotifAliasRing);
10690         pw.print("  mFixedVolumeDevices="); pw.println(dumpDeviceTypes(mFixedVolumeDevices));
10691         pw.print("  mFullVolumeDevices="); pw.println(dumpDeviceTypes(mFullVolumeDevices));
10692         pw.print("  mAbsoluteVolumeDevices.keySet()="); pw.println(dumpDeviceTypes(
10693                 mAbsoluteVolumeDeviceInfoMap.keySet()));
10694         pw.print("  mExtVolumeController="); pw.println(mExtVolumeController);
10695         pw.print("  mHdmiAudioSystemClient="); pw.println(mHdmiAudioSystemClient);
10696         pw.print("  mHdmiPlaybackClient="); pw.println(mHdmiPlaybackClient);
10697         pw.print("  mHdmiTvClient="); pw.println(mHdmiTvClient);
10698         pw.print("  mHdmiSystemAudioSupported="); pw.println(mHdmiSystemAudioSupported);
10699         pw.print("  mHdmiCecVolumeControlEnabled="); pw.println(mHdmiCecVolumeControlEnabled);
10700         pw.print("  mIsCallScreeningModeSupported="); pw.println(mIsCallScreeningModeSupported);
10701         pw.print("  mic mute FromSwitch=" + mMicMuteFromSwitch
10702                         + " FromRestrictions=" + mMicMuteFromRestrictions
10703                         + " FromApi=" + mMicMuteFromApi
10704                         + " from system=" + mMicMuteFromSystemCached);
10705         pw.print("  mCurrentImeUid="); pw.println(mCurrentImeUid);
10706         dumpAccessibilityServiceUids(pw);
10707         dumpAssistantServicesUids(pw);
10708 
10709         dumpAudioPolicies(pw);
10710         mDynPolicyLogger.dump(pw);
10711         mPlaybackMonitor.dump(pw);
10712         mRecordMonitor.dump(pw);
10713 
10714         pw.println("\nAudioDeviceBroker:");
10715         mDeviceBroker.dump(pw, "  ");
10716         pw.println("\nSoundEffects:");
10717         mSfxHelper.dump(pw, "  ");
10718 
10719         pw.println("\n");
10720         pw.println("\nEvent logs:");
10721         mModeLogger.dump(pw);
10722         pw.println("\n");
10723         sDeviceLogger.dump(pw);
10724         pw.println("\n");
10725         sForceUseLogger.dump(pw);
10726         pw.println("\n");
10727         sVolumeLogger.dump(pw);
10728         pw.println("\n");
10729         dumpSupportedSystemUsage(pw);
10730 
10731         pw.println("\n");
10732         pw.println("\nSpatial audio:");
10733         pw.println("mHasSpatializerEffect:" + mHasSpatializerEffect + " (effect present)");
10734         pw.println("isSpatializerEnabled:" + isSpatializerEnabled() + " (routing dependent)");
10735         mSpatializerHelper.dump(pw);
10736         sSpatialLogger.dump(pw);
10737 
10738         mAudioSystem.dump(pw);
10739     }
10740 
dumpSupportedSystemUsage(PrintWriter pw)10741     private void dumpSupportedSystemUsage(PrintWriter pw) {
10742         pw.println("Supported System Usages:");
10743         synchronized (mSupportedSystemUsagesLock) {
10744             for (int i = 0; i < mSupportedSystemUsages.length; i++) {
10745                 pw.printf("\t%s\n", AudioAttributes.usageToString(mSupportedSystemUsages[i]));
10746             }
10747         }
10748     }
10749 
dumpAssistantServicesUids(PrintWriter pw)10750     private void dumpAssistantServicesUids(PrintWriter pw) {
10751         synchronized (mSettingsLock) {
10752             if (mAssistantUids.size() > 0) {
10753                 pw.println("  Assistant service UIDs:");
10754                 for (int uid : mAssistantUids) {
10755                     pw.println("  - " + uid);
10756                 }
10757             } else {
10758                 pw.println("  No Assistant service Uids.");
10759             }
10760         }
10761     }
10762 
dumpAccessibilityServiceUids(PrintWriter pw)10763     private void dumpAccessibilityServiceUids(PrintWriter pw) {
10764         synchronized (mSupportedSystemUsagesLock) {
10765             if (mAccessibilityServiceUids != null && mAccessibilityServiceUids.length > 0) {
10766                 pw.println("  Accessibility service Uids:");
10767                 for (int uid : mAccessibilityServiceUids) {
10768                     pw.println("  - " + uid);
10769                 }
10770             } else {
10771                 pw.println("  No accessibility service Uids.");
10772             }
10773         }
10774     }
10775 
10776     /**
10777      * Audio Analytics ids.
10778      */
10779     private static final String mMetricsId = MediaMetrics.Name.AUDIO_SERVICE
10780             + MediaMetrics.SEPARATOR;
10781 
safeMediaVolumeStateToString(int state)10782     private static String safeMediaVolumeStateToString(int state) {
10783         switch(state) {
10784             case SAFE_MEDIA_VOLUME_NOT_CONFIGURED: return "SAFE_MEDIA_VOLUME_NOT_CONFIGURED";
10785             case SAFE_MEDIA_VOLUME_DISABLED: return "SAFE_MEDIA_VOLUME_DISABLED";
10786             case SAFE_MEDIA_VOLUME_INACTIVE: return "SAFE_MEDIA_VOLUME_INACTIVE";
10787             case SAFE_MEDIA_VOLUME_ACTIVE: return "SAFE_MEDIA_VOLUME_ACTIVE";
10788         }
10789         return null;
10790     }
10791 
10792     // Inform AudioFlinger of our device's low RAM attribute
readAndSetLowRamDevice()10793     private static void readAndSetLowRamDevice()
10794     {
10795         boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic();
10796         long totalMemory = 1024 * 1024 * 1024; // 1GB is the default if ActivityManager fails.
10797 
10798         try {
10799             final ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();
10800             ActivityManager.getService().getMemoryInfo(info);
10801             totalMemory = info.totalMem;
10802         } catch (RemoteException e) {
10803             Log.w(TAG, "Cannot obtain MemoryInfo from ActivityManager, assume low memory device");
10804             isLowRamDevice = true;
10805         }
10806 
10807         final int status = AudioSystem.setLowRamDevice(isLowRamDevice, totalMemory);
10808         if (status != 0) {
10809             Log.w(TAG, "AudioFlinger informed of device's low RAM attribute; status " + status);
10810         }
10811     }
10812 
enforceVolumeController(String action)10813     private void enforceVolumeController(String action) {
10814         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE,
10815                 "Only SystemUI can " + action);
10816     }
10817 
10818     @Override
setVolumeController(final IVolumeController controller)10819     public void setVolumeController(final IVolumeController controller) {
10820         enforceVolumeController("set the volume controller");
10821 
10822         // return early if things are not actually changing
10823         if (mVolumeController.isSameBinder(controller)) {
10824             return;
10825         }
10826 
10827         // dismiss the old volume controller
10828         mVolumeController.postDismiss();
10829         if (controller != null) {
10830             // we are about to register a new controller, listen for its death
10831             try {
10832                 controller.asBinder().linkToDeath(new DeathRecipient() {
10833                     @Override
10834                     public void binderDied() {
10835                         if (mVolumeController.isSameBinder(controller)) {
10836                             Log.w(TAG, "Current remote volume controller died, unregistering");
10837                             setVolumeController(null);
10838                         }
10839                     }
10840                 }, 0);
10841             } catch (RemoteException e) {
10842                 // noop
10843             }
10844         }
10845         mVolumeController.setController(controller);
10846         if (DEBUG_VOL) Log.d(TAG, "Volume controller: " + mVolumeController);
10847     }
10848 
10849     @Override
notifyVolumeControllerVisible(final IVolumeController controller, boolean visible)10850     public void notifyVolumeControllerVisible(final IVolumeController controller, boolean visible) {
10851         enforceVolumeController("notify about volume controller visibility");
10852 
10853         // return early if the controller is not current
10854         if (!mVolumeController.isSameBinder(controller)) {
10855             return;
10856         }
10857 
10858         mVolumeController.setVisible(visible);
10859         if (DEBUG_VOL) Log.d(TAG, "Volume controller visible: " + visible);
10860     }
10861 
10862     @Override
setVolumePolicy(VolumePolicy policy)10863     public void setVolumePolicy(VolumePolicy policy) {
10864         enforceVolumeController("set volume policy");
10865         if (policy != null && !policy.equals(mVolumePolicy)) {
10866             mVolumePolicy = policy;
10867             if (DEBUG_VOL) Log.d(TAG, "Volume policy changed: " + mVolumePolicy);
10868         }
10869     }
10870 
10871     public class VolumeController {
10872         private static final String TAG = "VolumeController";
10873 
10874         private IVolumeController mController;
10875         private boolean mVisible;
10876         private long mNextLongPress;
10877         private int mLongPressTimeout;
10878 
setController(IVolumeController controller)10879         public void setController(IVolumeController controller) {
10880             mController = controller;
10881             mVisible = false;
10882         }
10883 
loadSettings(ContentResolver cr)10884         public void loadSettings(ContentResolver cr) {
10885             mLongPressTimeout = mSettings.getSecureIntForUser(cr,
10886                     Settings.Secure.LONG_PRESS_TIMEOUT, 500, UserHandle.USER_CURRENT);
10887         }
10888 
suppressAdjustment(int resolvedStream, int flags, boolean isMute)10889         public boolean suppressAdjustment(int resolvedStream, int flags, boolean isMute) {
10890             if (isMute) {
10891                 return false;
10892             }
10893             boolean suppress = false;
10894             // Intended behavior:
10895             // 1/ if the stream is not the default UI stream, do not suppress (as it is not involved
10896             //    in bringing up the UI)
10897             // 2/ if the resolved and default stream is MUSIC, and media is playing, do not suppress
10898             // 3/ otherwise suppress the first adjustments that occur during the "long press
10899             //    timeout" interval. Note this is true regardless of whether this is a "real long
10900             //    press" (where the user keeps pressing on the volume button), or repeated single
10901             //    presses (here we don't know if we are in a real long press, or repeated fast
10902             //    button presses).
10903             //    Once the long press timeout occurs (mNextLongPress reset to 0), do not suppress.
10904             // Example: for a default and resolved stream of MUSIC, this allows modifying rapidly
10905             // the volume when media is playing (whether by long press or repeated individual
10906             // presses), or to bring up the volume UI when media is not playing, in order to make
10907             // another change (e.g. switch ringer modes) without changing media volume.
10908             if (resolvedStream == DEFAULT_VOL_STREAM_NO_PLAYBACK && mController != null) {
10909                 // never suppress media vol adjustement during media playback
10910                 if (resolvedStream == AudioSystem.STREAM_MUSIC
10911                         && mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, mLongPressTimeout))
10912                 {
10913                     // media is playing, adjust the volume right away
10914                     return false;
10915                 }
10916 
10917                 final long now = SystemClock.uptimeMillis();
10918                 if ((flags & AudioManager.FLAG_SHOW_UI) != 0 && !mVisible) {
10919                     // UI is not visible yet, adjustment is ignored
10920                     if (mNextLongPress < now) {
10921                         mNextLongPress = now + mLongPressTimeout;
10922                     }
10923                     suppress = true;
10924                 } else if (mNextLongPress > 0) {  // in a long-press
10925                     if (now > mNextLongPress) {
10926                         // long press triggered, no more suppression
10927                         mNextLongPress = 0;
10928                     } else {
10929                         // keep suppressing until the long press triggers
10930                         suppress = true;
10931                     }
10932                 }
10933             }
10934             return suppress;
10935         }
10936 
setVisible(boolean visible)10937         public void setVisible(boolean visible) {
10938             mVisible = visible;
10939         }
10940 
isSameBinder(IVolumeController controller)10941         public boolean isSameBinder(IVolumeController controller) {
10942             return Objects.equals(asBinder(), binder(controller));
10943         }
10944 
asBinder()10945         public IBinder asBinder() {
10946             return binder(mController);
10947         }
10948 
binder(IVolumeController controller)10949         private IBinder binder(IVolumeController controller) {
10950             return controller == null ? null : controller.asBinder();
10951         }
10952 
10953         @Override
toString()10954         public String toString() {
10955             return "VolumeController(" + asBinder() + ",mVisible=" + mVisible + ")";
10956         }
10957 
postDisplaySafeVolumeWarning(int flags)10958         public void postDisplaySafeVolumeWarning(int flags) {
10959             if (mController == null)
10960                 return;
10961             flags = flags | AudioManager.FLAG_SHOW_UI;
10962             try {
10963                 mController.displaySafeVolumeWarning(flags);
10964             } catch (RemoteException e) {
10965                 Log.w(TAG, "Error calling displaySafeVolumeWarning", e);
10966             }
10967         }
10968 
postVolumeChanged(int streamType, int flags)10969         public void postVolumeChanged(int streamType, int flags) {
10970             if (mController == null)
10971                 return;
10972             try {
10973                 mController.volumeChanged(streamType, flags);
10974             } catch (RemoteException e) {
10975                 Log.w(TAG, "Error calling volumeChanged", e);
10976             }
10977         }
10978 
postMasterMuteChanged(int flags)10979         public void postMasterMuteChanged(int flags) {
10980             if (mController == null)
10981                 return;
10982             try {
10983                 mController.masterMuteChanged(flags);
10984             } catch (RemoteException e) {
10985                 Log.w(TAG, "Error calling masterMuteChanged", e);
10986             }
10987         }
10988 
setLayoutDirection(int layoutDirection)10989         public void setLayoutDirection(int layoutDirection) {
10990             if (mController == null)
10991                 return;
10992             try {
10993                 mController.setLayoutDirection(layoutDirection);
10994             } catch (RemoteException e) {
10995                 Log.w(TAG, "Error calling setLayoutDirection", e);
10996             }
10997         }
10998 
postDismiss()10999         public void postDismiss() {
11000             if (mController == null)
11001                 return;
11002             try {
11003                 mController.dismiss();
11004             } catch (RemoteException e) {
11005                 Log.w(TAG, "Error calling dismiss", e);
11006             }
11007         }
11008 
setA11yMode(int a11yMode)11009         public void setA11yMode(int a11yMode) {
11010             if (mController == null)
11011                 return;
11012             try {
11013                 mController.setA11yMode(a11yMode);
11014             } catch (RemoteException e) {
11015                 Log.w(TAG, "Error calling setA11Mode", e);
11016             }
11017         }
11018     }
11019 
11020     /**
11021      * Interface for system components to get some extra functionality through
11022      * LocalServices.
11023      */
11024     final class AudioServiceInternal extends AudioManagerInternal {
11025         @Override
setRingerModeDelegate(RingerModeDelegate delegate)11026         public void setRingerModeDelegate(RingerModeDelegate delegate) {
11027             mRingerModeDelegate = delegate;
11028             if (mRingerModeDelegate != null) {
11029                 synchronized (mSettingsLock) {
11030                     updateRingerAndZenModeAffectedStreams();
11031                 }
11032                 setRingerModeInternal(getRingerModeInternal(), TAG + ".setRingerModeDelegate");
11033             }
11034         }
11035 
11036         @Override
getRingerModeInternal()11037         public int getRingerModeInternal() {
11038             return AudioService.this.getRingerModeInternal();
11039         }
11040 
11041         @Override
setRingerModeInternal(int ringerMode, String caller)11042         public void setRingerModeInternal(int ringerMode, String caller) {
11043             AudioService.this.setRingerModeInternal(ringerMode, caller);
11044         }
11045 
11046         @Override
silenceRingerModeInternal(String caller)11047         public void silenceRingerModeInternal(String caller) {
11048             AudioService.this.silenceRingerModeInternal(caller);
11049         }
11050 
11051         @Override
updateRingerModeAffectedStreamsInternal()11052         public void updateRingerModeAffectedStreamsInternal() {
11053             synchronized (mSettingsLock) {
11054                 if (updateRingerAndZenModeAffectedStreams()) {
11055                     setRingerModeInt(getRingerModeInternal(), false);
11056                 }
11057             }
11058         }
11059 
11060         @Override
addAssistantServiceUid(int uid)11061         public void addAssistantServiceUid(int uid) {
11062             sendMsg(mAudioHandler, MSG_ADD_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE,
11063                     uid, 0, null, 0);
11064         }
11065 
11066         @Override
removeAssistantServiceUid(int uid)11067         public void removeAssistantServiceUid(int uid) {
11068             sendMsg(mAudioHandler, MSG_REMOVE_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE,
11069                     uid, 0, null, 0);
11070         }
11071 
11072         @Override
setActiveAssistantServicesUids(IntArray activeUids)11073         public void setActiveAssistantServicesUids(IntArray activeUids) {
11074             synchronized (mSettingsLock) {
11075                 if (activeUids.size() == 0) {
11076                     mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS;
11077                 } else {
11078                     boolean changed = (mActiveAssistantServiceUids == null)
11079                             || (mActiveAssistantServiceUids.length != activeUids.size());
11080                     if (!changed) {
11081                         for (int i = 0; i < mActiveAssistantServiceUids.length; i++) {
11082                             if (activeUids.get(i) != mActiveAssistantServiceUids[i]) {
11083                                 changed = true;
11084                                 break;
11085                             }
11086                         }
11087                     }
11088                     if (changed) {
11089                         mActiveAssistantServiceUids = activeUids.toArray();
11090                     }
11091                 }
11092             }
11093             sendMsg(mAudioHandler, MSG_UPDATE_ACTIVE_ASSISTANT_SERVICE_UID, SENDMSG_REPLACE,
11094                     0, 0, null, 0);
11095         }
11096 
11097         @Override
setAccessibilityServiceUids(IntArray uids)11098         public void setAccessibilityServiceUids(IntArray uids) {
11099             // TODO(b/233287010): Fix voice interaction and a11y concurrency in audio policy service
11100             if (isPlatformAutomotive()) {
11101                 return;
11102             }
11103 
11104             synchronized (mAccessibilityServiceUidsLock) {
11105                 if (uids.size() == 0) {
11106                     mAccessibilityServiceUids = null;
11107                 } else {
11108                     boolean changed = (mAccessibilityServiceUids == null)
11109                             || (mAccessibilityServiceUids.length != uids.size());
11110                     if (!changed) {
11111                         for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
11112                             if (uids.get(i) != mAccessibilityServiceUids[i]) {
11113                                 changed = true;
11114                                 break;
11115                             }
11116                         }
11117                     }
11118                     if (changed) {
11119                         mAccessibilityServiceUids = uids.toArray();
11120                     }
11121                 }
11122                 sendMsg(mAudioHandler, MSG_UPDATE_A11Y_SERVICE_UIDS, SENDMSG_REPLACE,
11123                         0, 0, null, 0);
11124             }
11125         }
11126 
11127         /**
11128          * {@inheritDoc}
11129          */
11130         @Override
setInputMethodServiceUid(int uid)11131         public void setInputMethodServiceUid(int uid) {
11132             synchronized (mInputMethodServiceUidLock) {
11133                 if (mInputMethodServiceUid != uid) {
11134                     mAudioSystem.setCurrentImeUid(uid);
11135                     mInputMethodServiceUid = uid;
11136                 }
11137             }
11138         }
11139     }
11140 
onUpdateAccessibilityServiceUids()11141     private void onUpdateAccessibilityServiceUids() {
11142         int[] accessibilityServiceUids;
11143         synchronized (mAccessibilityServiceUidsLock) {
11144             accessibilityServiceUids = mAccessibilityServiceUids;
11145         }
11146         AudioSystem.setA11yServicesUids(accessibilityServiceUids);
11147     }
11148 
11149     //==========================================================================================
11150     // Audio policy management
11151     //==========================================================================================
registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection)11152     public String registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb,
11153             boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy,
11154             boolean isVolumeController, IMediaProjection projection) {
11155         AudioSystem.setDynamicPolicyCallback(mDynPolicyCallback);
11156 
11157         if (!isPolicyRegisterAllowed(policyConfig,
11158                                      isFocusPolicy || isTestFocusPolicy || hasFocusListener,
11159                                      isVolumeController,
11160                                      projection)) {
11161             Slog.w(TAG, "Permission denied to register audio policy for pid "
11162                     + Binder.getCallingPid() + " / uid " + Binder.getCallingUid()
11163                     + ", need system permission or a MediaProjection that can project audio");
11164             return null;
11165         }
11166 
11167         String regId = null;
11168         synchronized (mAudioPolicies) {
11169             if (mAudioPolicies.containsKey(pcb.asBinder())) {
11170                 Slog.e(TAG, "Cannot re-register policy");
11171                 return null;
11172             }
11173             try {
11174                 AudioPolicyProxy app = new AudioPolicyProxy(policyConfig, pcb, hasFocusListener,
11175                         isFocusPolicy, isTestFocusPolicy, isVolumeController, projection);
11176                 pcb.asBinder().linkToDeath(app, 0/*flags*/);
11177 
11178                 // logging after registration so we have the registration id
11179                 mDynPolicyLogger.log((new AudioEventLogger.StringEvent("registerAudioPolicy for "
11180                         + pcb.asBinder() + " u/pid:" + Binder.getCallingUid() + "/"
11181                         + Binder.getCallingPid() + " with config:" + app.toCompactLogString()))
11182                         .printLog(TAG));
11183 
11184                 regId = app.getRegistrationId();
11185                 mAudioPolicies.put(pcb.asBinder(), app);
11186             } catch (RemoteException e) {
11187                 // audio policy owner has already died!
11188                 Slog.w(TAG, "Audio policy registration failed, could not link to " + pcb +
11189                         " binder death", e);
11190                 return null;
11191             } catch (IllegalStateException e) {
11192                 Slog.w(TAG, "Audio policy registration failed for binder " + pcb, e);
11193                 return null;
11194             }
11195         }
11196         return regId;
11197     }
11198 
11199     /**
11200      * Apps with MODIFY_AUDIO_ROUTING can register any policy.
11201      * Apps with an audio capable MediaProjection are allowed to register a RENDER|LOOPBACK policy
11202      * as those policy do not modify the audio routing.
11203      */
isPolicyRegisterAllowed(AudioPolicyConfig policyConfig, boolean hasFocusAccess, boolean isVolumeController, IMediaProjection projection)11204     private boolean isPolicyRegisterAllowed(AudioPolicyConfig policyConfig,
11205                                             boolean hasFocusAccess,
11206                                             boolean isVolumeController,
11207                                             IMediaProjection projection) {
11208 
11209         boolean requireValidProjection = false;
11210         boolean requireCaptureAudioOrMediaOutputPerm = false;
11211         boolean requireModifyRouting = false;
11212         boolean requireCallAudioInterception = false;
11213         ArrayList<AudioMix> voiceCommunicationCaptureMixes = null;
11214 
11215 
11216         if (hasFocusAccess || isVolumeController) {
11217             requireModifyRouting |= true;
11218         } else if (policyConfig.getMixes().isEmpty()) {
11219             // An empty policy could be used to lock the focus or add mixes later
11220             requireModifyRouting |= true;
11221         }
11222         for (AudioMix mix : policyConfig.getMixes()) {
11223             // If mix is requesting privileged capture
11224             if (mix.getRule().allowPrivilegedMediaPlaybackCapture()) {
11225                 // then its format must be low quality enough
11226                 String privilegedMediaCaptureError =
11227                         mix.canBeUsedForPrivilegedMediaCapture(mix.getFormat());
11228                 if (privilegedMediaCaptureError != null) {
11229                     Log.e(TAG, privilegedMediaCaptureError);
11230                     return false;
11231                 }
11232                 // and it must have CAPTURE_MEDIA_OUTPUT or CAPTURE_AUDIO_OUTPUT permission
11233                 requireCaptureAudioOrMediaOutputPerm |= true;
11234 
11235             }
11236             // If mix is trying to explicitly capture USAGE_VOICE_COMMUNICATION
11237             if (mix.containsMatchAttributeRuleForUsage(
11238                     AudioAttributes.USAGE_VOICE_COMMUNICATION)
11239                     && (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER)) {
11240                 // It must have CAPTURE_USAGE_VOICE_COMMUNICATION_OUTPUT permission
11241                 // Note that for UID, USERID or EXCLDUE rules, the capture will be silenced
11242                 // in AudioPolicyMix
11243                 if (voiceCommunicationCaptureMixes == null) {
11244                     voiceCommunicationCaptureMixes = new ArrayList<AudioMix>();
11245                 }
11246                 voiceCommunicationCaptureMixes.add(mix);
11247             }
11248 
11249             // If mix is RENDER|LOOPBACK, then an audio MediaProjection is enough
11250             // otherwise MODIFY_AUDIO_ROUTING permission is required
11251             if (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER && projection != null) {
11252                 requireValidProjection |= true;
11253             } else if (mix.isForCallRedirection()) {
11254                 requireCallAudioInterception |= true;
11255             } else if (mix.containsMatchAttributeRuleForUsage(
11256                             AudioAttributes.USAGE_VOICE_COMMUNICATION)) {
11257                 requireModifyRouting |= true;
11258             }
11259         }
11260 
11261         if (requireCaptureAudioOrMediaOutputPerm
11262                 && !callerHasPermission(android.Manifest.permission.CAPTURE_MEDIA_OUTPUT)
11263                 && !callerHasPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT)) {
11264             Log.e(TAG, "Privileged audio capture requires CAPTURE_MEDIA_OUTPUT or "
11265                       + "CAPTURE_AUDIO_OUTPUT system permission");
11266             return false;
11267         }
11268 
11269         if (voiceCommunicationCaptureMixes != null && voiceCommunicationCaptureMixes.size() > 0) {
11270             if (!callerHasPermission(
11271                     android.Manifest.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT)) {
11272                 Log.e(TAG, "Audio capture for voice communication requires "
11273                         + "CAPTURE_VOICE_COMMUNICATION_OUTPUT system permission");
11274                 return false;
11275             }
11276 
11277             // If permission check succeeded, we set the flag in each of the mixing rules
11278             for (AudioMix mix : voiceCommunicationCaptureMixes) {
11279                 mix.getRule().setVoiceCommunicationCaptureAllowed(true);
11280             }
11281         }
11282 
11283         if (requireValidProjection && !canProjectAudio(projection)) {
11284             return false;
11285         }
11286 
11287         if (requireModifyRouting
11288                 && !callerHasPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)) {
11289             Log.e(TAG, "Can not capture audio without MODIFY_AUDIO_ROUTING");
11290             return false;
11291         }
11292 
11293         if (requireCallAudioInterception
11294                 && !callerHasPermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION)) {
11295             Log.e(TAG, "Can not capture audio without CALL_AUDIO_INTERCEPTION");
11296             return false;
11297         }
11298 
11299         return true;
11300     }
11301 
callerHasPermission(String permission)11302     private boolean callerHasPermission(String permission) {
11303         return mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED;
11304     }
11305 
11306     /** @return true if projection is a valid MediaProjection that can project audio. */
canProjectAudio(IMediaProjection projection)11307     private boolean canProjectAudio(IMediaProjection projection) {
11308         if (projection == null) {
11309             Log.e(TAG, "MediaProjection is null");
11310             return false;
11311         }
11312 
11313         IMediaProjectionManager projectionService = getProjectionService();
11314         if (projectionService == null) {
11315             Log.e(TAG, "Can't get service IMediaProjectionManager");
11316             return false;
11317         }
11318 
11319         try {
11320             if (!projectionService.isValidMediaProjection(projection)) {
11321                 Log.w(TAG, "App passed invalid MediaProjection token");
11322                 return false;
11323             }
11324         } catch (RemoteException e) {
11325             Log.e(TAG, "Can't call .isValidMediaProjection() on IMediaProjectionManager"
11326                     + projectionService.asBinder(), e);
11327             return false;
11328         }
11329 
11330         try {
11331             if (!projection.canProjectAudio()) {
11332                 Log.w(TAG, "App passed MediaProjection that can not project audio");
11333                 return false;
11334             }
11335         } catch (RemoteException e) {
11336             Log.e(TAG, "Can't call .canProjectAudio() on valid IMediaProjection"
11337                     + projection.asBinder(), e);
11338             return false;
11339         }
11340 
11341         return true;
11342     }
11343 
getProjectionService()11344     private IMediaProjectionManager getProjectionService() {
11345         if (mProjectionService == null) {
11346             IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE);
11347             mProjectionService = IMediaProjectionManager.Stub.asInterface(b);
11348         }
11349         return mProjectionService;
11350     }
11351 
11352     /**
11353      * See {@link AudioManager#unregisterAudioPolicyAsync(AudioPolicy)}
11354      * Declared oneway
11355      * @param pcb nullable because on service interface
11356      */
unregisterAudioPolicyAsync(@ullable IAudioPolicyCallback pcb)11357     public void unregisterAudioPolicyAsync(@Nullable IAudioPolicyCallback pcb) {
11358         if (pcb == null) {
11359             return;
11360         }
11361         unregisterAudioPolicyInt(pcb, "unregisterAudioPolicyAsync");
11362     }
11363 
11364     /**
11365      * See {@link AudioManager#unregisterAudioPolicy(AudioPolicy)}
11366      * @param pcb nullable because on service interface
11367      */
unregisterAudioPolicy(@ullable IAudioPolicyCallback pcb)11368     public void unregisterAudioPolicy(@Nullable IAudioPolicyCallback pcb) {
11369         if (pcb == null) {
11370             return;
11371         }
11372         unregisterAudioPolicyInt(pcb, "unregisterAudioPolicy");
11373     }
11374 
11375 
unregisterAudioPolicyInt(@onNull IAudioPolicyCallback pcb, String operationName)11376     private void unregisterAudioPolicyInt(@NonNull IAudioPolicyCallback pcb, String operationName) {
11377         mDynPolicyLogger.log((new AudioEventLogger.StringEvent(operationName + " for "
11378                 + pcb.asBinder()).printLog(TAG)));
11379         synchronized (mAudioPolicies) {
11380             AudioPolicyProxy app = mAudioPolicies.remove(pcb.asBinder());
11381             if (app == null) {
11382                 Slog.w(TAG, "Trying to unregister unknown audio policy for pid "
11383                         + Binder.getCallingPid() + " / uid " + Binder.getCallingUid());
11384                 return;
11385             } else {
11386                 pcb.asBinder().unlinkToDeath(app, 0/*flags*/);
11387             }
11388             app.release();
11389         }
11390         // TODO implement clearing mix attribute matching info in native audio policy
11391     }
11392 
11393     /**
11394      * Checks whether caller has MODIFY_AUDIO_ROUTING permission, and the policy is registered.
11395      * @param errorMsg log warning if permission check failed.
11396      * @return null if the operation on the audio mixes should be cancelled.
11397      */
11398     @GuardedBy("mAudioPolicies")
checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg)11399     private AudioPolicyProxy checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg) {
11400         // permission check
11401         final boolean hasPermissionForPolicy =
11402                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
11403                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
11404         if (!hasPermissionForPolicy) {
11405             Slog.w(TAG, errorMsg + " for pid " +
11406                     + Binder.getCallingPid() + " / uid "
11407                     + Binder.getCallingUid() + ", need MODIFY_AUDIO_ROUTING");
11408             return null;
11409         }
11410         // policy registered?
11411         final AudioPolicyProxy app = mAudioPolicies.get(pcb.asBinder());
11412         if (app == null) {
11413             Slog.w(TAG, errorMsg + " for pid " +
11414                     + Binder.getCallingPid() + " / uid "
11415                     + Binder.getCallingUid() + ", unregistered policy");
11416             return null;
11417         }
11418         return app;
11419     }
11420 
addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)11421     public int addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) {
11422         if (DEBUG_AP) { Log.d(TAG, "addMixForPolicy for " + pcb.asBinder()
11423                 + " with config:" + policyConfig); }
11424         synchronized (mAudioPolicies) {
11425             final AudioPolicyProxy app =
11426                     checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy");
11427             if (app == null){
11428                 return AudioManager.ERROR;
11429             }
11430             return app.addMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS
11431                 ? AudioManager.SUCCESS : AudioManager.ERROR;
11432         }
11433     }
11434 
removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)11435     public int removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) {
11436         if (DEBUG_AP) { Log.d(TAG, "removeMixForPolicy for " + pcb.asBinder()
11437                 + " with config:" + policyConfig); }
11438         synchronized (mAudioPolicies) {
11439             final AudioPolicyProxy app =
11440                     checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy");
11441             if (app == null) {
11442                 return AudioManager.ERROR;
11443             }
11444             return app.removeMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS
11445                 ? AudioManager.SUCCESS : AudioManager.ERROR;
11446         }
11447     }
11448 
11449     /** see AudioPolicy.setUidDeviceAffinity() */
setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)11450     public int setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid,
11451             @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) {
11452         if (DEBUG_AP) {
11453             Log.d(TAG, "setUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid);
11454         }
11455         synchronized (mAudioPolicies) {
11456             final AudioPolicyProxy app =
11457                     checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy");
11458             if (app == null) {
11459                 return AudioManager.ERROR;
11460             }
11461             if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) {
11462                 return AudioManager.ERROR;
11463             }
11464             return app.setUidDeviceAffinities(uid, deviceTypes, deviceAddresses);
11465         }
11466     }
11467 
11468     /** see AudioPolicy.setUserIdDeviceAffinity() */
setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)11469     public int setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId,
11470             @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) {
11471         if (DEBUG_AP) {
11472             Log.d(TAG, "setUserIdDeviceAffinity for " + pcb.asBinder() + " user:" + userId);
11473         }
11474 
11475         synchronized (mAudioPolicies) {
11476             final AudioPolicyProxy app =
11477                     checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy");
11478             if (app == null) {
11479                 return AudioManager.ERROR;
11480             }
11481             if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) {
11482                 return AudioManager.ERROR;
11483             }
11484             return app.setUserIdDeviceAffinities(userId, deviceTypes, deviceAddresses);
11485         }
11486     }
11487 
11488     /** see AudioPolicy.removeUidDeviceAffinity() */
removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid)11489     public int removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid) {
11490         if (DEBUG_AP) {
11491             Log.d(TAG, "removeUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid);
11492         }
11493         synchronized (mAudioPolicies) {
11494             final AudioPolicyProxy app =
11495                     checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy");
11496             if (app == null) {
11497                 return AudioManager.ERROR;
11498             }
11499             return app.removeUidDeviceAffinities(uid);
11500         }
11501     }
11502 
11503     /** see AudioPolicy.removeUserIdDeviceAffinity() */
removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId)11504     public int removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId) {
11505         if (DEBUG_AP) {
11506             Log.d(TAG, "removeUserIdDeviceAffinity for " + pcb.asBinder()
11507                     + " userId:" + userId);
11508         }
11509         synchronized (mAudioPolicies) {
11510             final AudioPolicyProxy app =
11511                     checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy");
11512             if (app == null) {
11513                 return AudioManager.ERROR;
11514             }
11515             return app.removeUserIdDeviceAffinities(userId);
11516         }
11517     }
11518 
setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb)11519     public int setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb) {
11520         if (DEBUG_AP) Log.d(TAG, "setFocusPropertiesForPolicy() duck behavior=" + duckingBehavior
11521                 + " policy " +  pcb.asBinder());
11522         synchronized (mAudioPolicies) {
11523             final AudioPolicyProxy app =
11524                     checkUpdateForPolicy(pcb, "Cannot change audio policy focus properties");
11525             if (app == null){
11526                 return AudioManager.ERROR;
11527             }
11528             if (!mAudioPolicies.containsKey(pcb.asBinder())) {
11529                 Slog.e(TAG, "Cannot change audio policy focus properties, unregistered policy");
11530                 return AudioManager.ERROR;
11531             }
11532             if (duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) {
11533                 // is there already one policy managing ducking?
11534                 for (AudioPolicyProxy policy : mAudioPolicies.values()) {
11535                     if (policy.mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) {
11536                         Slog.e(TAG, "Cannot change audio policy ducking behavior, already handled");
11537                         return AudioManager.ERROR;
11538                     }
11539                 }
11540             }
11541             app.mFocusDuckBehavior = duckingBehavior;
11542             mMediaFocusControl.setDuckingInExtPolicyAvailable(
11543                     duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY);
11544         }
11545         return AudioManager.SUCCESS;
11546     }
11547 
11548     /** @see AudioPolicy#getFocusStack() */
getFocusStack()11549     public List<AudioFocusInfo> getFocusStack() {
11550         enforceModifyAudioRoutingPermission();
11551         return mMediaFocusControl.getFocusStack();
11552     }
11553 
11554     /** @see AudioPolicy#sendFocusLoss */
sendFocusLoss(@onNull AudioFocusInfo focusLoser, @NonNull IAudioPolicyCallback apcb)11555     public boolean sendFocusLoss(@NonNull AudioFocusInfo focusLoser,
11556             @NonNull IAudioPolicyCallback apcb) {
11557         Objects.requireNonNull(focusLoser);
11558         Objects.requireNonNull(apcb);
11559         enforceModifyAudioRoutingPermission();
11560         if (!mAudioPolicies.containsKey(apcb.asBinder())) {
11561             throw new IllegalStateException("Only registered AudioPolicy can change focus");
11562         }
11563         if (!mAudioPolicies.get(apcb.asBinder()).mHasFocusListener) {
11564             throw new IllegalStateException("AudioPolicy must have focus listener to change focus");
11565         }
11566         return mMediaFocusControl.sendFocusLoss(focusLoser);
11567     }
11568 
11569     private static final String[] HAL_VERSIONS =
11570             new String[] {"7.1", "7.0", "6.0", "5.0", "4.0", "2.0"};
11571 
11572     /** @see AudioManager#getHalVersion */
getHalVersion()11573     public @Nullable String getHalVersion() {
11574         for (String version : HAL_VERSIONS) {
11575             try {
11576                 HwBinder.getService(
11577                         String.format("android.hardware.audio@%s::IDevicesFactory", version),
11578                         "default");
11579                 return version;
11580             } catch (NoSuchElementException e) {
11581                 // Ignore, the specified HAL interface is not found.
11582             } catch (RemoteException re) {
11583                 Log.e(TAG, "Remote exception when getting hardware audio service:", re);
11584             }
11585         }
11586         return null;
11587     }
11588 
11589     /** see AudioManager.hasRegisteredDynamicPolicy */
hasRegisteredDynamicPolicy()11590     public boolean hasRegisteredDynamicPolicy() {
11591         synchronized (mAudioPolicies) {
11592             return !mAudioPolicies.isEmpty();
11593         }
11594     }
11595 
11596     private final Object mExtVolumeControllerLock = new Object();
11597     private IAudioPolicyCallback mExtVolumeController;
setExtVolumeController(IAudioPolicyCallback apc)11598     private void setExtVolumeController(IAudioPolicyCallback apc) {
11599         if (!mContext.getResources().getBoolean(
11600                 com.android.internal.R.bool.config_handleVolumeKeysInWindowManager)) {
11601             Log.e(TAG, "Cannot set external volume controller: device not set for volume keys" +
11602                     " handled in PhoneWindowManager");
11603             return;
11604         }
11605         synchronized (mExtVolumeControllerLock) {
11606             if (mExtVolumeController != null && !mExtVolumeController.asBinder().pingBinder()) {
11607                 Log.e(TAG, "Cannot set external volume controller: existing controller");
11608             }
11609             mExtVolumeController = apc;
11610         }
11611     }
11612 
dumpAudioPolicies(PrintWriter pw)11613     private void dumpAudioPolicies(PrintWriter pw) {
11614         pw.println("\nAudio policies:");
11615         synchronized (mAudioPolicies) {
11616             for (AudioPolicyProxy policy : mAudioPolicies.values()) {
11617                 pw.println(policy.toLogFriendlyString());
11618             }
11619         }
11620     }
11621 
11622     //======================
11623     // Audio policy callbacks from AudioSystem for dynamic policies
11624     //======================
11625     private final AudioSystem.DynamicPolicyCallback mDynPolicyCallback =
11626             new AudioSystem.DynamicPolicyCallback() {
11627         public void onDynamicPolicyMixStateUpdate(String regId, int state) {
11628             if (!TextUtils.isEmpty(regId)) {
11629                 sendMsg(mAudioHandler, MSG_DYN_POLICY_MIX_STATE_UPDATE, SENDMSG_QUEUE,
11630                         state /*arg1*/, 0 /*arg2 ignored*/, regId /*obj*/, 0 /*delay*/);
11631             }
11632         }
11633     };
11634 
onDynPolicyMixStateUpdate(String regId, int state)11635     private void onDynPolicyMixStateUpdate(String regId, int state) {
11636         if (DEBUG_AP) Log.d(TAG, "onDynamicPolicyMixStateUpdate("+ regId + ", " + state +")");
11637         synchronized (mAudioPolicies) {
11638             for (AudioPolicyProxy policy : mAudioPolicies.values()) {
11639                 for (AudioMix mix : policy.getMixes()) {
11640                     if (mix.getRegistration().equals(regId)) {
11641                         try {
11642                             policy.mPolicyCallback.notifyMixStateUpdate(regId, state);
11643                         } catch (RemoteException e) {
11644                             Log.e(TAG, "Can't call notifyMixStateUpdate() on IAudioPolicyCallback "
11645                                     + policy.mPolicyCallback.asBinder(), e);
11646                         }
11647                         return;
11648                     }
11649                 }
11650             }
11651         }
11652     }
11653 
11654     //======================
11655     // Audio policy callbacks from AudioSystem for recording configuration updates
11656     //======================
11657     private final RecordingActivityMonitor mRecordMonitor;
11658 
registerRecordingCallback(IRecordingConfigDispatcher rcdb)11659     public void registerRecordingCallback(IRecordingConfigDispatcher rcdb) {
11660         final boolean isPrivileged =
11661                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
11662                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
11663         mRecordMonitor.registerRecordingCallback(rcdb, isPrivileged);
11664     }
11665 
unregisterRecordingCallback(IRecordingConfigDispatcher rcdb)11666     public void unregisterRecordingCallback(IRecordingConfigDispatcher rcdb) {
11667         mRecordMonitor.unregisterRecordingCallback(rcdb);
11668     }
11669 
getActiveRecordingConfigurations()11670     public List<AudioRecordingConfiguration> getActiveRecordingConfigurations() {
11671         final boolean isPrivileged =
11672                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
11673                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
11674         return mRecordMonitor.getActiveRecordingConfigurations(isPrivileged);
11675     }
11676 
11677     //======================
11678     // Audio recording state notification from clients
11679     //======================
11680     /**
11681      * Track a recorder provided by the client
11682      */
trackRecorder(IBinder recorder)11683     public int trackRecorder(IBinder recorder) {
11684         return mRecordMonitor.trackRecorder(recorder);
11685     }
11686 
11687     /**
11688      * Receive an event from the client about a tracked recorder
11689      */
recorderEvent(int riid, int event)11690     public void recorderEvent(int riid, int event) {
11691         mRecordMonitor.recorderEvent(riid, event);
11692     }
11693 
11694     /**
11695      * Stop tracking the recorder
11696      */
releaseRecorder(int riid)11697     public void releaseRecorder(int riid) {
11698         mRecordMonitor.releaseRecorder(riid);
11699     }
11700 
11701     //======================
11702     // Audio playback notification
11703     //======================
11704     private final PlaybackActivityMonitor mPlaybackMonitor;
11705 
registerPlaybackCallback(IPlaybackConfigDispatcher pcdb)11706     public void registerPlaybackCallback(IPlaybackConfigDispatcher pcdb) {
11707         final boolean isPrivileged =
11708                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
11709                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
11710         mPlaybackMonitor.registerPlaybackCallback(pcdb, isPrivileged);
11711     }
11712 
unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb)11713     public void unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb) {
11714         mPlaybackMonitor.unregisterPlaybackCallback(pcdb);
11715     }
11716 
getActivePlaybackConfigurations()11717     public List<AudioPlaybackConfiguration> getActivePlaybackConfigurations() {
11718         final boolean isPrivileged =
11719                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
11720                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
11721         return mPlaybackMonitor.getActivePlaybackConfigurations(isPrivileged);
11722     }
11723 
trackPlayer(PlayerBase.PlayerIdCard pic)11724     public int trackPlayer(PlayerBase.PlayerIdCard pic) {
11725         if (pic != null && pic.mAttributes != null) {
11726             validateAudioAttributesUsage(pic.mAttributes);
11727         }
11728         return mPlaybackMonitor.trackPlayer(pic);
11729     }
11730 
playerAttributes(int piid, AudioAttributes attr)11731     public void playerAttributes(int piid, AudioAttributes attr) {
11732         if (attr != null) {
11733             validateAudioAttributesUsage(attr);
11734         }
11735         mPlaybackMonitor.playerAttributes(piid, attr, Binder.getCallingUid());
11736     }
11737 
11738     /**
11739      * Update player session ID
11740      * @param piid Player id to update
11741      * @param sessionId The new audio session ID
11742      */
playerSessionId(int piid, int sessionId)11743     public void playerSessionId(int piid, int sessionId) {
11744         if (sessionId <= AudioSystem.AUDIO_SESSION_ALLOCATE) {
11745             throw new IllegalArgumentException("invalid session Id " + sessionId);
11746         }
11747         mPlaybackMonitor.playerSessionId(piid, sessionId, Binder.getCallingUid());
11748     }
11749 
11750     /**
11751      * Update player event
11752      * @param piid Player id to update
11753      * @param event The new player event
11754      * @param deviceId The new player device id
11755      */
playerEvent(int piid, int event, int deviceId)11756     public void playerEvent(int piid, int event, int deviceId) {
11757         mPlaybackMonitor.playerEvent(piid, event, deviceId, Binder.getCallingUid());
11758     }
11759 
playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio)11760     public void playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio) {
11761         mPlaybackMonitor.playerHasOpPlayAudio(piid, hasOpPlayAudio, Binder.getCallingUid());
11762     }
11763 
releasePlayer(int piid)11764     public void releasePlayer(int piid) {
11765         mPlaybackMonitor.releasePlayer(piid, Binder.getCallingUid());
11766     }
11767 
11768     /**
11769      * Specifies whether the audio played by this app may or may not be captured by other apps or
11770      * the system.
11771      *
11772      * @param capturePolicy one of
11773      *     {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL},
11774      *     {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM},
11775      *     {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}.
11776      * @return AudioSystem.AUDIO_STATUS_OK if set allowed capture policy succeed.
11777      * @throws IllegalArgumentException if the argument is not a valid value.
11778      */
setAllowedCapturePolicy(int capturePolicy)11779     public int setAllowedCapturePolicy(int capturePolicy) {
11780         int callingUid = Binder.getCallingUid();
11781         int flags = AudioAttributes.capturePolicyToFlags(capturePolicy, 0x0);
11782         final long identity = Binder.clearCallingIdentity();
11783         synchronized (mPlaybackMonitor) {
11784             int result = mAudioSystem.setAllowedCapturePolicy(callingUid, flags);
11785             if (result == AudioSystem.AUDIO_STATUS_OK) {
11786                 mPlaybackMonitor.setAllowedCapturePolicy(callingUid, capturePolicy);
11787             }
11788             Binder.restoreCallingIdentity(identity);
11789             return result;
11790         }
11791     }
11792 
11793     /**
11794      * Return the capture policy.
11795      * @return the cached capture policy for the calling uid.
11796      */
getAllowedCapturePolicy()11797     public int getAllowedCapturePolicy() {
11798         int callingUid = Binder.getCallingUid();
11799         final long identity = Binder.clearCallingIdentity();
11800         int capturePolicy = mPlaybackMonitor.getAllowedCapturePolicy(callingUid);
11801         Binder.restoreCallingIdentity(identity);
11802         return capturePolicy;
11803     }
11804 
11805     //======================
11806     // Audio device management
11807     //======================
11808     private final AudioDeviceBroker mDeviceBroker;
11809 
11810     //======================
11811     // Audio policy proxy
11812     //======================
11813     private static final class AudioDeviceArray {
11814         final @NonNull int[] mDeviceTypes;
11815         final @NonNull String[] mDeviceAddresses;
AudioDeviceArray(@onNull int[] types, @NonNull String[] addresses)11816         AudioDeviceArray(@NonNull int[] types,  @NonNull String[] addresses) {
11817             mDeviceTypes = types;
11818             mDeviceAddresses = addresses;
11819         }
11820     }
11821 
11822     /**
11823      * This internal class inherits from AudioPolicyConfig, each instance contains all the
11824      * mixes of an AudioPolicy and their configurations.
11825      */
11826     public class AudioPolicyProxy extends AudioPolicyConfig implements IBinder.DeathRecipient {
11827         private static final String TAG = "AudioPolicyProxy";
11828         final IAudioPolicyCallback mPolicyCallback;
11829         final boolean mHasFocusListener;
11830         final boolean mIsVolumeController;
11831         final HashMap<Integer, AudioDeviceArray> mUidDeviceAffinities =
11832                 new HashMap<Integer, AudioDeviceArray>();
11833 
11834         final HashMap<Integer, AudioDeviceArray> mUserIdDeviceAffinities =
11835                 new HashMap<>();
11836 
11837         final IMediaProjection mProjection;
11838         private final class UnregisterOnStopCallback extends IMediaProjectionCallback.Stub {
onStop()11839             public void onStop() {
11840                 unregisterAudioPolicyAsync(mPolicyCallback);
11841             }
11842         };
11843         UnregisterOnStopCallback mProjectionCallback;
11844 
11845         /**
11846          * Audio focus ducking behavior for an audio policy.
11847          * This variable reflects the value that was successfully set in
11848          * {@link AudioService#setFocusPropertiesForPolicy(int, IAudioPolicyCallback)}. This
11849          * implies that a value of FOCUS_POLICY_DUCKING_IN_POLICY means the corresponding policy
11850          * is handling ducking for audio focus.
11851          */
11852         int mFocusDuckBehavior = AudioPolicy.FOCUS_POLICY_DUCKING_DEFAULT;
11853         boolean mIsFocusPolicy = false;
11854         boolean mIsTestFocusPolicy = false;
11855 
AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection)11856         AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token,
11857                 boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy,
11858                 boolean isVolumeController, IMediaProjection projection) {
11859             super(config);
11860             setRegistration(new String(config.hashCode() + ":ap:" + mAudioPolicyCounter++));
11861             mPolicyCallback = token;
11862             mHasFocusListener = hasFocusListener;
11863             mIsVolumeController = isVolumeController;
11864             mProjection = projection;
11865             if (mHasFocusListener) {
11866                 mMediaFocusControl.addFocusFollower(mPolicyCallback);
11867                 // can only ever be true if there is a focus listener
11868                 if (isFocusPolicy) {
11869                     mIsFocusPolicy = true;
11870                     mIsTestFocusPolicy = isTestFocusPolicy;
11871                     mMediaFocusControl.setFocusPolicy(mPolicyCallback, mIsTestFocusPolicy);
11872                 }
11873             }
11874             if (mIsVolumeController) {
11875                 setExtVolumeController(mPolicyCallback);
11876             }
11877             if (mProjection != null) {
11878                 mProjectionCallback = new UnregisterOnStopCallback();
11879                 try {
11880                     mProjection.registerCallback(mProjectionCallback);
11881                 } catch (RemoteException e) {
11882                     release();
11883                     throw new IllegalStateException("MediaProjection callback registration failed, "
11884                             + "could not link to " + projection + " binder death", e);
11885                 }
11886             }
11887             int status = connectMixes();
11888             if (status != AudioSystem.SUCCESS) {
11889                 release();
11890                 throw new IllegalStateException("Could not connect mix, error: " + status);
11891             }
11892         }
11893 
binderDied()11894         public void binderDied() {
11895             mDynPolicyLogger.log((new AudioEventLogger.StringEvent("AudioPolicy "
11896                     + mPolicyCallback.asBinder() + " died").printLog(TAG)));
11897             release();
11898         }
11899 
getRegistrationId()11900         String getRegistrationId() {
11901             return getRegistration();
11902         }
11903 
release()11904         void release() {
11905             if (mIsFocusPolicy) {
11906                 mMediaFocusControl.unsetFocusPolicy(mPolicyCallback, mIsTestFocusPolicy);
11907             }
11908             if (mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) {
11909                 mMediaFocusControl.setDuckingInExtPolicyAvailable(false);
11910             }
11911             if (mHasFocusListener) {
11912                 mMediaFocusControl.removeFocusFollower(mPolicyCallback);
11913             }
11914             if (mProjectionCallback != null) {
11915                 try {
11916                     mProjection.unregisterCallback(mProjectionCallback);
11917                 } catch (RemoteException e) {
11918                     Log.e(TAG, "Fail to unregister Audiopolicy callback from MediaProjection");
11919                 }
11920             }
11921             if (mIsVolumeController) {
11922                 synchronized (mExtVolumeControllerLock) {
11923                     mExtVolumeController = null;
11924                 }
11925             }
11926             final long identity = Binder.clearCallingIdentity();
11927             mAudioSystem.registerPolicyMixes(mMixes, false);
11928             Binder.restoreCallingIdentity(identity);
11929             synchronized (mAudioPolicies) {
11930                 mAudioPolicies.remove(mPolicyCallback.asBinder());
11931             }
11932             try {
11933                 mPolicyCallback.notifyUnregistration();
11934             } catch (RemoteException e) { }
11935         }
11936 
hasMixAffectingUsage(int usage, int excludedFlags)11937         boolean hasMixAffectingUsage(int usage, int excludedFlags) {
11938             for (AudioMix mix : mMixes) {
11939                 if (mix.isAffectingUsage(usage)
11940                         && ((mix.getRouteFlags() & excludedFlags) != excludedFlags)) {
11941                     return true;
11942                 }
11943             }
11944             return false;
11945         }
11946 
11947         // Verify all the devices in the array are served by mixes defined in this policy
hasMixRoutedToDevices(@onNull int[] deviceTypes, @NonNull String[] deviceAddresses)11948         boolean hasMixRoutedToDevices(@NonNull int[] deviceTypes,
11949                 @NonNull String[] deviceAddresses) {
11950             for (int i = 0; i < deviceTypes.length; i++) {
11951                 boolean hasDevice = false;
11952                 for (AudioMix mix : mMixes) {
11953                     // this will check both that the mix has ROUTE_FLAG_RENDER and the device
11954                     // is reached by this mix
11955                     if (mix.isRoutedToDevice(deviceTypes[i], deviceAddresses[i])) {
11956                         hasDevice = true;
11957                         break;
11958                     }
11959                 }
11960                 if (!hasDevice) {
11961                     return false;
11962                 }
11963             }
11964             return true;
11965         }
11966 
addMixes(@onNull ArrayList<AudioMix> mixes)11967         int addMixes(@NonNull ArrayList<AudioMix> mixes) {
11968             // TODO optimize to not have to unregister the mixes already in place
11969             synchronized (mMixes) {
11970                 mAudioSystem.registerPolicyMixes(mMixes, false);
11971                 this.add(mixes);
11972                 return mAudioSystem.registerPolicyMixes(mMixes, true);
11973             }
11974         }
11975 
removeMixes(@onNull ArrayList<AudioMix> mixes)11976         int removeMixes(@NonNull ArrayList<AudioMix> mixes) {
11977             // TODO optimize to not have to unregister the mixes already in place
11978             synchronized (mMixes) {
11979                 mAudioSystem.registerPolicyMixes(mMixes, false);
11980                 this.remove(mixes);
11981                 return mAudioSystem.registerPolicyMixes(mMixes, true);
11982             }
11983         }
11984 
connectMixes()11985         @AudioSystem.AudioSystemError int connectMixes() {
11986             final long identity = Binder.clearCallingIdentity();
11987             int status = mAudioSystem.registerPolicyMixes(mMixes, true);
11988             Binder.restoreCallingIdentity(identity);
11989             return status;
11990         }
11991 
setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses)11992         int setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses) {
11993             final Integer Uid = new Integer(uid);
11994             if (mUidDeviceAffinities.remove(Uid) != null) {
11995                 if (removeUidDeviceAffinitiesFromSystem(uid) != AudioSystem.SUCCESS) {
11996                     Log.e(TAG, "AudioSystem. removeUidDeviceAffinities(" + uid + ") failed, "
11997                             + " cannot call AudioSystem.setUidDeviceAffinities");
11998                     return AudioManager.ERROR;
11999                 }
12000             }
12001             AudioDeviceArray deviceArray = new AudioDeviceArray(types, addresses);
12002             if (setUidDeviceAffinitiesOnSystem(uid, deviceArray) == AudioSystem.SUCCESS) {
12003                 mUidDeviceAffinities.put(Uid, deviceArray);
12004                 return AudioManager.SUCCESS;
12005             }
12006             Log.e(TAG, "AudioSystem. setUidDeviceAffinities(" + uid + ") failed");
12007             return AudioManager.ERROR;
12008         }
12009 
removeUidDeviceAffinities(int uid)12010         int removeUidDeviceAffinities(int uid) {
12011             if (mUidDeviceAffinities.remove(new Integer(uid)) != null) {
12012                 if (removeUidDeviceAffinitiesFromSystem(uid) == AudioSystem.SUCCESS) {
12013                     return AudioManager.SUCCESS;
12014                 }
12015             }
12016             Log.e(TAG, "AudioSystem. removeUidDeviceAffinities failed");
12017             return AudioManager.ERROR;
12018         }
12019 
removeUidDeviceAffinitiesFromSystem(int uid)12020         @AudioSystem.AudioSystemError private int removeUidDeviceAffinitiesFromSystem(int uid) {
12021             final long identity = Binder.clearCallingIdentity();
12022             try {
12023                 return mAudioSystem.removeUidDeviceAffinities(uid);
12024             } finally {
12025                 Binder.restoreCallingIdentity(identity);
12026             }
12027         }
12028 
setUidDeviceAffinitiesOnSystem(int uid, AudioDeviceArray deviceArray)12029         @AudioSystem.AudioSystemError private int setUidDeviceAffinitiesOnSystem(int uid,
12030                 AudioDeviceArray deviceArray) {
12031             final long identity = Binder.clearCallingIdentity();
12032             try {
12033                 return mAudioSystem.setUidDeviceAffinities(uid, deviceArray.mDeviceTypes,
12034                         deviceArray.mDeviceAddresses);
12035             } finally {
12036                 Binder.restoreCallingIdentity(identity);
12037             }
12038         }
12039 
setUserIdDeviceAffinities(int userId, @NonNull int[] types, @NonNull String[] addresses)12040         int setUserIdDeviceAffinities(int userId,
12041                 @NonNull int[] types, @NonNull String[] addresses) {
12042             final Integer UserId = new Integer(userId);
12043             if (mUserIdDeviceAffinities.remove(UserId) != null) {
12044                 if (removeUserIdDeviceAffinitiesFromSystem(userId) != AudioSystem.SUCCESS) {
12045                     Log.e(TAG, "AudioSystem. removeUserIdDeviceAffinities("
12046                             + UserId + ") failed, "
12047                             + " cannot call AudioSystem.setUserIdDeviceAffinities");
12048                     return AudioManager.ERROR;
12049                 }
12050             }
12051             AudioDeviceArray audioDeviceArray = new AudioDeviceArray(types, addresses);
12052             if (setUserIdDeviceAffinitiesOnSystem(userId, audioDeviceArray)
12053                     == AudioSystem.SUCCESS) {
12054                 mUserIdDeviceAffinities.put(UserId, audioDeviceArray);
12055                 return AudioManager.SUCCESS;
12056             }
12057             Log.e(TAG, "AudioSystem.setUserIdDeviceAffinities(" + userId + ") failed");
12058             return AudioManager.ERROR;
12059         }
12060 
removeUserIdDeviceAffinities(int userId)12061         int removeUserIdDeviceAffinities(int userId) {
12062             if (mUserIdDeviceAffinities.remove(new Integer(userId)) != null) {
12063                 if (removeUserIdDeviceAffinitiesFromSystem(userId) == AudioSystem.SUCCESS) {
12064                     return AudioManager.SUCCESS;
12065                 }
12066             }
12067             Log.e(TAG, "AudioSystem.removeUserIdDeviceAffinities failed");
12068             return AudioManager.ERROR;
12069         }
12070 
removeUserIdDeviceAffinitiesFromSystem( @serIdInt int userId)12071         @AudioSystem.AudioSystemError private int removeUserIdDeviceAffinitiesFromSystem(
12072                 @UserIdInt int userId) {
12073             final long identity = Binder.clearCallingIdentity();
12074             try {
12075                 return mAudioSystem.removeUserIdDeviceAffinities(userId);
12076             } finally {
12077                 Binder.restoreCallingIdentity(identity);
12078             }
12079         }
12080 
setUserIdDeviceAffinitiesOnSystem( @serIdInt int userId, AudioDeviceArray deviceArray)12081         @AudioSystem.AudioSystemError private int setUserIdDeviceAffinitiesOnSystem(
12082                 @UserIdInt int userId, AudioDeviceArray deviceArray) {
12083             final long identity = Binder.clearCallingIdentity();
12084             try {
12085                 return mAudioSystem.setUserIdDeviceAffinities(userId, deviceArray.mDeviceTypes,
12086                         deviceArray.mDeviceAddresses);
12087             } finally {
12088                 Binder.restoreCallingIdentity(identity);
12089             }
12090         }
12091 
setupDeviceAffinities()12092         @AudioSystem.AudioSystemError int setupDeviceAffinities() {
12093             for (Map.Entry<Integer, AudioDeviceArray> uidEntry : mUidDeviceAffinities.entrySet()) {
12094                 int uidStatus = removeUidDeviceAffinitiesFromSystem(uidEntry.getKey());
12095                 if (uidStatus != AudioSystem.SUCCESS) {
12096                     Log.e(TAG,
12097                             "setupDeviceAffinities failed to remove device affinity for uid "
12098                                     + uidEntry.getKey());
12099                     return uidStatus;
12100                 }
12101                 uidStatus = setUidDeviceAffinitiesOnSystem(uidEntry.getKey(), uidEntry.getValue());
12102                 if (uidStatus != AudioSystem.SUCCESS) {
12103                     Log.e(TAG,
12104                             "setupDeviceAffinities failed to set device affinity for uid "
12105                                     + uidEntry.getKey());
12106                     return uidStatus;
12107                 }
12108             }
12109 
12110             for (Map.Entry<Integer, AudioDeviceArray> userIdEntry :
12111                     mUserIdDeviceAffinities.entrySet()) {
12112                 int userIdStatus = removeUserIdDeviceAffinitiesFromSystem(userIdEntry.getKey());
12113                 if (userIdStatus != AudioSystem.SUCCESS) {
12114                     Log.e(TAG,
12115                             "setupDeviceAffinities failed to remove device affinity for userId "
12116                                     + userIdEntry.getKey());
12117                     return userIdStatus;
12118                 }
12119                 userIdStatus = setUserIdDeviceAffinitiesOnSystem(userIdEntry.getKey(),
12120                                 userIdEntry.getValue());
12121                 if (userIdStatus != AudioSystem.SUCCESS) {
12122                     Log.e(TAG,
12123                             "setupDeviceAffinities failed to set device affinity for userId "
12124                                     + userIdEntry.getKey());
12125                     return userIdStatus;
12126                 }
12127             }
12128             return AudioSystem.SUCCESS;
12129         }
12130 
12131         /** @return human readable debug informations summarizing the state of the object. */
toLogFriendlyString()12132         public String toLogFriendlyString() {
12133             String textDump = super.toLogFriendlyString();
12134             textDump += " Uid Device Affinities:\n";
12135             String spacer = "     ";
12136             textDump += logFriendlyAttributeDeviceArrayMap("Uid",
12137                     mUidDeviceAffinities, spacer);
12138             textDump += " UserId Device Affinities:\n";
12139             textDump += logFriendlyAttributeDeviceArrayMap("UserId",
12140                     mUserIdDeviceAffinities, spacer);
12141             textDump += " Proxy:\n";
12142             textDump += "   is focus policy= " + mIsFocusPolicy + "\n";
12143             if (mIsFocusPolicy) {
12144                 textDump += "     focus duck behaviour= " + mFocusDuckBehavior + "\n";
12145                 textDump += "     is test focus policy= " + mIsTestFocusPolicy + "\n";
12146                 textDump += "     has focus listener= " + mHasFocusListener  + "\n";
12147             }
12148             textDump += "   media projection= " + mProjection + "\n";
12149             return textDump;
12150         }
12151 
logFriendlyAttributeDeviceArrayMap(String attribute, Map<Integer, AudioDeviceArray> map, String spacer)12152         private String logFriendlyAttributeDeviceArrayMap(String attribute,
12153                 Map<Integer, AudioDeviceArray> map, String spacer) {
12154             final StringBuilder stringBuilder = new StringBuilder();
12155             for (Map.Entry<Integer, AudioDeviceArray> mapEntry : map.entrySet()) {
12156                 stringBuilder.append(spacer).append(attribute).append(": ")
12157                         .append(mapEntry.getKey()).append("\n");
12158                 AudioDeviceArray deviceArray = mapEntry.getValue();
12159                 String deviceSpacer = spacer + "   ";
12160                 for (int i = 0; i < deviceArray.mDeviceTypes.length; i++) {
12161                     stringBuilder.append(deviceSpacer).append("Type: 0x")
12162                             .append(Integer.toHexString(deviceArray.mDeviceTypes[i]))
12163                             .append(" Address: ").append(deviceArray.mDeviceAddresses[i])
12164                                     .append("\n");
12165                 }
12166             }
12167             return stringBuilder.toString();
12168         }
12169     };
12170 
12171     //======================
12172     // Audio policy: focus
12173     //======================
12174     /**  */
dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb)12175     public int dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb) {
12176         if (afi == null) {
12177             throw new IllegalArgumentException("Illegal null AudioFocusInfo");
12178         }
12179         if (pcb == null) {
12180             throw new IllegalArgumentException("Illegal null AudioPolicy callback");
12181         }
12182         synchronized (mAudioPolicies) {
12183             if (!mAudioPolicies.containsKey(pcb.asBinder())) {
12184                 throw new IllegalStateException("Unregistered AudioPolicy for focus dispatch");
12185             }
12186             return mMediaFocusControl.dispatchFocusChange(afi, focusChange);
12187         }
12188     }
12189 
setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult, IAudioPolicyCallback pcb)12190     public void setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult,
12191             IAudioPolicyCallback pcb) {
12192         if (afi == null) {
12193             throw new IllegalArgumentException("Illegal null AudioFocusInfo");
12194         }
12195         if (pcb == null) {
12196             throw new IllegalArgumentException("Illegal null AudioPolicy callback");
12197         }
12198         synchronized (mAudioPolicies) {
12199             if (!mAudioPolicies.containsKey(pcb.asBinder())) {
12200                 throw new IllegalStateException("Unregistered AudioPolicy for external focus");
12201             }
12202             mMediaFocusControl.setFocusRequestResultFromExtPolicy(afi, requestResult);
12203         }
12204     }
12205 
12206 
12207     //======================
12208     // Audioserver state dispatch
12209     //======================
12210     private class AsdProxy implements IBinder.DeathRecipient {
12211         private final IAudioServerStateDispatcher mAsd;
12212 
AsdProxy(IAudioServerStateDispatcher asd)12213         AsdProxy(IAudioServerStateDispatcher asd) {
12214             mAsd = asd;
12215         }
12216 
binderDied()12217         public void binderDied() {
12218             synchronized (mAudioServerStateListeners) {
12219                 mAudioServerStateListeners.remove(mAsd.asBinder());
12220             }
12221         }
12222 
callback()12223         IAudioServerStateDispatcher callback() {
12224             return mAsd;
12225         }
12226     }
12227 
12228     private final HashMap<IBinder, AsdProxy> mAudioServerStateListeners =
12229             new HashMap<IBinder, AsdProxy>();
12230 
checkMonitorAudioServerStatePermission()12231     private void checkMonitorAudioServerStatePermission() {
12232         if (!(mContext.checkCallingOrSelfPermission(
12233                     android.Manifest.permission.MODIFY_PHONE_STATE) ==
12234                 PackageManager.PERMISSION_GRANTED ||
12235               mContext.checkCallingOrSelfPermission(
12236                     android.Manifest.permission.MODIFY_AUDIO_ROUTING) ==
12237                 PackageManager.PERMISSION_GRANTED)) {
12238             throw new SecurityException("Not allowed to monitor audioserver state");
12239         }
12240     }
12241 
registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd)12242     public void registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd) {
12243         checkMonitorAudioServerStatePermission();
12244         synchronized (mAudioServerStateListeners) {
12245             if (mAudioServerStateListeners.containsKey(asd.asBinder())) {
12246                 Slog.w(TAG, "Cannot re-register audio server state dispatcher");
12247                 return;
12248             }
12249             AsdProxy asdp = new AsdProxy(asd);
12250             try {
12251                 asd.asBinder().linkToDeath(asdp, 0/*flags*/);
12252             } catch (RemoteException e) {
12253 
12254             }
12255             mAudioServerStateListeners.put(asd.asBinder(), asdp);
12256         }
12257     }
12258 
unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd)12259     public void unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd) {
12260         checkMonitorAudioServerStatePermission();
12261         synchronized (mAudioServerStateListeners) {
12262             AsdProxy asdp = mAudioServerStateListeners.remove(asd.asBinder());
12263             if (asdp == null) {
12264                 Slog.w(TAG, "Trying to unregister unknown audioserver state dispatcher for pid "
12265                         + Binder.getCallingPid() + " / uid " + Binder.getCallingUid());
12266                 return;
12267             } else {
12268                 asd.asBinder().unlinkToDeath(asdp, 0/*flags*/);
12269             }
12270         }
12271     }
12272 
isAudioServerRunning()12273     public boolean isAudioServerRunning() {
12274         checkMonitorAudioServerStatePermission();
12275         return (AudioSystem.checkAudioFlinger() == AudioSystem.AUDIO_STATUS_OK);
12276     }
12277 
12278     //======================
12279     // Audio HAL process dump
12280     //======================
12281 
12282     private static final String AUDIO_HAL_SERVICE_PREFIX = "android.hardware.audio";
12283 
getAudioHalPids()12284     private Set<Integer> getAudioHalPids() {
12285         try {
12286             IServiceManager serviceManager = IServiceManager.getService();
12287             ArrayList<IServiceManager.InstanceDebugInfo> dump =
12288                     serviceManager.debugDump();
12289             HashSet<Integer> pids = new HashSet<>();
12290             for (IServiceManager.InstanceDebugInfo info : dump) {
12291                 if (info.pid != IServiceManager.PidConstant.NO_PID
12292                         && info.interfaceName != null
12293                         && info.interfaceName.startsWith(AUDIO_HAL_SERVICE_PREFIX)) {
12294                     pids.add(info.pid);
12295                 }
12296             }
12297             return pids;
12298         } catch (RemoteException e) {
12299             return new HashSet<Integer>();
12300         }
12301     }
12302 
updateAudioHalPids()12303     private void updateAudioHalPids() {
12304         Set<Integer> pidsSet = getAudioHalPids();
12305         if (pidsSet.isEmpty()) {
12306             Slog.w(TAG, "Could not retrieve audio HAL service pids");
12307             return;
12308         }
12309         int[] pidsArray = pidsSet.stream().mapToInt(Integer::intValue).toArray();
12310         AudioSystem.setAudioHalPids(pidsArray);
12311     }
12312 
12313     //======================
12314     // Multi Audio Focus
12315     //======================
setMultiAudioFocusEnabled(boolean enabled)12316     public void setMultiAudioFocusEnabled(boolean enabled) {
12317         enforceModifyAudioRoutingPermission();
12318         if (mMediaFocusControl != null) {
12319             boolean mafEnabled = mMediaFocusControl.getMultiAudioFocusEnabled();
12320             if (mafEnabled != enabled) {
12321                 mMediaFocusControl.updateMultiAudioFocus(enabled);
12322                 if (!enabled) {
12323                     mDeviceBroker.postBroadcastBecomingNoisy();
12324                 }
12325             }
12326         }
12327     }
12328 
12329     /**
12330      * @hide
12331      * Sets an additional audio output device delay in milliseconds.
12332      *
12333      * The additional output delay is a request to the output device to
12334      * delay audio presentation (generally with respect to video presentation for better
12335      * synchronization).
12336      * It may not be supported by all output devices,
12337      * and typically increases the audio latency by the amount of additional
12338      * audio delay requested.
12339      *
12340      * If additional audio delay is supported by an audio output device,
12341      * it is expected to be supported for all output streams (and configurations)
12342      * opened on that device.
12343      *
12344      * @param deviceType
12345      * @param address
12346      * @param delayMillis delay in milliseconds desired.  This should be in range of {@code 0}
12347      *     to the value returned by {@link #getMaxAdditionalOutputDeviceDelay()}.
12348      * @return true if successful, false if the device does not support output device delay
12349      *     or the delay is not in range of {@link #getMaxAdditionalOutputDeviceDelay()}.
12350      */
12351     @Override
12352     //@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
setAdditionalOutputDeviceDelay( @onNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis)12353     public boolean setAdditionalOutputDeviceDelay(
12354             @NonNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis) {
12355         Objects.requireNonNull(device, "device must not be null");
12356         enforceModifyAudioRoutingPermission();
12357         final String getterKey = "additional_output_device_delay="
12358                 + device.getInternalType() + "," + device.getAddress(); // "getter" key as an id.
12359         final String setterKey = getterKey + "," + delayMillis;     // append the delay for setter
12360         return mRestorableParameters.setParameters(getterKey, setterKey)
12361                 == AudioSystem.AUDIO_STATUS_OK;
12362     }
12363 
12364     /**
12365      * @hide
12366      * Returns the current additional audio output device delay in milliseconds.
12367      *
12368      * @param deviceType
12369      * @param address
12370      * @return the additional output device delay. This is a non-negative number.
12371      *     {@code 0} is returned if unsupported.
12372      */
12373     @Override
12374     @IntRange(from = 0)
getAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)12375     public long getAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) {
12376         Objects.requireNonNull(device, "device must not be null");
12377         final String key = "additional_output_device_delay";
12378         final String reply = AudioSystem.getParameters(
12379                 key + "=" + device.getInternalType() + "," + device.getAddress());
12380         long delayMillis;
12381         try {
12382             delayMillis = Long.parseLong(reply.substring(key.length() + 1));
12383         } catch (NullPointerException e) {
12384             delayMillis = 0;
12385         }
12386         return delayMillis;
12387     }
12388 
12389     /**
12390      * @hide
12391      * Returns the maximum additional audio output device delay in milliseconds.
12392      *
12393      * @param deviceType
12394      * @param address
12395      * @return the maximum output device delay in milliseconds that can be set.
12396      *     This is a non-negative number
12397      *     representing the additional audio delay supported for the device.
12398      *     {@code 0} is returned if unsupported.
12399      */
12400     @Override
12401     @IntRange(from = 0)
getMaxAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)12402     public long getMaxAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) {
12403         Objects.requireNonNull(device, "device must not be null");
12404         final String key = "max_additional_output_device_delay";
12405         final String reply = AudioSystem.getParameters(
12406                 key + "=" + device.getInternalType() + "," + device.getAddress());
12407         long delayMillis;
12408         try {
12409             delayMillis = Long.parseLong(reply.substring(key.length() + 1));
12410         } catch (NullPointerException e) {
12411             delayMillis = 0;
12412         }
12413         return delayMillis;
12414     }
12415 
12416     /** @see AudioManager#addAssistantServicesUids(int []) */
12417     @Override
addAssistantServicesUids(int [] assistantUids)12418     public void addAssistantServicesUids(int [] assistantUids) {
12419         enforceModifyAudioRoutingPermission();
12420         Objects.requireNonNull(assistantUids);
12421 
12422         synchronized (mSettingsLock) {
12423             addAssistantServiceUidsLocked(assistantUids);
12424         }
12425     }
12426 
12427     /** @see AudioManager#removeAssistantServicesUids(int []) */
12428     @Override
removeAssistantServicesUids(int [] assistantUids)12429     public void removeAssistantServicesUids(int [] assistantUids) {
12430         enforceModifyAudioRoutingPermission();
12431         Objects.requireNonNull(assistantUids);
12432         synchronized (mSettingsLock) {
12433             removeAssistantServiceUidsLocked(assistantUids);
12434         }
12435     }
12436 
12437     /** @see AudioManager#getAssistantServicesUids() */
12438     @Override
getAssistantServicesUids()12439     public int[] getAssistantServicesUids() {
12440         enforceModifyAudioRoutingPermission();
12441         int [] assistantUids;
12442         synchronized (mSettingsLock) {
12443             assistantUids = mAssistantUids.stream().mapToInt(Integer::intValue).toArray();
12444         }
12445         return assistantUids;
12446     }
12447 
12448     /** @see AudioManager#setActiveAssistantServiceUids(int []) */
12449     @Override
setActiveAssistantServiceUids(int [] activeAssistantUids)12450     public void setActiveAssistantServiceUids(int [] activeAssistantUids) {
12451         enforceModifyAudioRoutingPermission();
12452         Objects.requireNonNull(activeAssistantUids);
12453         synchronized (mSettingsLock) {
12454             mActiveAssistantServiceUids = activeAssistantUids;
12455         }
12456         updateActiveAssistantServiceUids();
12457     }
12458 
12459     /** @see AudioManager#getActiveAssistantServiceUids() */
12460     @Override
getActiveAssistantServiceUids()12461     public int[] getActiveAssistantServiceUids() {
12462         enforceModifyAudioRoutingPermission();
12463         int [] activeAssistantUids;
12464         synchronized (mSettingsLock) {
12465             activeAssistantUids = mActiveAssistantServiceUids.clone();
12466         }
12467         return activeAssistantUids;
12468     }
12469 
getDeviceSensorUuid(AudioDeviceAttributes device)12470     UUID getDeviceSensorUuid(AudioDeviceAttributes device) {
12471         return mDeviceBroker.getDeviceSensorUuid(device);
12472     }
12473 
12474     //======================
12475     // misc
12476     //======================
12477     private final HashMap<IBinder, AudioPolicyProxy> mAudioPolicies =
12478             new HashMap<IBinder, AudioPolicyProxy>();
12479     @GuardedBy("mAudioPolicies")
12480     private int mAudioPolicyCounter = 0;
12481 
12482     //======================
12483     // Helper functions for full and fixed volume device
12484     //======================
isFixedVolumeDevice(int deviceType)12485     private boolean isFixedVolumeDevice(int deviceType) {
12486         if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX
12487                 && mRecordMonitor.isLegacyRemoteSubmixActive()) {
12488             return false;
12489         }
12490         return mFixedVolumeDevices.contains(deviceType);
12491     }
12492 
isFullVolumeDevice(int deviceType)12493     private boolean isFullVolumeDevice(int deviceType) {
12494         if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX
12495                 && mRecordMonitor.isLegacyRemoteSubmixActive()) {
12496             return false;
12497         }
12498         return mFullVolumeDevices.contains(deviceType);
12499     }
12500 
12501     /**
12502      * Returns whether the input device uses absolute volume behavior. This is distinct
12503      * from Bluetooth A2DP absolute volume behavior ({@link #isA2dpAbsoluteVolumeDevice}).
12504      */
isAbsoluteVolumeDevice(int deviceType)12505     private boolean isAbsoluteVolumeDevice(int deviceType) {
12506         return  mAbsoluteVolumeDeviceInfoMap.containsKey(deviceType);
12507     }
12508 
12509     /**
12510      * Returns whether the input device is a Bluetooth A2dp device that uses absolute volume
12511      * behavior. This is distinct from the general implementation of absolute volume behavior
12512      * ({@link #isAbsoluteVolumeDevice}).
12513      */
isA2dpAbsoluteVolumeDevice(int deviceType)12514     private boolean isA2dpAbsoluteVolumeDevice(int deviceType) {
12515         return mAvrcpAbsVolSupported && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(deviceType);
12516     }
12517 
12518     //====================
12519     // Helper functions for {set,get}DeviceVolumeBehavior
12520     //====================
getSettingsNameForDeviceVolumeBehavior(int deviceType)12521     private static String getSettingsNameForDeviceVolumeBehavior(int deviceType) {
12522         return "AudioService_DeviceVolumeBehavior_" + AudioSystem.getOutputDeviceName(deviceType);
12523     }
12524 
persistDeviceVolumeBehavior(int deviceType, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior)12525     private void persistDeviceVolumeBehavior(int deviceType,
12526             @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior) {
12527         if (DEBUG_VOL) {
12528             Log.d(TAG, "Persisting Volume Behavior for DeviceType: " + deviceType);
12529         }
12530         final long callingIdentity = Binder.clearCallingIdentity();
12531         try {
12532             mSettings.putSystemIntForUser(mContentResolver,
12533                     getSettingsNameForDeviceVolumeBehavior(deviceType),
12534                     deviceVolumeBehavior,
12535                     UserHandle.USER_CURRENT);
12536         } finally {
12537             Binder.restoreCallingIdentity(callingIdentity);
12538         }
12539     }
12540 
12541     @AudioManager.DeviceVolumeBehaviorState
retrieveStoredDeviceVolumeBehavior(int deviceType)12542     private int retrieveStoredDeviceVolumeBehavior(int deviceType) {
12543         return mSettings.getSystemIntForUser(mContentResolver,
12544                 getSettingsNameForDeviceVolumeBehavior(deviceType),
12545                 AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET,
12546                 UserHandle.USER_CURRENT);
12547     }
12548 
restoreDeviceVolumeBehavior()12549     private void restoreDeviceVolumeBehavior() {
12550         for (int deviceType : AudioSystem.DEVICE_OUT_ALL_SET) {
12551             if (DEBUG_VOL) {
12552                 Log.d(TAG, "Retrieving Volume Behavior for DeviceType: " + deviceType);
12553             }
12554             int deviceVolumeBehavior = retrieveStoredDeviceVolumeBehavior(deviceType);
12555             if (deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET) {
12556                 if (DEBUG_VOL) {
12557                     Log.d(TAG, "Skipping Setting Volume Behavior for DeviceType: " + deviceType);
12558                 }
12559                 continue;
12560             }
12561 
12562             setDeviceVolumeBehaviorInternal(new AudioDeviceAttributes(deviceType, ""),
12563                     deviceVolumeBehavior, "AudioService.restoreDeviceVolumeBehavior()");
12564         }
12565     }
12566 
12567     /**
12568      * @param audioSystemDeviceOut one of AudioSystem.DEVICE_OUT_*
12569      * @return whether {@code audioSystemDeviceOut} has previously been set to a specific volume
12570      * behavior
12571      */
hasDeviceVolumeBehavior( int audioSystemDeviceOut)12572     private boolean hasDeviceVolumeBehavior(
12573             int audioSystemDeviceOut) {
12574         return retrieveStoredDeviceVolumeBehavior(audioSystemDeviceOut)
12575                 != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET;
12576     }
12577 
addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut)12578     private boolean addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut) {
12579         if (DEBUG_VOL) {
12580             Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
12581                     + " to mFixedVolumeDevices");
12582         }
12583         return mFixedVolumeDevices.add(audioSystemDeviceOut);
12584     }
12585 
removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut)12586     private boolean removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut) {
12587         if (DEBUG_VOL) {
12588             Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
12589                     + " from mFixedVolumeDevices");
12590         }
12591         return mFixedVolumeDevices.remove(audioSystemDeviceOut);
12592     }
12593 
addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut)12594     private boolean addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut) {
12595         if (DEBUG_VOL) {
12596             Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
12597                     + " to mFullVolumeDevices");
12598         }
12599         return mFullVolumeDevices.add(audioSystemDeviceOut);
12600     }
12601 
removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut)12602     private boolean removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut) {
12603         if (DEBUG_VOL) {
12604             Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
12605                     + " from mFullVolumeDevices");
12606         }
12607         return mFullVolumeDevices.remove(audioSystemDeviceOut);
12608     }
12609 
addAudioSystemDeviceOutToAbsVolumeDevices( int audioSystemDeviceOut, AbsoluteVolumeDeviceInfo info)12610     private AbsoluteVolumeDeviceInfo addAudioSystemDeviceOutToAbsVolumeDevices(
12611             int audioSystemDeviceOut, AbsoluteVolumeDeviceInfo info) {
12612         if (DEBUG_VOL) {
12613             Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
12614                     + " from mAbsoluteVolumeDeviceInfoMap");
12615         }
12616         return mAbsoluteVolumeDeviceInfoMap.put(audioSystemDeviceOut, info);
12617     }
12618 
removeAudioSystemDeviceOutFromAbsVolumeDevices( int audioSystemDeviceOut)12619     private AbsoluteVolumeDeviceInfo removeAudioSystemDeviceOutFromAbsVolumeDevices(
12620             int audioSystemDeviceOut) {
12621         if (DEBUG_VOL) {
12622             Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
12623                     + " from mAbsoluteVolumeDeviceInfoMap");
12624         }
12625         return mAbsoluteVolumeDeviceInfoMap.remove(audioSystemDeviceOut);
12626     }
12627 
12628     //====================
12629     // Helper functions for app ops
12630     //====================
12631     /**
12632      * Validates, and notes an app op for a given uid and package name.
12633      * Validation comes from exception catching: a security exception indicates the package
12634      * doesn't exist, an IAE indicates the uid and package don't match. The code only checks
12635      * if exception was thrown for robustness to code changes in op validation
12636      * @param op the app op to check
12637      * @param uid the uid of the caller
12638      * @param packageName the package to check
12639      * @return true if the origin of the call is valid (no uid / package mismatch) and the caller
12640      *      is allowed to perform the operation
12641      */
checkNoteAppOp(int op, int uid, String packageName, String attributionTag)12642     private boolean checkNoteAppOp(int op, int uid, String packageName, String attributionTag) {
12643         try {
12644             if (mAppOps.noteOp(op, uid, packageName, attributionTag, null)
12645                     != AppOpsManager.MODE_ALLOWED) {
12646                 return false;
12647             }
12648         } catch (Exception e) {
12649             Log.e(TAG, "Error noting op:" + op + " on uid:" + uid + " for package:"
12650                     + packageName, e);
12651             return false;
12652         }
12653         return true;
12654     }
12655 }
12656