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.provider.Settings.Secure.VOLUME_HUSH_MUTE;
26 import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
27 import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE;
28 
29 import static com.android.server.audio.AudioEventLogger.Event.ALOGE;
30 import static com.android.server.audio.AudioEventLogger.Event.ALOGI;
31 import static com.android.server.audio.AudioEventLogger.Event.ALOGW;
32 
33 import android.Manifest;
34 import android.annotation.IntDef;
35 import android.annotation.IntRange;
36 import android.annotation.NonNull;
37 import android.annotation.Nullable;
38 import android.annotation.UserIdInt;
39 import android.app.ActivityManager;
40 import android.app.ActivityManagerInternal;
41 import android.app.AppGlobals;
42 import android.app.AppOpsManager;
43 import android.app.IUidObserver;
44 import android.app.NotificationManager;
45 import android.app.role.OnRoleHoldersChangedListener;
46 import android.app.role.RoleManager;
47 import android.bluetooth.BluetoothAdapter;
48 import android.bluetooth.BluetoothDevice;
49 import android.bluetooth.BluetoothHeadset;
50 import android.bluetooth.BluetoothProfile;
51 import android.content.BroadcastReceiver;
52 import android.content.ComponentName;
53 import android.content.ContentResolver;
54 import android.content.Context;
55 import android.content.Intent;
56 import android.content.IntentFilter;
57 import android.content.pm.ApplicationInfo;
58 import android.content.pm.PackageInfo;
59 import android.content.pm.PackageManager;
60 import android.content.pm.ResolveInfo;
61 import android.content.pm.UserInfo;
62 import android.content.res.Configuration;
63 import android.database.ContentObserver;
64 import android.hardware.SensorPrivacyManager;
65 import android.hardware.SensorPrivacyManagerInternal;
66 import android.hardware.hdmi.HdmiAudioSystemClient;
67 import android.hardware.hdmi.HdmiControlManager;
68 import android.hardware.hdmi.HdmiPlaybackClient;
69 import android.hardware.hdmi.HdmiTvClient;
70 import android.hardware.input.InputManager;
71 import android.hardware.usb.UsbManager;
72 import android.hidl.manager.V1_0.IServiceManager;
73 import android.media.AudioAttributes;
74 import android.media.AudioAttributes.AttributeSystemUsage;
75 import android.media.AudioDeviceAttributes;
76 import android.media.AudioDeviceInfo;
77 import android.media.AudioFocusInfo;
78 import android.media.AudioFocusRequest;
79 import android.media.AudioFormat;
80 import android.media.AudioManager;
81 import android.media.AudioManagerInternal;
82 import android.media.AudioPlaybackConfiguration;
83 import android.media.AudioRecordingConfiguration;
84 import android.media.AudioRoutesInfo;
85 import android.media.AudioSystem;
86 import android.media.IAudioFocusDispatcher;
87 import android.media.IAudioModeDispatcher;
88 import android.media.IAudioRoutesObserver;
89 import android.media.IAudioServerStateDispatcher;
90 import android.media.IAudioService;
91 import android.media.ICapturePresetDevicesRoleDispatcher;
92 import android.media.ICommunicationDeviceDispatcher;
93 import android.media.IPlaybackConfigDispatcher;
94 import android.media.IRecordingConfigDispatcher;
95 import android.media.IRingtonePlayer;
96 import android.media.ISpatializerCallback;
97 import android.media.ISpatializerHeadToSoundStagePoseCallback;
98 import android.media.ISpatializerHeadTrackingModeCallback;
99 import android.media.ISpatializerOutputCallback;
100 import android.media.IStrategyPreferredDevicesDispatcher;
101 import android.media.IVolumeController;
102 import android.media.MediaMetrics;
103 import android.media.MediaRecorder.AudioSource;
104 import android.media.PlayerBase;
105 import android.media.Spatializer;
106 import android.media.VolumePolicy;
107 import android.media.audiofx.AudioEffect;
108 import android.media.audiopolicy.AudioMix;
109 import android.media.audiopolicy.AudioPolicy;
110 import android.media.audiopolicy.AudioPolicyConfig;
111 import android.media.audiopolicy.AudioProductStrategy;
112 import android.media.audiopolicy.AudioVolumeGroup;
113 import android.media.audiopolicy.IAudioPolicyCallback;
114 import android.media.projection.IMediaProjection;
115 import android.media.projection.IMediaProjectionCallback;
116 import android.media.projection.IMediaProjectionManager;
117 import android.net.Uri;
118 import android.os.Binder;
119 import android.os.Build;
120 import android.os.Bundle;
121 import android.os.Handler;
122 import android.os.IBinder;
123 import android.os.Looper;
124 import android.os.Message;
125 import android.os.PowerManager;
126 import android.os.Process;
127 import android.os.RemoteCallbackList;
128 import android.os.RemoteException;
129 import android.os.ServiceManager;
130 import android.os.SystemClock;
131 import android.os.SystemProperties;
132 import android.os.UserHandle;
133 import android.os.UserManager;
134 import android.os.VibrationEffect;
135 import android.os.Vibrator;
136 import android.os.VibratorManager;
137 import android.provider.Settings;
138 import android.provider.Settings.System;
139 import android.service.notification.ZenModeConfig;
140 import android.telecom.TelecomManager;
141 import android.text.TextUtils;
142 import android.util.AndroidRuntimeException;
143 import android.util.IntArray;
144 import android.util.Log;
145 import android.util.MathUtils;
146 import android.util.PrintWriterPrinter;
147 import android.util.Slog;
148 import android.util.SparseArray;
149 import android.util.SparseIntArray;
150 import android.view.KeyEvent;
151 import android.view.accessibility.AccessibilityManager;
152 import android.widget.Toast;
153 
154 import com.android.internal.annotations.GuardedBy;
155 import com.android.internal.annotations.VisibleForTesting;
156 import com.android.internal.util.DumpUtils;
157 import com.android.internal.util.Preconditions;
158 import com.android.server.EventLogTags;
159 import com.android.server.LocalServices;
160 import com.android.server.SystemService;
161 import com.android.server.audio.AudioServiceEvents.PhoneStateEvent;
162 import com.android.server.audio.AudioServiceEvents.VolumeEvent;
163 import com.android.server.pm.UserManagerInternal;
164 import com.android.server.pm.UserManagerInternal.UserRestrictionsListener;
165 import com.android.server.pm.UserManagerService;
166 import com.android.server.wm.ActivityTaskManagerInternal;
167 
168 import java.io.FileDescriptor;
169 import java.io.PrintWriter;
170 import java.lang.annotation.Retention;
171 import java.lang.annotation.RetentionPolicy;
172 import java.text.SimpleDateFormat;
173 import java.util.ArrayList;
174 import java.util.Arrays;
175 import java.util.Collection;
176 import java.util.Date;
177 import java.util.HashMap;
178 import java.util.HashSet;
179 import java.util.Iterator;
180 import java.util.LinkedHashMap;
181 import java.util.List;
182 import java.util.Map;
183 import java.util.NoSuchElementException;
184 import java.util.Objects;
185 import java.util.Set;
186 import java.util.concurrent.Executor;
187 import java.util.concurrent.atomic.AtomicBoolean;
188 import java.util.concurrent.atomic.AtomicInteger;
189 import java.util.function.BooleanSupplier;
190 import java.util.stream.Collectors;
191 
192 /**
193  * The implementation of the audio service for volume, audio focus, device management...
194  * <p>
195  * This implementation focuses on delivering a responsive UI. Most methods are
196  * asynchronous to external calls. For example, the task of setting a volume
197  * will update our internal state, but in a separate thread will set the system
198  * volume and later persist to the database. Similarly, setting the ringer mode
199  * will update the state and broadcast a change and in a separate thread later
200  * persist the ringer mode.
201  *
202  * @hide
203  */
204 public class AudioService extends IAudioService.Stub
205         implements AccessibilityManager.TouchExplorationStateChangeListener,
206             AccessibilityManager.AccessibilityServicesStateChangeListener,
207             AudioSystemAdapter.OnRoutingUpdatedListener {
208 
209     private static final String TAG = "AS.AudioService";
210 
211     private final AudioSystemAdapter mAudioSystem;
212     private final SystemServerAdapter mSystemServer;
213 
214     /** Debug audio mode */
215     protected static final boolean DEBUG_MODE = false;
216 
217     /** Debug audio policy feature */
218     protected static final boolean DEBUG_AP = false;
219 
220     /** Debug volumes */
221     protected static final boolean DEBUG_VOL = false;
222 
223     /** debug calls to devices APIs */
224     protected static final boolean DEBUG_DEVICES = false;
225 
226     /** Debug communication route */
227     protected static final boolean DEBUG_COMM_RTE = false;
228 
229     /** How long to delay before persisting a change in volume/ringer mode. */
230     private static final int PERSIST_DELAY = 500;
231 
232     /** How long to delay after a volume down event before unmuting a stream */
233     private static final int UNMUTE_STREAM_DELAY = 350;
234 
235     /**
236      * Delay before disconnecting a device that would cause BECOMING_NOISY intent to be sent,
237      * to give a chance to applications to pause.
238      */
239     @VisibleForTesting
240     public static final int BECOMING_NOISY_DELAY_MS = 1000;
241 
242     /**
243      * Only used in the result from {@link #checkForRingerModeChange(int, int, int)}
244      */
245     private static final int FLAG_ADJUST_VOLUME = 1;
246 
247     final Context mContext;
248     private final ContentResolver mContentResolver;
249     private final AppOpsManager mAppOps;
250 
251     // the platform type affects volume and silent mode behavior
252     private final int mPlatformType;
253 
254     // indicates whether the system maps all streams to a single stream.
255     private final boolean mIsSingleVolume;
256 
isPlatformVoice()257     /*package*/ boolean isPlatformVoice() {
258         return mPlatformType == AudioSystem.PLATFORM_VOICE;
259     }
260 
isPlatformTelevision()261     /*package*/ boolean isPlatformTelevision() {
262         return mPlatformType == AudioSystem.PLATFORM_TELEVISION;
263     }
264 
isPlatformAutomotive()265     /*package*/ boolean isPlatformAutomotive() {
266         return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
267     }
268 
269     /** The controller for the volume UI. */
270     private final VolumeController mVolumeController = new VolumeController();
271 
272     // sendMsg() flags
273     /** If the msg is already queued, replace it with this one. */
274     private static final int SENDMSG_REPLACE = 0;
275     /** If the msg is already queued, ignore this one and leave the old. */
276     private static final int SENDMSG_NOOP = 1;
277     /** If the msg is already queued, queue this one and leave the old. */
278     private static final int SENDMSG_QUEUE = 2;
279 
280     // AudioHandler messages
281     private static final int MSG_SET_DEVICE_VOLUME = 0;
282     private static final int MSG_PERSIST_VOLUME = 1;
283     private static final int MSG_PERSIST_VOLUME_GROUP = 2;
284     private static final int MSG_PERSIST_RINGER_MODE = 3;
285     private static final int MSG_AUDIO_SERVER_DIED = 4;
286     private static final int MSG_PLAY_SOUND_EFFECT = 5;
287     private static final int MSG_LOAD_SOUND_EFFECTS = 7;
288     private static final int MSG_SET_FORCE_USE = 8;
289     private static final int MSG_BT_HEADSET_CNCT_FAILED = 9;
290     private static final int MSG_SET_ALL_VOLUMES = 10;
291     private static final int MSG_CHECK_MUSIC_ACTIVE = 11;
292     private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME = 12;
293     private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED = 13;
294     private static final int MSG_PERSIST_SAFE_VOLUME_STATE = 14;
295     private static final int MSG_UNLOAD_SOUND_EFFECTS = 15;
296     private static final int MSG_SYSTEM_READY = 16;
297     private static final int MSG_PERSIST_MUSIC_ACTIVE_MS = 17;
298     private static final int MSG_UNMUTE_STREAM = 18;
299     private static final int MSG_DYN_POLICY_MIX_STATE_UPDATE = 19;
300     private static final int MSG_INDICATE_SYSTEM_READY = 20;
301     private static final int MSG_ACCESSORY_PLUG_MEDIA_UNMUTE = 21;
302     private static final int MSG_NOTIFY_VOL_EVENT = 22;
303     private static final int MSG_DISPATCH_AUDIO_SERVER_STATE = 23;
304     private static final int MSG_ENABLE_SURROUND_FORMATS = 24;
305     private static final int MSG_UPDATE_RINGER_MODE = 25;
306     private static final int MSG_SET_DEVICE_STREAM_VOLUME = 26;
307     private static final int MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS = 27;
308     private static final int MSG_HDMI_VOLUME_CHECK = 28;
309     private static final int MSG_PLAYBACK_CONFIG_CHANGE = 29;
310     private static final int MSG_BROADCAST_MICROPHONE_MUTE = 30;
311     private static final int MSG_CHECK_MODE_FOR_UID = 31;
312     private static final int MSG_STREAM_DEVICES_CHANGED = 32;
313     private static final int MSG_UPDATE_VOLUME_STATES_FOR_DEVICE = 33;
314     private static final int MSG_REINIT_VOLUMES = 34;
315     private static final int MSG_UPDATE_A11Y_SERVICE_UIDS = 35;
316     private static final int MSG_UPDATE_AUDIO_MODE = 36;
317     private static final int MSG_RECORDING_CONFIG_CHANGE = 37;
318     private static final int MSG_SET_A2DP_DEV_CONNECTION_STATE = 38;
319     private static final int MSG_A2DP_DEV_CONFIG_CHANGE = 39;
320     private static final int MSG_DISPATCH_AUDIO_MODE = 40;
321     private static final int MSG_ROUTING_UPDATED = 41;
322     private static final int MSG_INIT_HEADTRACKING_SENSORS = 42;
323     private static final int MSG_PERSIST_SPATIAL_AUDIO_ENABLED = 43;
324 
325     // start of messages handled under wakelock
326     //   these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
327     //   and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
328     private static final int MSG_DISABLE_AUDIO_FOR_UID = 100;
329     private static final int MSG_INIT_STREAMS_VOLUMES = 101;
330     private static final int MSG_INIT_SPATIALIZER = 102;
331     // end of messages handled under wakelock
332 
333     // retry delay in case of failure to indicate system ready to AudioFlinger
334     private static final int INDICATE_SYSTEM_READY_RETRY_DELAY_MS = 1000;
335 
336     /** @see AudioSystemThread */
337     private AudioSystemThread mAudioSystemThread;
338     /** @see AudioHandler */
339     private AudioHandler mAudioHandler;
340     /** @see VolumeStreamState */
341     private VolumeStreamState[] mStreamStates;
342 
getVssVolumeForDevice(int stream, int device)343     /*package*/ int getVssVolumeForDevice(int stream, int device) {
344         return mStreamStates[stream].getIndex(device);
345     }
346 
347     private SettingsObserver mSettingsObserver;
348 
349     private AtomicInteger mMode = new AtomicInteger(AudioSystem.MODE_NORMAL);
350 
351     // protects mRingerMode
352     private final Object mSettingsLock = new Object();
353 
354    /** Maximum volume index values for audio streams */
355     protected static int[] MAX_STREAM_VOLUME = new int[] {
356         5,  // STREAM_VOICE_CALL
357         7,  // STREAM_SYSTEM
358         7,  // STREAM_RING
359         15, // STREAM_MUSIC
360         7,  // STREAM_ALARM
361         7,  // STREAM_NOTIFICATION
362         15, // STREAM_BLUETOOTH_SCO
363         7,  // STREAM_SYSTEM_ENFORCED
364         15, // STREAM_DTMF
365         15, // STREAM_TTS
366         15, // STREAM_ACCESSIBILITY
367         15  // STREAM_ASSISTANT
368     };
369 
370     /** Minimum volume index values for audio streams */
371     protected static int[] MIN_STREAM_VOLUME = new int[] {
372         1,  // STREAM_VOICE_CALL
373         0,  // STREAM_SYSTEM
374         0,  // STREAM_RING
375         0,  // STREAM_MUSIC
376         1,  // STREAM_ALARM
377         0,  // STREAM_NOTIFICATION
378         0,  // STREAM_BLUETOOTH_SCO
379         0,  // STREAM_SYSTEM_ENFORCED
380         0,  // STREAM_DTMF
381         0,  // STREAM_TTS
382         1,  // STREAM_ACCESSIBILITY
383         0   // STREAM_ASSISTANT
384     };
385 
386     /* mStreamVolumeAlias[] indicates for each stream if it uses the volume settings
387      * of another stream: This avoids multiplying the volume settings for hidden
388      * stream types that follow other stream behavior for volume settings
389      * NOTE: do not create loops in aliases!
390      * Some streams alias to different streams according to device category (phone or tablet) or
391      * use case (in call vs off call...). See updateStreamVolumeAlias() for more details.
392      *  mStreamVolumeAlias contains STREAM_VOLUME_ALIAS_VOICE aliases for a voice capable device
393      *  (phone), STREAM_VOLUME_ALIAS_TELEVISION for a television or set-top box and
394      *  STREAM_VOLUME_ALIAS_DEFAULT for other devices (e.g. tablets).*/
395     private final int[] STREAM_VOLUME_ALIAS_VOICE = new int[] {
396         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
397         AudioSystem.STREAM_RING,            // STREAM_SYSTEM
398         AudioSystem.STREAM_RING,            // STREAM_RING
399         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
400         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
401         AudioSystem.STREAM_RING,            // STREAM_NOTIFICATION
402         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
403         AudioSystem.STREAM_RING,            // STREAM_SYSTEM_ENFORCED
404         AudioSystem.STREAM_RING,            // STREAM_DTMF
405         AudioSystem.STREAM_MUSIC,           // STREAM_TTS
406         AudioSystem.STREAM_MUSIC,           // STREAM_ACCESSIBILITY
407         AudioSystem.STREAM_MUSIC            // STREAM_ASSISTANT
408     };
409     private final int[] STREAM_VOLUME_ALIAS_TELEVISION = new int[] {
410         AudioSystem.STREAM_MUSIC,       // STREAM_VOICE_CALL
411         AudioSystem.STREAM_MUSIC,       // STREAM_SYSTEM
412         AudioSystem.STREAM_MUSIC,       // STREAM_RING
413         AudioSystem.STREAM_MUSIC,       // STREAM_MUSIC
414         AudioSystem.STREAM_MUSIC,       // STREAM_ALARM
415         AudioSystem.STREAM_MUSIC,       // STREAM_NOTIFICATION
416         AudioSystem.STREAM_BLUETOOTH_SCO,       // STREAM_BLUETOOTH_SCO
417         AudioSystem.STREAM_MUSIC,       // STREAM_SYSTEM_ENFORCED
418         AudioSystem.STREAM_MUSIC,       // STREAM_DTMF
419         AudioSystem.STREAM_MUSIC,       // STREAM_TTS
420         AudioSystem.STREAM_MUSIC,       // STREAM_ACCESSIBILITY
421         AudioSystem.STREAM_MUSIC        // STREAM_ASSISTANT
422     };
423     /**
424      * Using Volume groups configuration allows to control volume per attributes
425      * and group definition may differ from stream aliases.
426      * So, do not alias any stream on one another when using volume groups.
427      * TODO(b/181140246): volume group definition hosting alias definition.
428      */
429     private final int[] STREAM_VOLUME_ALIAS_NONE = new int[] {
430         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
431         AudioSystem.STREAM_SYSTEM,          // STREAM_SYSTEM
432         AudioSystem.STREAM_RING,            // STREAM_RING
433         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
434         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
435         AudioSystem.STREAM_NOTIFICATION,    // STREAM_NOTIFICATION
436         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
437         AudioSystem.STREAM_SYSTEM_ENFORCED, // STREAM_SYSTEM_ENFORCED
438         AudioSystem.STREAM_DTMF,            // STREAM_DTMF
439         AudioSystem.STREAM_TTS,             // STREAM_TTS
440         AudioSystem.STREAM_ACCESSIBILITY,   // STREAM_ACCESSIBILITY
441         AudioSystem.STREAM_ASSISTANT        // STREAM_ASSISTANT
442     };
443     private final int[] STREAM_VOLUME_ALIAS_DEFAULT = new int[] {
444         AudioSystem.STREAM_VOICE_CALL,      // STREAM_VOICE_CALL
445         AudioSystem.STREAM_RING,            // STREAM_SYSTEM
446         AudioSystem.STREAM_RING,            // STREAM_RING
447         AudioSystem.STREAM_MUSIC,           // STREAM_MUSIC
448         AudioSystem.STREAM_ALARM,           // STREAM_ALARM
449         AudioSystem.STREAM_RING,            // STREAM_NOTIFICATION
450         AudioSystem.STREAM_BLUETOOTH_SCO,   // STREAM_BLUETOOTH_SCO
451         AudioSystem.STREAM_RING,            // STREAM_SYSTEM_ENFORCED
452         AudioSystem.STREAM_RING,            // STREAM_DTMF
453         AudioSystem.STREAM_MUSIC,           // STREAM_TTS
454         AudioSystem.STREAM_MUSIC,           // STREAM_ACCESSIBILITY
455         AudioSystem.STREAM_MUSIC            // STREAM_ASSISTANT
456     };
457     protected static int[] mStreamVolumeAlias;
458     private static final int UNSET_INDEX = -1;
459 
460     /**
461      * Map AudioSystem.STREAM_* constants to app ops.  This should be used
462      * after mapping through mStreamVolumeAlias.
463      */
464     private static final int[] STREAM_VOLUME_OPS = new int[] {
465         AppOpsManager.OP_AUDIO_VOICE_VOLUME,            // STREAM_VOICE_CALL
466         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_SYSTEM
467         AppOpsManager.OP_AUDIO_RING_VOLUME,             // STREAM_RING
468         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_MUSIC
469         AppOpsManager.OP_AUDIO_ALARM_VOLUME,            // STREAM_ALARM
470         AppOpsManager.OP_AUDIO_NOTIFICATION_VOLUME,     // STREAM_NOTIFICATION
471         AppOpsManager.OP_AUDIO_BLUETOOTH_VOLUME,        // STREAM_BLUETOOTH_SCO
472         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_SYSTEM_ENFORCED
473         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_DTMF
474         AppOpsManager.OP_AUDIO_MEDIA_VOLUME,            // STREAM_TTS
475         AppOpsManager.OP_AUDIO_ACCESSIBILITY_VOLUME,    // STREAM_ACCESSIBILITY
476         AppOpsManager.OP_AUDIO_MEDIA_VOLUME             // STREAM_ASSISTANT
477     };
478 
479     private final boolean mUseFixedVolume;
480     private final boolean mUseVolumeGroupAliases;
481 
482     // If absolute volume is supported in AVRCP device
483     private volatile boolean mAvrcpAbsVolSupported = false;
484 
485     /**
486     * Default stream type used for volume control in the absence of playback
487     * e.g. user on homescreen, no app playing anything, presses hardware volume buttons, this
488     *    stream type is controlled.
489     */
490     protected static final int DEFAULT_VOL_STREAM_NO_PLAYBACK = AudioSystem.STREAM_MUSIC;
491 
492     private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() {
493         public void onError(int error) {
494             switch (error) {
495                 case AudioSystem.AUDIO_STATUS_SERVER_DIED:
496                     // check for null in case error callback is called during instance creation
497                     if (mRecordMonitor != null) {
498                         mRecordMonitor.onAudioServerDied();
499                     }
500                     sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED,
501                             SENDMSG_NOOP, 0, 0, null, 0);
502                     sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE,
503                             SENDMSG_QUEUE, 0, 0, null, 0);
504                     break;
505                 default:
506                     break;
507             }
508         }
509     };
510 
511     /**
512      * Current ringer mode from one of {@link AudioManager#RINGER_MODE_NORMAL},
513      * {@link AudioManager#RINGER_MODE_SILENT}, or
514      * {@link AudioManager#RINGER_MODE_VIBRATE}.
515      */
516     @GuardedBy("mSettingsLock")
517     private int mRingerMode;  // internal ringer mode, affects muting of underlying streams
518     @GuardedBy("mSettingsLock")
519     private int mRingerModeExternal = -1;  // reported ringer mode to outside clients (AudioManager)
520 
521     /** @see System#MODE_RINGER_STREAMS_AFFECTED */
522     private int mRingerModeAffectedStreams = 0;
523 
524     private int mZenModeAffectedStreams = 0;
525 
526     // Streams currently muted by ringer mode and dnd
527     private int mRingerAndZenModeMutedStreams;
528 
529     /** Streams that can be muted. Do not resolve to aliases when checking.
530      * @see System#MUTE_STREAMS_AFFECTED */
531     private int mMuteAffectedStreams;
532 
533     @NonNull
534     private SoundEffectsHelper mSfxHelper;
535 
536     /**
537      * NOTE: setVibrateSetting(), getVibrateSetting(), shouldVibrate() are deprecated.
538      * mVibrateSetting is just maintained during deprecation period but vibration policy is
539      * now only controlled by mHasVibrator and mRingerMode
540      */
541     private int mVibrateSetting;
542 
543     // Is there a vibrator
544     private final boolean mHasVibrator;
545     // Used to play vibrations
546     private Vibrator mVibrator;
547     private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
548             .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
549             .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
550             .build();
551 
552     // Broadcast receiver for device connections intent broadcasts
553     private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver();
554 
555     private IMediaProjectionManager mProjectionService; // to validate projection token
556 
557     /** Interface for UserManagerService. */
558     private final UserManagerInternal mUserManagerInternal;
559     private final ActivityManagerInternal mActivityManagerInternal;
560     private final SensorPrivacyManagerInternal mSensorPrivacyManagerInternal;
561 
562     private final UserRestrictionsListener mUserRestrictionsListener =
563             new AudioServiceUserRestrictionsListener();
564 
565     // List of binder death handlers for setMode() client processes.
566     // The last process to have called setMode() is at the top of the list.
567     // package-private so it can be accessed in AudioDeviceBroker.getSetModeDeathHandlers
568     //TODO candidate to be moved to separate class that handles synchronization
569     @GuardedBy("mDeviceBroker.mSetModeLock")
570     /*package*/ final ArrayList<SetModeDeathHandler> mSetModeDeathHandlers =
571             new ArrayList<SetModeDeathHandler>();
572 
573     // true if boot sequence has been completed
574     private boolean mSystemReady;
575     // true if Intent.ACTION_USER_SWITCHED has ever been received
576     private boolean mUserSwitchedReceived;
577     // previous volume adjustment direction received by checkForRingerModeChange()
578     private int mPrevVolDirection = AudioManager.ADJUST_SAME;
579     // mVolumeControlStream is set by VolumePanel to temporarily force the stream type which volume
580     // is controlled by Vol keys.
581     private int mVolumeControlStream = -1;
582     // interpretation of whether the volume stream has been selected by the user by clicking on a
583     // volume slider to change which volume is controlled by the volume keys. Is false
584     // when mVolumeControlStream is -1.
585     private boolean mUserSelectedVolumeControlStream = false;
586     private final Object mForceControlStreamLock = new Object();
587     // VolumePanel is currently the only client of forceVolumeControlStream() and runs in system
588     // server process so in theory it is not necessary to monitor the client death.
589     // However it is good to be ready for future evolutions.
590     private ForceControlStreamClient mForceControlStreamClient = null;
591     // Used to play ringtones outside system_server
592     private volatile IRingtonePlayer mRingtonePlayer;
593 
594     // Devices for which the volume is fixed (volume is either max or muted)
595     Set<Integer> mFixedVolumeDevices = new HashSet<>(Arrays.asList(
596             AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET,
597             AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET,
598             AudioSystem.DEVICE_OUT_HDMI_ARC,
599             AudioSystem.DEVICE_OUT_HDMI_EARC,
600             AudioSystem.DEVICE_OUT_AUX_LINE));
601     // Devices for which the volume is always max, no volume panel
602     Set<Integer> mFullVolumeDevices = new HashSet<>();
603     // Devices for the which use the "absolute volume" concept (framework sends audio signal
604     // full scale, and volume control separately) and can be used for multiple use cases reflected
605     // by the audio mode (e.g. media playback in MODE_NORMAL, and phone calls in MODE_IN_CALL).
606     Set<Integer> mAbsVolumeMultiModeCaseDevices = new HashSet<>(
607             Arrays.asList(AudioSystem.DEVICE_OUT_HEARING_AID));
608 
609     private final boolean mMonitorRotation;
610 
611     private boolean mDockAudioMediaEnabled = true;
612 
613     /**
614      * RestorableParameters is a thread-safe class used to store a
615      * first-in first-out history of parameters for replay / restoration.
616      *
617      * The idealized implementation of restoration would have a list of setting methods and
618      * values to be called for restoration.  Explicitly managing such setters and
619      * values would be tedious - a simpler method is to store the values and the
620      * method implicitly by lambda capture (the values must be immutable or synchronization
621      * needs to be taken).
622      *
623      * We provide queueRestoreWithRemovalIfTrue() to allow
624      * the caller to provide a BooleanSupplier lambda, which conveniently packages
625      * the setter and its parameters needed for restoration.  If during restoration,
626      * the BooleanSupplier returns true, e.g. on error, it is removed from the mMap
627      * so as not to be called on a subsequent restore.
628      *
629      * We provide a setParameters() method as an example helper method.
630      */
631     private static class RestorableParameters {
632         /**
633          * Sets a parameter and queues for restoration if successful.
634          *
635          * @param id a string handle associated with this parameter.
636          * @param parameter the actual parameter string.
637          * @return the result of AudioSystem.setParameters
638          */
setParameters(@onNull String id, @NonNull String parameter)639         public int setParameters(@NonNull String id, @NonNull String parameter) {
640             Objects.requireNonNull(id, "id must not be null");
641             Objects.requireNonNull(parameter, "parameter must not be null");
642             synchronized (mMap) {
643                 final int status = AudioSystem.setParameters(parameter);
644                 if (status == AudioSystem.AUDIO_STATUS_OK) { // Java uses recursive mutexes.
645                     queueRestoreWithRemovalIfTrue(id, () -> { // remove me if set fails.
646                         return AudioSystem.setParameters(parameter) != AudioSystem.AUDIO_STATUS_OK;
647                     });
648                 }
649                 // Implementation detail: We do not mMap.remove(id); on failure.
650                 return status;
651             }
652         }
653 
654         /**
655          * Queues a restore method which is executed on restoreAll().
656          *
657          * If the supplier null, the id is removed from the restore map.
658          *
659          * Note: When the BooleanSupplier restore method is executed
660          * during restoreAll, if it returns true, it is removed from the
661          * restore map.
662          *
663          * @param id a unique tag associated with the restore method.
664          * @param supplier is a BooleanSupplier lambda.
665          */
queueRestoreWithRemovalIfTrue( @onNull String id, @Nullable BooleanSupplier supplier)666         public void queueRestoreWithRemovalIfTrue(
667                 @NonNull String id, @Nullable BooleanSupplier supplier) {
668             Objects.requireNonNull(id, "id must not be null");
669             synchronized (mMap) {
670                 if (supplier != null) {
671                     mMap.put(id, supplier);
672                 } else {
673                     mMap.remove(id);
674                 }
675             }
676         }
677 
678         /**
679          * Restore all parameters
680          *
681          * During restoration after audioserver death, any BooleanSupplier that returns
682          * true, for example on parameter restoration error, will be removed from mMap
683          * so as not to be executed on a subsequent restoreAll().
684          */
restoreAll()685         public void restoreAll() {
686             synchronized (mMap) {
687                 // Note: removing from values() also removes from the backing map.
688                 // TODO: Consider catching exceptions?
689                 mMap.values().removeIf(v -> {
690                     return v.getAsBoolean(); // this iterates the setters().
691                 });
692             }
693         }
694 
695         /**
696          * mMap is a LinkedHashMap<Key, Value> of parameters restored by restore().
697          * The Key is a unique id tag for identification.
698          * The Value is a lambda expression which returns true if the entry is to
699          *     be removed.
700          *
701          * 1) For memory limitation purposes, mMap keeps the latest MAX_ENTRIES
702          *    accessed in the map.
703          * 2) Parameters are restored in order of queuing, first in first out,
704          *    from earliest to latest.
705          */
706         @GuardedBy("mMap")
707         private Map</* @NonNull */ String, /* @NonNull */ BooleanSupplier> mMap =
708                 new LinkedHashMap<>() {
709             // TODO: do we need this memory limitation?
710             private static final int MAX_ENTRIES = 1000;  // limit our memory for now.
711             @Override
712             protected boolean removeEldestEntry(Map.Entry eldest) {
713                 if (size() <= MAX_ENTRIES) return false;
714                 Log.w(TAG, "Parameter map exceeds "
715                         + MAX_ENTRIES + " removing " + eldest.getKey()); // don't silently remove.
716                 return true;
717             }
718         };
719     }
720 
721     // We currently have one instance for mRestorableParameters used for
722     // setAdditionalOutputDeviceDelay().  Other methods requiring restoration could share this
723     // or use their own instance.
724     private RestorableParameters mRestorableParameters = new RestorableParameters();
725 
726     private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
727 
728     // Used when safe volume warning message display is requested by setStreamVolume(). In this
729     // case, the new requested volume, stream type and device are stored in mPendingVolumeCommand
730     // and used later when/if disableSafeMediaVolume() is called.
731     private StreamVolumeCommand mPendingVolumeCommand;
732 
733     private PowerManager.WakeLock mAudioEventWakeLock;
734 
735     private final MediaFocusControl mMediaFocusControl;
736 
737     // Pre-scale for Bluetooth Absolute Volume
738     private float[] mPrescaleAbsoluteVolume = new float[] {
739         0.6f,    // Pre-scale for index 1
740         0.8f,    // Pre-scale for index 2
741         0.9f,   // Pre-scale for index 3
742     };
743 
744     private NotificationManager mNm;
745     private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate;
746     private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT;
747     private long mLoweredFromNormalToVibrateTime;
748 
749     // Uid of the active hotword detection service to check if caller is the one or not.
750     @GuardedBy("mHotwordDetectionServiceUidLock")
751     private int mHotwordDetectionServiceUid = android.os.Process.INVALID_UID;
752     private final Object mHotwordDetectionServiceUidLock = new Object();
753 
754     // Array of Uids of valid accessibility services to check if caller is one of them
755     private final Object mAccessibilityServiceUidsLock = new Object();
756     @GuardedBy("mAccessibilityServiceUidsLock")
757     private int[] mAccessibilityServiceUids;
758 
759     // Uid of the active input method service to check if caller is the one or not.
760     private int mInputMethodServiceUid = android.os.Process.INVALID_UID;
761     private final Object mInputMethodServiceUidLock = new Object();
762 
763     private int mEncodedSurroundMode;
764     private String mEnabledSurroundFormats;
765     private boolean mSurroundModeChanged;
766 
767     private boolean mSupportsMicPrivacyToggle;
768 
769     private boolean mMicMuteFromSwitch;
770     private boolean mMicMuteFromApi;
771     private boolean mMicMuteFromRestrictions;
772     private boolean mMicMuteFromPrivacyToggle;
773     // caches the value returned by AudioSystem.isMicrophoneMuted()
774     private boolean mMicMuteFromSystemCached;
775 
776     private boolean mNavigationRepeatSoundEffectsEnabled;
777     private boolean mHomeSoundEffectEnabled;
778 
779     @GuardedBy("mSettingsLock")
780     private int mAssistantUid;
781 
782     @GuardedBy("mSettingsLock")
783     private int mCurrentImeUid;
784 
785     private final Object mSupportedSystemUsagesLock = new Object();
786     @GuardedBy("mSupportedSystemUsagesLock")
787     private @AttributeSystemUsage int[] mSupportedSystemUsages =
788             new int[]{AudioAttributes.USAGE_CALL_ASSISTANT};
789 
790     // Defines the format for the connection "address" for ALSA devices
makeAlsaAddressString(int card, int device)791     public static String makeAlsaAddressString(int card, int device) {
792         return "card=" + card + ";device=" + device + ";";
793     }
794 
795     public static final class Lifecycle extends SystemService {
796         private AudioService mService;
797 
Lifecycle(Context context)798         public Lifecycle(Context context) {
799             super(context);
800             mService = new AudioService(context);
801         }
802 
803         @Override
onStart()804         public void onStart() {
805             publishBinderService(Context.AUDIO_SERVICE, mService);
806         }
807 
808         @Override
onBootPhase(int phase)809         public void onBootPhase(int phase) {
810             if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
811                 mService.systemReady();
812             }
813         }
814     }
815 
816     final private IUidObserver mUidObserver = new IUidObserver.Stub() {
817         @Override public void onUidStateChanged(int uid, int procState, long procStateSeq,
818             int capability) {
819         }
820 
821         @Override public void onUidGone(int uid, boolean disabled) {
822             // Once the uid is no longer running, no need to keep trying to disable its audio.
823             disableAudioForUid(false, uid);
824         }
825 
826         @Override public void onUidActive(int uid) throws RemoteException {
827         }
828 
829         @Override public void onUidIdle(int uid, boolean disabled) {
830         }
831 
832         @Override public void onUidCachedChanged(int uid, boolean cached) {
833             disableAudioForUid(cached, uid);
834         }
835 
836         private void disableAudioForUid(boolean disable, int uid) {
837             queueMsgUnderWakeLock(mAudioHandler, MSG_DISABLE_AUDIO_FOR_UID,
838                     disable ? 1 : 0 /* arg1 */,  uid /* arg2 */,
839                     null /* obj */,  0 /* delay */);
840         }
841     };
842 
843     @GuardedBy("mSettingsLock")
844     private boolean mRttEnabled = false;
845 
846     ///////////////////////////////////////////////////////////////////////////
847     // Construction
848     ///////////////////////////////////////////////////////////////////////////
849 
850     /** @hide */
AudioService(Context context)851     public AudioService(Context context) {
852         this(context, AudioSystemAdapter.getDefaultAdapter(),
853                 SystemServerAdapter.getDefaultAdapter(context));
854     }
855 
AudioService(Context context, AudioSystemAdapter audioSystem, SystemServerAdapter systemServer)856     public AudioService(Context context, AudioSystemAdapter audioSystem,
857             SystemServerAdapter systemServer) {
858         sLifecycleLogger.log(new AudioEventLogger.StringEvent("AudioService()"));
859         mContext = context;
860         mContentResolver = context.getContentResolver();
861         mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
862 
863         mAudioSystem = audioSystem;
864         mSystemServer = systemServer;
865 
866         mPlatformType = AudioSystem.getPlatformType(context);
867 
868         mIsSingleVolume = AudioSystem.isSingleVolume(context);
869 
870         mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
871         mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
872         mSensorPrivacyManagerInternal =
873                 LocalServices.getService(SensorPrivacyManagerInternal.class);
874 
875         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
876         mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent");
877 
878         mSfxHelper = new SoundEffectsHelper(mContext);
879 
880         mSpatializerHelper = new SpatializerHelper(this, mAudioSystem);
881 
882         mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
883         mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator();
884 
885         mSupportsMicPrivacyToggle = context.getSystemService(SensorPrivacyManager.class)
886                 .supportsSensorToggle(SensorPrivacyManager.Sensors.MICROPHONE);
887 
888         mUseVolumeGroupAliases = mContext.getResources().getBoolean(
889                 com.android.internal.R.bool.config_handleVolumeAliasesUsingVolumeGroups);
890 
891         // Initialize volume
892         // Priority 1 - Android Property
893         // Priority 2 - Audio Policy Service
894         // Priority 3 - Default Value
895         if (AudioProductStrategy.getAudioProductStrategies().size() > 0) {
896             int numStreamTypes = AudioSystem.getNumStreamTypes();
897 
898             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
899                 AudioAttributes attr =
900                         AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(
901                                 streamType);
902                 int maxVolume = AudioSystem.getMaxVolumeIndexForAttributes(attr);
903                 if (maxVolume != -1) {
904                     MAX_STREAM_VOLUME[streamType] = maxVolume;
905                 }
906                 int minVolume = AudioSystem.getMinVolumeIndexForAttributes(attr);
907                 if (minVolume != -1) {
908                     MIN_STREAM_VOLUME[streamType] = minVolume;
909                 }
910             }
911             if (mUseVolumeGroupAliases) {
912                 // Set all default to uninitialized.
913                 for (int stream = 0; stream < AudioSystem.DEFAULT_STREAM_VOLUME.length; stream++) {
914                     AudioSystem.DEFAULT_STREAM_VOLUME[stream] = UNSET_INDEX;
915                 }
916             }
917         }
918 
919         int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1);
920         if (maxCallVolume != -1) {
921             MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxCallVolume;
922         }
923 
924         int defaultCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_default", -1);
925         if (defaultCallVolume != -1 &&
926                 defaultCallVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] &&
927                 defaultCallVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]) {
928             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = defaultCallVolume;
929         } else {
930             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] =
931                     (MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] * 3) / 4;
932         }
933 
934         int maxMusicVolume = SystemProperties.getInt("ro.config.media_vol_steps", -1);
935         if (maxMusicVolume != -1) {
936             MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxMusicVolume;
937         }
938 
939         int defaultMusicVolume = SystemProperties.getInt("ro.config.media_vol_default", -1);
940         if (defaultMusicVolume != -1 &&
941                 defaultMusicVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] &&
942                 defaultMusicVolume >= MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) {
943             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = defaultMusicVolume;
944         } else {
945             if (isPlatformTelevision()) {
946                 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] =
947                         MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 4;
948             } else {
949                 AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] =
950                         MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] / 3;
951             }
952         }
953 
954         int maxAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_steps", -1);
955         if (maxAlarmVolume != -1) {
956             MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = maxAlarmVolume;
957         }
958 
959         int defaultAlarmVolume = SystemProperties.getInt("ro.config.alarm_vol_default", -1);
960         if (defaultAlarmVolume != -1 &&
961                 defaultAlarmVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]) {
962             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] = defaultAlarmVolume;
963         } else {
964             // Default is 6 out of 7 (default maximum), so scale accordingly.
965             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_ALARM] =
966                         6 * MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM] / 7;
967         }
968 
969         int maxSystemVolume = SystemProperties.getInt("ro.config.system_vol_steps", -1);
970         if (maxSystemVolume != -1) {
971             MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = maxSystemVolume;
972         }
973 
974         int defaultSystemVolume = SystemProperties.getInt("ro.config.system_vol_default", -1);
975         if (defaultSystemVolume != -1 &&
976                 defaultSystemVolume <= MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM]) {
977             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] = defaultSystemVolume;
978         } else {
979             // Default is to use maximum.
980             AudioSystem.DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM] =
981                         MAX_STREAM_VOLUME[AudioSystem.STREAM_SYSTEM];
982         }
983 
984         createAudioSystemThread();
985 
986         AudioSystem.setErrorCallback(mAudioSystemCallback);
987 
988         updateAudioHalPids();
989 
990         boolean cameraSoundForced = readCameraSoundForced();
991         mCameraSoundForced = new Boolean(cameraSoundForced);
992         sendMsg(mAudioHandler,
993                 MSG_SET_FORCE_USE,
994                 SENDMSG_QUEUE,
995                 AudioSystem.FOR_SYSTEM,
996                 cameraSoundForced ?
997                         AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE,
998                 new String("AudioService ctor"),
999                 0);
1000 
1001         mSafeMediaVolumeState = Settings.Global.getInt(mContentResolver,
1002                                             Settings.Global.AUDIO_SAFE_VOLUME_STATE,
1003                                             SAFE_MEDIA_VOLUME_NOT_CONFIGURED);
1004         // The default safe volume index read here will be replaced by the actual value when
1005         // the mcc is read by onConfigureSafeVolume()
1006         mSafeMediaVolumeIndex = mContext.getResources().getInteger(
1007                 com.android.internal.R.integer.config_safe_media_volume_index) * 10;
1008 
1009         mUseFixedVolume = mContext.getResources().getBoolean(
1010                 com.android.internal.R.bool.config_useFixedVolume);
1011 
1012         mDeviceBroker = new AudioDeviceBroker(mContext, this);
1013 
1014         mRecordMonitor = new RecordingActivityMonitor(mContext);
1015         mRecordMonitor.registerRecordingCallback(mVoiceRecordingActivityMonitor, true);
1016 
1017         // must be called before readPersistedSettings() which needs a valid mStreamVolumeAlias[]
1018         // array initialized by updateStreamVolumeAlias()
1019         updateStreamVolumeAlias(false /*updateVolumes*/, TAG);
1020         readPersistedSettings();
1021         readUserRestrictions();
1022 
1023         mPlaybackMonitor =
1024                 new PlaybackActivityMonitor(context, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]);
1025         mPlaybackMonitor.registerPlaybackCallback(mVoicePlaybackActivityMonitor, true);
1026 
1027         mMediaFocusControl = new MediaFocusControl(mContext, mPlaybackMonitor);
1028 
1029         readAndSetLowRamDevice();
1030 
1031         mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported();
1032 
1033         if (mSystemServer.isPrivileged()) {
1034             LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal());
1035 
1036             mUserManagerInternal.addUserRestrictionsListener(mUserRestrictionsListener);
1037 
1038             mRecordMonitor.initMonitor();
1039         }
1040 
1041         mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false);
1042 
1043         mHasSpatializerEffect = SystemProperties.getBoolean("ro.audio.spatializer_enabled", false);
1044 
1045         // done with service initialization, continue additional work in our Handler thread
1046         queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_STREAMS_VOLUMES,
1047                 0 /* arg1 */,  0 /* arg2 */, null /* obj */,  0 /* delay */);
1048         queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_SPATIALIZER,
1049                 0 /* arg1 */, 0 /* arg2 */, null /* obj */, 0 /* delay */);
1050     }
1051 
1052     /**
1053      * Called by handling of MSG_INIT_STREAMS_VOLUMES
1054      */
onInitStreamsAndVolumes()1055     private void onInitStreamsAndVolumes() {
1056         createStreamStates();
1057 
1058         // must be called after createStreamStates() as it uses MUSIC volume as default if no
1059         // persistent data
1060         initVolumeGroupStates();
1061 
1062         // mSafeUsbMediaVolumeIndex must be initialized after createStreamStates() because it
1063         // relies on audio policy having correct ranges for volume indexes.
1064         mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex();
1065 
1066         // Call setRingerModeInt() to apply correct mute
1067         // state on streams affected by ringer mode.
1068         mRingerAndZenModeMutedStreams = 0;
1069         setRingerModeInt(getRingerModeInternal(), false);
1070 
1071         final float[] preScale = new float[3];
1072         preScale[0] = mContext.getResources().getFraction(
1073                 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index1,
1074                 1, 1);
1075         preScale[1] = mContext.getResources().getFraction(
1076                 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index2,
1077                 1, 1);
1078         preScale[2] = mContext.getResources().getFraction(
1079                 com.android.internal.R.fraction.config_prescaleAbsoluteVolume_index3,
1080                 1, 1);
1081         for (int i = 0; i < preScale.length; i++) {
1082             if (0.0f <= preScale[i] && preScale[i] <= 1.0f) {
1083                 mPrescaleAbsoluteVolume[i] = preScale[i];
1084             }
1085         }
1086 
1087         initExternalEventReceivers();
1088 
1089         // check on volume initialization
1090         checkVolumeRangeInitialization("AudioService()");
1091     }
1092 
1093     /**
1094      * Initialize intent receives and settings observers for this service.
1095      * Must be called after createStreamStates() as the handling of some events
1096      * may affect or need volumes, e.g. BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED
1097      * (for intent receiver), or Settings.Global.ZEN_MODE (for settings observer)
1098      */
initExternalEventReceivers()1099     private void initExternalEventReceivers() {
1100         mSettingsObserver = new SettingsObserver();
1101 
1102         // Register for device connection intent broadcasts.
1103         IntentFilter intentFilter =
1104                 new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
1105         intentFilter.addAction(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED);
1106         intentFilter.addAction(Intent.ACTION_DOCK_EVENT);
1107         intentFilter.addAction(Intent.ACTION_SCREEN_ON);
1108         intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
1109         intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
1110         intentFilter.addAction(Intent.ACTION_USER_BACKGROUND);
1111         intentFilter.addAction(Intent.ACTION_USER_FOREGROUND);
1112         intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
1113         intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
1114         intentFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
1115 
1116         intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
1117         if (mMonitorRotation) {
1118             RotationHelper.init(mContext, mAudioHandler);
1119         }
1120 
1121         intentFilter.addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION);
1122         intentFilter.addAction(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION);
1123 
1124         mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null);
1125 
1126     }
1127 
systemReady()1128     public void systemReady() {
1129         sendMsg(mAudioHandler, MSG_SYSTEM_READY, SENDMSG_QUEUE,
1130                 0, 0, null, 0);
1131         if (false) {
1132             // This is turned off for now, because it is racy and thus causes apps to break.
1133             // Currently banning a uid means that if an app tries to start playing an audio
1134             // stream, that will be preventing, and unbanning it will not allow that stream
1135             // to resume.  However these changes in uid state are racy with what the app is doing,
1136             // so that after taking a process out of the cached state we can't guarantee that
1137             // we will unban the uid before the app actually tries to start playing audio.
1138             // (To do that, the activity manager would need to wait until it knows for sure
1139             // that the ban has been removed, before telling the app to do whatever it is
1140             // supposed to do that caused it to go out of the cached state.)
1141             try {
1142                 ActivityManager.getService().registerUidObserver(mUidObserver,
1143                         ActivityManager.UID_OBSERVER_CACHED | ActivityManager.UID_OBSERVER_GONE,
1144                         ActivityManager.PROCESS_STATE_UNKNOWN, null);
1145             } catch (RemoteException e) {
1146                 // ignored; both services live in system_server
1147             }
1148         }
1149     }
1150 
updateVibratorInfos()1151     private void updateVibratorInfos() {
1152         VibratorManager vibratorManager = mContext.getSystemService(VibratorManager.class);
1153         if (vibratorManager == null) {
1154             Slog.e(TAG, "Vibrator manager is not found");
1155             return;
1156         }
1157         int[] vibratorIds = vibratorManager.getVibratorIds();
1158         if (vibratorIds.length == 0) {
1159             Slog.d(TAG, "No vibrator found");
1160             return;
1161         }
1162         List<Vibrator> vibrators = new ArrayList<>(vibratorIds.length);
1163         for (int id : vibratorIds) {
1164             Vibrator vibrator = vibratorManager.getVibrator(id);
1165             if (vibrator != null) {
1166                 vibrators.add(vibrator);
1167             } else {
1168                 Slog.w(TAG, "Vibrator(" + id + ") is not found");
1169             }
1170         }
1171         if (vibrators.isEmpty()) {
1172             Slog.w(TAG, "Cannot find any available vibrator");
1173             return;
1174         }
1175         AudioSystem.setVibratorInfos(vibrators);
1176     }
1177 
onSystemReady()1178     public void onSystemReady() {
1179         mSystemReady = true;
1180         scheduleLoadSoundEffects();
1181 
1182         mDeviceBroker.onSystemReady();
1183 
1184         if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_HDMI_CEC)) {
1185             synchronized (mHdmiClientLock) {
1186                 mHdmiManager = mContext.getSystemService(HdmiControlManager.class);
1187                 if (mHdmiManager != null) {
1188                     mHdmiManager.addHdmiControlStatusChangeListener(
1189                             mHdmiControlStatusChangeListenerCallback);
1190                     mHdmiManager.addHdmiCecVolumeControlFeatureListener(mContext.getMainExecutor(),
1191                             mMyHdmiCecVolumeControlFeatureListener);
1192                 }
1193                 mHdmiTvClient = mHdmiManager.getTvClient();
1194                 if (mHdmiTvClient != null) {
1195                     mFixedVolumeDevices.removeAll(
1196                             AudioSystem.DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET);
1197                 }
1198                 mHdmiPlaybackClient = mHdmiManager.getPlaybackClient();
1199                 mHdmiAudioSystemClient = mHdmiManager.getAudioSystemClient();
1200             }
1201         }
1202 
1203         if (mSupportsMicPrivacyToggle) {
1204             mSensorPrivacyManagerInternal.addSensorPrivacyListenerForAllUsers(
1205                     SensorPrivacyManager.Sensors.MICROPHONE, (userId, enabled) -> {
1206                         if (userId == getCurrentUserId()) {
1207                             mMicMuteFromPrivacyToggle = enabled;
1208                             setMicrophoneMuteNoCallerCheck(getCurrentUserId());
1209                         }
1210                     });
1211         }
1212 
1213         mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
1214 
1215         sendMsg(mAudioHandler,
1216                 MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED,
1217                 SENDMSG_REPLACE,
1218                 0,
1219                 0,
1220                 TAG,
1221                 SystemProperties.getBoolean("audio.safemedia.bypass", false) ?
1222                         0 : SAFE_VOLUME_CONFIGURE_TIMEOUT_MS);
1223 
1224         initA11yMonitoring();
1225 
1226         mRoleObserver = new RoleObserver();
1227         mRoleObserver.register();
1228 
1229         onIndicateSystemReady();
1230 
1231         mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted();
1232         setMicMuteFromSwitchInput();
1233 
1234         initMinStreamVolumeWithoutModifyAudioSettings();
1235 
1236         updateVibratorInfos();
1237     }
1238 
1239     //-----------------------------------------------------------------
1240     // routing monitoring from AudioSystemAdapter
1241     @Override
onRoutingUpdatedFromNative()1242     public void onRoutingUpdatedFromNative() {
1243         if (!mHasSpatializerEffect) {
1244             return;
1245         }
1246         sendMsg(mAudioHandler,
1247                 MSG_ROUTING_UPDATED,
1248                 SENDMSG_REPLACE, 0, 0, null,
1249                 /*delay*/ 0);
1250     }
1251 
monitorRoutingChanges(boolean enabled)1252     void monitorRoutingChanges(boolean enabled) {
1253         mAudioSystem.setRoutingListener(enabled ? this : null);
1254     }
1255 
1256 
1257     //-----------------------------------------------------------------
1258     RoleObserver mRoleObserver;
1259 
1260     class RoleObserver implements OnRoleHoldersChangedListener {
1261         private RoleManager mRm;
1262         private final Executor mExecutor;
1263 
RoleObserver()1264         RoleObserver() {
1265             mExecutor = mContext.getMainExecutor();
1266         }
1267 
register()1268         public void register() {
1269             mRm = (RoleManager) mContext.getSystemService(Context.ROLE_SERVICE);
1270             if (mRm != null) {
1271                 mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.ALL);
1272                 updateAssistantUId(true);
1273             }
1274         }
1275 
1276         @Override
onRoleHoldersChanged(@onNull String roleName, @NonNull UserHandle user)1277         public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
1278             if (RoleManager.ROLE_ASSISTANT.equals(roleName)) {
1279                 updateAssistantUId(false);
1280             }
1281         }
1282 
getAssistantRoleHolder()1283         public String getAssistantRoleHolder() {
1284             String assitantPackage = "";
1285             if (mRm != null) {
1286                 List<String> assistants = mRm.getRoleHolders(RoleManager.ROLE_ASSISTANT);
1287                 assitantPackage = assistants.size() == 0 ? "" : assistants.get(0);
1288             }
1289             return assitantPackage;
1290         }
1291     }
1292 
onIndicateSystemReady()1293     void onIndicateSystemReady() {
1294         if (AudioSystem.systemReady() == AudioSystem.SUCCESS) {
1295             return;
1296         }
1297         sendMsg(mAudioHandler,
1298                 MSG_INDICATE_SYSTEM_READY,
1299                 SENDMSG_REPLACE,
1300                 0,
1301                 0,
1302                 null,
1303                 INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
1304     }
1305 
onAudioServerDied()1306     public void onAudioServerDied() {
1307         if (!mSystemReady ||
1308                 (AudioSystem.checkAudioFlinger() != AudioSystem.AUDIO_STATUS_OK)) {
1309             Log.e(TAG, "Audioserver died.");
1310             sLifecycleLogger.log(new AudioEventLogger.StringEvent(
1311                     "onAudioServerDied() audioserver died"));
1312             sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED, SENDMSG_NOOP, 0, 0,
1313                     null, 500);
1314             return;
1315         }
1316         Log.i(TAG, "Audioserver started.");
1317         sLifecycleLogger.log(new AudioEventLogger.StringEvent(
1318                 "onAudioServerDied() audioserver started"));
1319 
1320         updateAudioHalPids();
1321 
1322         // indicate to audio HAL that we start the reconfiguration phase after a media
1323         // server crash
1324         // Note that we only execute this when the media server
1325         // process restarts after a crash, not the first time it is started.
1326         AudioSystem.setParameters("restarting=true");
1327 
1328         readAndSetLowRamDevice();
1329 
1330         mIsCallScreeningModeSupported = AudioSystem.isCallScreeningModeSupported();
1331 
1332         // Restore device connection states, BT state
1333         mDeviceBroker.onAudioServerDied();
1334 
1335         // Restore call state
1336         synchronized (mDeviceBroker.mSetModeLock) {
1337             onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(),
1338                     mContext.getPackageName(), true /*force*/);
1339         }
1340         final int forSys;
1341         synchronized (mSettingsLock) {
1342             forSys = mCameraSoundForced ?
1343                     AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE;
1344         }
1345 
1346         mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM, forSys, "onAudioServerDied");
1347 
1348         // Restore stream volumes
1349         onReinitVolumes("after audioserver restart");
1350 
1351         // Restore audio volume groups
1352         restoreVolumeGroups();
1353 
1354         // Restore mono mode
1355         updateMasterMono(mContentResolver);
1356 
1357         // Restore audio balance
1358         updateMasterBalance(mContentResolver);
1359 
1360         // Restore ringer mode
1361         setRingerModeInt(getRingerModeInternal(), false);
1362 
1363         // Reset device rotation (if monitored for this device)
1364         if (mMonitorRotation) {
1365             RotationHelper.updateOrientation();
1366         }
1367 
1368         // Restore setParameters and other queued setters.
1369         mRestorableParameters.restoreAll();
1370 
1371         synchronized (mSettingsLock) {
1372             final int forDock = mDockAudioMediaEnabled ?
1373                     AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE;
1374             mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, forDock, "onAudioServerDied");
1375             sendEncodedSurroundMode(mContentResolver, "onAudioServerDied");
1376             sendEnabledSurroundFormats(mContentResolver, true);
1377             updateAssistantUId(true);
1378             AudioSystem.setRttEnabled(mRttEnabled);
1379         }
1380         synchronized (mHotwordDetectionServiceUidLock) {
1381             AudioSystem.setHotwordDetectionServiceUid(mHotwordDetectionServiceUid);
1382         }
1383         synchronized (mAccessibilityServiceUidsLock) {
1384             AudioSystem.setA11yServicesUids(mAccessibilityServiceUids);
1385         }
1386         synchronized (mInputMethodServiceUidLock) {
1387             mAudioSystem.setCurrentImeUid(mInputMethodServiceUid);
1388         }
1389         synchronized (mHdmiClientLock) {
1390             if (mHdmiManager != null && mHdmiTvClient != null) {
1391                 setHdmiSystemAudioSupported(mHdmiSystemAudioSupported);
1392             }
1393         }
1394 
1395         synchronized (mSupportedSystemUsagesLock) {
1396             AudioSystem.setSupportedSystemUsages(mSupportedSystemUsages);
1397         }
1398 
1399         synchronized (mAudioPolicies) {
1400             for (AudioPolicyProxy policy : mAudioPolicies.values()) {
1401                 final int status = policy.connectMixes();
1402                 if (status != AudioSystem.SUCCESS) {
1403                     // note that PERMISSION_DENIED may also indicate trouble getting to APService
1404                     Log.e(TAG, "onAudioServerDied: error "
1405                             + AudioSystem.audioSystemErrorToString(status)
1406                             + " when connecting mixes for policy " + policy.toLogFriendlyString());
1407                     policy.release();
1408                 } else {
1409                     final int deviceAffinitiesStatus = policy.setupDeviceAffinities();
1410                     if (deviceAffinitiesStatus != AudioSystem.SUCCESS) {
1411                         Log.e(TAG, "onAudioServerDied: error "
1412                                 + AudioSystem.audioSystemErrorToString(deviceAffinitiesStatus)
1413                                 + " when connecting device affinities for policy "
1414                                 + policy.toLogFriendlyString());
1415                         policy.release();
1416                     }
1417                 }
1418             }
1419         }
1420 
1421         // Restore capture policies
1422         synchronized (mPlaybackMonitor) {
1423             HashMap<Integer, Integer> allowedCapturePolicies =
1424                     mPlaybackMonitor.getAllAllowedCapturePolicies();
1425             for (HashMap.Entry<Integer, Integer> entry : allowedCapturePolicies.entrySet()) {
1426                 int result = mAudioSystem.setAllowedCapturePolicy(
1427                         entry.getKey(),
1428                         AudioAttributes.capturePolicyToFlags(entry.getValue(), 0x0));
1429                 if (result != AudioSystem.AUDIO_STATUS_OK) {
1430                     Log.e(TAG, "Failed to restore capture policy, uid: "
1431                             + entry.getKey() + ", capture policy: " + entry.getValue()
1432                             + ", result: " + result);
1433                     // When restoring capture policy failed, set the capture policy as
1434                     // ALLOW_CAPTURE_BY_ALL, which will result in removing the cached
1435                     // capture policy in PlaybackActivityMonitor.
1436                     mPlaybackMonitor.setAllowedCapturePolicy(
1437                             entry.getKey(), AudioAttributes.ALLOW_CAPTURE_BY_ALL);
1438                 }
1439             }
1440         }
1441 
1442         if (mHasSpatializerEffect) {
1443             mSpatializerHelper.reset(/* featureEnabled */ isSpatialAudioEnabled());
1444             monitorRoutingChanges(true);
1445         }
1446 
1447         onIndicateSystemReady();
1448         // indicate the end of reconfiguration phase to audio HAL
1449         AudioSystem.setParameters("restarting=false");
1450 
1451         sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE,
1452                 SENDMSG_QUEUE, 1, 0, null, 0);
1453 
1454         setMicrophoneMuteNoCallerCheck(getCurrentUserId()); // will also update the mic mute cache
1455         setMicMuteFromSwitchInput();
1456 
1457         // Restore vibrator info
1458         updateVibratorInfos();
1459     }
1460 
onReinitVolumes(@onNull String caller)1461     private void onReinitVolumes(@NonNull String caller) {
1462         final int numStreamTypes = AudioSystem.getNumStreamTypes();
1463         // keep track of any error during stream volume initialization
1464         int status = AudioSystem.AUDIO_STATUS_OK;
1465         for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
1466             VolumeStreamState streamState = mStreamStates[streamType];
1467             final int res = AudioSystem.initStreamVolume(
1468                     streamType, streamState.mIndexMin / 10, streamState.mIndexMax / 10);
1469             if (res != AudioSystem.AUDIO_STATUS_OK) {
1470                 status = res;
1471                 Log.e(TAG, "Failed to initStreamVolume (" + res + ") for stream " + streamType);
1472                 // stream volume initialization failed, no need to try the others, it will be
1473                 // attempted again when MSG_REINIT_VOLUMES is handled
1474                 break;
1475             }
1476             streamState.applyAllVolumes();
1477         }
1478 
1479         // did it work? check based on status
1480         if (status != AudioSystem.AUDIO_STATUS_OK) {
1481             sLifecycleLogger.log(new AudioEventLogger.StringEvent(
1482                     caller + ": initStreamVolume failed with " + status + " will retry")
1483                     .printLog(ALOGE, TAG));
1484             sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0,
1485                     caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
1486             return;
1487         }
1488 
1489         // did it work? check based on min/max values of some basic streams
1490         if (!checkVolumeRangeInitialization(caller)) {
1491             return;
1492         }
1493 
1494         // success
1495         sLifecycleLogger.log(new AudioEventLogger.StringEvent(
1496                 caller + ": initStreamVolume succeeded").printLog(ALOGI, TAG));
1497     }
1498 
1499     /**
1500      * Check volume ranges were properly initialized
1501      * @return true if volume ranges were successfully initialized
1502      */
checkVolumeRangeInitialization(String caller)1503     private boolean checkVolumeRangeInitialization(String caller) {
1504         boolean success = true;
1505         final int[] basicStreams = { AudioSystem.STREAM_ALARM, AudioSystem.STREAM_RING,
1506                 AudioSystem.STREAM_MUSIC, AudioSystem.STREAM_VOICE_CALL,
1507                 AudioSystem.STREAM_ACCESSIBILITY };
1508         for (int streamType : basicStreams) {
1509             final AudioAttributes aa = new AudioAttributes.Builder()
1510                     .setInternalLegacyStreamType(streamType).build();
1511             if (AudioSystem.getMaxVolumeIndexForAttributes(aa) < 0
1512                     || AudioSystem.getMinVolumeIndexForAttributes(aa) < 0) {
1513                 success = false;
1514                 break;
1515             }
1516         }
1517         if (!success) {
1518             sLifecycleLogger.log(new AudioEventLogger.StringEvent(
1519                     caller + ": initStreamVolume succeeded but invalid mix/max levels, will retry")
1520                     .printLog(ALOGW, TAG));
1521             sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0,
1522                     caller /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
1523         }
1524         return success;
1525     }
1526 
onDispatchAudioServerStateChange(boolean state)1527     private void onDispatchAudioServerStateChange(boolean state) {
1528         synchronized (mAudioServerStateListeners) {
1529             for (AsdProxy asdp : mAudioServerStateListeners.values()) {
1530                 try {
1531                     asdp.callback().dispatchAudioServerStateChange(state);
1532                 } catch (RemoteException e) {
1533                     Log.w(TAG, "Could not call dispatchAudioServerStateChange()", e);
1534                 }
1535             }
1536         }
1537     }
1538 
createAudioSystemThread()1539     private void createAudioSystemThread() {
1540         mAudioSystemThread = new AudioSystemThread();
1541         mAudioSystemThread.start();
1542         waitForAudioHandlerCreation();
1543     }
1544 
1545     /** Waits for the volume handler to be created by the other thread. */
waitForAudioHandlerCreation()1546     private void waitForAudioHandlerCreation() {
1547         synchronized(this) {
1548             while (mAudioHandler == null) {
1549                 try {
1550                     // Wait for mAudioHandler to be set by the other thread
1551                     wait();
1552                 } catch (InterruptedException e) {
1553                     Log.e(TAG, "Interrupted while waiting on volume handler.");
1554                 }
1555             }
1556         }
1557     }
1558 
1559     /**
1560      * @see AudioManager#setSupportedSystemUsages(int[])
1561      */
setSupportedSystemUsages(@onNull @ttributeSystemUsage int[] systemUsages)1562     public void setSupportedSystemUsages(@NonNull @AttributeSystemUsage int[] systemUsages) {
1563         enforceModifyAudioRoutingPermission();
1564         verifySystemUsages(systemUsages);
1565 
1566         synchronized (mSupportedSystemUsagesLock) {
1567             AudioSystem.setSupportedSystemUsages(systemUsages);
1568             mSupportedSystemUsages = systemUsages;
1569         }
1570     }
1571 
1572     /**
1573      * @see AudioManager#getSupportedSystemUsages()
1574      */
getSupportedSystemUsages()1575     public @NonNull @AttributeSystemUsage int[] getSupportedSystemUsages() {
1576         enforceModifyAudioRoutingPermission();
1577         synchronized (mSupportedSystemUsagesLock) {
1578             return Arrays.copyOf(mSupportedSystemUsages, mSupportedSystemUsages.length);
1579         }
1580     }
1581 
verifySystemUsages(@onNull int[] systemUsages)1582     private void verifySystemUsages(@NonNull int[] systemUsages) {
1583         for (int i = 0; i < systemUsages.length; i++) {
1584             if (!AudioAttributes.isSystemUsage(systemUsages[i])) {
1585                 throw new IllegalArgumentException("Non-system usage provided: " + systemUsages[i]);
1586             }
1587         }
1588     }
1589 
1590     /**
1591      * @return the {@link android.media.audiopolicy.AudioProductStrategy} discovered from the
1592      * platform configuration file.
1593      */
1594     @NonNull
getAudioProductStrategies()1595     public List<AudioProductStrategy> getAudioProductStrategies() {
1596         // verify permissions
1597         enforceModifyAudioRoutingPermission();
1598         return AudioProductStrategy.getAudioProductStrategies();
1599     }
1600 
1601     /**
1602      * @return the List of {@link android.media.audiopolicy.AudioVolumeGroup} discovered from the
1603      * platform configuration file.
1604      */
1605     @NonNull
getAudioVolumeGroups()1606     public List<AudioVolumeGroup> getAudioVolumeGroups() {
1607         // verify permissions
1608         enforceModifyAudioRoutingPermission();
1609         return AudioVolumeGroup.getAudioVolumeGroups();
1610     }
1611 
checkAllAliasStreamVolumes()1612     private void checkAllAliasStreamVolumes() {
1613         synchronized (mSettingsLock) {
1614             synchronized (VolumeStreamState.class) {
1615                 int numStreamTypes = AudioSystem.getNumStreamTypes();
1616                 for (int streamType = 0; streamType < numStreamTypes; streamType++) {
1617                     mStreamStates[streamType]
1618                             .setAllIndexes(mStreamStates[mStreamVolumeAlias[streamType]], TAG);
1619                     // apply stream volume
1620                     if (!mStreamStates[streamType].mIsMuted) {
1621                         mStreamStates[streamType].applyAllVolumes();
1622                     }
1623                 }
1624             }
1625         }
1626     }
1627 
1628 
1629     /**
1630      * Called from AudioDeviceBroker when DEVICE_OUT_HDMI is connected or disconnected.
1631      */
postCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)1632     /*package*/ void postCheckVolumeCecOnHdmiConnection(
1633             @AudioService.ConnectionState  int state, String caller) {
1634         sendMsg(mAudioHandler, MSG_HDMI_VOLUME_CHECK, SENDMSG_REPLACE,
1635                 state /*arg1*/, 0 /*arg2 ignored*/, caller /*obj*/, 0 /*delay*/);
1636     }
1637 
onCheckVolumeCecOnHdmiConnection( @udioService.ConnectionState int state, String caller)1638     private void onCheckVolumeCecOnHdmiConnection(
1639             @AudioService.ConnectionState int state, String caller) {
1640         if (state == AudioService.CONNECTION_STATE_CONNECTED) {
1641             // DEVICE_OUT_HDMI is now connected
1642             if (mSafeMediaVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI)) {
1643                 sendMsg(mAudioHandler,
1644                         MSG_CHECK_MUSIC_ACTIVE,
1645                         SENDMSG_REPLACE,
1646                         0,
1647                         0,
1648                         caller,
1649                         MUSIC_ACTIVE_POLL_PERIOD_MS);
1650             }
1651 
1652             if (isPlatformTelevision()) {
1653                 synchronized (mHdmiClientLock) {
1654                     if (mHdmiManager != null && mHdmiPlaybackClient != null) {
1655                         updateHdmiCecSinkLocked(
1656                                 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI));
1657                     }
1658                 }
1659             }
1660             sendEnabledSurroundFormats(mContentResolver, true);
1661         } else {
1662             // DEVICE_OUT_HDMI disconnected
1663             if (isPlatformTelevision()) {
1664                 synchronized (mHdmiClientLock) {
1665                     if (mHdmiManager != null) {
1666                         updateHdmiCecSinkLocked(
1667                                 mFullVolumeDevices.contains(AudioSystem.DEVICE_OUT_HDMI));
1668                     }
1669                 }
1670             }
1671         }
1672     }
1673 
1674     /**
1675      * Asynchronously update volume states for the given device.
1676      *
1677      * @param device a single audio device, ensure that this is not a devices bitmask
1678      * @param caller caller of this method
1679      */
postUpdateVolumeStatesForAudioDevice(int device, String caller)1680     private void postUpdateVolumeStatesForAudioDevice(int device, String caller) {
1681         sendMsg(mAudioHandler,
1682                 MSG_UPDATE_VOLUME_STATES_FOR_DEVICE,
1683                 SENDMSG_QUEUE, device /*arg1*/, 0 /*arg2*/, caller /*obj*/,
1684                 0 /*delay*/);
1685     }
1686 
1687     /**
1688      * Update volume states for the given device.
1689      *
1690      * This will initialize the volume index if no volume index is available.
1691      * If the device is the currently routed device, fixed/full volume policies will be applied.
1692      *
1693      * @param device a single audio device, ensure that this is not a devices bitmask
1694      * @param caller caller of this method
1695      */
onUpdateVolumeStatesForAudioDevice(int device, String caller)1696     private void onUpdateVolumeStatesForAudioDevice(int device, String caller) {
1697         final int numStreamTypes = AudioSystem.getNumStreamTypes();
1698         synchronized (mSettingsLock) {
1699             synchronized (VolumeStreamState.class) {
1700                 for (int streamType = 0; streamType < numStreamTypes; streamType++) {
1701                     updateVolumeStates(device, streamType, caller);
1702                 }
1703             }
1704         }
1705     }
1706 
1707     /**
1708      * Update volume states for the given device and given stream.
1709      *
1710      * This will initialize the volume index if no volume index is available.
1711      * If the device is the currently routed device, fixed/full volume policies will be applied.
1712      *
1713      * @param device a single audio device, ensure that this is not a devices bitmask
1714      * @param streamType streamType to be updated
1715      * @param caller caller of this method
1716      */
updateVolumeStates(int device, int streamType, String caller)1717     private void updateVolumeStates(int device, int streamType, String caller) {
1718         if (!mStreamStates[streamType].hasIndexForDevice(device)) {
1719             // set the default value, if device is affected by a full/fix/abs volume rule, it
1720             // will taken into account in checkFixedVolumeDevices()
1721             mStreamStates[streamType].setIndex(
1722                     mStreamStates[mStreamVolumeAlias[streamType]]
1723                             .getIndex(AudioSystem.DEVICE_OUT_DEFAULT),
1724                     device, caller, true /*hasModifyAudioSettings*/);
1725         }
1726 
1727         // Check if device to be updated is routed for the given audio stream
1728         List<AudioDeviceAttributes> devicesForAttributes = getDevicesForAttributesInt(
1729                 new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build());
1730         for (AudioDeviceAttributes deviceAttributes : devicesForAttributes) {
1731             if (deviceAttributes.getType() == AudioDeviceInfo.convertInternalDeviceToDeviceType(
1732                     device)) {
1733                 mStreamStates[streamType].checkFixedVolumeDevices();
1734 
1735                 // Unmute streams if required and device is full volume
1736                 if (isStreamMute(streamType) && mFullVolumeDevices.contains(device)) {
1737                     mStreamStates[streamType].mute(false);
1738                 }
1739             }
1740         }
1741     }
1742 
checkAllFixedVolumeDevices()1743     private void checkAllFixedVolumeDevices()
1744     {
1745         int numStreamTypes = AudioSystem.getNumStreamTypes();
1746         for (int streamType = 0; streamType < numStreamTypes; streamType++) {
1747             mStreamStates[streamType].checkFixedVolumeDevices();
1748         }
1749     }
1750 
checkAllFixedVolumeDevices(int streamType)1751     private void checkAllFixedVolumeDevices(int streamType) {
1752         mStreamStates[streamType].checkFixedVolumeDevices();
1753     }
1754 
checkMuteAffectedStreams()1755     private void checkMuteAffectedStreams() {
1756         // any stream with a min level > 0 is not muteable by definition
1757         // STREAM_VOICE_CALL and STREAM_BLUETOOTH_SCO can be muted by applications
1758         // that has the the MODIFY_PHONE_STATE permission.
1759         for (int i = 0; i < mStreamStates.length; i++) {
1760             final VolumeStreamState vss = mStreamStates[i];
1761             if (vss.mIndexMin > 0 &&
1762                 (vss.mStreamType != AudioSystem.STREAM_VOICE_CALL &&
1763                 vss.mStreamType != AudioSystem.STREAM_BLUETOOTH_SCO)) {
1764                 mMuteAffectedStreams &= ~(1 << vss.mStreamType);
1765             }
1766         }
1767     }
1768 
createStreamStates()1769     private void createStreamStates() {
1770         int numStreamTypes = AudioSystem.getNumStreamTypes();
1771         VolumeStreamState[] streams = mStreamStates = new VolumeStreamState[numStreamTypes];
1772 
1773         for (int i = 0; i < numStreamTypes; i++) {
1774             streams[i] =
1775                     new VolumeStreamState(System.VOLUME_SETTINGS_INT[mStreamVolumeAlias[i]], i);
1776         }
1777 
1778         checkAllFixedVolumeDevices();
1779         checkAllAliasStreamVolumes();
1780         checkMuteAffectedStreams();
1781         updateDefaultVolumes();
1782     }
1783 
1784     /**
1785      * Update default indexes from aliased streams. Must be called after mStreamStates is created
1786      * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for default
1787      * index. Need to make default index configurable and independent of streams.
1788      * Fallback on music stream for default initialization to take benefit of property based default
1789      * initialization.
1790      * For other volume groups not linked to any streams, default music stream index is considered.
1791      */
updateDefaultVolumes()1792     private void updateDefaultVolumes() {
1793         for (int stream = 0; stream < mStreamStates.length; stream++) {
1794             int streamVolumeAlias = mStreamVolumeAlias[stream];
1795             if (mUseVolumeGroupAliases) {
1796                 if (AudioSystem.DEFAULT_STREAM_VOLUME[stream] != UNSET_INDEX) {
1797                     // Already initialized through default property based mecanism.
1798                     continue;
1799                 }
1800                 streamVolumeAlias = AudioSystem.STREAM_MUSIC;
1801                 int defaultAliasVolume = getUiDefaultRescaledIndex(streamVolumeAlias, stream);
1802                 if ((defaultAliasVolume >= MIN_STREAM_VOLUME[stream])
1803                         && (defaultAliasVolume <= MAX_STREAM_VOLUME[stream])) {
1804                     AudioSystem.DEFAULT_STREAM_VOLUME[stream] = defaultAliasVolume;
1805                     continue;
1806                 }
1807             }
1808             if (stream != streamVolumeAlias) {
1809                 AudioSystem.DEFAULT_STREAM_VOLUME[stream] =
1810                         getUiDefaultRescaledIndex(streamVolumeAlias, stream);
1811             }
1812         }
1813     }
1814 
getUiDefaultRescaledIndex(int srcStream, int dstStream)1815     private int getUiDefaultRescaledIndex(int srcStream, int dstStream) {
1816         return (rescaleIndex(AudioSystem.DEFAULT_STREAM_VOLUME[srcStream] * 10,
1817                 srcStream, dstStream) + 5) / 10;
1818     }
1819 
dumpStreamStates(PrintWriter pw)1820     private void dumpStreamStates(PrintWriter pw) {
1821         pw.println("\nStream volumes (device: index)");
1822         int numStreamTypes = AudioSystem.getNumStreamTypes();
1823         for (int i = 0; i < numStreamTypes; i++) {
1824             pw.println("- " + AudioSystem.STREAM_NAMES[i] + ":");
1825             mStreamStates[i].dump(pw);
1826             pw.println("");
1827         }
1828         pw.print("\n- mute affected streams = 0x");
1829         pw.println(Integer.toHexString(mMuteAffectedStreams));
1830     }
1831 
updateStreamVolumeAlias(boolean updateVolumes, String caller)1832     private void updateStreamVolumeAlias(boolean updateVolumes, String caller) {
1833         int dtmfStreamAlias;
1834         final int a11yStreamAlias = sIndependentA11yVolume ?
1835                 AudioSystem.STREAM_ACCESSIBILITY : AudioSystem.STREAM_MUSIC;
1836         final int assistantStreamAlias = mContext.getResources().getBoolean(
1837                 com.android.internal.R.bool.config_useAssistantVolume) ?
1838                 AudioSystem.STREAM_ASSISTANT : AudioSystem.STREAM_MUSIC;
1839 
1840         if (mIsSingleVolume) {
1841             mStreamVolumeAlias = STREAM_VOLUME_ALIAS_TELEVISION;
1842             dtmfStreamAlias = AudioSystem.STREAM_MUSIC;
1843         } else if (mUseVolumeGroupAliases) {
1844             mStreamVolumeAlias = STREAM_VOLUME_ALIAS_NONE;
1845             dtmfStreamAlias = AudioSystem.STREAM_DTMF;
1846         } else {
1847             switch (mPlatformType) {
1848                 case AudioSystem.PLATFORM_VOICE:
1849                     mStreamVolumeAlias = STREAM_VOLUME_ALIAS_VOICE;
1850                     dtmfStreamAlias = AudioSystem.STREAM_RING;
1851                     break;
1852                 default:
1853                     mStreamVolumeAlias = STREAM_VOLUME_ALIAS_DEFAULT;
1854                     dtmfStreamAlias = AudioSystem.STREAM_MUSIC;
1855             }
1856         }
1857 
1858         if (mIsSingleVolume) {
1859             mRingerModeAffectedStreams = 0;
1860         } else {
1861             if (isInCommunication()) {
1862                 dtmfStreamAlias = AudioSystem.STREAM_VOICE_CALL;
1863                 mRingerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF);
1864             } else {
1865                 mRingerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF);
1866             }
1867         }
1868 
1869         mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias;
1870         mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY] = a11yStreamAlias;
1871         mStreamVolumeAlias[AudioSystem.STREAM_ASSISTANT] = assistantStreamAlias;
1872 
1873         if (updateVolumes && mStreamStates != null) {
1874             updateDefaultVolumes();
1875 
1876             synchronized (mSettingsLock) {
1877                 synchronized (VolumeStreamState.class) {
1878                     mStreamStates[AudioSystem.STREAM_DTMF]
1879                             .setAllIndexes(mStreamStates[dtmfStreamAlias], caller);
1880                     mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].mVolumeIndexSettingName =
1881                             System.VOLUME_SETTINGS_INT[a11yStreamAlias];
1882                     mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setAllIndexes(
1883                             mStreamStates[a11yStreamAlias], caller);
1884                 }
1885             }
1886             if (sIndependentA11yVolume) {
1887                 // restore the a11y values from the settings
1888                 mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].readSettings();
1889             }
1890 
1891             // apply stream mute states according to new value of mRingerModeAffectedStreams
1892             setRingerModeInt(getRingerModeInternal(), false);
1893             sendMsg(mAudioHandler,
1894                     MSG_SET_ALL_VOLUMES,
1895                     SENDMSG_QUEUE,
1896                     0,
1897                     0,
1898                     mStreamStates[AudioSystem.STREAM_DTMF], 0);
1899             sendMsg(mAudioHandler,
1900                     MSG_SET_ALL_VOLUMES,
1901                     SENDMSG_QUEUE,
1902                     0,
1903                     0,
1904                     mStreamStates[AudioSystem.STREAM_ACCESSIBILITY], 0);
1905         }
1906     }
1907 
readDockAudioSettings(ContentResolver cr)1908     private void readDockAudioSettings(ContentResolver cr)
1909     {
1910         mDockAudioMediaEnabled = Settings.Global.getInt(
1911                                         cr, Settings.Global.DOCK_AUDIO_MEDIA_ENABLED, 0) == 1;
1912 
1913         sendMsg(mAudioHandler,
1914                 MSG_SET_FORCE_USE,
1915                 SENDMSG_QUEUE,
1916                 AudioSystem.FOR_DOCK,
1917                 mDockAudioMediaEnabled ?
1918                         AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE,
1919                 new String("readDockAudioSettings"),
1920                 0);
1921     }
1922 
1923 
updateMasterMono(ContentResolver cr)1924     private void updateMasterMono(ContentResolver cr)
1925     {
1926         final boolean masterMono = System.getIntForUser(
1927                 cr, System.MASTER_MONO, 0 /* default */, UserHandle.USER_CURRENT) == 1;
1928         if (DEBUG_VOL) {
1929             Log.d(TAG, String.format("Master mono %b", masterMono));
1930         }
1931         AudioSystem.setMasterMono(masterMono);
1932     }
1933 
updateMasterBalance(ContentResolver cr)1934     private void updateMasterBalance(ContentResolver cr) {
1935         final float masterBalance = System.getFloatForUser(
1936                 cr, System.MASTER_BALANCE, 0.f /* default */, UserHandle.USER_CURRENT);
1937         if (DEBUG_VOL) {
1938             Log.d(TAG, String.format("Master balance %f", masterBalance));
1939         }
1940         if (AudioSystem.setMasterBalance(masterBalance) != 0) {
1941             Log.e(TAG, String.format("setMasterBalance failed for %f", masterBalance));
1942         }
1943     }
1944 
sendEncodedSurroundMode(ContentResolver cr, String eventSource)1945     private void sendEncodedSurroundMode(ContentResolver cr, String eventSource)
1946     {
1947         final int encodedSurroundMode = Settings.Global.getInt(
1948                 cr, Settings.Global.ENCODED_SURROUND_OUTPUT,
1949                 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
1950         sendEncodedSurroundMode(encodedSurroundMode, eventSource);
1951     }
1952 
sendEncodedSurroundMode(int encodedSurroundMode, String eventSource)1953     private void sendEncodedSurroundMode(int encodedSurroundMode, String eventSource)
1954     {
1955         // initialize to guaranteed bad value
1956         int forceSetting = AudioSystem.NUM_FORCE_CONFIG;
1957         switch (encodedSurroundMode) {
1958             case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO:
1959                 forceSetting = AudioSystem.FORCE_NONE;
1960                 break;
1961             case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER:
1962                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_NEVER;
1963                 break;
1964             case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS:
1965                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_ALWAYS;
1966                 break;
1967             case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL:
1968                 forceSetting = AudioSystem.FORCE_ENCODED_SURROUND_MANUAL;
1969                 break;
1970             default:
1971                 Log.e(TAG, "updateSurroundSoundSettings: illegal value "
1972                         + encodedSurroundMode);
1973                 break;
1974         }
1975         if (forceSetting != AudioSystem.NUM_FORCE_CONFIG) {
1976             mDeviceBroker.setForceUse_Async(AudioSystem.FOR_ENCODED_SURROUND, forceSetting,
1977                     eventSource);
1978         }
1979     }
1980 
1981     /** @see AudioManager#getSurroundFormats() */
1982     @Override
getSurroundFormats()1983     public Map<Integer, Boolean> getSurroundFormats() {
1984         Map<Integer, Boolean> surroundFormats = new HashMap<>();
1985         int status = AudioSystem.getSurroundFormats(surroundFormats);
1986         if (status != AudioManager.SUCCESS) {
1987             // fail and bail!
1988             Log.e(TAG, "getSurroundFormats failed:" + status);
1989             return new HashMap<>(); // Always return a map.
1990         }
1991         return surroundFormats;
1992     }
1993 
1994     /** @see AudioManager#getReportedSurroundFormats() */
1995     @Override
getReportedSurroundFormats()1996     public List<Integer> getReportedSurroundFormats() {
1997         ArrayList<Integer> reportedSurroundFormats = new ArrayList<>();
1998         int status = AudioSystem.getReportedSurroundFormats(reportedSurroundFormats);
1999         if (status != AudioManager.SUCCESS) {
2000             // fail and bail!
2001             Log.e(TAG, "getReportedSurroundFormats failed:" + status);
2002             return new ArrayList<>(); // Always return a list.
2003         }
2004         return reportedSurroundFormats;
2005     }
2006 
2007     /** @see AudioManager#isSurroundFormatEnabled(int) */
2008     @Override
isSurroundFormatEnabled(int audioFormat)2009     public boolean isSurroundFormatEnabled(int audioFormat) {
2010         if (!isSurroundFormat(audioFormat)) {
2011             Log.w(TAG, "audioFormat to enable is not a surround format.");
2012             return false;
2013         }
2014         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS)
2015                 != PackageManager.PERMISSION_GRANTED) {
2016             throw new SecurityException("Missing WRITE_SETTINGS permission");
2017         }
2018 
2019         final long token = Binder.clearCallingIdentity();
2020         try {
2021             synchronized (mSettingsLock) {
2022                 HashSet<Integer> enabledFormats = getEnabledFormats();
2023                 return enabledFormats.contains(audioFormat);
2024             }
2025         } finally {
2026             Binder.restoreCallingIdentity(token);
2027         }
2028     }
2029 
2030     /** @see AudioManager#setSurroundFormatEnabled(int, boolean) */
2031     @Override
setSurroundFormatEnabled(int audioFormat, boolean enabled)2032     public boolean setSurroundFormatEnabled(int audioFormat, boolean enabled) {
2033         if (!isSurroundFormat(audioFormat)) {
2034             Log.w(TAG, "audioFormat to enable is not a surround format.");
2035             return false;
2036         }
2037         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS)
2038                 != PackageManager.PERMISSION_GRANTED) {
2039             throw new SecurityException("Missing WRITE_SETTINGS permission");
2040         }
2041 
2042         HashSet<Integer> enabledFormats = getEnabledFormats();
2043         if (enabled) {
2044             enabledFormats.add(audioFormat);
2045         } else {
2046             enabledFormats.remove(audioFormat);
2047         }
2048         final long token = Binder.clearCallingIdentity();
2049         try {
2050             synchronized (mSettingsLock) {
2051                 Settings.Global.putString(mContentResolver,
2052                         Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
2053                         TextUtils.join(",", enabledFormats));
2054             }
2055         } finally {
2056             Binder.restoreCallingIdentity(token);
2057         }
2058         return true;
2059     }
2060 
2061     /** @see AudioManager#setEncodedSurroundMode(int) */
2062     @Override
setEncodedSurroundMode(@udioManager.EncodedSurroundOutputMode int mode)2063     public boolean setEncodedSurroundMode(@AudioManager.EncodedSurroundOutputMode int mode) {
2064         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS)
2065                 != PackageManager.PERMISSION_GRANTED) {
2066             throw new SecurityException("Missing WRITE_SETTINGS permission");
2067         }
2068 
2069         final long token = Binder.clearCallingIdentity();
2070         try {
2071             synchronized (mSettingsLock) {
2072                 Settings.Global.putInt(mContentResolver,
2073                         Settings.Global.ENCODED_SURROUND_OUTPUT,
2074                         toEncodedSurroundSetting(mode));
2075             }
2076         } finally {
2077             Binder.restoreCallingIdentity(token);
2078         }
2079         return true;
2080     }
2081 
2082     /** @see AudioManager#getEncodedSurroundMode() */
2083     @Override
getEncodedSurroundMode(int targetSdkVersion)2084     public int getEncodedSurroundMode(int targetSdkVersion) {
2085         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS)
2086                 != PackageManager.PERMISSION_GRANTED) {
2087             throw new SecurityException("Missing WRITE_SETTINGS permission");
2088         }
2089 
2090         final long token = Binder.clearCallingIdentity();
2091         try {
2092             synchronized (mSettingsLock) {
2093                 int encodedSurroundSetting = Settings.Global.getInt(mContentResolver,
2094                         Settings.Global.ENCODED_SURROUND_OUTPUT,
2095                         AudioManager.ENCODED_SURROUND_OUTPUT_AUTO);
2096                 return toEncodedSurroundOutputMode(encodedSurroundSetting, targetSdkVersion);
2097             }
2098         } finally {
2099             Binder.restoreCallingIdentity(token);
2100         }
2101     }
2102 
2103     /** @return the formats that are enabled in global settings */
getEnabledFormats()2104     private HashSet<Integer> getEnabledFormats() {
2105         HashSet<Integer> formats = new HashSet<>();
2106         String enabledFormats = Settings.Global.getString(mContentResolver,
2107                 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
2108         if (enabledFormats != null) {
2109             try {
2110                 Arrays.stream(TextUtils.split(enabledFormats, ","))
2111                         .mapToInt(Integer::parseInt)
2112                         .forEach(formats::add);
2113             } catch (NumberFormatException e) {
2114                 Log.w(TAG, "ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS misformatted.", e);
2115             }
2116         }
2117         return formats;
2118     }
2119 
2120     @SuppressWarnings("AndroidFrameworkCompatChange")
2121     @AudioManager.EncodedSurroundOutputMode
toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion)2122     private int toEncodedSurroundOutputMode(int encodedSurroundSetting, int targetSdkVersion) {
2123         if (targetSdkVersion <= Build.VERSION_CODES.S
2124                 && encodedSurroundSetting > Settings.Global.ENCODED_SURROUND_SC_MAX) {
2125             return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN;
2126         }
2127         switch (encodedSurroundSetting) {
2128             case Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO:
2129                 return AudioManager.ENCODED_SURROUND_OUTPUT_AUTO;
2130             case Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER:
2131                 return AudioManager.ENCODED_SURROUND_OUTPUT_NEVER;
2132             case Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS:
2133                 return AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS;
2134             case Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL:
2135                 return AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL;
2136             default:
2137                 return AudioManager.ENCODED_SURROUND_OUTPUT_UNKNOWN;
2138         }
2139     }
2140 
toEncodedSurroundSetting( @udioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode)2141     private int toEncodedSurroundSetting(
2142             @AudioManager.EncodedSurroundOutputMode int encodedSurroundOutputMode) {
2143         switch (encodedSurroundOutputMode) {
2144             case AudioManager.ENCODED_SURROUND_OUTPUT_NEVER:
2145                 return Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER;
2146             case AudioManager.ENCODED_SURROUND_OUTPUT_ALWAYS:
2147                 return Settings.Global.ENCODED_SURROUND_OUTPUT_ALWAYS;
2148             case AudioManager.ENCODED_SURROUND_OUTPUT_MANUAL:
2149                 return Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL;
2150             default:
2151                 return Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO;
2152         }
2153     }
2154 
isSurroundFormat(int audioFormat)2155     private boolean isSurroundFormat(int audioFormat) {
2156         for (int sf : AudioFormat.SURROUND_SOUND_ENCODING) {
2157             if (sf == audioFormat) {
2158                 return true;
2159             }
2160         }
2161         return false;
2162     }
2163 
sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate)2164     private void sendEnabledSurroundFormats(ContentResolver cr, boolean forceUpdate) {
2165         if (mEncodedSurroundMode != Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL) {
2166             // Manually enable surround formats only when the setting is in manual mode.
2167             return;
2168         }
2169         String enabledSurroundFormats = Settings.Global.getString(
2170                 cr, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
2171         if (enabledSurroundFormats == null) {
2172             // Never allow enabledSurroundFormats as a null, which could happen when
2173             // ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS is not appear in settings DB.
2174             enabledSurroundFormats = "";
2175         }
2176         if (!forceUpdate && TextUtils.equals(enabledSurroundFormats, mEnabledSurroundFormats)) {
2177             // Update enabled surround formats to AudioPolicyManager only when forceUpdate
2178             // is true or enabled surround formats changed.
2179             return;
2180         }
2181 
2182         mEnabledSurroundFormats = enabledSurroundFormats;
2183         String[] surroundFormats = TextUtils.split(enabledSurroundFormats, ",");
2184         ArrayList<Integer> formats = new ArrayList<>();
2185         for (String format : surroundFormats) {
2186             try {
2187                 int audioFormat = Integer.valueOf(format);
2188                 if (isSurroundFormat(audioFormat) && !formats.contains(audioFormat)) {
2189                     formats.add(audioFormat);
2190                 }
2191             } catch (Exception e) {
2192                 Log.e(TAG, "Invalid enabled surround format:" + format);
2193             }
2194         }
2195         // Set filtered surround formats to settings DB in case
2196         // there are invalid surround formats in original settings.
2197         Settings.Global.putString(mContext.getContentResolver(),
2198                 Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS,
2199                 TextUtils.join(",", formats));
2200         sendMsg(mAudioHandler, MSG_ENABLE_SURROUND_FORMATS, SENDMSG_QUEUE, 0, 0, formats, 0);
2201     }
2202 
onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats)2203     private void onEnableSurroundFormats(ArrayList<Integer> enabledSurroundFormats) {
2204         // Set surround format enabled accordingly.
2205         for (int surroundFormat : AudioFormat.SURROUND_SOUND_ENCODING) {
2206             boolean enabled = enabledSurroundFormats.contains(surroundFormat);
2207             int ret = AudioSystem.setSurroundFormatEnabled(surroundFormat, enabled);
2208             Log.i(TAG, "enable surround format:" + surroundFormat + " " + enabled + " " + ret);
2209         }
2210     }
2211 
2212     @GuardedBy("mSettingsLock")
updateAssistantUId(boolean forceUpdate)2213     private void updateAssistantUId(boolean forceUpdate) {
2214         int assistantUid = 0;
2215 
2216         // Consider assistants in the following order of priority:
2217         // 1) apk in assistant role
2218         // 2) voice interaction service
2219         // 3) assistant service
2220 
2221         String packageName = "";
2222         if (mRoleObserver != null) {
2223             packageName = mRoleObserver.getAssistantRoleHolder();
2224         }
2225         if (TextUtils.isEmpty(packageName)) {
2226             String assistantName = Settings.Secure.getStringForUser(
2227                             mContentResolver,
2228                             Settings.Secure.VOICE_INTERACTION_SERVICE, UserHandle.USER_CURRENT);
2229             if (TextUtils.isEmpty(assistantName)) {
2230                 assistantName = Settings.Secure.getStringForUser(
2231                         mContentResolver,
2232                         Settings.Secure.ASSISTANT, UserHandle.USER_CURRENT);
2233             }
2234             if (!TextUtils.isEmpty(assistantName)) {
2235                 ComponentName componentName = ComponentName.unflattenFromString(assistantName);
2236                 if (componentName == null) {
2237                     Slog.w(TAG, "Invalid service name for "
2238                             + Settings.Secure.VOICE_INTERACTION_SERVICE + ": " + assistantName);
2239                     return;
2240                 }
2241                 packageName = componentName.getPackageName();
2242             }
2243         }
2244         if (!TextUtils.isEmpty(packageName)) {
2245             PackageManager pm = mContext.getPackageManager();
2246             ActivityManager am =
2247                           (ActivityManager) mContext.getSystemService(mContext.ACTIVITY_SERVICE);
2248 
2249             if (pm.checkPermission(Manifest.permission.CAPTURE_AUDIO_HOTWORD, packageName)
2250                     == PackageManager.PERMISSION_GRANTED) {
2251                 try {
2252                     assistantUid = pm.getPackageUidAsUser(packageName, am.getCurrentUser());
2253                 } catch (PackageManager.NameNotFoundException e) {
2254                     Log.e(TAG,
2255                             "updateAssistantUId() could not find UID for package: " + packageName);
2256                 }
2257             }
2258         }
2259 
2260         if (assistantUid != mAssistantUid || forceUpdate) {
2261             AudioSystem.setAssistantUid(assistantUid);
2262             mAssistantUid = assistantUid;
2263         }
2264     }
2265 
readPersistedSettings()2266     private void readPersistedSettings() {
2267         if (!mSystemServer.isPrivileged()) {
2268             return;
2269         }
2270         final ContentResolver cr = mContentResolver;
2271 
2272         int ringerModeFromSettings =
2273                 Settings.Global.getInt(
2274                         cr, Settings.Global.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
2275         int ringerMode = ringerModeFromSettings;
2276         // validity check in case the settings are restored from a device with incompatible
2277         // ringer modes
2278         if (!isValidRingerMode(ringerMode)) {
2279             ringerMode = AudioManager.RINGER_MODE_NORMAL;
2280         }
2281         if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) {
2282             ringerMode = AudioManager.RINGER_MODE_SILENT;
2283         }
2284         if (ringerMode != ringerModeFromSettings) {
2285             Settings.Global.putInt(cr, Settings.Global.MODE_RINGER, ringerMode);
2286         }
2287         if (mUseFixedVolume || mIsSingleVolume) {
2288             ringerMode = AudioManager.RINGER_MODE_NORMAL;
2289         }
2290         synchronized(mSettingsLock) {
2291             mRingerMode = ringerMode;
2292             if (mRingerModeExternal == -1) {
2293                 mRingerModeExternal = mRingerMode;
2294             }
2295 
2296             // System.VIBRATE_ON is not used any more but defaults for mVibrateSetting
2297             // are still needed while setVibrateSetting() and getVibrateSetting() are being
2298             // deprecated.
2299             mVibrateSetting = AudioSystem.getValueForVibrateSetting(0,
2300                                             AudioManager.VIBRATE_TYPE_NOTIFICATION,
2301                                             mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT
2302                                                             : AudioManager.VIBRATE_SETTING_OFF);
2303             mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting,
2304                                             AudioManager.VIBRATE_TYPE_RINGER,
2305                                             mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT
2306                                                             : AudioManager.VIBRATE_SETTING_OFF);
2307 
2308             updateRingerAndZenModeAffectedStreams();
2309             readDockAudioSettings(cr);
2310             sendEncodedSurroundMode(cr, "readPersistedSettings");
2311             sendEnabledSurroundFormats(cr, true);
2312             updateAssistantUId(true);
2313             AudioSystem.setRttEnabled(mRttEnabled);
2314         }
2315 
2316         mMuteAffectedStreams = System.getIntForUser(cr,
2317                 System.MUTE_STREAMS_AFFECTED, AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED,
2318                 UserHandle.USER_CURRENT);
2319 
2320         updateMasterMono(cr);
2321 
2322         updateMasterBalance(cr);
2323 
2324         // Each stream will read its own persisted settings
2325 
2326         // Broadcast the sticky intents
2327         broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, mRingerModeExternal);
2328         broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, mRingerMode);
2329 
2330         // Broadcast vibrate settings
2331         broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
2332         broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION);
2333 
2334         // Load settings for the volume controller
2335         mVolumeController.loadSettings(cr);
2336     }
2337 
readUserRestrictions()2338     private void readUserRestrictions() {
2339         if (!mSystemServer.isPrivileged()) {
2340             return;
2341         }
2342         final int currentUser = getCurrentUserId();
2343 
2344         // Check the current user restriction.
2345         boolean masterMute =
2346                 mUserManagerInternal.getUserRestriction(currentUser,
2347                         UserManager.DISALLOW_UNMUTE_DEVICE)
2348                         || mUserManagerInternal.getUserRestriction(currentUser,
2349                         UserManager.DISALLOW_ADJUST_VOLUME);
2350         if (mUseFixedVolume) {
2351             masterMute = false;
2352             AudioSystem.setMasterVolume(1.0f);
2353         }
2354         if (DEBUG_VOL) {
2355             Log.d(TAG, String.format("Master mute %s, user=%d", masterMute, currentUser));
2356         }
2357         setSystemAudioMute(masterMute);
2358         AudioSystem.setMasterMute(masterMute);
2359         broadcastMasterMuteStatus(masterMute);
2360 
2361         mMicMuteFromRestrictions = mUserManagerInternal.getUserRestriction(
2362                 currentUser, UserManager.DISALLOW_UNMUTE_MICROPHONE);
2363         if (DEBUG_VOL) {
2364             Log.d(TAG, String.format("Mic mute %b, user=%d", mMicMuteFromRestrictions,
2365                     currentUser));
2366         }
2367         setMicrophoneMuteNoCallerCheck(currentUser);
2368     }
2369 
getIndexRange(int streamType)2370     private int getIndexRange(int streamType) {
2371         return (mStreamStates[streamType].getMaxIndex() - mStreamStates[streamType].getMinIndex());
2372     }
2373 
rescaleIndex(int index, int srcStream, int dstStream)2374     private int rescaleIndex(int index, int srcStream, int dstStream) {
2375         int srcRange = getIndexRange(srcStream);
2376         int dstRange = getIndexRange(dstStream);
2377         if (srcRange == 0) {
2378             Log.e(TAG, "rescaleIndex : index range should not be zero");
2379             return mStreamStates[dstStream].getMinIndex();
2380         }
2381 
2382         return mStreamStates[dstStream].getMinIndex()
2383                 + ((index - mStreamStates[srcStream].getMinIndex()) * dstRange + srcRange / 2)
2384                 / srcRange;
2385     }
2386 
rescaleStep(int step, int srcStream, int dstStream)2387     private int rescaleStep(int step, int srcStream, int dstStream) {
2388         int srcRange = getIndexRange(srcStream);
2389         int dstRange = getIndexRange(dstStream);
2390         if (srcRange == 0) {
2391             Log.e(TAG, "rescaleStep : index range should not be zero");
2392             return 0;
2393         }
2394 
2395         return ((step * dstRange + srcRange / 2) / srcRange);
2396     }
2397 
2398     ///////////////////////////////////////////////////////////////////////////
2399     // IPC methods
2400     ///////////////////////////////////////////////////////////////////////////
2401     /**
2402      * @see AudioManager#setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes)
2403      * @see AudioManager#setPreferredDevicesForStrategy(AudioProductStrategy,
2404      *                                                  List<AudioDeviceAttributes>)
2405      */
setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices)2406     public int setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices) {
2407         if (devices == null) {
2408             return AudioSystem.ERROR;
2409         }
2410         enforceModifyAudioRoutingPermission();
2411         final String logString = String.format(
2412                 "setPreferredDeviceForStrategy u/pid:%d/%d strat:%d dev:%s",
2413                 Binder.getCallingUid(), Binder.getCallingPid(), strategy,
2414                 devices.stream().map(e -> e.toString()).collect(Collectors.joining(",")));
2415         sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG));
2416         if (devices.stream().anyMatch(device ->
2417                 device.getRole() == AudioDeviceAttributes.ROLE_INPUT)) {
2418             Log.e(TAG, "Unsupported input routing in " + logString);
2419             return AudioSystem.ERROR;
2420         }
2421 
2422         final int status = mDeviceBroker.setPreferredDevicesForStrategySync(strategy, devices);
2423         if (status != AudioSystem.SUCCESS) {
2424             Log.e(TAG, String.format("Error %d in %s)", status, logString));
2425         }
2426 
2427         return status;
2428     }
2429 
2430     /** @see AudioManager#removePreferredDeviceForStrategy(AudioProductStrategy) */
removePreferredDevicesForStrategy(int strategy)2431     public int removePreferredDevicesForStrategy(int strategy) {
2432         enforceModifyAudioRoutingPermission();
2433         final String logString =
2434                 String.format("removePreferredDeviceForStrategy strat:%d", strategy);
2435         sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG));
2436 
2437         final int status = mDeviceBroker.removePreferredDevicesForStrategySync(strategy);
2438         if (status != AudioSystem.SUCCESS) {
2439             Log.e(TAG, String.format("Error %d in %s)", status, logString));
2440         }
2441         return status;
2442     }
2443 
2444     /**
2445      * @see AudioManager#getPreferredDeviceForStrategy(AudioProductStrategy)
2446      * @see AudioManager#getPreferredDevicesForStrategy(AudioProductStrategy)
2447      */
getPreferredDevicesForStrategy(int strategy)2448     public List<AudioDeviceAttributes> getPreferredDevicesForStrategy(int strategy) {
2449         enforceModifyAudioRoutingPermission();
2450         List<AudioDeviceAttributes> devices = new ArrayList<>();
2451         final long identity = Binder.clearCallingIdentity();
2452         final int status = AudioSystem.getDevicesForRoleAndStrategy(
2453                 strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
2454         Binder.restoreCallingIdentity(identity);
2455         if (status != AudioSystem.SUCCESS) {
2456             Log.e(TAG, String.format("Error %d in getPreferredDeviceForStrategy(%d)",
2457                     status, strategy));
2458             return new ArrayList<AudioDeviceAttributes>();
2459         } else {
2460             return devices;
2461         }
2462     }
2463 
2464     /** @see AudioManager#addOnPreferredDevicesForStrategyChangedListener(
2465      *               Executor, AudioManager.OnPreferredDevicesForStrategyChangedListener)
2466      */
registerStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)2467     public void registerStrategyPreferredDevicesDispatcher(
2468             @Nullable IStrategyPreferredDevicesDispatcher dispatcher) {
2469         if (dispatcher == null) {
2470             return;
2471         }
2472         enforceModifyAudioRoutingPermission();
2473         mDeviceBroker.registerStrategyPreferredDevicesDispatcher(dispatcher);
2474     }
2475 
2476     /** @see AudioManager#removeOnPreferredDevicesForStrategyChangedListener(
2477      *               AudioManager.OnPreferredDevicesForStrategyChangedListener)
2478      */
unregisterStrategyPreferredDevicesDispatcher( @ullable IStrategyPreferredDevicesDispatcher dispatcher)2479     public void unregisterStrategyPreferredDevicesDispatcher(
2480             @Nullable IStrategyPreferredDevicesDispatcher dispatcher) {
2481         if (dispatcher == null) {
2482             return;
2483         }
2484         enforceModifyAudioRoutingPermission();
2485         mDeviceBroker.unregisterStrategyPreferredDevicesDispatcher(dispatcher);
2486     }
2487 
2488     /**
2489      * @see AudioManager#setPreferredDeviceForCapturePreset(int, AudioDeviceAttributes)
2490      */
setPreferredDevicesForCapturePreset( int capturePreset, List<AudioDeviceAttributes> devices)2491     public int setPreferredDevicesForCapturePreset(
2492             int capturePreset, List<AudioDeviceAttributes> devices) {
2493         if (devices == null) {
2494             return AudioSystem.ERROR;
2495         }
2496         enforceModifyAudioRoutingPermission();
2497         final String logString = String.format(
2498                 "setPreferredDevicesForCapturePreset u/pid:%d/%d source:%d dev:%s",
2499                 Binder.getCallingUid(), Binder.getCallingPid(), capturePreset,
2500                 devices.stream().map(e -> e.toString()).collect(Collectors.joining(",")));
2501         sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG));
2502         if (devices.stream().anyMatch(device ->
2503                 device.getRole() == AudioDeviceAttributes.ROLE_OUTPUT)) {
2504             Log.e(TAG, "Unsupported output routing in " + logString);
2505             return AudioSystem.ERROR;
2506         }
2507 
2508         final int status = mDeviceBroker.setPreferredDevicesForCapturePresetSync(
2509                 capturePreset, devices);
2510         if (status != AudioSystem.SUCCESS) {
2511             Log.e(TAG, String.format("Error %d in %s)", status, logString));
2512         }
2513 
2514         return status;
2515     }
2516 
2517     /** @see AudioManager#clearPreferredDevicesForCapturePreset(int) */
clearPreferredDevicesForCapturePreset(int capturePreset)2518     public int clearPreferredDevicesForCapturePreset(int capturePreset) {
2519         enforceModifyAudioRoutingPermission();
2520         final String logString = String.format(
2521                 "removePreferredDeviceForCapturePreset source:%d", capturePreset);
2522         sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG));
2523 
2524         final int status = mDeviceBroker.clearPreferredDevicesForCapturePresetSync(capturePreset);
2525         if (status != AudioSystem.SUCCESS) {
2526             Log.e(TAG, String.format("Error %d in %s", status, logString));
2527         }
2528         return status;
2529     }
2530 
2531     /**
2532      * @see AudioManager#getPreferredDevicesForCapturePreset(int)
2533      */
getPreferredDevicesForCapturePreset(int capturePreset)2534     public List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(int capturePreset) {
2535         enforceModifyAudioRoutingPermission();
2536         List<AudioDeviceAttributes> devices = new ArrayList<>();
2537         final long identity = Binder.clearCallingIdentity();
2538         final int status = AudioSystem.getDevicesForRoleAndCapturePreset(
2539                 capturePreset, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
2540         Binder.restoreCallingIdentity(identity);
2541         if (status != AudioSystem.SUCCESS) {
2542             Log.e(TAG, String.format("Error %d in getPreferredDeviceForCapturePreset(%d)",
2543                     status, capturePreset));
2544             return new ArrayList<AudioDeviceAttributes>();
2545         } else {
2546             return devices;
2547         }
2548     }
2549 
2550     /**
2551      * @see AudioManager#addOnPreferredDevicesForCapturePresetChangedListener(
2552      *              Executor, OnPreferredDevicesForCapturePresetChangedListener)
2553      */
registerCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)2554     public void registerCapturePresetDevicesRoleDispatcher(
2555             @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) {
2556         if (dispatcher == null) {
2557             return;
2558         }
2559         enforceModifyAudioRoutingPermission();
2560         mDeviceBroker.registerCapturePresetDevicesRoleDispatcher(dispatcher);
2561     }
2562 
2563     /**
2564      * @see AudioManager#removeOnPreferredDevicesForCapturePresetChangedListener(
2565      *              AudioManager.OnPreferredDevicesForCapturePresetChangedListener)
2566      */
unregisterCapturePresetDevicesRoleDispatcher( @ullable ICapturePresetDevicesRoleDispatcher dispatcher)2567     public void unregisterCapturePresetDevicesRoleDispatcher(
2568             @Nullable ICapturePresetDevicesRoleDispatcher dispatcher) {
2569         if (dispatcher == null) {
2570             return;
2571         }
2572         enforceModifyAudioRoutingPermission();
2573         mDeviceBroker.unregisterCapturePresetDevicesRoleDispatcher(dispatcher);
2574     }
2575 
2576     /** @see AudioManager#getDevicesForAttributes(AudioAttributes) */
getDevicesForAttributes( @onNull AudioAttributes attributes)2577     public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes(
2578             @NonNull AudioAttributes attributes) {
2579         enforceQueryStateOrModifyRoutingPermission();
2580         return getDevicesForAttributesInt(attributes);
2581     }
2582 
2583     /**
2584      * @see AudioManager#isMusicActive()
2585      * @param remotely true if query is for remote playback (cast), false for local playback.
2586      */
isMusicActive(boolean remotely)2587     public boolean isMusicActive(boolean remotely) {
2588         // no permission required
2589         final long token = Binder.clearCallingIdentity();
2590         try {
2591             if (remotely) {
2592                 return AudioSystem.isStreamActiveRemotely(AudioSystem.STREAM_MUSIC, 0);
2593             } else {
2594                 return AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0);
2595             }
2596         } finally {
2597             Binder.restoreCallingIdentity(token);
2598         }
2599     }
2600 
getDevicesForAttributesInt( @onNull AudioAttributes attributes)2601     protected @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesInt(
2602             @NonNull AudioAttributes attributes) {
2603         Objects.requireNonNull(attributes);
2604         return mAudioSystem.getDevicesForAttributes(attributes);
2605     }
2606 
2607     /** Indicates no special treatment in the handling of the volume adjustement */
2608     private static final int VOL_ADJUST_NORMAL = 0;
2609     /** Indicates the start of a volume adjustement */
2610     private static final int VOL_ADJUST_START = 1;
2611     /** Indicates the end of a volume adjustment */
2612     private static final int VOL_ADJUST_END = 2;
2613 
2614     // pre-condition: event.getKeyCode() is one of KeyEvent.KEYCODE_VOLUME_UP,
2615     //                                   KeyEvent.KEYCODE_VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_MUTE
handleVolumeKey(@onNull KeyEvent event, boolean isOnTv, @NonNull String callingPackage, @NonNull String caller)2616     public void handleVolumeKey(@NonNull KeyEvent event, boolean isOnTv,
2617             @NonNull String callingPackage, @NonNull String caller) {
2618         int keyEventMode = VOL_ADJUST_NORMAL;
2619         if (isOnTv) {
2620             if (event.getAction() == KeyEvent.ACTION_DOWN) {
2621                 keyEventMode = VOL_ADJUST_START;
2622             } else { // may catch more than ACTION_UP, but will end vol adjustement
2623                 // the vol key is either released (ACTION_UP), or multiple keys are pressed
2624                 // (ACTION_MULTIPLE) and we don't know what to do for volume control on CEC, end
2625                 // the repeated volume adjustement
2626                 keyEventMode = VOL_ADJUST_END;
2627             }
2628         } else if (event.getAction() != KeyEvent.ACTION_DOWN) {
2629             return;
2630         }
2631 
2632         int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND
2633                 | AudioManager.FLAG_FROM_KEY;
2634 
2635         switch (event.getKeyCode()) {
2636             case KeyEvent.KEYCODE_VOLUME_UP:
2637                     adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE,
2638                             AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller,
2639                             Binder.getCallingUid(), Binder.getCallingPid(), true, keyEventMode);
2640                 break;
2641             case KeyEvent.KEYCODE_VOLUME_DOWN:
2642                     adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER,
2643                             AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller,
2644                             Binder.getCallingUid(), Binder.getCallingPid(), true, keyEventMode);
2645                 break;
2646             case KeyEvent.KEYCODE_VOLUME_MUTE:
2647                 if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
2648                     adjustSuggestedStreamVolume(AudioManager.ADJUST_TOGGLE_MUTE,
2649                             AudioManager.USE_DEFAULT_STREAM_TYPE, flags, callingPackage, caller,
2650                             Binder.getCallingUid(), Binder.getCallingPid(),
2651                             true, VOL_ADJUST_NORMAL);
2652                 }
2653                 break;
2654             default:
2655                 Log.e(TAG, "Invalid key code " + event.getKeyCode() + " sent by " + callingPackage);
2656                 return; // not needed but added if code gets added below this switch statement
2657         }
2658     }
2659 
2660     /** @see AudioManager#adjustVolume(int, int) */
adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, String callingPackage, String caller)2661     public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
2662             String callingPackage, String caller) {
2663         adjustSuggestedStreamVolume(direction, suggestedStreamType, flags, callingPackage,
2664                 caller, Binder.getCallingUid(), Binder.getCallingPid(),
2665                 callingHasAudioSettingsPermission(), VOL_ADJUST_NORMAL);
2666     }
2667 
setNavigationRepeatSoundEffectsEnabled(boolean enabled)2668     public void setNavigationRepeatSoundEffectsEnabled(boolean enabled) {
2669         mNavigationRepeatSoundEffectsEnabled = enabled;
2670     }
2671 
2672     /**
2673      * @return true if the fast scroll sound effects are enabled
2674      */
areNavigationRepeatSoundEffectsEnabled()2675     public boolean areNavigationRepeatSoundEffectsEnabled() {
2676         return mNavigationRepeatSoundEffectsEnabled;
2677     }
2678 
setHomeSoundEffectEnabled(boolean enabled)2679     public void setHomeSoundEffectEnabled(boolean enabled) {
2680         mHomeSoundEffectEnabled = enabled;
2681     }
2682 
2683     /**
2684      * @return true if the home sound effect is enabled
2685      */
isHomeSoundEffectEnabled()2686     public boolean isHomeSoundEffectEnabled() {
2687         return mHomeSoundEffectEnabled;
2688     }
2689 
adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags, String callingPackage, String caller, int uid, int pid, boolean hasModifyAudioSettings, int keyEventMode)2690     private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
2691             String callingPackage, String caller, int uid, int pid, boolean hasModifyAudioSettings,
2692             int keyEventMode) {
2693         if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream=" + suggestedStreamType
2694                 + ", flags=" + flags + ", caller=" + caller
2695                 + ", volControlStream=" + mVolumeControlStream
2696                 + ", userSelect=" + mUserSelectedVolumeControlStream);
2697         if (direction != AudioManager.ADJUST_SAME) {
2698             sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_SUGG_VOL, suggestedStreamType,
2699                     direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage)
2700                     .append("/").append(caller).append(" uid:").append(uid).toString()));
2701         }
2702 
2703         boolean hasExternalVolumeController = notifyExternalVolumeController(direction);
2704 
2705         new MediaMetrics.Item(mMetricsId + "adjustSuggestedStreamVolume")
2706                 .setUid(Binder.getCallingUid())
2707                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage)
2708                 .set(MediaMetrics.Property.CLIENT_NAME, caller)
2709                 .set(MediaMetrics.Property.DIRECTION, direction > 0
2710                         ? MediaMetrics.Value.UP : MediaMetrics.Value.DOWN)
2711                 .set(MediaMetrics.Property.EXTERNAL, hasExternalVolumeController
2712                         ? MediaMetrics.Value.YES : MediaMetrics.Value.NO)
2713                 .set(MediaMetrics.Property.FLAGS, flags)
2714                 .record();
2715 
2716         if (hasExternalVolumeController) {
2717             return;
2718         }
2719 
2720         final int streamType;
2721         synchronized (mForceControlStreamLock) {
2722             // Request lock in case mVolumeControlStream is changed by other thread.
2723             if (mUserSelectedVolumeControlStream) { // implies mVolumeControlStream != -1
2724                 streamType = mVolumeControlStream;
2725             } else {
2726                 final int maybeActiveStreamType = getActiveStreamType(suggestedStreamType);
2727                 final boolean activeForReal;
2728                 if (maybeActiveStreamType == AudioSystem.STREAM_RING
2729                         || maybeActiveStreamType == AudioSystem.STREAM_NOTIFICATION) {
2730                     activeForReal = wasStreamActiveRecently(maybeActiveStreamType, 0);
2731                 } else {
2732                     activeForReal = mAudioSystem.isStreamActive(maybeActiveStreamType, 0);
2733                 }
2734                 if (activeForReal || mVolumeControlStream == -1) {
2735                     streamType = maybeActiveStreamType;
2736                 } else {
2737                     streamType = mVolumeControlStream;
2738                 }
2739             }
2740         }
2741 
2742         final boolean isMute = isMuteAdjust(direction);
2743 
2744         ensureValidStreamType(streamType);
2745         final int resolvedStream = mStreamVolumeAlias[streamType];
2746 
2747         // Play sounds on STREAM_RING only.
2748         if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 &&
2749                 resolvedStream != AudioSystem.STREAM_RING) {
2750             flags &= ~AudioManager.FLAG_PLAY_SOUND;
2751         }
2752 
2753         // For notifications/ring, show the ui before making any adjustments
2754         // Don't suppress mute/unmute requests
2755         // Don't suppress adjustments for single volume device
2756         if (mVolumeController.suppressAdjustment(resolvedStream, flags, isMute)
2757                 && !mIsSingleVolume) {
2758             direction = 0;
2759             flags &= ~AudioManager.FLAG_PLAY_SOUND;
2760             flags &= ~AudioManager.FLAG_VIBRATE;
2761             if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment");
2762         }
2763 
2764         adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid, pid,
2765                 hasModifyAudioSettings, keyEventMode);
2766     }
2767 
notifyExternalVolumeController(int direction)2768     private boolean notifyExternalVolumeController(int direction) {
2769         final IAudioPolicyCallback externalVolumeController;
2770         synchronized (mExtVolumeControllerLock) {
2771             externalVolumeController = mExtVolumeController;
2772         }
2773         if (externalVolumeController == null) {
2774             return false;
2775         }
2776 
2777         sendMsg(mAudioHandler, MSG_NOTIFY_VOL_EVENT, SENDMSG_QUEUE,
2778                 direction, 0 /*ignored*/,
2779                 externalVolumeController, 0 /*delay*/);
2780         return true;
2781     }
2782 
2783     /** @see AudioManager#adjustStreamVolume(int, int, int)
2784      * Part of service interface, check permissions here */
adjustStreamVolume(int streamType, int direction, int flags, String callingPackage)2785     public void adjustStreamVolume(int streamType, int direction, int flags,
2786             String callingPackage) {
2787         if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {
2788             Log.w(TAG, "Trying to call adjustStreamVolume() for a11y without"
2789                     + "CHANGE_ACCESSIBILITY_VOLUME / callingPackage=" + callingPackage);
2790             return;
2791         }
2792 
2793         sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_STREAM_VOL, streamType,
2794                 direction/*val1*/, flags/*val2*/, callingPackage));
2795         adjustStreamVolume(streamType, direction, flags, callingPackage, callingPackage,
2796                 Binder.getCallingUid(), Binder.getCallingPid(),
2797                 callingHasAudioSettingsPermission(), VOL_ADJUST_NORMAL);
2798     }
2799 
adjustStreamVolume(int streamType, int direction, int flags, String callingPackage, String caller, int uid, int pid, boolean hasModifyAudioSettings, int keyEventMode)2800     protected void adjustStreamVolume(int streamType, int direction, int flags,
2801             String callingPackage, String caller, int uid, int pid, boolean hasModifyAudioSettings,
2802             int keyEventMode) {
2803         if (mUseFixedVolume) {
2804             return;
2805         }
2806         if (DEBUG_VOL) Log.d(TAG, "adjustStreamVolume() stream=" + streamType + ", dir=" + direction
2807                 + ", flags=" + flags + ", caller=" + caller);
2808 
2809         ensureValidDirection(direction);
2810         ensureValidStreamType(streamType);
2811 
2812         boolean isMuteAdjust = isMuteAdjust(direction);
2813 
2814         if (isMuteAdjust && !isStreamAffectedByMute(streamType)) {
2815             return;
2816         }
2817 
2818         // If adjust is mute and the stream is STREAM_VOICE_CALL or STREAM_BLUETOOTH_SCO, make sure
2819         // that the calling app have the MODIFY_PHONE_STATE permission.
2820         if (isMuteAdjust &&
2821             (streamType == AudioSystem.STREAM_VOICE_CALL ||
2822                 streamType == AudioSystem.STREAM_BLUETOOTH_SCO) &&
2823                 mContext.checkPermission(android.Manifest.permission.MODIFY_PHONE_STATE, pid, uid)
2824                     != PackageManager.PERMISSION_GRANTED) {
2825             Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: adjustStreamVolume from pid="
2826                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
2827             return;
2828         }
2829 
2830         // If the stream is STREAM_ASSISTANT,
2831         // make sure that the calling app have the MODIFY_AUDIO_ROUTING permission.
2832         if (streamType == AudioSystem.STREAM_ASSISTANT &&
2833                 mContext.checkPermission(
2834                 android.Manifest.permission.MODIFY_AUDIO_ROUTING, pid, uid)
2835                     != PackageManager.PERMISSION_GRANTED) {
2836             Log.w(TAG, "MODIFY_AUDIO_ROUTING Permission Denial: adjustStreamVolume from pid="
2837                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
2838             return;
2839         }
2840 
2841         // use stream type alias here so that streams with same alias have the same behavior,
2842         // including with regard to silent mode control (e.g the use of STREAM_RING below and in
2843         // checkForRingerModeChange() in place of STREAM_RING or STREAM_NOTIFICATION)
2844         int streamTypeAlias = mStreamVolumeAlias[streamType];
2845 
2846         VolumeStreamState streamState = mStreamStates[streamTypeAlias];
2847 
2848         final int device = getDeviceForStream(streamTypeAlias);
2849 
2850         int aliasIndex = streamState.getIndex(device);
2851         boolean adjustVolume = true;
2852         int step;
2853 
2854         // skip a2dp absolute volume control request when the device
2855         // is not an a2dp device
2856         if (!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
2857                 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) {
2858             return;
2859         }
2860 
2861         // If we are being called by the system (e.g. hardware keys) check for current user
2862         // so we handle user restrictions correctly.
2863         if (uid == android.os.Process.SYSTEM_UID) {
2864             uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid));
2865         }
2866         // validate calling package and app op
2867         if (!checkNoteAppOp(STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage)) {
2868             return;
2869         }
2870 
2871         // reset any pending volume command
2872         synchronized (mSafeMediaVolumeStateLock) {
2873             mPendingVolumeCommand = null;
2874         }
2875 
2876         flags &= ~AudioManager.FLAG_FIXED_VOLUME;
2877         if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) {
2878             flags |= AudioManager.FLAG_FIXED_VOLUME;
2879 
2880             // Always toggle between max safe volume and 0 for fixed volume devices where safe
2881             // volume is enforced, and max and 0 for the others.
2882             // This is simulated by stepping by the full allowed volume range
2883             if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE &&
2884                     mSafeMediaVolumeDevices.contains(device)) {
2885                 step = safeMediaVolumeIndex(device);
2886             } else {
2887                 step = streamState.getMaxIndex();
2888             }
2889             if (aliasIndex != 0) {
2890                 aliasIndex = step;
2891             }
2892         } else {
2893             // convert one UI step (+/-1) into a number of internal units on the stream alias
2894             step = rescaleStep(10, streamType, streamTypeAlias);
2895         }
2896 
2897         // If either the client forces allowing ringer modes for this adjustment,
2898         // or the stream type is one that is affected by ringer modes
2899         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
2900                 (isUiSoundsStreamType(streamTypeAlias))) {
2901             int ringerMode = getRingerModeInternal();
2902             // do not vibrate if already in vibrate mode
2903             if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
2904                 flags &= ~AudioManager.FLAG_VIBRATE;
2905             }
2906             // Check if the ringer mode handles this adjustment. If it does we don't
2907             // need to adjust the volume further.
2908             final int result = checkForRingerModeChange(aliasIndex, direction, step,
2909                     streamState.mIsMuted, callingPackage, flags);
2910             adjustVolume = (result & FLAG_ADJUST_VOLUME) != 0;
2911             // If suppressing a volume adjustment in silent mode, display the UI hint
2912             if ((result & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) {
2913                 flags |= AudioManager.FLAG_SHOW_SILENT_HINT;
2914             }
2915             // If suppressing a volume down adjustment in vibrate mode, display the UI hint
2916             if ((result & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0) {
2917                 flags |= AudioManager.FLAG_SHOW_VIBRATE_HINT;
2918             }
2919         }
2920 
2921         // If the ringer mode or zen is muting the stream, do not change stream unless
2922         // it'll cause us to exit dnd
2923         if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) {
2924             adjustVolume = false;
2925         }
2926         int oldIndex = mStreamStates[streamType].getIndex(device);
2927 
2928         if (adjustVolume
2929                 && (direction != AudioManager.ADJUST_SAME) && (keyEventMode != VOL_ADJUST_END)) {
2930             mAudioHandler.removeMessages(MSG_UNMUTE_STREAM);
2931 
2932             if (isMuteAdjust && !mFullVolumeDevices.contains(device)) {
2933                 boolean state;
2934                 if (direction == AudioManager.ADJUST_TOGGLE_MUTE) {
2935                     state = !streamState.mIsMuted;
2936                 } else {
2937                     state = direction == AudioManager.ADJUST_MUTE;
2938                 }
2939                 if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
2940                     setSystemAudioMute(state);
2941                 }
2942                 for (int stream = 0; stream < mStreamStates.length; stream++) {
2943                     if (streamTypeAlias == mStreamVolumeAlias[stream]) {
2944                         if (!(readCameraSoundForced()
2945                                     && (mStreamStates[stream].getStreamType()
2946                                         == AudioSystem.STREAM_SYSTEM_ENFORCED))) {
2947                             mStreamStates[stream].mute(state);
2948                         }
2949                     }
2950                 }
2951             } else if ((direction == AudioManager.ADJUST_RAISE) &&
2952                     !checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) {
2953                 Log.e(TAG, "adjustStreamVolume() safe volume index = " + oldIndex);
2954                 mVolumeController.postDisplaySafeVolumeWarning(flags);
2955             } else if (!isFullVolumeDevice(device)
2956                     && (streamState.adjustIndex(direction * step, device, caller,
2957                             hasModifyAudioSettings)
2958                             || streamState.mIsMuted)) {
2959                 // Post message to set system volume (it in turn will post a
2960                 // message to persist).
2961                 if (streamState.mIsMuted) {
2962                     // Unmute the stream if it was previously muted
2963                     if (direction == AudioManager.ADJUST_RAISE) {
2964                         // unmute immediately for volume up
2965                         streamState.mute(false);
2966                     } else if (direction == AudioManager.ADJUST_LOWER) {
2967                         if (mIsSingleVolume) {
2968                             sendMsg(mAudioHandler, MSG_UNMUTE_STREAM, SENDMSG_QUEUE,
2969                                     streamTypeAlias, flags, null, UNMUTE_STREAM_DELAY);
2970                         }
2971                     }
2972                 }
2973                 sendMsg(mAudioHandler,
2974                         MSG_SET_DEVICE_VOLUME,
2975                         SENDMSG_QUEUE,
2976                         device,
2977                         0,
2978                         streamState,
2979                         0);
2980             }
2981 
2982             int newIndex = mStreamStates[streamType].getIndex(device);
2983 
2984             // Check if volume update should be send to AVRCP
2985             if (streamTypeAlias == AudioSystem.STREAM_MUSIC
2986                     && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
2987                     && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
2988                 if (DEBUG_VOL) {
2989                     Log.d(TAG, "adjustSreamVolume: postSetAvrcpAbsoluteVolumeIndex index="
2990                             + newIndex + "stream=" + streamType);
2991                 }
2992                 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(newIndex / 10);
2993             }
2994 
2995             // Check if volume update should be send to Hearing Aid
2996             if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
2997                 // only modify the hearing aid attenuation when the stream to modify matches
2998                 // the one expected by the hearing aid
2999                 if (streamType == getHearingAidStreamType()) {
3000                     if (DEBUG_VOL) {
3001                         Log.d(TAG, "adjustSreamVolume postSetHearingAidVolumeIndex index="
3002                                 + newIndex + " stream=" + streamType);
3003                     }
3004                     mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType);
3005                 }
3006             }
3007 
3008             // Check if volume update should be sent to Hdmi system audio.
3009             if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
3010                 setSystemAudioVolume(oldIndex, newIndex, getStreamMaxVolume(streamType), flags);
3011             }
3012         }
3013 
3014         final int newIndex = mStreamStates[streamType].getIndex(device);
3015 
3016         if (adjustVolume) {
3017             synchronized (mHdmiClientLock) {
3018                 if (mHdmiManager != null) {
3019                     if (mHdmiPlaybackClient != null
3020                             && mHdmiCecVolumeControlEnabled
3021                             && streamTypeAlias == AudioSystem.STREAM_MUSIC
3022                             // vol change on a full volume device
3023                             && isFullVolumeDevice(device)) {
3024                         int keyCode = KeyEvent.KEYCODE_UNKNOWN;
3025                         switch (direction) {
3026                             case AudioManager.ADJUST_RAISE:
3027                                 keyCode = KeyEvent.KEYCODE_VOLUME_UP;
3028                                 break;
3029                             case AudioManager.ADJUST_LOWER:
3030                                 keyCode = KeyEvent.KEYCODE_VOLUME_DOWN;
3031                                 break;
3032                             case AudioManager.ADJUST_TOGGLE_MUTE:
3033                                 keyCode = KeyEvent.KEYCODE_VOLUME_MUTE;
3034                                 break;
3035                             default:
3036                                 break;
3037                         }
3038                         if (keyCode != KeyEvent.KEYCODE_UNKNOWN) {
3039                             final long ident = Binder.clearCallingIdentity();
3040                             try {
3041                                 final long time = java.lang.System.currentTimeMillis();
3042                                 switch (keyEventMode) {
3043                                     case VOL_ADJUST_NORMAL:
3044                                         mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, true);
3045                                         mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, false);
3046                                         break;
3047                                     case VOL_ADJUST_START:
3048                                         mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, true);
3049                                         break;
3050                                     case VOL_ADJUST_END:
3051                                         mHdmiPlaybackClient.sendVolumeKeyEvent(keyCode, false);
3052                                         break;
3053                                     default:
3054                                         Log.e(TAG, "Invalid keyEventMode " + keyEventMode);
3055                                 }
3056                             } finally {
3057                                 Binder.restoreCallingIdentity(ident);
3058                             }
3059                         }
3060                     }
3061 
3062                     if (streamTypeAlias == AudioSystem.STREAM_MUSIC
3063                             && (oldIndex != newIndex || isMuteAdjust)) {
3064                         maybeSendSystemAudioStatusCommand(isMuteAdjust);
3065                     }
3066                 }
3067             }
3068         }
3069         sendVolumeUpdate(streamType, oldIndex, newIndex, flags, device);
3070     }
3071 
3072     // Called after a delay when volume down is pressed while muted
onUnmuteStream(int stream, int flags)3073     private void onUnmuteStream(int stream, int flags) {
3074         boolean wasMuted;
3075         synchronized (VolumeStreamState.class) {
3076             final VolumeStreamState streamState = mStreamStates[stream];
3077             wasMuted = streamState.mute(false); // if unmuting causes a change, it was muted
3078 
3079             final int device = getDeviceForStream(stream);
3080             final int index = streamState.getIndex(device);
3081             sendVolumeUpdate(stream, index, index, flags, device);
3082         }
3083         if (stream == AudioSystem.STREAM_MUSIC && wasMuted) {
3084             synchronized (mHdmiClientLock) {
3085                 maybeSendSystemAudioStatusCommand(true);
3086             }
3087         }
3088     }
3089 
3090     @GuardedBy("mHdmiClientLock")
maybeSendSystemAudioStatusCommand(boolean isMuteAdjust)3091     private void maybeSendSystemAudioStatusCommand(boolean isMuteAdjust) {
3092         if (mHdmiAudioSystemClient == null
3093                 || !mHdmiSystemAudioSupported
3094                 || !mHdmiCecVolumeControlEnabled) {
3095             return;
3096         }
3097 
3098         final long identity = Binder.clearCallingIdentity();
3099         mHdmiAudioSystemClient.sendReportAudioStatusCecCommand(
3100                 isMuteAdjust, getStreamVolume(AudioSystem.STREAM_MUSIC),
3101                 getStreamMaxVolume(AudioSystem.STREAM_MUSIC),
3102                 isStreamMute(AudioSystem.STREAM_MUSIC));
3103         Binder.restoreCallingIdentity(identity);
3104     }
3105 
setSystemAudioVolume(int oldVolume, int newVolume, int maxVolume, int flags)3106     private void setSystemAudioVolume(int oldVolume, int newVolume, int maxVolume, int flags) {
3107         // Sets the audio volume of AVR when we are in system audio mode. The new volume info
3108         // is tranformed to HDMI-CEC commands and passed through CEC bus.
3109         synchronized (mHdmiClientLock) {
3110             if (mHdmiManager == null
3111                     || mHdmiTvClient == null
3112                     || oldVolume == newVolume
3113                     || (flags & AudioManager.FLAG_HDMI_SYSTEM_AUDIO_VOLUME) != 0
3114                     || !mHdmiSystemAudioSupported
3115                     || !mHdmiCecVolumeControlEnabled) {
3116                 return;
3117             }
3118             final long token = Binder.clearCallingIdentity();
3119             try {
3120                 mHdmiTvClient.setSystemAudioVolume(oldVolume, newVolume, maxVolume);
3121             } finally {
3122                 Binder.restoreCallingIdentity(token);
3123             }
3124         }
3125     }
3126 
3127     // StreamVolumeCommand contains the information needed to defer the process of
3128     // setStreamVolume() in case the user has to acknowledge the safe volume warning message.
3129     static class StreamVolumeCommand {
3130         public final int mStreamType;
3131         public final int mIndex;
3132         public final int mFlags;
3133         public final int mDevice;
3134 
StreamVolumeCommand(int streamType, int index, int flags, int device)3135         StreamVolumeCommand(int streamType, int index, int flags, int device) {
3136             mStreamType = streamType;
3137             mIndex = index;
3138             mFlags = flags;
3139             mDevice = device;
3140         }
3141 
3142         @Override
toString()3143         public String toString() {
3144             return new StringBuilder().append("{streamType=").append(mStreamType).append(",index=")
3145                     .append(mIndex).append(",flags=").append(mFlags).append(",device=")
3146                     .append(mDevice).append('}').toString();
3147         }
3148     }
3149 
getNewRingerMode(int stream, int index, int flags)3150     private int getNewRingerMode(int stream, int index, int flags) {
3151         // setRingerMode does nothing if the device is single volume,so the value would be unchanged
3152         if (mIsSingleVolume) {
3153             return getRingerModeExternal();
3154         }
3155 
3156         // setting volume on ui sounds stream type also controls silent mode
3157         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
3158                 (stream == getUiSoundsStreamType())) {
3159             int newRingerMode;
3160             if (index == 0) {
3161                 newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE
3162                         : mVolumePolicy.volumeDownToEnterSilent ? AudioManager.RINGER_MODE_SILENT
3163                                 : AudioManager.RINGER_MODE_NORMAL;
3164             } else {
3165                 newRingerMode = AudioManager.RINGER_MODE_NORMAL;
3166             }
3167             return newRingerMode;
3168         }
3169         return getRingerModeExternal();
3170     }
3171 
isAndroidNPlus(String caller)3172     private boolean isAndroidNPlus(String caller) {
3173         try {
3174             final ApplicationInfo applicationInfo =
3175                     mContext.getPackageManager().getApplicationInfoAsUser(
3176                             caller, 0, UserHandle.getUserId(Binder.getCallingUid()));
3177             if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N) {
3178                 return true;
3179             }
3180             return false;
3181         } catch (PackageManager.NameNotFoundException e) {
3182             return true;
3183         }
3184     }
3185 
wouldToggleZenMode(int newMode)3186     private boolean wouldToggleZenMode(int newMode) {
3187         if (getRingerModeExternal() == AudioManager.RINGER_MODE_SILENT
3188                 && newMode != AudioManager.RINGER_MODE_SILENT) {
3189             return true;
3190         } else if (getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT
3191                 && newMode == AudioManager.RINGER_MODE_SILENT) {
3192             return true;
3193         }
3194         return false;
3195     }
3196 
onSetStreamVolume(int streamType, int index, int flags, int device, String caller, boolean hasModifyAudioSettings)3197     private void onSetStreamVolume(int streamType, int index, int flags, int device,
3198             String caller, boolean hasModifyAudioSettings) {
3199         final int stream = mStreamVolumeAlias[streamType];
3200         setStreamVolumeInt(stream, index, device, false, caller, hasModifyAudioSettings);
3201         // setting volume on ui sounds stream type also controls silent mode
3202         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
3203                 (stream == getUiSoundsStreamType())) {
3204             setRingerMode(getNewRingerMode(stream, index, flags),
3205                     TAG + ".onSetStreamVolume", false /*external*/);
3206         }
3207         // setting non-zero volume for a muted stream unmutes the stream and vice versa,
3208         // except for BT SCO stream where only explicit mute is allowed to comply to BT requirements
3209         if (streamType != AudioSystem.STREAM_BLUETOOTH_SCO) {
3210             mStreamStates[stream].mute(index == 0);
3211         }
3212     }
3213 
enforceModifyAudioRoutingPermission()3214     private void enforceModifyAudioRoutingPermission() {
3215         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
3216                 != PackageManager.PERMISSION_GRANTED) {
3217             throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission");
3218         }
3219     }
3220 
enforceQueryStateOrModifyRoutingPermission()3221     private void enforceQueryStateOrModifyRoutingPermission() {
3222         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
3223                 != PackageManager.PERMISSION_GRANTED
3224                 && mContext.checkCallingOrSelfPermission(Manifest.permission.QUERY_AUDIO_STATE)
3225                 != PackageManager.PERMISSION_GRANTED) {
3226             throw new SecurityException(
3227                     "Missing MODIFY_AUDIO_ROUTING or QUERY_AUDIO_STATE permissions");
3228         }
3229     }
3230 
3231     /** @see AudioManager#setVolumeIndexForAttributes(attr, int, int) */
setVolumeIndexForAttributes(@onNull AudioAttributes attr, int index, int flags, String callingPackage)3232     public void setVolumeIndexForAttributes(@NonNull AudioAttributes attr, int index, int flags,
3233                                             String callingPackage) {
3234         enforceModifyAudioRoutingPermission();
3235         Objects.requireNonNull(attr, "attr must not be null");
3236         final int volumeGroup = getVolumeGroupIdForAttributes(attr);
3237         if (sVolumeGroupStates.indexOfKey(volumeGroup) < 0) {
3238             Log.e(TAG, ": no volume group found for attributes " + attr.toString());
3239             return;
3240         }
3241         final VolumeGroupState vgs = sVolumeGroupStates.get(volumeGroup);
3242 
3243         sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_SET_GROUP_VOL, attr, vgs.name(),
3244                 index/*val1*/, flags/*val2*/, callingPackage));
3245 
3246         vgs.setVolumeIndex(index, flags);
3247 
3248         // For legacy reason, propagate to all streams associated to this volume group
3249         for (final int groupedStream : vgs.getLegacyStreamTypes()) {
3250             try {
3251                 ensureValidStreamType(groupedStream);
3252             } catch (IllegalArgumentException e) {
3253                 Log.d(TAG, "volume group " + volumeGroup + " has internal streams (" + groupedStream
3254                         + "), do not change associated stream volume");
3255                 continue;
3256             }
3257             setStreamVolume(groupedStream, index, flags, callingPackage, callingPackage,
3258                             Binder.getCallingUid(), true /*hasModifyAudioSettings*/);
3259         }
3260     }
3261 
3262     @Nullable
getAudioVolumeGroupById(int volumeGroupId)3263     private AudioVolumeGroup getAudioVolumeGroupById(int volumeGroupId) {
3264         for (final AudioVolumeGroup avg : AudioVolumeGroup.getAudioVolumeGroups()) {
3265             if (avg.getId() == volumeGroupId) {
3266                 return avg;
3267             }
3268         }
3269 
3270         Log.e(TAG, ": invalid volume group id: " + volumeGroupId + " requested");
3271         return null;
3272     }
3273 
3274     /** @see AudioManager#getVolumeIndexForAttributes(attr) */
getVolumeIndexForAttributes(@onNull AudioAttributes attr)3275     public int getVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
3276         enforceModifyAudioRoutingPermission();
3277         Objects.requireNonNull(attr, "attr must not be null");
3278         final int volumeGroup = getVolumeGroupIdForAttributes(attr);
3279         if (sVolumeGroupStates.indexOfKey(volumeGroup) < 0) {
3280             throw new IllegalArgumentException("No volume group for attributes " + attr);
3281         }
3282         final VolumeGroupState vgs = sVolumeGroupStates.get(volumeGroup);
3283         return vgs.getVolumeIndex();
3284     }
3285 
3286     /** @see AudioManager#getMaxVolumeIndexForAttributes(attr) */
getMaxVolumeIndexForAttributes(@onNull AudioAttributes attr)3287     public int getMaxVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
3288         enforceModifyAudioRoutingPermission();
3289         Objects.requireNonNull(attr, "attr must not be null");
3290         return AudioSystem.getMaxVolumeIndexForAttributes(attr);
3291     }
3292 
3293     /** @see AudioManager#getMinVolumeIndexForAttributes(attr) */
getMinVolumeIndexForAttributes(@onNull AudioAttributes attr)3294     public int getMinVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
3295         enforceModifyAudioRoutingPermission();
3296         Objects.requireNonNull(attr, "attr must not be null");
3297         return AudioSystem.getMinVolumeIndexForAttributes(attr);
3298     }
3299 
3300     /** @see AudioManager#setStreamVolume(int, int, int)
3301      * Part of service interface, check permissions here */
setStreamVolume(int streamType, int index, int flags, String callingPackage)3302     public void setStreamVolume(int streamType, int index, int flags, String callingPackage) {
3303         if ((streamType == AudioManager.STREAM_ACCESSIBILITY) && !canChangeAccessibilityVolume()) {
3304             Log.w(TAG, "Trying to call setStreamVolume() for a11y without"
3305                     + " CHANGE_ACCESSIBILITY_VOLUME  callingPackage=" + callingPackage);
3306             return;
3307         }
3308         if ((streamType == AudioManager.STREAM_VOICE_CALL) && (index == 0)
3309                 && (mContext.checkCallingOrSelfPermission(
3310                     android.Manifest.permission.MODIFY_PHONE_STATE)
3311                     != PackageManager.PERMISSION_GRANTED)) {
3312             Log.w(TAG, "Trying to call setStreamVolume() for STREAM_VOICE_CALL and index 0 without"
3313                     + " MODIFY_PHONE_STATE  callingPackage=" + callingPackage);
3314             return;
3315         }
3316         if ((streamType == AudioManager.STREAM_ASSISTANT)
3317             && (mContext.checkCallingOrSelfPermission(
3318                     android.Manifest.permission.MODIFY_AUDIO_ROUTING)
3319                     != PackageManager.PERMISSION_GRANTED)) {
3320             Log.w(TAG, "Trying to call setStreamVolume() for STREAM_ASSISTANT without"
3321                     + " MODIFY_AUDIO_ROUTING  callingPackage=" + callingPackage);
3322             return;
3323         }
3324 
3325         sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_SET_STREAM_VOL, streamType,
3326                 index/*val1*/, flags/*val2*/, callingPackage));
3327         setStreamVolume(streamType, index, flags, callingPackage, callingPackage,
3328                 Binder.getCallingUid(), callingOrSelfHasAudioSettingsPermission());
3329     }
3330 
canChangeAccessibilityVolume()3331     private boolean canChangeAccessibilityVolume() {
3332         synchronized (mAccessibilityServiceUidsLock) {
3333             if (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
3334                     android.Manifest.permission.CHANGE_ACCESSIBILITY_VOLUME)) {
3335                 return true;
3336             }
3337             if (mAccessibilityServiceUids != null) {
3338                 int callingUid = Binder.getCallingUid();
3339                 for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
3340                     if (mAccessibilityServiceUids[i] == callingUid) {
3341                         return true;
3342                     }
3343                 }
3344             }
3345             return false;
3346         }
3347     }
3348 
getHearingAidStreamType()3349     /*package*/ int getHearingAidStreamType() {
3350         return getHearingAidStreamType(mMode.get());
3351     }
3352 
getHearingAidStreamType(int mode)3353     private int getHearingAidStreamType(int mode) {
3354         switch (mode) {
3355             case AudioSystem.MODE_IN_COMMUNICATION:
3356             case AudioSystem.MODE_IN_CALL:
3357                 return AudioSystem.STREAM_VOICE_CALL;
3358             case AudioSystem.MODE_NORMAL:
3359             default:
3360                 // other conditions will influence the stream type choice, read on...
3361                 break;
3362         }
3363         if (mVoicePlaybackActive.get()) {
3364             return AudioSystem.STREAM_VOICE_CALL;
3365         }
3366         return AudioSystem.STREAM_MUSIC;
3367     }
3368 
3369     private AtomicBoolean mVoicePlaybackActive = new AtomicBoolean(false);
3370 
3371     private final IPlaybackConfigDispatcher mVoicePlaybackActivityMonitor =
3372             new IPlaybackConfigDispatcher.Stub() {
3373         @Override
3374         public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs,
3375                                                  boolean flush) {
3376             sendMsg(mAudioHandler, MSG_PLAYBACK_CONFIG_CHANGE, SENDMSG_REPLACE,
3377                     0 /*arg1 ignored*/, 0 /*arg2 ignored*/,
3378                     configs /*obj*/, 0 /*delay*/);
3379         }
3380     };
3381 
onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs)3382     private void onPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) {
3383         boolean voiceActive = false;
3384         for (AudioPlaybackConfiguration config : configs) {
3385             final int usage = config.getAudioAttributes().getUsage();
3386             if ((usage == AudioAttributes.USAGE_VOICE_COMMUNICATION
3387                     || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING)
3388                     && config.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
3389                 voiceActive = true;
3390                 break;
3391             }
3392         }
3393         if (mVoicePlaybackActive.getAndSet(voiceActive) != voiceActive) {
3394             updateHearingAidVolumeOnVoiceActivityUpdate();
3395         }
3396 
3397         // Update playback active state for all apps in audio mode stack.
3398         // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE
3399         // and request an audio mode update immediately. Upon any other change, queue the message
3400         // and request an audio mode update after a grace period.
3401         synchronized (mDeviceBroker.mSetModeLock) {
3402             boolean updateAudioMode = false;
3403             int existingMsgPolicy = SENDMSG_QUEUE;
3404             int delay = CHECK_MODE_FOR_UID_PERIOD_MS;
3405             for (SetModeDeathHandler h : mSetModeDeathHandlers) {
3406                 boolean wasActive = h.isActive();
3407                 h.setPlaybackActive(false);
3408                 for (AudioPlaybackConfiguration config : configs) {
3409                     final int usage = config.getAudioAttributes().getUsage();
3410                     if (config.getClientUid() == h.getUid()
3411                             && (usage == AudioAttributes.USAGE_VOICE_COMMUNICATION
3412                                 || usage == AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING)
3413                             && config.getPlayerState()
3414                                 == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
3415                         h.setPlaybackActive(true);
3416                         break;
3417                     }
3418                 }
3419                 if (wasActive != h.isActive()) {
3420                     updateAudioMode = true;
3421                     if (h.isActive() && h == getAudioModeOwnerHandler()) {
3422                         existingMsgPolicy = SENDMSG_REPLACE;
3423                         delay = 0;
3424                     }
3425                 }
3426             }
3427             if (updateAudioMode) {
3428                 sendMsg(mAudioHandler,
3429                         MSG_UPDATE_AUDIO_MODE,
3430                         existingMsgPolicy,
3431                         AudioSystem.MODE_CURRENT,
3432                         android.os.Process.myPid(),
3433                         mContext.getPackageName(),
3434                         delay);
3435             }
3436         }
3437     }
3438 
3439     private final IRecordingConfigDispatcher mVoiceRecordingActivityMonitor =
3440             new IRecordingConfigDispatcher.Stub() {
3441         @Override
3442         public void dispatchRecordingConfigChange(List<AudioRecordingConfiguration> configs) {
3443             sendMsg(mAudioHandler, MSG_RECORDING_CONFIG_CHANGE, SENDMSG_REPLACE,
3444                     0 /*arg1 ignored*/, 0 /*arg2 ignored*/,
3445                     configs /*obj*/, 0 /*delay*/);
3446         }
3447     };
3448 
onRecordingConfigChange(List<AudioRecordingConfiguration> configs)3449     private void onRecordingConfigChange(List<AudioRecordingConfiguration> configs) {
3450         // Update recording active state for all apps in audio mode stack.
3451         // When the audio mode owner becomes active, replace any delayed MSG_UPDATE_AUDIO_MODE
3452         // and request an audio mode update immediately. Upon any other change, queue the message
3453         // and request an audio mode update after a grace period.
3454         synchronized (mDeviceBroker.mSetModeLock) {
3455             boolean updateAudioMode = false;
3456             int existingMsgPolicy = SENDMSG_QUEUE;
3457             int delay = CHECK_MODE_FOR_UID_PERIOD_MS;
3458             for (SetModeDeathHandler h : mSetModeDeathHandlers) {
3459                 boolean wasActive = h.isActive();
3460                 h.setRecordingActive(false);
3461                 for (AudioRecordingConfiguration config : configs) {
3462                     if (config.getClientUid() == h.getUid()
3463                             && config.getAudioSource() == AudioSource.VOICE_COMMUNICATION) {
3464                         h.setRecordingActive(true);
3465                         break;
3466                     }
3467                 }
3468                 if (wasActive != h.isActive()) {
3469                     updateAudioMode = true;
3470                     if (h.isActive() && h == getAudioModeOwnerHandler()) {
3471                         existingMsgPolicy = SENDMSG_REPLACE;
3472                         delay = 0;
3473                     }
3474                 }
3475             }
3476             if (updateAudioMode) {
3477                 sendMsg(mAudioHandler,
3478                         MSG_UPDATE_AUDIO_MODE,
3479                         existingMsgPolicy,
3480                         AudioSystem.MODE_CURRENT,
3481                         android.os.Process.myPid(),
3482                         mContext.getPackageName(),
3483                         delay);
3484             }
3485         }
3486     }
3487 
dumpAudioMode(PrintWriter pw)3488     private void dumpAudioMode(PrintWriter pw) {
3489         pw.println("\nAudio mode: ");
3490         pw.println("- Requested mode = " + AudioSystem.modeToString(getMode()));
3491         pw.println("- Actual mode = " + AudioSystem.modeToString(mMode.get()));
3492         pw.println("- Mode owner: ");
3493         SetModeDeathHandler hdlr = getAudioModeOwnerHandler();
3494         if (hdlr != null) {
3495             hdlr.dump(pw, -1);
3496         } else {
3497             pw.println("   None");
3498         }
3499         pw.println("- Mode owner stack: ");
3500         if (mSetModeDeathHandlers.isEmpty()) {
3501             pw.println("   Empty");
3502         } else {
3503             for (int i = 0; i < mSetModeDeathHandlers.size(); i++) {
3504                 mSetModeDeathHandlers.get(i).dump(pw, i);
3505             }
3506         }
3507     }
3508 
updateHearingAidVolumeOnVoiceActivityUpdate()3509     private void updateHearingAidVolumeOnVoiceActivityUpdate() {
3510         final int streamType = getHearingAidStreamType();
3511         final int index = getStreamVolume(streamType);
3512         sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_HEARING_AID,
3513                 mVoicePlaybackActive.get(), streamType, index));
3514         mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
3515 
3516     }
3517 
3518     /**
3519      * Manage an audio mode change for audio devices that use an "absolute volume" model,
3520      * i.e. the framework sends the full scale signal, and the actual volume for the use case
3521      * is communicated separately.
3522      */
updateAbsVolumeMultiModeDevices(int oldMode, int newMode)3523     void updateAbsVolumeMultiModeDevices(int oldMode, int newMode) {
3524         if (oldMode == newMode) {
3525             return;
3526         }
3527         switch (newMode) {
3528             case AudioSystem.MODE_IN_COMMUNICATION:
3529             case AudioSystem.MODE_IN_CALL:
3530             case AudioSystem.MODE_NORMAL:
3531                 break;
3532             case AudioSystem.MODE_RINGTONE:
3533                 // not changing anything for ringtone
3534                 return;
3535             case AudioSystem.MODE_CURRENT:
3536             case AudioSystem.MODE_INVALID:
3537             default:
3538                 // don't know what to do in this case, better bail
3539                 return;
3540         }
3541 
3542         int streamType = getHearingAidStreamType(newMode);
3543 
3544         final Set<Integer> deviceTypes = AudioSystem.generateAudioDeviceTypesSet(
3545                 mAudioSystem.getDevicesForStream(streamType));
3546         final Set<Integer> absVolumeMultiModeCaseDevices = AudioSystem.intersectionAudioDeviceTypes(
3547                 mAbsVolumeMultiModeCaseDevices, deviceTypes);
3548         if (absVolumeMultiModeCaseDevices.isEmpty()) {
3549             return;
3550         }
3551 
3552         // handling of specific interfaces goes here:
3553         if (AudioSystem.isSingleAudioDeviceType(
3554                 absVolumeMultiModeCaseDevices, AudioSystem.DEVICE_OUT_HEARING_AID)) {
3555             final int index = getStreamVolume(streamType);
3556             sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_MODE_CHANGE_HEARING_AID,
3557                     newMode, streamType, index));
3558             mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
3559         }
3560     }
3561 
setStreamVolume(int streamType, int index, int flags, String callingPackage, String caller, int uid, boolean hasModifyAudioSettings)3562     private void setStreamVolume(int streamType, int index, int flags, String callingPackage,
3563             String caller, int uid, boolean hasModifyAudioSettings) {
3564         if (DEBUG_VOL) {
3565             Log.d(TAG, "setStreamVolume(stream=" + streamType+", index=" + index
3566                     + ", calling=" + callingPackage + ")");
3567         }
3568         if (mUseFixedVolume) {
3569             return;
3570         }
3571 
3572         ensureValidStreamType(streamType);
3573         int streamTypeAlias = mStreamVolumeAlias[streamType];
3574         VolumeStreamState streamState = mStreamStates[streamTypeAlias];
3575 
3576         final int device = getDeviceForStream(streamType);
3577         int oldIndex;
3578 
3579         // skip a2dp absolute volume control request when the device
3580         // is not an a2dp device
3581         if (!AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
3582                 && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) {
3583             return;
3584         }
3585         // If we are being called by the system (e.g. hardware keys) check for current user
3586         // so we handle user restrictions correctly.
3587         if (uid == android.os.Process.SYSTEM_UID) {
3588             uid = UserHandle.getUid(getCurrentUserId(), UserHandle.getAppId(uid));
3589         }
3590         if (!checkNoteAppOp(STREAM_VOLUME_OPS[streamTypeAlias], uid, callingPackage)) {
3591             return;
3592         }
3593 
3594         if (isAndroidNPlus(callingPackage)
3595                 && wouldToggleZenMode(getNewRingerMode(streamTypeAlias, index, flags))
3596                 && !mNm.isNotificationPolicyAccessGrantedForPackage(callingPackage)) {
3597             throw new SecurityException("Not allowed to change Do Not Disturb state");
3598         }
3599 
3600         if (!volumeAdjustmentAllowedByDnd(streamTypeAlias, flags)) {
3601             return;
3602         }
3603 
3604         synchronized (mSafeMediaVolumeStateLock) {
3605             // reset any pending volume command
3606             mPendingVolumeCommand = null;
3607 
3608             oldIndex = streamState.getIndex(device);
3609 
3610             index = rescaleIndex(index * 10, streamType, streamTypeAlias);
3611 
3612             if (streamTypeAlias == AudioSystem.STREAM_MUSIC
3613                     && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
3614                     && (flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {
3615                 if (DEBUG_VOL) {
3616                     Log.d(TAG, "setStreamVolume postSetAvrcpAbsoluteVolumeIndex index=" + index
3617                             + "stream=" + streamType);
3618                 }
3619                 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index / 10);
3620             }
3621 
3622             if (device == AudioSystem.DEVICE_OUT_HEARING_AID
3623                     && streamType == getHearingAidStreamType()) {
3624                 Log.i(TAG, "setStreamVolume postSetHearingAidVolumeIndex index=" + index
3625                         + " stream=" + streamType);
3626                 mDeviceBroker.postSetHearingAidVolumeIndex(index, streamType);
3627             }
3628 
3629             if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
3630                 setSystemAudioVolume(oldIndex, index, getStreamMaxVolume(streamType), flags);
3631             }
3632 
3633             flags &= ~AudioManager.FLAG_FIXED_VOLUME;
3634             if (streamTypeAlias == AudioSystem.STREAM_MUSIC && isFixedVolumeDevice(device)) {
3635                 flags |= AudioManager.FLAG_FIXED_VOLUME;
3636 
3637                 // volume is either 0 or max allowed for fixed volume devices
3638                 if (index != 0) {
3639                     if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE &&
3640                             mSafeMediaVolumeDevices.contains(device)) {
3641                         index = safeMediaVolumeIndex(device);
3642                     } else {
3643                         index = streamState.getMaxIndex();
3644                     }
3645                 }
3646             }
3647 
3648             if (!checkSafeMediaVolume(streamTypeAlias, index, device)) {
3649                 mVolumeController.postDisplaySafeVolumeWarning(flags);
3650                 mPendingVolumeCommand = new StreamVolumeCommand(
3651                                                     streamType, index, flags, device);
3652             } else {
3653                 onSetStreamVolume(streamType, index, flags, device, caller, hasModifyAudioSettings);
3654                 index = mStreamStates[streamType].getIndex(device);
3655             }
3656         }
3657         synchronized (mHdmiClientLock) {
3658             if (streamTypeAlias == AudioSystem.STREAM_MUSIC
3659                     && (oldIndex != index)) {
3660                 maybeSendSystemAudioStatusCommand(false);
3661             }
3662         }
3663         sendVolumeUpdate(streamType, oldIndex, index, flags, device);
3664     }
3665 
3666 
3667 
getVolumeGroupIdForAttributes(@onNull AudioAttributes attributes)3668     private int getVolumeGroupIdForAttributes(@NonNull AudioAttributes attributes) {
3669         Objects.requireNonNull(attributes, "attributes must not be null");
3670         int volumeGroupId = getVolumeGroupIdForAttributesInt(attributes);
3671         if (volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
3672             return volumeGroupId;
3673         }
3674         // The default volume group is the one hosted by default product strategy, i.e.
3675         // supporting Default Attributes
3676         return getVolumeGroupIdForAttributesInt(AudioProductStrategy.sDefaultAttributes);
3677     }
3678 
getVolumeGroupIdForAttributesInt(@onNull AudioAttributes attributes)3679     private int getVolumeGroupIdForAttributesInt(@NonNull AudioAttributes attributes) {
3680         Objects.requireNonNull(attributes, "attributes must not be null");
3681         for (final AudioProductStrategy productStrategy :
3682                 AudioProductStrategy.getAudioProductStrategies()) {
3683             int volumeGroupId = productStrategy.getVolumeGroupIdForAudioAttributes(attributes);
3684             if (volumeGroupId != AudioVolumeGroup.DEFAULT_VOLUME_GROUP) {
3685                 return volumeGroupId;
3686             }
3687         }
3688         return AudioVolumeGroup.DEFAULT_VOLUME_GROUP;
3689     }
3690 
3691 
3692     // No ringer or zen muted stream volumes can be changed unless it'll exit dnd
volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags)3693     private boolean volumeAdjustmentAllowedByDnd(int streamTypeAlias, int flags) {
3694         switch (mNm.getZenMode()) {
3695             case Settings.Global.ZEN_MODE_OFF:
3696                 return true;
3697             case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
3698             case Settings.Global.ZEN_MODE_ALARMS:
3699             case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
3700                 return !isStreamMutedByRingerOrZenMode(streamTypeAlias)
3701                         || isUiSoundsStreamType(streamTypeAlias)
3702                         || (flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0;
3703         }
3704 
3705         return true;
3706     }
3707 
3708     /** @see AudioManager#forceVolumeControlStream(int) */
forceVolumeControlStream(int streamType, IBinder cb)3709     public void forceVolumeControlStream(int streamType, IBinder cb) {
3710         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
3711                 != PackageManager.PERMISSION_GRANTED) {
3712             return;
3713         }
3714         if (DEBUG_VOL) { Log.d(TAG, String.format("forceVolumeControlStream(%d)", streamType)); }
3715         synchronized(mForceControlStreamLock) {
3716             if (mVolumeControlStream != -1 && streamType != -1) {
3717                 mUserSelectedVolumeControlStream = true;
3718             }
3719             mVolumeControlStream = streamType;
3720             if (mVolumeControlStream == -1) {
3721                 if (mForceControlStreamClient != null) {
3722                     mForceControlStreamClient.release();
3723                     mForceControlStreamClient = null;
3724                 }
3725                 mUserSelectedVolumeControlStream = false;
3726             } else {
3727                 if (null == mForceControlStreamClient) {
3728                     mForceControlStreamClient = new ForceControlStreamClient(cb);
3729                 } else {
3730                     if (mForceControlStreamClient.getBinder() == cb) {
3731                         Log.d(TAG, "forceVolumeControlStream cb:" + cb + " is already linked.");
3732                     } else {
3733                         mForceControlStreamClient.release();
3734                         mForceControlStreamClient = new ForceControlStreamClient(cb);
3735                     }
3736                 }
3737             }
3738         }
3739     }
3740 
3741     private class ForceControlStreamClient implements IBinder.DeathRecipient {
3742         private IBinder mCb; // To be notified of client's death
3743 
ForceControlStreamClient(IBinder cb)3744         ForceControlStreamClient(IBinder cb) {
3745             if (cb != null) {
3746                 try {
3747                     cb.linkToDeath(this, 0);
3748                 } catch (RemoteException e) {
3749                     // Client has died!
3750                     Log.w(TAG, "ForceControlStreamClient() could not link to "+cb+" binder death");
3751                     cb = null;
3752                 }
3753             }
3754             mCb = cb;
3755         }
3756 
binderDied()3757         public void binderDied() {
3758             synchronized(mForceControlStreamLock) {
3759                 Log.w(TAG, "SCO client died");
3760                 if (mForceControlStreamClient != this) {
3761                     Log.w(TAG, "unregistered control stream client died");
3762                 } else {
3763                     mForceControlStreamClient = null;
3764                     mVolumeControlStream = -1;
3765                     mUserSelectedVolumeControlStream = false;
3766                 }
3767             }
3768         }
3769 
release()3770         public void release() {
3771             if (mCb != null) {
3772                 mCb.unlinkToDeath(this, 0);
3773                 mCb = null;
3774             }
3775         }
3776 
getBinder()3777         public IBinder getBinder() {
3778             return mCb;
3779         }
3780     }
3781 
sendBroadcastToAll(Intent intent)3782     private void sendBroadcastToAll(Intent intent) {
3783         if (!mSystemServer.isPrivileged()) {
3784             return;
3785         }
3786         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
3787         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
3788         final long ident = Binder.clearCallingIdentity();
3789         try {
3790             mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
3791         } finally {
3792             Binder.restoreCallingIdentity(ident);
3793         }
3794     }
3795 
sendStickyBroadcastToAll(Intent intent)3796     private void sendStickyBroadcastToAll(Intent intent) {
3797         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
3798         final long ident = Binder.clearCallingIdentity();
3799         try {
3800             mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
3801         } finally {
3802             Binder.restoreCallingIdentity(ident);
3803         }
3804     }
3805 
getCurrentUserId()3806     private int getCurrentUserId() {
3807         final long ident = Binder.clearCallingIdentity();
3808         try {
3809             UserInfo currentUser = ActivityManager.getService().getCurrentUser();
3810             return currentUser.id;
3811         } catch (RemoteException e) {
3812             // Activity manager not running, nothing we can do assume user 0.
3813         } finally {
3814             Binder.restoreCallingIdentity(ident);
3815         }
3816         return UserHandle.USER_SYSTEM;
3817     }
3818 
3819     // UI update and Broadcast Intent
sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device)3820     protected void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags, int device)
3821     {
3822         streamType = mStreamVolumeAlias[streamType];
3823 
3824         if (streamType == AudioSystem.STREAM_MUSIC) {
3825             flags = updateFlagsForTvPlatform(flags);
3826             if (isFullVolumeDevice(device)) {
3827                 flags &= ~AudioManager.FLAG_SHOW_UI;
3828             }
3829         }
3830         mVolumeController.postVolumeChanged(streamType, flags);
3831     }
3832 
3833     // Don't show volume UI when:
3834     //  - Hdmi-CEC system audio mode is on and we are a TV panel
updateFlagsForTvPlatform(int flags)3835     private int updateFlagsForTvPlatform(int flags) {
3836         synchronized (mHdmiClientLock) {
3837             if (mHdmiTvClient != null && mHdmiSystemAudioSupported
3838                     && mHdmiCecVolumeControlEnabled) {
3839                 flags &= ~AudioManager.FLAG_SHOW_UI;
3840             }
3841         }
3842         return flags;
3843     }
3844     // UI update and Broadcast Intent
sendMasterMuteUpdate(boolean muted, int flags)3845     private void sendMasterMuteUpdate(boolean muted, int flags) {
3846         mVolumeController.postMasterMuteChanged(updateFlagsForTvPlatform(flags));
3847         broadcastMasterMuteStatus(muted);
3848     }
3849 
broadcastMasterMuteStatus(boolean muted)3850     private void broadcastMasterMuteStatus(boolean muted) {
3851         Intent intent = new Intent(AudioManager.MASTER_MUTE_CHANGED_ACTION);
3852         intent.putExtra(AudioManager.EXTRA_MASTER_VOLUME_MUTED, muted);
3853         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
3854                 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
3855         sendStickyBroadcastToAll(intent);
3856     }
3857 
3858     /**
3859      * Sets the stream state's index, and posts a message to set system volume.
3860      * This will not call out to the UI. Assumes a valid stream type.
3861      *
3862      * @param streamType Type of the stream
3863      * @param index Desired volume index of the stream
3864      * @param device the device whose volume must be changed
3865      * @param force If true, set the volume even if the desired volume is same
3866      * @param caller
3867      * @param hasModifyAudioSettings true if the caller is granted MODIFY_AUDIO_SETTINGS or
3868      *                              MODIFY_AUDIO_ROUTING permission
3869      * as the current volume.
3870      */
setStreamVolumeInt(int streamType, int index, int device, boolean force, String caller, boolean hasModifyAudioSettings)3871     private void setStreamVolumeInt(int streamType,
3872                                     int index,
3873                                     int device,
3874                                     boolean force,
3875                                     String caller, boolean hasModifyAudioSettings) {
3876         if (isFullVolumeDevice(device)) {
3877             return;
3878         }
3879         VolumeStreamState streamState = mStreamStates[streamType];
3880 
3881         if (streamState.setIndex(index, device, caller, hasModifyAudioSettings) || force) {
3882             // Post message to set system volume (it in turn will post a message
3883             // to persist).
3884             sendMsg(mAudioHandler,
3885                     MSG_SET_DEVICE_VOLUME,
3886                     SENDMSG_QUEUE,
3887                     device,
3888                     0,
3889                     streamState,
3890                     0);
3891         }
3892     }
3893 
setSystemAudioMute(boolean state)3894     private void setSystemAudioMute(boolean state) {
3895         synchronized (mHdmiClientLock) {
3896             if (mHdmiManager == null || mHdmiTvClient == null || !mHdmiSystemAudioSupported) return;
3897             final long token = Binder.clearCallingIdentity();
3898             try {
3899                 mHdmiTvClient.setSystemAudioMute(state);
3900             } finally {
3901                 Binder.restoreCallingIdentity(token);
3902             }
3903         }
3904     }
3905 
3906     /** get stream mute state. */
isStreamMute(int streamType)3907     public boolean isStreamMute(int streamType) {
3908         if (streamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
3909             streamType = getActiveStreamType(streamType);
3910         }
3911         synchronized (VolumeStreamState.class) {
3912             ensureValidStreamType(streamType);
3913             return mStreamStates[streamType].mIsMuted;
3914         }
3915     }
3916 
3917     private class RmtSbmxFullVolDeathHandler implements IBinder.DeathRecipient {
3918         private IBinder mICallback; // To be notified of client's death
3919 
RmtSbmxFullVolDeathHandler(IBinder cb)3920         RmtSbmxFullVolDeathHandler(IBinder cb) {
3921             mICallback = cb;
3922             try {
3923                 cb.linkToDeath(this, 0/*flags*/);
3924             } catch (RemoteException e) {
3925                 Log.e(TAG, "can't link to death", e);
3926             }
3927         }
3928 
isHandlerFor(IBinder cb)3929         boolean isHandlerFor(IBinder cb) {
3930             return mICallback.equals(cb);
3931         }
3932 
forget()3933         void forget() {
3934             try {
3935                 mICallback.unlinkToDeath(this, 0/*flags*/);
3936             } catch (NoSuchElementException e) {
3937                 Log.e(TAG, "error unlinking to death", e);
3938             }
3939         }
3940 
binderDied()3941         public void binderDied() {
3942             Log.w(TAG, "Recorder with remote submix at full volume died " + mICallback);
3943             forceRemoteSubmixFullVolume(false, mICallback);
3944         }
3945     }
3946 
3947     /**
3948      * call must be synchronized on mRmtSbmxFullVolDeathHandlers
3949      * @return true if there is a registered death handler, false otherwise */
discardRmtSbmxFullVolDeathHandlerFor(IBinder cb)3950     private boolean discardRmtSbmxFullVolDeathHandlerFor(IBinder cb) {
3951         Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator();
3952         while (it.hasNext()) {
3953             final RmtSbmxFullVolDeathHandler handler = it.next();
3954             if (handler.isHandlerFor(cb)) {
3955                 handler.forget();
3956                 mRmtSbmxFullVolDeathHandlers.remove(handler);
3957                 return true;
3958             }
3959         }
3960         return false;
3961     }
3962 
3963     /** call synchronized on mRmtSbmxFullVolDeathHandlers */
hasRmtSbmxFullVolDeathHandlerFor(IBinder cb)3964     private boolean hasRmtSbmxFullVolDeathHandlerFor(IBinder cb) {
3965         Iterator<RmtSbmxFullVolDeathHandler> it = mRmtSbmxFullVolDeathHandlers.iterator();
3966         while (it.hasNext()) {
3967             if (it.next().isHandlerFor(cb)) {
3968                 return true;
3969             }
3970         }
3971         return false;
3972     }
3973 
3974     private int mRmtSbmxFullVolRefCount = 0;
3975     private final ArrayList<RmtSbmxFullVolDeathHandler> mRmtSbmxFullVolDeathHandlers =
3976             new ArrayList<RmtSbmxFullVolDeathHandler>();
3977 
forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb)3978     public void forceRemoteSubmixFullVolume(boolean startForcing, IBinder cb) {
3979         if (cb == null) {
3980             return;
3981         }
3982         if ((PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
3983                         android.Manifest.permission.CAPTURE_AUDIO_OUTPUT))) {
3984             Log.w(TAG, "Trying to call forceRemoteSubmixFullVolume() without CAPTURE_AUDIO_OUTPUT");
3985             return;
3986         }
3987         synchronized(mRmtSbmxFullVolDeathHandlers) {
3988             boolean applyRequired = false;
3989             if (startForcing) {
3990                 if (!hasRmtSbmxFullVolDeathHandlerFor(cb)) {
3991                     mRmtSbmxFullVolDeathHandlers.add(new RmtSbmxFullVolDeathHandler(cb));
3992                     if (mRmtSbmxFullVolRefCount == 0) {
3993                         mFullVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
3994                         mFixedVolumeDevices.add(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
3995                         applyRequired = true;
3996                     }
3997                     mRmtSbmxFullVolRefCount++;
3998                 }
3999             } else {
4000                 if (discardRmtSbmxFullVolDeathHandlerFor(cb) && (mRmtSbmxFullVolRefCount > 0)) {
4001                     mRmtSbmxFullVolRefCount--;
4002                     if (mRmtSbmxFullVolRefCount == 0) {
4003                         mFullVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
4004                         mFixedVolumeDevices.remove(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
4005                         applyRequired = true;
4006                     }
4007                 }
4008             }
4009             if (applyRequired) {
4010                 // Assumes only STREAM_MUSIC going through DEVICE_OUT_REMOTE_SUBMIX
4011                 checkAllFixedVolumeDevices(AudioSystem.STREAM_MUSIC);
4012                 mStreamStates[AudioSystem.STREAM_MUSIC].applyAllVolumes();
4013             }
4014         }
4015     }
4016 
setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid, int userId, int pid)4017     private void setMasterMuteInternal(boolean mute, int flags, String callingPackage, int uid,
4018             int userId, int pid) {
4019         // If we are being called by the system check for user we are going to change
4020         // so we handle user restrictions correctly.
4021         if (uid == android.os.Process.SYSTEM_UID) {
4022             uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4023         }
4024         // If OP_AUDIO_MASTER_VOLUME is set, disallow unmuting.
4025         if (!mute && !checkNoteAppOp(AppOpsManager.OP_AUDIO_MASTER_VOLUME, uid, callingPackage)) {
4026             return;
4027         }
4028         if (userId != UserHandle.getCallingUserId() &&
4029                 mContext.checkPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4030                         pid, uid)
4031                 != PackageManager.PERMISSION_GRANTED) {
4032             return;
4033         }
4034         setMasterMuteInternalNoCallerCheck(mute, flags, userId);
4035     }
4036 
setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId)4037     private void setMasterMuteInternalNoCallerCheck(boolean mute, int flags, int userId) {
4038         if (DEBUG_VOL) {
4039             Log.d(TAG, String.format("Master mute %s, %d, user=%d", mute, flags, userId));
4040         }
4041         if (!isPlatformAutomotive() && mUseFixedVolume) {
4042             // If using fixed volume, we don't mute.
4043             // TODO: remove the isPlatformAutomotive check here.
4044             // The isPlatformAutomotive check is added for safety but may not be necessary.
4045             return;
4046         }
4047         // For automotive,
4048         // - the car service is always running as system user
4049         // - foreground users are non-system users
4050         // Car service is in charge of dispatching the key event include global mute to Android.
4051         // Therefore, the getCurrentUser() is always different to the foreground user.
4052         if ((isPlatformAutomotive() && userId == UserHandle.USER_SYSTEM)
4053                 || (getCurrentUserId() == userId)) {
4054             if (mute != AudioSystem.getMasterMute()) {
4055                 setSystemAudioMute(mute);
4056                 AudioSystem.setMasterMute(mute);
4057                 sendMasterMuteUpdate(mute, flags);
4058             }
4059         }
4060     }
4061 
4062     /** get global mute state. */
isMasterMute()4063     public boolean isMasterMute() {
4064         return AudioSystem.getMasterMute();
4065     }
4066 
setMasterMute(boolean mute, int flags, String callingPackage, int userId)4067     public void setMasterMute(boolean mute, int flags, String callingPackage, int userId) {
4068         enforceModifyAudioRoutingPermission();
4069         setMasterMuteInternal(mute, flags, callingPackage, Binder.getCallingUid(),
4070                 userId, Binder.getCallingPid());
4071     }
4072 
4073     /** @see AudioManager#getStreamVolume(int) */
getStreamVolume(int streamType)4074     public int getStreamVolume(int streamType) {
4075         ensureValidStreamType(streamType);
4076         int device = getDeviceForStream(streamType);
4077         synchronized (VolumeStreamState.class) {
4078             int index = mStreamStates[streamType].getIndex(device);
4079 
4080             // by convention getStreamVolume() returns 0 when a stream is muted.
4081             if (mStreamStates[streamType].mIsMuted) {
4082                 index = 0;
4083             }
4084             if (index != 0 && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) &&
4085                     isFixedVolumeDevice(device)) {
4086                 index = mStreamStates[streamType].getMaxIndex();
4087             }
4088             return (index + 5) / 10;
4089         }
4090     }
4091 
4092     /** @see AudioManager#getStreamMaxVolume(int) */
getStreamMaxVolume(int streamType)4093     public int getStreamMaxVolume(int streamType) {
4094         ensureValidStreamType(streamType);
4095         return (mStreamStates[streamType].getMaxIndex() + 5) / 10;
4096     }
4097 
4098     /** @see AudioManager#getStreamMinVolumeInt(int)
4099      * Part of service interface, check permissions here */
getStreamMinVolume(int streamType)4100     public int getStreamMinVolume(int streamType) {
4101         ensureValidStreamType(streamType);
4102         final boolean isPrivileged =
4103                 Binder.getCallingUid() == Process.SYSTEM_UID
4104                  || callingHasAudioSettingsPermission()
4105                  || (mContext.checkCallingPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)
4106                         == PackageManager.PERMISSION_GRANTED);
4107         return (mStreamStates[streamType].getMinIndex(isPrivileged) + 5) / 10;
4108     }
4109 
4110     /** Get last audible volume before stream was muted. */
getLastAudibleStreamVolume(int streamType)4111     public int getLastAudibleStreamVolume(int streamType) {
4112         ensureValidStreamType(streamType);
4113         int device = getDeviceForStream(streamType);
4114         return (mStreamStates[streamType].getIndex(device) + 5) / 10;
4115     }
4116 
4117     /** @see AudioManager#getUiSoundsStreamType()
4118      * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for
4119      * UI Sounds identification.
4120      * Fallback on Voice configuration to ensure correct behavior of DnD feature.
4121      */
getUiSoundsStreamType()4122     public int getUiSoundsStreamType() {
4123         return mUseVolumeGroupAliases ? STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM]
4124                 : mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM];
4125     }
4126 
4127     /**
4128      * TODO(b/181140246): when using VolumeGroup alias, we are lacking configurability for
4129      * UI Sounds identification.
4130      * Fallback on Voice configuration to ensure correct behavior of DnD feature.
4131      */
isUiSoundsStreamType(int aliasStreamType)4132     private boolean isUiSoundsStreamType(int aliasStreamType) {
4133         return mUseVolumeGroupAliases
4134                 ? STREAM_VOLUME_ALIAS_VOICE[aliasStreamType]
4135                         == STREAM_VOLUME_ALIAS_VOICE[AudioSystem.STREAM_SYSTEM]
4136                 : aliasStreamType == mStreamVolumeAlias[AudioSystem.STREAM_SYSTEM];
4137     }
4138 
4139     /** @see AudioManager#setMicrophoneMute(boolean) */
4140     @Override
setMicrophoneMute(boolean on, String callingPackage, int userId)4141     public void setMicrophoneMute(boolean on, String callingPackage, int userId) {
4142         // If we are being called by the system check for user we are going to change
4143         // so we handle user restrictions correctly.
4144         int uid = Binder.getCallingUid();
4145         if (uid == android.os.Process.SYSTEM_UID) {
4146             uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4147         }
4148         MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
4149                 .setUid(uid)
4150                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackage)
4151                 .set(MediaMetrics.Property.EVENT, "setMicrophoneMute")
4152                 .set(MediaMetrics.Property.REQUEST, on
4153                         ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE);
4154 
4155         // If OP_MUTE_MICROPHONE is set, disallow unmuting.
4156         if (!on && !checkNoteAppOp(AppOpsManager.OP_MUTE_MICROPHONE, uid, callingPackage)) {
4157             mmi.set(MediaMetrics.Property.EARLY_RETURN, "disallow unmuting").record();
4158             return;
4159         }
4160         if (!checkAudioSettingsPermission("setMicrophoneMute()")) {
4161             mmi.set(MediaMetrics.Property.EARLY_RETURN, "!checkAudioSettingsPermission").record();
4162             return;
4163         }
4164         if (userId != UserHandle.getCallingUserId() &&
4165                 mContext.checkCallingOrSelfPermission(
4166                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
4167                 != PackageManager.PERMISSION_GRANTED) {
4168             mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission").record();
4169             return;
4170         }
4171         mMicMuteFromApi = on;
4172         mmi.record(); // record now, the no caller check will set the mute state.
4173         setMicrophoneMuteNoCallerCheck(userId);
4174     }
4175 
4176     /** @see AudioManager#setMicrophoneMuteFromSwitch(boolean) */
setMicrophoneMuteFromSwitch(boolean on)4177     public void setMicrophoneMuteFromSwitch(boolean on) {
4178         int userId = Binder.getCallingUid();
4179         if (userId != android.os.Process.SYSTEM_UID) {
4180             Log.e(TAG, "setMicrophoneMuteFromSwitch() called from non system user!");
4181             return;
4182         }
4183         mMicMuteFromSwitch = on;
4184         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
4185                 .setUid(userId)
4186                 .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteFromSwitch")
4187                 .set(MediaMetrics.Property.REQUEST, on
4188                         ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE)
4189                 .record();
4190         setMicrophoneMuteNoCallerCheck(userId);
4191     }
4192 
setMicMuteFromSwitchInput()4193     private void setMicMuteFromSwitchInput() {
4194         InputManager im = mContext.getSystemService(InputManager.class);
4195         final int isMicMuted = im.isMicMuted();
4196         if (isMicMuted != InputManager.SWITCH_STATE_UNKNOWN) {
4197             setMicrophoneMuteFromSwitch(im.isMicMuted() != InputManager.SWITCH_STATE_OFF);
4198         }
4199     }
4200 
4201     /**
4202      * Returns the microphone mute state as seen from the native audio system
4203      * @return true if microphone is reported as muted by primary HAL
4204      */
isMicrophoneMuted()4205     public boolean isMicrophoneMuted() {
4206         return mMicMuteFromSystemCached
4207                 && (!mMicMuteFromPrivacyToggle
4208                         || mMicMuteFromApi || mMicMuteFromRestrictions || mMicMuteFromSwitch);
4209     }
4210 
isMicrophoneSupposedToBeMuted()4211     private boolean isMicrophoneSupposedToBeMuted() {
4212         return mMicMuteFromSwitch || mMicMuteFromRestrictions || mMicMuteFromApi
4213                 || mMicMuteFromPrivacyToggle;
4214     }
4215 
setMicrophoneMuteNoCallerCheck(int userId)4216     private void setMicrophoneMuteNoCallerCheck(int userId) {
4217         final boolean muted = isMicrophoneSupposedToBeMuted();
4218         if (DEBUG_VOL) {
4219             Log.d(TAG, String.format("Mic mute %b, user=%d", muted, userId));
4220         }
4221         // only mute for the current user
4222         if (getCurrentUserId() == userId || userId == android.os.Process.SYSTEM_UID) {
4223             final boolean currentMute = mAudioSystem.isMicrophoneMuted();
4224             final long identity = Binder.clearCallingIdentity();
4225             final int ret = mAudioSystem.muteMicrophone(muted);
4226 
4227             // update cache with the real state independently from what was set
4228             mMicMuteFromSystemCached = mAudioSystem.isMicrophoneMuted();
4229             if (ret != AudioSystem.AUDIO_STATUS_OK) {
4230                 Log.e(TAG, "Error changing mic mute state to " + muted + " current:"
4231                         + mMicMuteFromSystemCached);
4232             }
4233 
4234             new MediaMetrics.Item(MediaMetrics.Name.AUDIO_MIC)
4235                     .setUid(userId)
4236                     .set(MediaMetrics.Property.EVENT, "setMicrophoneMuteNoCallerCheck")
4237                     .set(MediaMetrics.Property.MUTE, mMicMuteFromSystemCached
4238                             ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
4239                     .set(MediaMetrics.Property.REQUEST, muted
4240                             ? MediaMetrics.Value.MUTE : MediaMetrics.Value.UNMUTE)
4241                     .set(MediaMetrics.Property.STATUS, ret)
4242                     .record();
4243 
4244             try {
4245                 // send the intent even if there was a failure to change the actual mute state:
4246                 // the AudioManager.setMicrophoneMute API doesn't have a return value to
4247                 // indicate if the call failed to successfully change the mute state, and receiving
4248                 // the intent may be the only time an application can resynchronize its mic mute
4249                 // state with the actual system mic mute state
4250                 if (muted != currentMute) {
4251                     sendMsg(mAudioHandler, MSG_BROADCAST_MICROPHONE_MUTE,
4252                                 SENDMSG_NOOP, 0, 0, null, 0);
4253                 }
4254             } finally {
4255                 Binder.restoreCallingIdentity(identity);
4256             }
4257         }
4258     }
4259 
4260     @Override
getRingerModeExternal()4261     public int getRingerModeExternal() {
4262         synchronized(mSettingsLock) {
4263             return mRingerModeExternal;
4264         }
4265     }
4266 
4267     @Override
getRingerModeInternal()4268     public int getRingerModeInternal() {
4269         synchronized(mSettingsLock) {
4270             return mRingerMode;
4271         }
4272     }
4273 
ensureValidRingerMode(int ringerMode)4274     private void ensureValidRingerMode(int ringerMode) {
4275         if (!isValidRingerMode(ringerMode)) {
4276             throw new IllegalArgumentException("Bad ringer mode " + ringerMode);
4277         }
4278     }
4279 
4280     /** @see AudioManager#isValidRingerMode(int) */
isValidRingerMode(int ringerMode)4281     public boolean isValidRingerMode(int ringerMode) {
4282         return ringerMode >= 0 && ringerMode <= AudioManager.RINGER_MODE_MAX;
4283     }
4284 
setRingerModeExternal(int ringerMode, String caller)4285     public void setRingerModeExternal(int ringerMode, String caller) {
4286         if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode)
4287                 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)) {
4288             throw new SecurityException("Not allowed to change Do Not Disturb state");
4289         }
4290 
4291         setRingerMode(ringerMode, caller, true /*external*/);
4292     }
4293 
setRingerModeInternal(int ringerMode, String caller)4294     public void setRingerModeInternal(int ringerMode, String caller) {
4295         enforceVolumeController("setRingerModeInternal");
4296         setRingerMode(ringerMode, caller, false /*external*/);
4297     }
4298 
silenceRingerModeInternal(String reason)4299     public void silenceRingerModeInternal(String reason) {
4300         VibrationEffect effect = null;
4301         int ringerMode = AudioManager.RINGER_MODE_SILENT;
4302         int toastText = 0;
4303 
4304         int silenceRingerSetting = Settings.Secure.VOLUME_HUSH_OFF;
4305         if (mContext.getResources()
4306                 .getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled)) {
4307             silenceRingerSetting = Settings.Secure.getIntForUser(mContentResolver,
4308                     Settings.Secure.VOLUME_HUSH_GESTURE, VOLUME_HUSH_OFF,
4309                     UserHandle.USER_CURRENT);
4310         }
4311 
4312         switch(silenceRingerSetting) {
4313             case VOLUME_HUSH_MUTE:
4314                 effect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK);
4315                 ringerMode = AudioManager.RINGER_MODE_SILENT;
4316                 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_silent;
4317                 break;
4318             case VOLUME_HUSH_VIBRATE:
4319                 effect = VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK);
4320                 ringerMode = AudioManager.RINGER_MODE_VIBRATE;
4321                 toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_vibrate;
4322                 break;
4323         }
4324         maybeVibrate(effect, reason);
4325         setRingerModeInternal(ringerMode, reason);
4326         Toast.makeText(mContext, toastText, Toast.LENGTH_SHORT).show();
4327     }
4328 
maybeVibrate(VibrationEffect effect, String reason)4329     private boolean maybeVibrate(VibrationEffect effect, String reason) {
4330         if (!mHasVibrator) {
4331             return false;
4332         }
4333         final boolean hapticsDisabled = Settings.System.getIntForUser(mContext.getContentResolver(),
4334                 Settings.System.HAPTIC_FEEDBACK_ENABLED, 0, UserHandle.USER_CURRENT) == 0;
4335         if (hapticsDisabled) {
4336             return false;
4337         }
4338 
4339         if (effect == null) {
4340             return false;
4341         }
4342         mVibrator.vibrate(Binder.getCallingUid(), mContext.getOpPackageName(), effect,
4343                 reason, VIBRATION_ATTRIBUTES);
4344         return true;
4345     }
4346 
setRingerMode(int ringerMode, String caller, boolean external)4347     private void setRingerMode(int ringerMode, String caller, boolean external) {
4348         if (mUseFixedVolume || mIsSingleVolume) {
4349             return;
4350         }
4351         if (caller == null || caller.length() == 0) {
4352             throw new IllegalArgumentException("Bad caller: " + caller);
4353         }
4354         ensureValidRingerMode(ringerMode);
4355         if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) {
4356             ringerMode = AudioManager.RINGER_MODE_SILENT;
4357         }
4358         final long identity = Binder.clearCallingIdentity();
4359         try {
4360             synchronized (mSettingsLock) {
4361                 final int ringerModeInternal = getRingerModeInternal();
4362                 final int ringerModeExternal = getRingerModeExternal();
4363                 if (external) {
4364                     setRingerModeExt(ringerMode);
4365                     if (mRingerModeDelegate != null) {
4366                         ringerMode = mRingerModeDelegate.onSetRingerModeExternal(ringerModeExternal,
4367                                 ringerMode, caller, ringerModeInternal, mVolumePolicy);
4368                     }
4369                     if (ringerMode != ringerModeInternal) {
4370                         setRingerModeInt(ringerMode, true /*persist*/);
4371                     }
4372                 } else /*internal*/ {
4373                     if (ringerMode != ringerModeInternal) {
4374                         setRingerModeInt(ringerMode, true /*persist*/);
4375                     }
4376                     if (mRingerModeDelegate != null) {
4377                         ringerMode = mRingerModeDelegate.onSetRingerModeInternal(ringerModeInternal,
4378                                 ringerMode, caller, ringerModeExternal, mVolumePolicy);
4379                     }
4380                     setRingerModeExt(ringerMode);
4381                 }
4382             }
4383         } finally {
4384             Binder.restoreCallingIdentity(identity);
4385         }
4386     }
4387 
setRingerModeExt(int ringerMode)4388     private void setRingerModeExt(int ringerMode) {
4389         synchronized(mSettingsLock) {
4390             if (ringerMode == mRingerModeExternal) return;
4391             mRingerModeExternal = ringerMode;
4392         }
4393         // Send sticky broadcast
4394         broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, ringerMode);
4395     }
4396 
4397     @GuardedBy("mSettingsLock")
muteRingerModeStreams()4398     private void muteRingerModeStreams() {
4399         // Mute stream if not previously muted by ringer mode and (ringer mode
4400         // is not RINGER_MODE_NORMAL OR stream is zen muted) and stream is affected by ringer mode.
4401         // Unmute stream if previously muted by ringer/zen mode and ringer mode
4402         // is RINGER_MODE_NORMAL or stream is not affected by ringer mode.
4403         int numStreamTypes = AudioSystem.getNumStreamTypes();
4404 
4405         if (mNm == null) {
4406             mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
4407         }
4408 
4409         final int ringerMode = mRingerMode; // Read ringer mode as reading primitives is atomic
4410         final boolean ringerModeMute = ringerMode == AudioManager.RINGER_MODE_VIBRATE
4411                 || ringerMode == AudioManager.RINGER_MODE_SILENT;
4412         final boolean shouldRingSco = ringerMode == AudioManager.RINGER_MODE_VIBRATE
4413                 && mDeviceBroker.isBluetoothScoActive();
4414         // Ask audio policy engine to force use Bluetooth SCO channel if needed
4415         final String eventSource = "muteRingerModeStreams() from u/pid:" + Binder.getCallingUid()
4416                 + "/" + Binder.getCallingPid();
4417         sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, AudioSystem.FOR_VIBRATE_RINGING,
4418                 shouldRingSco ? AudioSystem.FORCE_BT_SCO : AudioSystem.FORCE_NONE, eventSource, 0);
4419 
4420         for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
4421             final boolean isMuted = isStreamMutedByRingerOrZenMode(streamType);
4422             final boolean muteAllowedBySco =
4423                     !(shouldRingSco && streamType == AudioSystem.STREAM_RING);
4424             final boolean shouldZenMute = shouldZenMuteStream(streamType);
4425             final boolean shouldMute = shouldZenMute || (ringerModeMute
4426                     && isStreamAffectedByRingerMode(streamType) && muteAllowedBySco);
4427             if (isMuted == shouldMute) continue;
4428             if (!shouldMute) {
4429                 // unmute
4430                 // ring and notifications volume should never be 0 when not silenced
4431                 if (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING) {
4432                     synchronized (VolumeStreamState.class) {
4433                         final VolumeStreamState vss = mStreamStates[streamType];
4434                         for (int i = 0; i < vss.mIndexMap.size(); i++) {
4435                             int device = vss.mIndexMap.keyAt(i);
4436                             int value = vss.mIndexMap.valueAt(i);
4437                             if (value == 0) {
4438                                 vss.setIndex(10, device, TAG, true /*hasModifyAudioSettings*/);
4439                             }
4440                         }
4441                         // Persist volume for stream ring when it is changed here
4442                       final int device = getDeviceForStream(streamType);
4443                       sendMsg(mAudioHandler,
4444                               MSG_PERSIST_VOLUME,
4445                               SENDMSG_QUEUE,
4446                               device,
4447                               0,
4448                               mStreamStates[streamType],
4449                               PERSIST_DELAY);
4450                     }
4451                 }
4452                 mStreamStates[streamType].mute(false);
4453                 mRingerAndZenModeMutedStreams &= ~(1 << streamType);
4454             } else {
4455                 // mute
4456                 mStreamStates[streamType].mute(true);
4457                 mRingerAndZenModeMutedStreams |= (1 << streamType);
4458             }
4459         }
4460     }
4461 
isAlarm(int streamType)4462     private boolean isAlarm(int streamType) {
4463         return streamType == AudioSystem.STREAM_ALARM;
4464     }
4465 
isNotificationOrRinger(int streamType)4466     private boolean isNotificationOrRinger(int streamType) {
4467         return streamType == AudioSystem.STREAM_NOTIFICATION
4468                 || streamType == AudioSystem.STREAM_RING;
4469     }
4470 
isMedia(int streamType)4471     private boolean isMedia(int streamType) {
4472         return streamType == AudioSystem.STREAM_MUSIC;
4473     }
4474 
4475 
isSystem(int streamType)4476     private boolean isSystem(int streamType) {
4477         return streamType == AudioSystem.STREAM_SYSTEM;
4478     }
4479 
setRingerModeInt(int ringerMode, boolean persist)4480     private void setRingerModeInt(int ringerMode, boolean persist) {
4481         final boolean change;
4482         synchronized(mSettingsLock) {
4483             change = mRingerMode != ringerMode;
4484             mRingerMode = ringerMode;
4485             muteRingerModeStreams();
4486         }
4487 
4488         // Post a persist ringer mode msg
4489         if (persist) {
4490             sendMsg(mAudioHandler, MSG_PERSIST_RINGER_MODE,
4491                     SENDMSG_REPLACE, 0, 0, null, PERSIST_DELAY);
4492         }
4493         if (change) {
4494             // Send sticky broadcast
4495             broadcastRingerMode(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION, ringerMode);
4496         }
4497     }
4498 
postUpdateRingerModeServiceInt()4499     /*package*/ void postUpdateRingerModeServiceInt() {
4500         sendMsg(mAudioHandler, MSG_UPDATE_RINGER_MODE, SENDMSG_QUEUE, 0, 0, null, 0);
4501     }
4502 
onUpdateRingerModeServiceInt()4503     private void onUpdateRingerModeServiceInt() {
4504         setRingerModeInt(getRingerModeInternal(), false);
4505     }
4506 
4507     /** @see AudioManager#shouldVibrate(int) */
shouldVibrate(int vibrateType)4508     public boolean shouldVibrate(int vibrateType) {
4509         if (!mHasVibrator) return false;
4510 
4511         switch (getVibrateSetting(vibrateType)) {
4512 
4513             case AudioManager.VIBRATE_SETTING_ON:
4514                 return getRingerModeExternal() != AudioManager.RINGER_MODE_SILENT;
4515 
4516             case AudioManager.VIBRATE_SETTING_ONLY_SILENT:
4517                 return getRingerModeExternal() == AudioManager.RINGER_MODE_VIBRATE;
4518 
4519             case AudioManager.VIBRATE_SETTING_OFF:
4520                 // return false, even for incoming calls
4521                 return false;
4522 
4523             default:
4524                 return false;
4525         }
4526     }
4527 
4528     /** @see AudioManager#getVibrateSetting(int) */
getVibrateSetting(int vibrateType)4529     public int getVibrateSetting(int vibrateType) {
4530         if (!mHasVibrator) return AudioManager.VIBRATE_SETTING_OFF;
4531         return (mVibrateSetting >> (vibrateType * 2)) & 3;
4532     }
4533 
4534     /** @see AudioManager#setVibrateSetting(int, int) */
setVibrateSetting(int vibrateType, int vibrateSetting)4535     public void setVibrateSetting(int vibrateType, int vibrateSetting) {
4536 
4537         if (!mHasVibrator) return;
4538 
4539         mVibrateSetting = AudioSystem.getValueForVibrateSetting(mVibrateSetting, vibrateType,
4540                 vibrateSetting);
4541 
4542         // Broadcast change
4543         broadcastVibrateSetting(vibrateType);
4544 
4545     }
4546 
4547     private class SetModeDeathHandler implements IBinder.DeathRecipient {
4548         private final IBinder mCb; // To be notified of client's death
4549         private final int mPid;
4550         private final int mUid;
4551         private final boolean mIsPrivileged;
4552         private final String mPackage;
4553         private int mMode;
4554         private long mUpdateTime;
4555         private boolean mPlaybackActive = false;
4556         private boolean mRecordingActive = false;
4557 
SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged, String caller, int mode)4558         SetModeDeathHandler(IBinder cb, int pid, int uid, boolean isPrivileged,
4559                             String caller, int mode) {
4560             mMode = mode;
4561             mCb = cb;
4562             mPid = pid;
4563             mUid = uid;
4564             mPackage = caller;
4565             mIsPrivileged = isPrivileged;
4566             mUpdateTime = java.lang.System.currentTimeMillis();
4567         }
4568 
binderDied()4569         public void binderDied() {
4570             synchronized (mDeviceBroker.mSetModeLock) {
4571                 Log.w(TAG, "SetModeDeathHandler client died");
4572                 int index = mSetModeDeathHandlers.indexOf(this);
4573                 if (index < 0) {
4574                     Log.w(TAG, "unregistered SetModeDeathHandler client died");
4575                 } else {
4576                     SetModeDeathHandler h = mSetModeDeathHandlers.get(index);
4577                     mSetModeDeathHandlers.remove(index);
4578                     sendMsg(mAudioHandler,
4579                             MSG_UPDATE_AUDIO_MODE,
4580                             SENDMSG_QUEUE,
4581                             AudioSystem.MODE_CURRENT,
4582                             android.os.Process.myPid(),
4583                             mContext.getPackageName(),
4584                             0);
4585                 }
4586             }
4587         }
4588 
getPid()4589         public int getPid() {
4590             return mPid;
4591         }
4592 
setMode(int mode)4593         public void setMode(int mode) {
4594             mMode = mode;
4595             mUpdateTime = java.lang.System.currentTimeMillis();
4596         }
4597 
getMode()4598         public int getMode() {
4599             return mMode;
4600         }
4601 
getBinder()4602         public IBinder getBinder() {
4603             return mCb;
4604         }
4605 
getUid()4606         public int getUid() {
4607             return mUid;
4608         }
4609 
getPackage()4610         public String getPackage() {
4611             return mPackage;
4612         }
4613 
isPrivileged()4614         public boolean isPrivileged() {
4615             return mIsPrivileged;
4616         }
4617 
getUpdateTime()4618         public long getUpdateTime() {
4619             return mUpdateTime;
4620         }
4621 
setPlaybackActive(boolean active)4622         public void setPlaybackActive(boolean active) {
4623             mPlaybackActive = active;
4624         }
4625 
setRecordingActive(boolean active)4626         public void setRecordingActive(boolean active) {
4627             mRecordingActive = active;
4628         }
4629 
4630         /**
4631          * An app is considered active if:
4632          * - It is privileged (has MODIFY_PHONE_STATE permission)
4633          *  or
4634          * - It requests mode MODE_IN_COMMUNICATION, and it is either playing
4635          * or recording for VOICE_COMMUNICATION.
4636          *   or
4637          * - It requests a mode different from MODE_IN_COMMUNICATION or MODE_NORMAL
4638          */
isActive()4639         public boolean isActive() {
4640             return mIsPrivileged
4641                     || ((mMode == AudioSystem.MODE_IN_COMMUNICATION)
4642                         && (mRecordingActive || mPlaybackActive))
4643                     || mMode == AudioSystem.MODE_IN_CALL
4644                     || mMode == AudioSystem.MODE_RINGTONE
4645                     || mMode == AudioSystem.MODE_CALL_SCREENING;
4646         }
4647 
dump(PrintWriter pw, int index)4648         public void dump(PrintWriter pw, int index) {
4649             SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm:ss:SSS");
4650 
4651             if (index >= 0) {
4652                 pw.println("  Requester # " + (index + 1) + ":");
4653             }
4654             pw.println("  - Mode: " + AudioSystem.modeToString(mMode));
4655             pw.println("  - Binder: " + mCb);
4656             pw.println("  - Pid: " + mPid);
4657             pw.println("  - Uid: " + mUid);
4658             pw.println("  - Package: " + mPackage);
4659             pw.println("  - Privileged: " + mIsPrivileged);
4660             pw.println("  - Active: " + isActive());
4661             pw.println("    Playback active: " + mPlaybackActive);
4662             pw.println("    Recording active: " + mRecordingActive);
4663             pw.println("  - update time: " + format.format(new Date(mUpdateTime)));
4664         }
4665     }
4666 
4667     @GuardedBy("mDeviceBroker.mSetModeLock")
getAudioModeOwnerHandler()4668     private SetModeDeathHandler getAudioModeOwnerHandler() {
4669         // The Audio mode owner is:
4670         // 1) the most recent privileged app in the stack
4671         // 2) the most recent active app in the tack
4672         SetModeDeathHandler modeOwner = null;
4673         SetModeDeathHandler privilegedModeOwner = null;
4674         for (SetModeDeathHandler h : mSetModeDeathHandlers) {
4675             if (h.isActive()) {
4676                 // privileged apps are always active
4677                 if (h.isPrivileged()) {
4678                     if (privilegedModeOwner == null
4679                             || h.getUpdateTime() > privilegedModeOwner.getUpdateTime()) {
4680                         privilegedModeOwner = h;
4681                     }
4682                 } else {
4683                     if (modeOwner == null
4684                             || h.getUpdateTime() > modeOwner.getUpdateTime()) {
4685                         modeOwner = h;
4686                     }
4687                 }
4688             }
4689         }
4690         return privilegedModeOwner != null ? privilegedModeOwner :  modeOwner;
4691     }
4692 
4693     /**
4694      * Return the pid of the current audio mode owner
4695      * @return 0 if nobody owns the mode
4696      */
4697     @GuardedBy("mDeviceBroker.mSetModeLock")
getModeOwnerPid()4698     /*package*/ int getModeOwnerPid() {
4699         SetModeDeathHandler hdlr = getAudioModeOwnerHandler();
4700         if (hdlr != null) {
4701             return hdlr.getPid();
4702         }
4703         return 0;
4704     }
4705 
4706     /**
4707      * Return the uid of the current audio mode owner
4708      * @return 0 if nobody owns the mode
4709      */
4710     @GuardedBy("mDeviceBroker.mSetModeLock")
getModeOwnerUid()4711     /*package*/ int getModeOwnerUid() {
4712         SetModeDeathHandler hdlr = getAudioModeOwnerHandler();
4713         if (hdlr != null) {
4714             return hdlr.getUid();
4715         }
4716         return 0;
4717     }
4718 
4719     /** @see AudioManager#setMode(int) */
setMode(int mode, IBinder cb, String callingPackage)4720     public void setMode(int mode, IBinder cb, String callingPackage) {
4721         int pid = Binder.getCallingPid();
4722         int uid = Binder.getCallingUid();
4723         if (DEBUG_MODE) {
4724             Log.v(TAG, "setMode(mode=" + mode + ", pid=" + pid
4725                     + ", uid=" + uid + ", caller=" + callingPackage + ")");
4726         }
4727         if (!checkAudioSettingsPermission("setMode()")) {
4728             return;
4729         }
4730         if (cb == null) {
4731             Log.e(TAG, "setMode() called with null binder");
4732             return;
4733         }
4734         if (mode < AudioSystem.MODE_CURRENT || mode >= AudioSystem.NUM_MODES) {
4735             Log.w(TAG, "setMode() invalid mode: " + mode);
4736             return;
4737         }
4738 
4739         if (mode == AudioSystem.MODE_CURRENT) {
4740             mode = getMode();
4741         }
4742 
4743         if (mode == AudioSystem.MODE_CALL_SCREENING && !mIsCallScreeningModeSupported) {
4744             Log.w(TAG, "setMode(MODE_CALL_SCREENING) not permitted "
4745                     + "when call screening is not supported");
4746             return;
4747         }
4748 
4749         final boolean hasModifyPhoneStatePermission = mContext.checkCallingOrSelfPermission(
4750                 android.Manifest.permission.MODIFY_PHONE_STATE)
4751                 == PackageManager.PERMISSION_GRANTED;
4752         if ((mode == AudioSystem.MODE_IN_CALL) && !hasModifyPhoneStatePermission) {
4753             Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setMode(MODE_IN_CALL) from pid="
4754                     + pid + ", uid=" + Binder.getCallingUid());
4755             return;
4756         }
4757 
4758         SetModeDeathHandler currentModeHandler = null;
4759         synchronized (mDeviceBroker.mSetModeLock) {
4760             for (SetModeDeathHandler h : mSetModeDeathHandlers) {
4761                 if (h.getPid() == pid) {
4762                     currentModeHandler = h;
4763                     break;
4764                 }
4765             }
4766 
4767             if (mode == AudioSystem.MODE_NORMAL) {
4768                 if (currentModeHandler != null) {
4769                     if (!currentModeHandler.isPrivileged()
4770                             && currentModeHandler.getMode() == AudioSystem.MODE_IN_COMMUNICATION) {
4771                         mAudioHandler.removeEqualMessages(
4772                                 MSG_CHECK_MODE_FOR_UID, currentModeHandler);
4773                     }
4774                     mSetModeDeathHandlers.remove(currentModeHandler);
4775                     if (DEBUG_MODE) {
4776                         Log.v(TAG, "setMode(" + mode + ") removing hldr for pid: " + pid);
4777                     }
4778                     try {
4779                         currentModeHandler.getBinder().unlinkToDeath(currentModeHandler, 0);
4780                     } catch (NoSuchElementException e) {
4781                         Log.w(TAG, "setMode link does not exist ...");
4782                     }
4783                 }
4784             } else {
4785                 if (currentModeHandler != null) {
4786                     currentModeHandler.setMode(mode);
4787                     if (DEBUG_MODE) {
4788                         Log.v(TAG, "setMode(" + mode + ") updating hldr for pid: " + pid);
4789                     }
4790                 } else {
4791                     currentModeHandler = new SetModeDeathHandler(cb, pid, uid,
4792                             hasModifyPhoneStatePermission, callingPackage, mode);
4793                     // Register for client death notification
4794                     try {
4795                         cb.linkToDeath(currentModeHandler, 0);
4796                     } catch (RemoteException e) {
4797                         // Client has died!
4798                         Log.w(TAG, "setMode() could not link to " + cb + " binder death");
4799                         return;
4800                     }
4801                     mSetModeDeathHandlers.add(currentModeHandler);
4802                     if (DEBUG_MODE) {
4803                         Log.v(TAG, "setMode(" + mode + ") adding handler for pid=" + pid);
4804                     }
4805                 }
4806                 if (mode == AudioSystem.MODE_IN_COMMUNICATION) {
4807                     // Force active state when entering/updating the stack to avoid glitches when
4808                     // an app starts playing/recording after settng the audio mode,
4809                     // and send a reminder to check activity after a grace period.
4810                     if (!currentModeHandler.isPrivileged()) {
4811                         currentModeHandler.setPlaybackActive(true);
4812                         currentModeHandler.setRecordingActive(true);
4813                         sendMsg(mAudioHandler,
4814                                 MSG_CHECK_MODE_FOR_UID,
4815                                 SENDMSG_QUEUE,
4816                                 0,
4817                                 0,
4818                                 currentModeHandler,
4819                                 CHECK_MODE_FOR_UID_PERIOD_MS);
4820                     }
4821                 }
4822             }
4823 
4824             sendMsg(mAudioHandler,
4825                     MSG_UPDATE_AUDIO_MODE,
4826                     SENDMSG_REPLACE,
4827                     mode,
4828                     pid,
4829                     callingPackage,
4830                     0);
4831         }
4832     }
4833 
4834     @GuardedBy("mDeviceBroker.mSetModeLock")
onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage, boolean force)4835     void onUpdateAudioMode(int requestedMode, int requesterPid, String requesterPackage,
4836                            boolean force) {
4837         if (requestedMode == AudioSystem.MODE_CURRENT) {
4838             requestedMode = getMode();
4839         }
4840         int mode = AudioSystem.MODE_NORMAL;
4841         int uid = 0;
4842         int pid = 0;
4843         SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler();
4844         if (currentModeHandler != null) {
4845             mode = currentModeHandler.getMode();
4846             uid = currentModeHandler.getUid();
4847             pid = currentModeHandler.getPid();
4848         }
4849         if (DEBUG_MODE) {
4850             Log.v(TAG, "onUpdateAudioMode() new mode: " + mode + ", current mode: "
4851                     + mMode.get() + " requested mode: " + requestedMode);
4852         }
4853         if (mode != mMode.get() || force) {
4854             final long identity = Binder.clearCallingIdentity();
4855             int status = mAudioSystem.setPhoneState(mode, uid);
4856             Binder.restoreCallingIdentity(identity);
4857             if (status == AudioSystem.AUDIO_STATUS_OK) {
4858                 if (DEBUG_MODE) {
4859                     Log.v(TAG, "onUpdateAudioMode: mode successfully set to " + mode);
4860                 }
4861                 sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_MODE, SENDMSG_REPLACE, mode, 0,
4862                         /*obj*/ null, /*delay*/ 0);
4863                 int previousMode = mMode.getAndSet(mode);
4864                 // Note: newModeOwnerPid is always 0 when actualMode is MODE_NORMAL
4865                 mModeLogger.log(new PhoneStateEvent(requesterPackage, requesterPid,
4866                         requestedMode, pid, mode));
4867 
4868                 int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
4869                 int device = getDeviceForStream(streamType);
4870                 int index = mStreamStates[mStreamVolumeAlias[streamType]].getIndex(device);
4871                 setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, true,
4872                         requesterPackage, true /*hasModifyAudioSettings*/);
4873 
4874                 updateStreamVolumeAlias(true /*updateVolumes*/, requesterPackage);
4875 
4876                 // change of mode may require volume to be re-applied on some devices
4877                 updateAbsVolumeMultiModeDevices(previousMode, mode);
4878 
4879                 // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all SCO
4880                 // connections not started by the application changing the mode when pid changes
4881                 mDeviceBroker.postSetModeOwnerPid(pid, mode);
4882             } else {
4883                 Log.w(TAG, "onUpdateAudioMode: failed to set audio mode to: " + mode);
4884             }
4885         }
4886     }
4887 
4888     /** @see AudioManager#getMode() */
getMode()4889     public int getMode() {
4890         synchronized (mDeviceBroker.mSetModeLock) {
4891             SetModeDeathHandler currentModeHandler = getAudioModeOwnerHandler();
4892             if (currentModeHandler != null) {
4893                 return currentModeHandler.getMode();
4894             }
4895             return AudioSystem.MODE_NORMAL;
4896         }
4897     }
4898 
4899     /** cached value read from audiopolicy manager after initialization. */
4900     private boolean mIsCallScreeningModeSupported = false;
4901 
4902     /** @see AudioManager#isCallScreeningModeSupported() */
isCallScreeningModeSupported()4903     public boolean isCallScreeningModeSupported() {
4904         return mIsCallScreeningModeSupported;
4905     }
4906 
dispatchMode(int mode)4907     protected void dispatchMode(int mode) {
4908         final int nbDispatchers = mModeDispatchers.beginBroadcast();
4909         for (int i = 0; i < nbDispatchers; i++) {
4910             try {
4911                 mModeDispatchers.getBroadcastItem(i).dispatchAudioModeChanged(mode);
4912             } catch (RemoteException e) {
4913             }
4914         }
4915         mModeDispatchers.finishBroadcast();
4916     }
4917 
4918     final RemoteCallbackList<IAudioModeDispatcher> mModeDispatchers =
4919             new RemoteCallbackList<IAudioModeDispatcher>();
4920 
4921     /**
4922      * @see {@link AudioManager#addOnModeChangedListener(Executor, AudioManager.OnModeChangedListener)}
4923      * @param dispatcher
4924      */
registerModeDispatcher( @onNull IAudioModeDispatcher dispatcher)4925     public void registerModeDispatcher(
4926             @NonNull IAudioModeDispatcher dispatcher) {
4927         mModeDispatchers.register(dispatcher);
4928     }
4929 
4930     /**
4931      * @see {@link AudioManager#removeOnModeChangedListener(AudioManager.OnModeChangedListener)}
4932      * @param dispatcher
4933      */
unregisterModeDispatcher( @onNull IAudioModeDispatcher dispatcher)4934     public void unregisterModeDispatcher(
4935             @NonNull IAudioModeDispatcher dispatcher) {
4936         mModeDispatchers.unregister(dispatcher);
4937     }
4938 
4939     /** @see AudioManager#setRttEnabled() */
4940     @Override
setRttEnabled(boolean rttEnabled)4941     public void setRttEnabled(boolean rttEnabled) {
4942         if (mContext.checkCallingOrSelfPermission(
4943                 android.Manifest.permission.MODIFY_PHONE_STATE)
4944                 != PackageManager.PERMISSION_GRANTED) {
4945             Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setRttEnabled from pid="
4946                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
4947             return;
4948         }
4949         synchronized (mSettingsLock) {
4950             mRttEnabled = rttEnabled;
4951             final long identity = Binder.clearCallingIdentity();
4952             try {
4953                 AudioSystem.setRttEnabled(rttEnabled);
4954             } finally {
4955                 Binder.restoreCallingIdentity(identity);
4956             }
4957         }
4958     }
4959 
4960     /** @see AudioManager#adjustSuggestedStreamVolumeForUid(int, int, int, String, int, int, int) */
4961     @Override
adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)4962     public void adjustSuggestedStreamVolumeForUid(int streamType, int direction, int flags,
4963             @NonNull String packageName, int uid, int pid, UserHandle userHandle,
4964             int targetSdkVersion) {
4965         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
4966             throw new SecurityException("Should only be called from system process");
4967         }
4968 
4969         // direction and stream type swap here because the public
4970         // adjustSuggested has a different order than the other methods.
4971         adjustSuggestedStreamVolume(direction, streamType, flags, packageName, packageName,
4972                 uid, pid, hasAudioSettingsPermission(uid, pid), VOL_ADJUST_NORMAL);
4973     }
4974 
4975     /** @see AudioManager#adjustStreamVolumeForUid(int, int, int, String, int, int, int) */
4976     @Override
adjustStreamVolumeForUid(int streamType, int direction, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)4977     public void adjustStreamVolumeForUid(int streamType, int direction, int flags,
4978             @NonNull String packageName, int uid, int pid, UserHandle userHandle,
4979             int targetSdkVersion) {
4980         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
4981             throw new SecurityException("Should only be called from system process");
4982         }
4983 
4984         if (direction != AudioManager.ADJUST_SAME) {
4985             sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_ADJUST_VOL_UID, streamType,
4986                     direction/*val1*/, flags/*val2*/,
4987                     new StringBuilder(packageName).append(" uid:").append(uid)
4988                     .toString()));
4989         }
4990 
4991         adjustStreamVolume(streamType, direction, flags, packageName, packageName, uid, pid,
4992                 hasAudioSettingsPermission(uid, pid), VOL_ADJUST_NORMAL);
4993     }
4994 
4995     /** @see AudioManager#setStreamVolumeForUid(int, int, int, String, int, int, int) */
4996     @Override
setStreamVolumeForUid(int streamType, int index, int flags, @NonNull String packageName, int uid, int pid, UserHandle userHandle, int targetSdkVersion)4997     public void setStreamVolumeForUid(int streamType, int index, int flags,
4998             @NonNull String packageName, int uid, int pid, UserHandle userHandle,
4999             int targetSdkVersion) {
5000         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
5001             throw new SecurityException("Should only be called from system process");
5002         }
5003 
5004         setStreamVolume(streamType, index, flags, packageName, packageName, uid,
5005                 hasAudioSettingsPermission(uid, pid));
5006     }
5007 
5008     //==========================================================================================
5009     // Sound Effects
5010     //==========================================================================================
5011     private static final class LoadSoundEffectReply
5012             implements SoundEffectsHelper.OnEffectsLoadCompleteHandler {
5013         private static final int SOUND_EFFECTS_LOADING = 1;
5014         private static final int SOUND_EFFECTS_LOADED = 0;
5015         private static final int SOUND_EFFECTS_ERROR = -1;
5016         private static final int SOUND_EFFECTS_LOAD_TIMEOUT_MS = 5000;
5017 
5018         private int mStatus = SOUND_EFFECTS_LOADING;
5019 
5020         @Override
run(boolean success)5021         public synchronized void run(boolean success) {
5022             mStatus = success ? SOUND_EFFECTS_LOADED : SOUND_EFFECTS_ERROR;
5023             notify();
5024         }
5025 
waitForLoaded(int attempts)5026         public synchronized boolean waitForLoaded(int attempts) {
5027             while ((mStatus == SOUND_EFFECTS_LOADING) && (attempts-- > 0)) {
5028                 try {
5029                     wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS);
5030                 } catch (InterruptedException e) {
5031                     Log.w(TAG, "Interrupted while waiting sound pool loaded.");
5032                 }
5033             }
5034             return mStatus == SOUND_EFFECTS_LOADED;
5035         }
5036     }
5037 
5038     /** @see AudioManager#playSoundEffect(int) */
playSoundEffect(int effectType)5039     public void playSoundEffect(int effectType) {
5040         playSoundEffectVolume(effectType, -1.0f);
5041     }
5042 
5043     /** @see AudioManager#playSoundEffect(int, float) */
playSoundEffectVolume(int effectType, float volume)5044     public void playSoundEffectVolume(int effectType, float volume) {
5045         // do not try to play the sound effect if the system stream is muted
5046         if (isStreamMute(STREAM_SYSTEM)) {
5047             return;
5048         }
5049 
5050         if (effectType >= AudioManager.NUM_SOUND_EFFECTS || effectType < 0) {
5051             Log.w(TAG, "AudioService effectType value " + effectType + " out of range");
5052             return;
5053         }
5054 
5055         sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SENDMSG_QUEUE,
5056                 effectType, (int) (volume * 1000), null, 0);
5057     }
5058 
5059     /**
5060      * Loads samples into the soundpool.
5061      * This method must be called at first when sound effects are enabled
5062      */
loadSoundEffects()5063     public boolean loadSoundEffects() {
5064         LoadSoundEffectReply reply = new LoadSoundEffectReply();
5065         sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, reply, 0);
5066         return reply.waitForLoaded(3 /*attempts*/);
5067     }
5068 
5069     /**
5070      * Schedule loading samples into the soundpool.
5071      * This method can be overridden to schedule loading at a later time.
5072      */
scheduleLoadSoundEffects()5073     protected void scheduleLoadSoundEffects() {
5074         sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0);
5075     }
5076 
5077     /**
5078      *  Unloads samples from the sound pool.
5079      *  This method can be called to free some memory when
5080      *  sound effects are disabled.
5081      */
unloadSoundEffects()5082     public void unloadSoundEffects() {
5083         sendMsg(mAudioHandler, MSG_UNLOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, null, 0);
5084     }
5085 
5086     /** @see AudioManager#reloadAudioSettings() */
reloadAudioSettings()5087     public void reloadAudioSettings() {
5088         readAudioSettings(false /*userSwitch*/);
5089     }
5090 
readAudioSettings(boolean userSwitch)5091     private void readAudioSettings(boolean userSwitch) {
5092         // restore ringer mode, ringer mode affected streams, mute affected streams and vibrate settings
5093         readPersistedSettings();
5094         readUserRestrictions();
5095 
5096         // restore volume settings
5097         int numStreamTypes = AudioSystem.getNumStreamTypes();
5098         for (int streamType = 0; streamType < numStreamTypes; streamType++) {
5099             VolumeStreamState streamState = mStreamStates[streamType];
5100 
5101             if (userSwitch && mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC) {
5102                 continue;
5103             }
5104 
5105             streamState.readSettings();
5106             synchronized (VolumeStreamState.class) {
5107                 // unmute stream that was muted but is not affect by mute anymore
5108                 if (streamState.mIsMuted && ((!isStreamAffectedByMute(streamType) &&
5109                         !isStreamMutedByRingerOrZenMode(streamType)) || mUseFixedVolume)) {
5110                     streamState.mIsMuted = false;
5111                 }
5112             }
5113         }
5114 
5115         // apply new ringer mode before checking volume for alias streams so that streams
5116         // muted by ringer mode have the correct volume
5117         setRingerModeInt(getRingerModeInternal(), false);
5118 
5119         checkAllFixedVolumeDevices();
5120         checkAllAliasStreamVolumes();
5121         checkMuteAffectedStreams();
5122 
5123         synchronized (mSafeMediaVolumeStateLock) {
5124             mMusicActiveMs = MathUtils.constrain(Settings.Secure.getIntForUser(mContentResolver,
5125                     Settings.Secure.UNSAFE_VOLUME_MUSIC_ACTIVE_MS, 0, UserHandle.USER_CURRENT),
5126                     0, UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX);
5127             if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE) {
5128                 enforceSafeMediaVolume(TAG);
5129             }
5130         }
5131 
5132         readVolumeGroupsSettings();
5133 
5134         if (DEBUG_VOL) {
5135             Log.d(TAG, "Restoring device volume behavior");
5136         }
5137         restoreDeviceVolumeBehavior();
5138     }
5139 
5140     private static final int[] VALID_COMMUNICATION_DEVICE_TYPES = {
5141         AudioDeviceInfo.TYPE_BUILTIN_SPEAKER,
5142         AudioDeviceInfo.TYPE_BLUETOOTH_SCO,
5143         AudioDeviceInfo.TYPE_WIRED_HEADSET,
5144         AudioDeviceInfo.TYPE_USB_HEADSET,
5145         AudioDeviceInfo.TYPE_BUILTIN_EARPIECE,
5146         AudioDeviceInfo.TYPE_WIRED_HEADPHONES,
5147         AudioDeviceInfo.TYPE_HEARING_AID,
5148         AudioDeviceInfo.TYPE_BLE_HEADSET,
5149         AudioDeviceInfo.TYPE_USB_DEVICE,
5150         AudioDeviceInfo.TYPE_BLE_SPEAKER,
5151         AudioDeviceInfo.TYPE_LINE_ANALOG,
5152         AudioDeviceInfo.TYPE_HDMI,
5153         AudioDeviceInfo.TYPE_AUX_LINE
5154     };
5155 
isValidCommunicationDevice(AudioDeviceInfo device)5156     private boolean isValidCommunicationDevice(AudioDeviceInfo device) {
5157         for (int type : VALID_COMMUNICATION_DEVICE_TYPES) {
5158             if (device.getType() == type) {
5159                 return true;
5160             }
5161         }
5162         return false;
5163     }
5164 
5165     /** @see AudioManager#getAvailableCommunicationDevices(int) */
getAvailableCommunicationDeviceIds()5166     public int[] getAvailableCommunicationDeviceIds() {
5167         ArrayList<Integer> deviceIds = new ArrayList<>();
5168         AudioDeviceInfo[] devices = AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_OUTPUTS);
5169         for (AudioDeviceInfo device : devices) {
5170             if (isValidCommunicationDevice(device)) {
5171                 deviceIds.add(device.getId());
5172             }
5173         }
5174         return deviceIds.stream().mapToInt(Integer::intValue).toArray();
5175     }
5176         /** @see AudioManager#setCommunicationDevice(int) */
setCommunicationDevice(IBinder cb, int portId)5177     public boolean setCommunicationDevice(IBinder cb, int portId) {
5178         final int uid = Binder.getCallingUid();
5179         final int pid = Binder.getCallingPid();
5180 
5181         AudioDeviceInfo device = null;
5182         if (portId != 0) {
5183             device = AudioManager.getDeviceForPortId(portId, AudioManager.GET_DEVICES_OUTPUTS);
5184             if (device == null) {
5185                 throw new IllegalArgumentException("invalid portID " + portId);
5186             }
5187             if (!isValidCommunicationDevice(device)) {
5188                 throw new IllegalArgumentException("invalid device type " + device.getType());
5189             }
5190         }
5191         final String eventSource = new StringBuilder("setCommunicationDevice(")
5192                 .append(") from u/pid:").append(uid).append("/")
5193                 .append(pid).toString();
5194 
5195         int deviceType = AudioSystem.DEVICE_OUT_DEFAULT;
5196         String deviceAddress = null;
5197         if (device != null) {
5198             deviceType = device.getPort().type();
5199             deviceAddress = device.getAddress();
5200         } else {
5201             AudioDeviceInfo curDevice = mDeviceBroker.getCommunicationDevice();
5202             if (curDevice != null) {
5203                 deviceType = curDevice.getPort().type();
5204                 deviceAddress = curDevice.getAddress();
5205             }
5206         }
5207         // do not log metrics if clearing communication device while no communication device
5208         // was selected
5209         if (deviceType != AudioSystem.DEVICE_OUT_DEFAULT) {
5210             new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
5211                     + MediaMetrics.SEPARATOR + "setCommunicationDevice")
5212                     .set(MediaMetrics.Property.DEVICE,
5213                             AudioSystem.getDeviceName(deviceType))
5214                     .set(MediaMetrics.Property.ADDRESS, deviceAddress)
5215                     .set(MediaMetrics.Property.STATE, device != null
5216                             ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED)
5217                     .record();
5218         }
5219 
5220         final long ident = Binder.clearCallingIdentity();
5221         boolean status =
5222                 mDeviceBroker.setCommunicationDevice(cb, pid, device, eventSource);
5223         Binder.restoreCallingIdentity(ident);
5224         return status;
5225     }
5226 
5227     /** @see AudioManager#getCommunicationDevice() */
getCommunicationDevice()5228     public int getCommunicationDevice() {
5229         final long ident = Binder.clearCallingIdentity();
5230         AudioDeviceInfo device = mDeviceBroker.getCommunicationDevice();
5231         Binder.restoreCallingIdentity(ident);
5232         if (device == null) {
5233             return 0;
5234         }
5235         return device.getId();
5236     }
5237 
5238     /** @see AudioManager#addOnCommunicationDeviceChangedListener(
5239      *               Executor, AudioManager.OnCommunicationDeviceChangedListener)
5240      */
registerCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)5241     public void registerCommunicationDeviceDispatcher(
5242             @Nullable ICommunicationDeviceDispatcher dispatcher) {
5243         if (dispatcher == null) {
5244             return;
5245         }
5246         mDeviceBroker.registerCommunicationDeviceDispatcher(dispatcher);
5247     }
5248 
5249     /** @see AudioManager#removeOnCommunicationDeviceChangedListener(
5250      *               AudioManager.OnCommunicationDeviceChangedListener)
5251      */
unregisterCommunicationDeviceDispatcher( @ullable ICommunicationDeviceDispatcher dispatcher)5252     public void unregisterCommunicationDeviceDispatcher(
5253             @Nullable ICommunicationDeviceDispatcher dispatcher) {
5254         if (dispatcher == null) {
5255             return;
5256         }
5257         mDeviceBroker.unregisterCommunicationDeviceDispatcher(dispatcher);
5258     }
5259 
5260     /** @see AudioManager#setSpeakerphoneOn(boolean) */
setSpeakerphoneOn(IBinder cb, boolean on)5261     public void setSpeakerphoneOn(IBinder cb, boolean on) {
5262         if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) {
5263             return;
5264         }
5265 
5266         // for logging only
5267         final int uid = Binder.getCallingUid();
5268         final int pid = Binder.getCallingPid();
5269 
5270         final String eventSource = new StringBuilder("setSpeakerphoneOn(").append(on)
5271                 .append(") from u/pid:").append(uid).append("/")
5272                 .append(pid).toString();
5273         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
5274                 + MediaMetrics.SEPARATOR + "setSpeakerphoneOn")
5275                 .setUid(uid)
5276                 .setPid(pid)
5277                 .set(MediaMetrics.Property.STATE, on
5278                         ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
5279                 .record();
5280         final long ident = Binder.clearCallingIdentity();
5281         mDeviceBroker.setSpeakerphoneOn(cb, pid, on, eventSource);
5282         Binder.restoreCallingIdentity(ident);
5283     }
5284 
5285     /** @see AudioManager#isSpeakerphoneOn() */
isSpeakerphoneOn()5286     public boolean isSpeakerphoneOn() {
5287         return mDeviceBroker.isSpeakerphoneOn();
5288     }
5289 
5290 
5291     /** BT SCO audio state seen by apps using the deprecated API setBluetoothScoOn().
5292      * @see isBluetoothScoOn() */
5293     private boolean mBtScoOnByApp;
5294 
5295     /** @see AudioManager#setBluetoothScoOn(boolean) */
setBluetoothScoOn(boolean on)5296     public void setBluetoothScoOn(boolean on) {
5297         if (!checkAudioSettingsPermission("setBluetoothScoOn()")) {
5298             return;
5299         }
5300 
5301         // Only enable calls from system components
5302         if (UserHandle.getCallingAppId() >= FIRST_APPLICATION_UID) {
5303             mBtScoOnByApp = on;
5304             return;
5305         }
5306 
5307         // for logging only
5308         final int uid = Binder.getCallingUid();
5309         final int pid = Binder.getCallingPid();
5310         final String eventSource = new StringBuilder("setBluetoothScoOn(").append(on)
5311                 .append(") from u/pid:").append(uid).append("/").append(pid).toString();
5312 
5313         //bt sco
5314         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
5315                 + MediaMetrics.SEPARATOR + "setBluetoothScoOn")
5316                 .setUid(uid)
5317                 .setPid(pid)
5318                 .set(MediaMetrics.Property.STATE, on
5319                         ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
5320                 .record();
5321 
5322         mDeviceBroker.setBluetoothScoOn(on, eventSource);
5323     }
5324 
5325     /** @see AudioManager#isBluetoothScoOn()
5326      * Note that it doesn't report internal state, but state seen by apps (which may have
5327      * called setBluetoothScoOn() */
isBluetoothScoOn()5328     public boolean isBluetoothScoOn() {
5329         return mBtScoOnByApp || mDeviceBroker.isBluetoothScoOn();
5330     }
5331 
5332     // TODO investigate internal users due to deprecation of SDK API
5333     /** @see AudioManager#setBluetoothA2dpOn(boolean) */
setBluetoothA2dpOn(boolean on)5334     public void setBluetoothA2dpOn(boolean on) {
5335         if (!checkAudioSettingsPermission("setBluetoothA2dpOn()")) {
5336             return;
5337         }
5338 
5339         // for logging only
5340         final int uid = Binder.getCallingUid();
5341         final int pid = Binder.getCallingPid();
5342         final String eventSource = new StringBuilder("setBluetoothA2dpOn(").append(on)
5343                 .append(") from u/pid:").append(uid).append("/")
5344                 .append(pid).toString();
5345 
5346         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
5347                 + MediaMetrics.SEPARATOR + "setBluetoothA2dpOn")
5348                 .setUid(uid)
5349                 .setPid(pid)
5350                 .set(MediaMetrics.Property.STATE, on
5351                         ? MediaMetrics.Value.ON : MediaMetrics.Value.OFF)
5352                 .record();
5353 
5354         mDeviceBroker.setBluetoothA2dpOn_Async(on, eventSource);
5355     }
5356 
5357     /** @see AudioManager#isBluetoothA2dpOn() */
isBluetoothA2dpOn()5358     public boolean isBluetoothA2dpOn() {
5359         return mDeviceBroker.isBluetoothA2dpOn();
5360     }
5361 
5362     /** @see AudioManager#startBluetoothSco() */
startBluetoothSco(IBinder cb, int targetSdkVersion)5363     public void startBluetoothSco(IBinder cb, int targetSdkVersion) {
5364         if (!checkAudioSettingsPermission("startBluetoothSco()")) {
5365             return;
5366         }
5367 
5368         final int uid = Binder.getCallingUid();
5369         final int pid = Binder.getCallingPid();
5370         final int scoAudioMode =
5371                 (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2) ?
5372                         BtHelper.SCO_MODE_VIRTUAL_CALL : BtHelper.SCO_MODE_UNDEFINED;
5373         final String eventSource = new StringBuilder("startBluetoothSco()")
5374                 .append(") from u/pid:").append(uid).append("/")
5375                 .append(pid).toString();
5376 
5377         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
5378                 .setUid(uid)
5379                 .setPid(pid)
5380                 .set(MediaMetrics.Property.EVENT, "startBluetoothSco")
5381                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
5382                         BtHelper.scoAudioModeToString(scoAudioMode))
5383                 .record();
5384         startBluetoothScoInt(cb, pid, scoAudioMode, eventSource);
5385 
5386     }
5387 
5388     /** @see AudioManager#startBluetoothScoVirtualCall() */
startBluetoothScoVirtualCall(IBinder cb)5389     public void startBluetoothScoVirtualCall(IBinder cb) {
5390         if (!checkAudioSettingsPermission("startBluetoothScoVirtualCall()")) {
5391             return;
5392         }
5393 
5394         final int uid = Binder.getCallingUid();
5395         final int pid = Binder.getCallingPid();
5396         final String eventSource = new StringBuilder("startBluetoothScoVirtualCall()")
5397                 .append(") from u/pid:").append(uid).append("/")
5398                 .append(pid).toString();
5399 
5400         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
5401                 .setUid(uid)
5402                 .setPid(pid)
5403                 .set(MediaMetrics.Property.EVENT, "startBluetoothScoVirtualCall")
5404                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
5405                         BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_VIRTUAL_CALL))
5406                 .record();
5407         startBluetoothScoInt(cb, pid, BtHelper.SCO_MODE_VIRTUAL_CALL, eventSource);
5408     }
5409 
startBluetoothScoInt(IBinder cb, int pid, int scoAudioMode, @NonNull String eventSource)5410     void startBluetoothScoInt(IBinder cb, int pid, int scoAudioMode, @NonNull String eventSource) {
5411         MediaMetrics.Item mmi = new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
5412                 .set(MediaMetrics.Property.EVENT, "startBluetoothScoInt")
5413                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
5414                         BtHelper.scoAudioModeToString(scoAudioMode));
5415 
5416         if (!checkAudioSettingsPermission("startBluetoothSco()") ||
5417                 !mSystemReady) {
5418             mmi.set(MediaMetrics.Property.EARLY_RETURN, "permission or systemReady").record();
5419             return;
5420         }
5421         final long ident = Binder.clearCallingIdentity();
5422         mDeviceBroker.startBluetoothScoForClient(cb, pid, scoAudioMode, eventSource);
5423         Binder.restoreCallingIdentity(ident);
5424         mmi.record();
5425     }
5426 
5427     /** @see AudioManager#stopBluetoothSco() */
stopBluetoothSco(IBinder cb)5428     public void stopBluetoothSco(IBinder cb){
5429         if (!checkAudioSettingsPermission("stopBluetoothSco()") ||
5430                 !mSystemReady) {
5431             return;
5432         }
5433         final int uid = Binder.getCallingUid();
5434         final int pid = Binder.getCallingPid();
5435         final String eventSource =  new StringBuilder("stopBluetoothSco()")
5436                 .append(") from u/pid:").append(uid).append("/")
5437                 .append(pid).toString();
5438         final long ident = Binder.clearCallingIdentity();
5439         mDeviceBroker.stopBluetoothScoForClient(cb, pid, eventSource);
5440         Binder.restoreCallingIdentity(ident);
5441         new MediaMetrics.Item(MediaMetrics.Name.AUDIO_BLUETOOTH)
5442                 .setUid(uid)
5443                 .setPid(pid)
5444                 .set(MediaMetrics.Property.EVENT, "stopBluetoothSco")
5445                 .set(MediaMetrics.Property.SCO_AUDIO_MODE,
5446                         BtHelper.scoAudioModeToString(BtHelper.SCO_MODE_UNDEFINED))
5447                 .record();
5448     }
5449 
5450 
getContentResolver()5451     /*package*/ ContentResolver getContentResolver() {
5452         return mContentResolver;
5453     }
5454 
onCheckMusicActive(String caller)5455     private void onCheckMusicActive(String caller) {
5456         synchronized (mSafeMediaVolumeStateLock) {
5457             if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE) {
5458                 int device = getDeviceForStream(AudioSystem.STREAM_MUSIC);
5459 
5460                 if (mSafeMediaVolumeDevices.contains(device)) {
5461                     sendMsg(mAudioHandler,
5462                             MSG_CHECK_MUSIC_ACTIVE,
5463                             SENDMSG_REPLACE,
5464                             0,
5465                             0,
5466                             caller,
5467                             MUSIC_ACTIVE_POLL_PERIOD_MS);
5468                     int index = mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(device);
5469                     if (mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)
5470                             && (index > safeMediaVolumeIndex(device))) {
5471                         // Approximate cumulative active music time
5472                         mMusicActiveMs += MUSIC_ACTIVE_POLL_PERIOD_MS;
5473                         if (mMusicActiveMs > UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX) {
5474                             setSafeMediaVolumeEnabled(true, caller);
5475                             mMusicActiveMs = 0;
5476                         }
5477                         saveMusicActiveMs();
5478                     }
5479                 }
5480             }
5481         }
5482     }
5483 
saveMusicActiveMs()5484     private void saveMusicActiveMs() {
5485         mAudioHandler.obtainMessage(MSG_PERSIST_MUSIC_ACTIVE_MS, mMusicActiveMs, 0).sendToTarget();
5486     }
5487 
getSafeUsbMediaVolumeIndex()5488     private int getSafeUsbMediaVolumeIndex() {
5489         // determine UI volume index corresponding to the wanted safe gain in dBFS
5490         int min = MIN_STREAM_VOLUME[AudioSystem.STREAM_MUSIC];
5491         int max = MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC];
5492 
5493         mSafeUsbMediaVolumeDbfs = mContext.getResources().getInteger(
5494                 com.android.internal.R.integer.config_safe_media_volume_usb_mB) / 100.0f;
5495 
5496         while (Math.abs(max - min) > 1) {
5497             int index = (max + min) / 2;
5498             float gainDB = AudioSystem.getStreamVolumeDB(
5499                     AudioSystem.STREAM_MUSIC, index, AudioSystem.DEVICE_OUT_USB_HEADSET);
5500             if (Float.isNaN(gainDB)) {
5501                 //keep last min in case of read error
5502                 break;
5503             } else if (gainDB == mSafeUsbMediaVolumeDbfs) {
5504                 min = index;
5505                 break;
5506             } else if (gainDB < mSafeUsbMediaVolumeDbfs) {
5507                 min = index;
5508             } else {
5509                 max = index;
5510             }
5511         }
5512         return min * 10;
5513     }
5514 
onConfigureSafeVolume(boolean force, String caller)5515     private void onConfigureSafeVolume(boolean force, String caller) {
5516         synchronized (mSafeMediaVolumeStateLock) {
5517             int mcc = mContext.getResources().getConfiguration().mcc;
5518             if ((mMcc != mcc) || ((mMcc == 0) && force)) {
5519                 mSafeMediaVolumeIndex = mContext.getResources().getInteger(
5520                         com.android.internal.R.integer.config_safe_media_volume_index) * 10;
5521 
5522                 mSafeUsbMediaVolumeIndex = getSafeUsbMediaVolumeIndex();
5523 
5524                 boolean safeMediaVolumeEnabled =
5525                         SystemProperties.getBoolean("audio.safemedia.force", false)
5526                         || mContext.getResources().getBoolean(
5527                                 com.android.internal.R.bool.config_safe_media_volume_enabled);
5528 
5529                 boolean safeMediaVolumeBypass =
5530                         SystemProperties.getBoolean("audio.safemedia.bypass", false);
5531 
5532                 // The persisted state is either "disabled" or "active": this is the state applied
5533                 // next time we boot and cannot be "inactive"
5534                 int persistedState;
5535                 if (safeMediaVolumeEnabled && !safeMediaVolumeBypass) {
5536                     persistedState = SAFE_MEDIA_VOLUME_ACTIVE;
5537                     // The state can already be "inactive" here if the user has forced it before
5538                     // the 30 seconds timeout for forced configuration. In this case we don't reset
5539                     // it to "active".
5540                     if (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_INACTIVE) {
5541                         if (mMusicActiveMs == 0) {
5542                             mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE;
5543                             enforceSafeMediaVolume(caller);
5544                         } else {
5545                             // We have existing playback time recorded, already confirmed.
5546                             mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_INACTIVE;
5547                         }
5548                     }
5549                 } else {
5550                     persistedState = SAFE_MEDIA_VOLUME_DISABLED;
5551                     mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_DISABLED;
5552                 }
5553                 mMcc = mcc;
5554                 sendMsg(mAudioHandler,
5555                         MSG_PERSIST_SAFE_VOLUME_STATE,
5556                         SENDMSG_QUEUE,
5557                         persistedState,
5558                         0,
5559                         null,
5560                         0);
5561             }
5562         }
5563     }
5564 
5565     ///////////////////////////////////////////////////////////////////////////
5566     // Internal methods
5567     ///////////////////////////////////////////////////////////////////////////
5568 
5569     /**
5570      * Checks if the adjustment should change ringer mode instead of just
5571      * adjusting volume. If so, this will set the proper ringer mode and volume
5572      * indices on the stream states.
5573      */
checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted, String caller, int flags)5574     private int checkForRingerModeChange(int oldIndex, int direction, int step, boolean isMuted,
5575             String caller, int flags) {
5576         int result = FLAG_ADJUST_VOLUME;
5577         if (isPlatformTelevision() || mIsSingleVolume) {
5578             return result;
5579         }
5580 
5581         int ringerMode = getRingerModeInternal();
5582 
5583         switch (ringerMode) {
5584         case RINGER_MODE_NORMAL:
5585             if (direction == AudioManager.ADJUST_LOWER) {
5586                 if (mHasVibrator) {
5587                     // "step" is the delta in internal index units corresponding to a
5588                     // change of 1 in UI index units.
5589                     // Because of rounding when rescaling from one stream index range to its alias
5590                     // index range, we cannot simply test oldIndex == step:
5591                     //   (step <= oldIndex < 2 * step) is equivalent to: (old UI index == 1)
5592                     if (step <= oldIndex && oldIndex < 2 * step) {
5593                         ringerMode = RINGER_MODE_VIBRATE;
5594                         mLoweredFromNormalToVibrateTime = SystemClock.uptimeMillis();
5595                     }
5596                 } else {
5597                     if (oldIndex == step && mVolumePolicy.volumeDownToEnterSilent) {
5598                         ringerMode = RINGER_MODE_SILENT;
5599                     }
5600                 }
5601             } else if (mIsSingleVolume && (direction == AudioManager.ADJUST_TOGGLE_MUTE
5602                     || direction == AudioManager.ADJUST_MUTE)) {
5603                 if (mHasVibrator) {
5604                     ringerMode = RINGER_MODE_VIBRATE;
5605                 } else {
5606                     ringerMode = RINGER_MODE_SILENT;
5607                 }
5608                 // Setting the ringer mode will toggle mute
5609                 result &= ~FLAG_ADJUST_VOLUME;
5610             }
5611             break;
5612         case RINGER_MODE_VIBRATE:
5613             if (!mHasVibrator) {
5614                 Log.e(TAG, "checkForRingerModeChange() current ringer mode is vibrate" +
5615                         "but no vibrator is present");
5616                 break;
5617             }
5618             if ((direction == AudioManager.ADJUST_LOWER)) {
5619                 // This is the case we were muted with the volume turned up
5620                 if (mIsSingleVolume && oldIndex >= 2 * step && isMuted) {
5621                     ringerMode = RINGER_MODE_NORMAL;
5622                 } else if (mPrevVolDirection != AudioManager.ADJUST_LOWER) {
5623                     if (mVolumePolicy.volumeDownToEnterSilent) {
5624                         final long diff = SystemClock.uptimeMillis()
5625                                 - mLoweredFromNormalToVibrateTime;
5626                         if (diff > mVolumePolicy.vibrateToSilentDebounce
5627                                 && mRingerModeDelegate.canVolumeDownEnterSilent()) {
5628                             ringerMode = RINGER_MODE_SILENT;
5629                         }
5630                     } else {
5631                         result |= AudioManager.FLAG_SHOW_VIBRATE_HINT;
5632                     }
5633                 }
5634             } else if (direction == AudioManager.ADJUST_RAISE
5635                     || direction == AudioManager.ADJUST_TOGGLE_MUTE
5636                     || direction == AudioManager.ADJUST_UNMUTE) {
5637                 ringerMode = RINGER_MODE_NORMAL;
5638             }
5639             result &= ~FLAG_ADJUST_VOLUME;
5640             break;
5641         case RINGER_MODE_SILENT:
5642             if (mIsSingleVolume && direction == AudioManager.ADJUST_LOWER && oldIndex >= 2 * step && isMuted) {
5643                 // This is the case we were muted with the volume turned up
5644                 ringerMode = RINGER_MODE_NORMAL;
5645             } else if (direction == AudioManager.ADJUST_RAISE
5646                     || direction == AudioManager.ADJUST_TOGGLE_MUTE
5647                     || direction == AudioManager.ADJUST_UNMUTE) {
5648                 if (!mVolumePolicy.volumeUpToExitSilent) {
5649                     result |= AudioManager.FLAG_SHOW_SILENT_HINT;
5650                 } else {
5651                   if (mHasVibrator && direction == AudioManager.ADJUST_RAISE) {
5652                       ringerMode = RINGER_MODE_VIBRATE;
5653                   } else {
5654                       // If we don't have a vibrator or they were toggling mute
5655                       // go straight back to normal.
5656                       ringerMode = RINGER_MODE_NORMAL;
5657                   }
5658                 }
5659             }
5660             result &= ~FLAG_ADJUST_VOLUME;
5661             break;
5662         default:
5663             Log.e(TAG, "checkForRingerModeChange() wrong ringer mode: "+ringerMode);
5664             break;
5665         }
5666 
5667         if (isAndroidNPlus(caller) && wouldToggleZenMode(ringerMode)
5668                 && !mNm.isNotificationPolicyAccessGrantedForPackage(caller)
5669                 && (flags & AudioManager.FLAG_FROM_KEY) == 0) {
5670             throw new SecurityException("Not allowed to change Do Not Disturb state");
5671         }
5672 
5673         setRingerMode(ringerMode, TAG + ".checkForRingerModeChange", false /*external*/);
5674 
5675         mPrevVolDirection = direction;
5676 
5677         return result;
5678     }
5679 
5680     @Override
isStreamAffectedByRingerMode(int streamType)5681     public boolean isStreamAffectedByRingerMode(int streamType) {
5682         return (mRingerModeAffectedStreams & (1 << streamType)) != 0;
5683     }
5684 
shouldZenMuteStream(int streamType)5685     private boolean shouldZenMuteStream(int streamType) {
5686         if (mNm.getZenMode() != Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
5687             return false;
5688         }
5689 
5690         NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy();
5691         final boolean muteAlarms = (zenPolicy.priorityCategories
5692                 & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0;
5693         final boolean muteMedia = (zenPolicy.priorityCategories
5694                 & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0;
5695         final boolean muteSystem = (zenPolicy.priorityCategories
5696                 & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0;
5697         final boolean muteNotificationAndRing = ZenModeConfig
5698                 .areAllPriorityOnlyRingerSoundsMuted(zenPolicy);
5699         return muteAlarms && isAlarm(streamType)
5700                 || muteMedia && isMedia(streamType)
5701                 || muteSystem && isSystem(streamType)
5702                 || muteNotificationAndRing && isNotificationOrRinger(streamType);
5703     }
5704 
isStreamMutedByRingerOrZenMode(int streamType)5705     private boolean isStreamMutedByRingerOrZenMode(int streamType) {
5706         return (mRingerAndZenModeMutedStreams & (1 << streamType)) != 0;
5707     }
5708 
5709     /**
5710      * Notifications, ringer and system sounds are controlled by the ringer:
5711      * {@link ZenModeHelper.RingerModeDelegate#getRingerModeAffectedStreams(int)} but can
5712      * also be muted by DND based on the DND mode:
5713      * DND total silence: media and alarms streams can be muted by DND
5714      * DND alarms only: no streams additionally controlled by DND
5715      * DND priority only: alarms, media, system, ringer and notification streams can be muted by
5716      * DND.  The current applied zenPolicy determines which streams will be muted by DND.
5717      * @return true if changed, else false
5718      */
updateZenModeAffectedStreams()5719     private boolean updateZenModeAffectedStreams() {
5720         if (!mSystemReady) {
5721             return false;
5722         }
5723 
5724         int zenModeAffectedStreams = 0;
5725         final int zenMode = mNm.getZenMode();
5726 
5727         if (zenMode == Settings.Global.ZEN_MODE_NO_INTERRUPTIONS) {
5728             zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM;
5729             zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC;
5730         } else if (zenMode == Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS) {
5731             NotificationManager.Policy zenPolicy = mNm.getConsolidatedNotificationPolicy();
5732             if ((zenPolicy.priorityCategories
5733                     & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) == 0) {
5734                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_ALARM;
5735             }
5736 
5737             if ((zenPolicy.priorityCategories
5738                     & NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA) == 0) {
5739                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_MUSIC;
5740             }
5741 
5742             // even if zen isn't muting the system stream, the ringer mode can still mute
5743             // the system stream
5744             if ((zenPolicy.priorityCategories
5745                     & NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM) == 0) {
5746                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_SYSTEM;
5747             }
5748 
5749             if (ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(zenPolicy)) {
5750                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_NOTIFICATION;
5751                 zenModeAffectedStreams |= 1 << AudioManager.STREAM_RING;
5752             }
5753         }
5754 
5755         if (mZenModeAffectedStreams != zenModeAffectedStreams) {
5756             mZenModeAffectedStreams = zenModeAffectedStreams;
5757             return true;
5758         }
5759 
5760         return false;
5761     }
5762 
5763     @GuardedBy("mSettingsLock")
updateRingerAndZenModeAffectedStreams()5764     private boolean updateRingerAndZenModeAffectedStreams() {
5765         boolean updatedZenModeAffectedStreams = updateZenModeAffectedStreams();
5766         int ringerModeAffectedStreams = Settings.System.getIntForUser(mContentResolver,
5767                 Settings.System.MODE_RINGER_STREAMS_AFFECTED,
5768                 ((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
5769                  (1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)),
5770                  UserHandle.USER_CURRENT);
5771 
5772         if (mIsSingleVolume) {
5773             ringerModeAffectedStreams = 0;
5774         } else if (mRingerModeDelegate != null) {
5775             ringerModeAffectedStreams = mRingerModeDelegate
5776                     .getRingerModeAffectedStreams(ringerModeAffectedStreams);
5777         }
5778         if (mCameraSoundForced) {
5779             ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
5780         } else {
5781             ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
5782         }
5783         if (mStreamVolumeAlias[AudioSystem.STREAM_DTMF] == AudioSystem.STREAM_RING) {
5784             ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_DTMF);
5785         } else {
5786             ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_DTMF);
5787         }
5788 
5789         if (ringerModeAffectedStreams != mRingerModeAffectedStreams) {
5790             Settings.System.putIntForUser(mContentResolver,
5791                     Settings.System.MODE_RINGER_STREAMS_AFFECTED,
5792                     ringerModeAffectedStreams,
5793                     UserHandle.USER_CURRENT);
5794             mRingerModeAffectedStreams = ringerModeAffectedStreams;
5795             return true;
5796         }
5797         return updatedZenModeAffectedStreams;
5798     }
5799 
5800     @Override
isStreamAffectedByMute(int streamType)5801     public boolean isStreamAffectedByMute(int streamType) {
5802         return (mMuteAffectedStreams & (1 << streamType)) != 0;
5803     }
5804 
ensureValidDirection(int direction)5805     private void ensureValidDirection(int direction) {
5806         switch (direction) {
5807             case AudioManager.ADJUST_LOWER:
5808             case AudioManager.ADJUST_RAISE:
5809             case AudioManager.ADJUST_SAME:
5810             case AudioManager.ADJUST_MUTE:
5811             case AudioManager.ADJUST_UNMUTE:
5812             case AudioManager.ADJUST_TOGGLE_MUTE:
5813                 break;
5814             default:
5815                 throw new IllegalArgumentException("Bad direction " + direction);
5816         }
5817     }
5818 
ensureValidStreamType(int streamType)5819     private void ensureValidStreamType(int streamType) {
5820         if (streamType < 0 || streamType >= mStreamStates.length) {
5821             throw new IllegalArgumentException("Bad stream type " + streamType);
5822         }
5823     }
5824 
isMuteAdjust(int adjust)5825     private boolean isMuteAdjust(int adjust) {
5826         return adjust == AudioManager.ADJUST_MUTE || adjust == AudioManager.ADJUST_UNMUTE
5827                 || adjust == AudioManager.ADJUST_TOGGLE_MUTE;
5828     }
5829 
5830     /** only public for mocking/spying, do not call outside of AudioService */
5831     @VisibleForTesting
isInCommunication()5832     public boolean isInCommunication() {
5833         boolean IsInCall = false;
5834 
5835         TelecomManager telecomManager =
5836                 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
5837 
5838         final long ident = Binder.clearCallingIdentity();
5839         IsInCall = telecomManager.isInCall();
5840         Binder.restoreCallingIdentity(ident);
5841 
5842         int mode = mMode.get();
5843         return (IsInCall
5844                 || mode == AudioManager.MODE_IN_COMMUNICATION
5845                 || mode == AudioManager.MODE_IN_CALL);
5846     }
5847 
5848     /**
5849      * For code clarity for getActiveStreamType(int)
5850      * @param delay_ms max time since last stream activity to consider
5851      * @return true if stream is active in streams handled by AudioFlinger now or
5852      *     in the last "delay_ms" ms.
5853      */
wasStreamActiveRecently(int stream, int delay_ms)5854     private boolean wasStreamActiveRecently(int stream, int delay_ms) {
5855         return mAudioSystem.isStreamActive(stream, delay_ms)
5856                 || mAudioSystem.isStreamActiveRemotely(stream, delay_ms);
5857     }
5858 
getActiveStreamType(int suggestedStreamType)5859     private int getActiveStreamType(int suggestedStreamType) {
5860         if (mIsSingleVolume
5861                 && suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
5862             return AudioSystem.STREAM_MUSIC;
5863         }
5864 
5865         switch (mPlatformType) {
5866         case AudioSystem.PLATFORM_VOICE:
5867             if (isInCommunication()) {
5868                 if (mDeviceBroker.isBluetoothScoActive()) {
5869                     // Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO...");
5870                     return AudioSystem.STREAM_BLUETOOTH_SCO;
5871                 } else {
5872                     // Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL...");
5873                     return AudioSystem.STREAM_VOICE_CALL;
5874                 }
5875             } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
5876                 if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
5877                     if (DEBUG_VOL)
5878                         Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active");
5879                     return AudioSystem.STREAM_RING;
5880                 } else if (wasStreamActiveRecently(
5881                         AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
5882                     if (DEBUG_VOL)
5883                         Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION stream active");
5884                     return AudioSystem.STREAM_NOTIFICATION;
5885                 } else {
5886                     if (DEBUG_VOL) {
5887                         Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK("
5888                                 + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default");
5889                     }
5890                     return DEFAULT_VOL_STREAM_NO_PLAYBACK;
5891                 }
5892             } else if (
5893                     wasStreamActiveRecently(AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
5894                 if (DEBUG_VOL)
5895                     Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION stream active");
5896                 return AudioSystem.STREAM_NOTIFICATION;
5897             } else if (wasStreamActiveRecently(AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
5898                 if (DEBUG_VOL)
5899                     Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING stream active");
5900                 return AudioSystem.STREAM_RING;
5901             }
5902         default:
5903             if (isInCommunication()) {
5904                 if (mDeviceBroker.isBluetoothScoActive()) {
5905                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO");
5906                     return AudioSystem.STREAM_BLUETOOTH_SCO;
5907                 } else {
5908                     if (DEBUG_VOL)  Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL");
5909                     return AudioSystem.STREAM_VOICE_CALL;
5910                 }
5911             } else if (mAudioSystem.isStreamActive(
5912                     AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
5913                 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION");
5914                 return AudioSystem.STREAM_NOTIFICATION;
5915             } else if (mAudioSystem.isStreamActive(
5916                     AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
5917                 if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING");
5918                 return AudioSystem.STREAM_RING;
5919             } else if (suggestedStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
5920                 if (mAudioSystem.isStreamActive(
5921                         AudioSystem.STREAM_NOTIFICATION, sStreamOverrideDelayMs)) {
5922                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_NOTIFICATION");
5923                     return AudioSystem.STREAM_NOTIFICATION;
5924                 }
5925                 if (mAudioSystem.isStreamActive(
5926                         AudioSystem.STREAM_RING, sStreamOverrideDelayMs)) {
5927                     if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_RING");
5928                     return AudioSystem.STREAM_RING;
5929                 }
5930                 if (DEBUG_VOL) {
5931                     Log.v(TAG, "getActiveStreamType: Forcing DEFAULT_VOL_STREAM_NO_PLAYBACK("
5932                             + DEFAULT_VOL_STREAM_NO_PLAYBACK + ") b/c default");
5933                 }
5934                 return DEFAULT_VOL_STREAM_NO_PLAYBACK;
5935             }
5936             break;
5937         }
5938         if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Returning suggested type "
5939                 + suggestedStreamType);
5940         return suggestedStreamType;
5941     }
5942 
broadcastRingerMode(String action, int ringerMode)5943     private void broadcastRingerMode(String action, int ringerMode) {
5944         if (!mSystemServer.isPrivileged()) {
5945             return;
5946         }
5947         // Send sticky broadcast
5948         Intent broadcast = new Intent(action);
5949         broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, ringerMode);
5950         broadcast.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
5951                 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
5952         sendStickyBroadcastToAll(broadcast);
5953     }
5954 
broadcastVibrateSetting(int vibrateType)5955     private void broadcastVibrateSetting(int vibrateType) {
5956         if (!mSystemServer.isPrivileged()) {
5957             return;
5958         }
5959         // Send broadcast
5960         if (mActivityManagerInternal.isSystemReady()) {
5961             Intent broadcast = new Intent(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
5962             broadcast.putExtra(AudioManager.EXTRA_VIBRATE_TYPE, vibrateType);
5963             broadcast.putExtra(AudioManager.EXTRA_VIBRATE_SETTING, getVibrateSetting(vibrateType));
5964             sendBroadcastToAll(broadcast);
5965         }
5966     }
5967 
5968     // Message helper methods
5969     /**
5970      * Queue a message on the given handler's message queue, after acquiring the service wake lock.
5971      * Note that the wake lock needs to be released after the message has been handled.
5972      */
queueMsgUnderWakeLock(Handler handler, int msg, int arg1, int arg2, Object obj, int delay)5973     private void queueMsgUnderWakeLock(Handler handler, int msg,
5974             int arg1, int arg2, Object obj, int delay) {
5975         final long ident = Binder.clearCallingIdentity();
5976         // Always acquire the wake lock as AudioService because it is released by the
5977         // message handler.
5978         mAudioEventWakeLock.acquire();
5979         Binder.restoreCallingIdentity(ident);
5980         sendMsg(handler, msg, SENDMSG_QUEUE, arg1, arg2, obj, delay);
5981     }
5982 
sendMsg(Handler handler, int msg, int existingMsgPolicy, int arg1, int arg2, Object obj, int delay)5983     private static void sendMsg(Handler handler, int msg,
5984             int existingMsgPolicy, int arg1, int arg2, Object obj, int delay) {
5985         if (existingMsgPolicy == SENDMSG_REPLACE) {
5986             handler.removeMessages(msg);
5987         } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) {
5988             return;
5989         }
5990 
5991         final long time = SystemClock.uptimeMillis() + delay;
5992         handler.sendMessageAtTime(handler.obtainMessage(msg, arg1, arg2, obj), time);
5993     }
5994 
checkAudioSettingsPermission(String method)5995     boolean checkAudioSettingsPermission(String method) {
5996         if (callingOrSelfHasAudioSettingsPermission()) {
5997             return true;
5998         }
5999         String msg = "Audio Settings Permission Denial: " + method + " from pid="
6000                 + Binder.getCallingPid()
6001                 + ", uid=" + Binder.getCallingUid();
6002         Log.w(TAG, msg);
6003         return false;
6004     }
6005 
callingOrSelfHasAudioSettingsPermission()6006     private boolean callingOrSelfHasAudioSettingsPermission() {
6007         return mContext.checkCallingOrSelfPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS)
6008                 == PackageManager.PERMISSION_GRANTED;
6009     }
6010 
callingHasAudioSettingsPermission()6011     private boolean callingHasAudioSettingsPermission() {
6012         return mContext.checkCallingPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS)
6013                 == PackageManager.PERMISSION_GRANTED;
6014     }
6015 
hasAudioSettingsPermission(int uid, int pid)6016     private boolean hasAudioSettingsPermission(int uid, int pid) {
6017         return mContext.checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, pid, uid)
6018                 == PackageManager.PERMISSION_GRANTED;
6019     }
6020 
6021     /**
6022      * Minimum attenuation that can be set for alarms over speaker by an application that
6023      * doesn't have the MODIFY_AUDIO_SETTINGS permission.
6024      */
6025     protected static final float MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB = -36.0f;
6026 
6027     /**
6028      * Configures the VolumeStreamState instances for minimum stream index that can be accessed
6029      * without MODIFY_AUDIO_SETTINGS permission.
6030      * Can only be done successfully once audio policy has finished reading its configuration files
6031      * for the volume curves. If not, getStreamVolumeDB will return NaN, and the min value will
6032      * remain at the stream min index value.
6033      */
initMinStreamVolumeWithoutModifyAudioSettings()6034     protected void initMinStreamVolumeWithoutModifyAudioSettings() {
6035         int idx;
6036         int deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER_SAFE;
6037         if (Float.isNaN(AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM,
6038                 MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM], deviceForAlarm))) {
6039             deviceForAlarm = AudioSystem.DEVICE_OUT_SPEAKER;
6040         }
6041         for (idx = MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM];
6042                 idx >= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]; idx--) {
6043             if (AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_ALARM, idx, deviceForAlarm)
6044                     < MIN_ALARM_ATTENUATION_NON_PRIVILEGED_DB) {
6045                 break;
6046             }
6047         }
6048         final int safeIndex = idx <= MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]
6049                 ? MIN_STREAM_VOLUME[AudioSystem.STREAM_ALARM]
6050                 : Math.min(idx + 1, MAX_STREAM_VOLUME[AudioSystem.STREAM_ALARM]);
6051         // update the VolumeStreamState for STREAM_ALARM and its aliases
6052         for (int stream : mStreamVolumeAlias) {
6053             if (mStreamVolumeAlias[stream] == AudioSystem.STREAM_ALARM) {
6054                 mStreamStates[stream].updateNoPermMinIndex(safeIndex);
6055             }
6056         }
6057     }
6058 
6059     /** only public for mocking/spying, do not call outside of AudioService */
6060     @VisibleForTesting
getDeviceForStream(int stream)6061     public int getDeviceForStream(int stream) {
6062         int device = getDevicesForStreamInt(stream);
6063         if ((device & (device - 1)) != 0) {
6064             // Multiple device selection is either:
6065             //  - speaker + one other device: give priority to speaker in this case.
6066             //  - one A2DP device + another device: happens with duplicated output. In this case
6067             // retain the device on the A2DP output as the other must not correspond to an active
6068             // selection if not the speaker.
6069             //  - HDMI-CEC system audio mode only output: give priority to available item in order.
6070             // FIXME: Haven't applied audio device type refactor to this API
6071             //  as it is going to be deprecated.
6072             if ((device & AudioSystem.DEVICE_OUT_SPEAKER) != 0) {
6073                 device = AudioSystem.DEVICE_OUT_SPEAKER;
6074             } else if ((device & AudioSystem.DEVICE_OUT_HDMI_ARC) != 0) {
6075                 // FIXME(b/184944421): DEVICE_OUT_HDMI_EARC has two bits set,
6076                 // so it must be handled correctly as it aliases
6077                 // with DEVICE_OUT_HDMI_ARC | DEVICE_OUT_EARPIECE.
6078                 device = AudioSystem.DEVICE_OUT_HDMI_ARC;
6079             } else if ((device & AudioSystem.DEVICE_OUT_SPDIF) != 0) {
6080                 device = AudioSystem.DEVICE_OUT_SPDIF;
6081             } else if ((device & AudioSystem.DEVICE_OUT_AUX_LINE) != 0) {
6082                 device = AudioSystem.DEVICE_OUT_AUX_LINE;
6083             } else {
6084                 for (int deviceType : AudioSystem.DEVICE_OUT_ALL_A2DP_SET) {
6085                     if ((deviceType & device) == deviceType) {
6086                         return deviceType;
6087                     }
6088                 }
6089             }
6090         }
6091         return device;
6092     }
6093 
6094     /**
6095      * @see AudioManager#getDevicesForStream(int)
6096      */
getDevicesForStream(int streamType)6097     public int getDevicesForStream(int streamType) {
6098         ensureValidStreamType(streamType);
6099         final long token = Binder.clearCallingIdentity();
6100         try {
6101             return mAudioSystem.getDevicesForStream(streamType);
6102         } finally {
6103             Binder.restoreCallingIdentity(token);
6104         }
6105     }
6106 
getDevicesForStreamInt(int stream)6107     private int getDevicesForStreamInt(int stream) {
6108         ensureValidStreamType(stream);
6109         synchronized (VolumeStreamState.class) {
6110             return mStreamStates[stream].observeDevicesForStream_syncVSS(true);
6111         }
6112     }
6113 
onObserveDevicesForAllStreams(int skipStream)6114     private void onObserveDevicesForAllStreams(int skipStream) {
6115         synchronized (mSettingsLock) {
6116             synchronized (VolumeStreamState.class) {
6117                 for (int stream = 0; stream < mStreamStates.length; stream++) {
6118                     if (stream != skipStream) {
6119                         int devices = mStreamStates[stream].observeDevicesForStream_syncVSS(
6120                                 false /*checkOthers*/);
6121 
6122                         Set<Integer> devicesSet = AudioSystem.generateAudioDeviceTypesSet(devices);
6123                         for (Integer device : devicesSet) {
6124                             // Update volume states for devices routed for the stream
6125                             updateVolumeStates(device, stream,
6126                                     "AudioService#onObserveDevicesForAllStreams");
6127                         }
6128                     }
6129                 }
6130             }
6131         }
6132     }
6133 
6134     /** only public for mocking/spying, do not call outside of AudioService */
6135     @VisibleForTesting
postObserveDevicesForAllStreams()6136     public void postObserveDevicesForAllStreams() {
6137         postObserveDevicesForAllStreams(-1);
6138     }
6139 
6140     /** only public for mocking/spying, do not call outside of AudioService */
6141     @VisibleForTesting
postObserveDevicesForAllStreams(int skipStream)6142     public void postObserveDevicesForAllStreams(int skipStream) {
6143         sendMsg(mAudioHandler,
6144                 MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS,
6145                 SENDMSG_QUEUE, skipStream /*arg1*/, 0 /*arg2*/, null /*obj*/,
6146                 0 /*delay*/);
6147     }
6148 
6149     /**
6150      * @see AudioManager#setDeviceVolumeBehavior(AudioDeviceAttributes, int)
6151      * @param device the audio device to be affected
6152      * @param deviceVolumeBehavior one of the device behaviors
6153      */
setDeviceVolumeBehavior(@onNull AudioDeviceAttributes device, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName)6154     public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
6155             @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName) {
6156         // verify permissions
6157         enforceModifyAudioRoutingPermission();
6158         // verify arguments
6159         Objects.requireNonNull(device);
6160         AudioManager.enforceValidVolumeBehavior(deviceVolumeBehavior);
6161         if (pkgName == null) {
6162             pkgName = "";
6163         }
6164 
6165         int audioSystemDeviceOut = AudioDeviceInfo.convertDeviceTypeToInternalDevice(
6166                 device.getType());
6167         setDeviceVolumeBehaviorInternal(audioSystemDeviceOut, deviceVolumeBehavior, pkgName);
6168 
6169         persistDeviceVolumeBehavior(audioSystemDeviceOut, deviceVolumeBehavior);
6170     }
6171 
setDeviceVolumeBehaviorInternal(int audioSystemDeviceOut, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller)6172     private void setDeviceVolumeBehaviorInternal(int audioSystemDeviceOut,
6173             @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller) {
6174         // update device masks based on volume behavior
6175         switch (deviceVolumeBehavior) {
6176             case AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE:
6177                 removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut);
6178                 removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut);
6179                 break;
6180             case AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED:
6181                 removeAudioSystemDeviceOutFromFullVolumeDevices(audioSystemDeviceOut);
6182                 addAudioSystemDeviceOutToFixedVolumeDevices(audioSystemDeviceOut);
6183                 break;
6184             case AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL:
6185                 addAudioSystemDeviceOutToFullVolumeDevices(audioSystemDeviceOut);
6186                 removeAudioSystemDeviceOutFromFixedVolumeDevices(audioSystemDeviceOut);
6187                 break;
6188             case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE:
6189             case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE:
6190                 throw new IllegalArgumentException("Absolute volume unsupported for now");
6191         }
6192 
6193         // log event and caller
6194         sDeviceLogger.log(new AudioEventLogger.StringEvent(
6195                 "Volume behavior " + deviceVolumeBehavior + " for dev=0x"
6196                       + Integer.toHexString(audioSystemDeviceOut) + " from:" + caller));
6197         // make sure we have a volume entry for this device, and that volume is updated according
6198         // to volume behavior
6199         postUpdateVolumeStatesForAudioDevice(audioSystemDeviceOut,
6200                 "setDeviceVolumeBehavior:" + caller);
6201     }
6202 
6203     /**
6204      * @see AudioManager#getDeviceVolumeBehavior(AudioDeviceAttributes)
6205      * @param device the audio output device type
6206      * @return the volume behavior for the device
6207      */
6208     public @AudioManager.DeviceVolumeBehavior
getDeviceVolumeBehavior(@onNull AudioDeviceAttributes device)6209     int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
6210         // verify permissions
6211         enforceQueryStateOrModifyRoutingPermission();
6212 
6213         // translate Java device type to native device type (for the devices masks for full / fixed)
6214         final int audioSystemDeviceOut = AudioDeviceInfo.convertDeviceTypeToInternalDevice(
6215                 device.getType());
6216 
6217         int setDeviceVolumeBehavior = retrieveStoredDeviceVolumeBehavior(audioSystemDeviceOut);
6218         if (setDeviceVolumeBehavior != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET) {
6219             return setDeviceVolumeBehavior;
6220         }
6221 
6222         // setDeviceVolumeBehavior has not been explicitly called for the device type. Deduce the
6223         // current volume behavior.
6224         if ((mFullVolumeDevices.contains(audioSystemDeviceOut))) {
6225             return AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL;
6226         }
6227         if ((mFixedVolumeDevices.contains(audioSystemDeviceOut))) {
6228             return AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED;
6229         }
6230         if ((mAbsVolumeMultiModeCaseDevices.contains(audioSystemDeviceOut))) {
6231             return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE;
6232         }
6233         if (audioSystemDeviceOut == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP
6234                 && mAvrcpAbsVolSupported) {
6235             return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE;
6236         }
6237         return AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE;
6238     }
6239 
6240     /*package*/ static final int CONNECTION_STATE_DISCONNECTED = 0;
6241     /*package*/ static final int CONNECTION_STATE_CONNECTED = 1;
6242     /**
6243      * The states that can be used with AudioService.setWiredDeviceConnectionState()
6244      * Attention: those values differ from those in BluetoothProfile, follow annotations to
6245      * distinguish between @ConnectionState and @BtProfileConnectionState
6246      */
6247     @IntDef({
6248             CONNECTION_STATE_DISCONNECTED,
6249             CONNECTION_STATE_CONNECTED,
6250     })
6251     @Retention(RetentionPolicy.SOURCE)
6252     public @interface ConnectionState {}
6253 
6254     /**
6255      * see AudioManager.setWiredDeviceConnectionState()
6256      */
setWiredDeviceConnectionState(int type, @ConnectionState int state, String address, String name, String caller)6257     public void setWiredDeviceConnectionState(int type,
6258             @ConnectionState int state, String address, String name,
6259             String caller) {
6260         enforceModifyAudioRoutingPermission();
6261         if (state != CONNECTION_STATE_CONNECTED
6262                 && state != CONNECTION_STATE_DISCONNECTED) {
6263             throw new IllegalArgumentException("Invalid state " + state);
6264         }
6265         new MediaMetrics.Item(mMetricsId + "setWiredDeviceConnectionState")
6266                 .set(MediaMetrics.Property.ADDRESS, address)
6267                 .set(MediaMetrics.Property.CLIENT_NAME, caller)
6268                 .set(MediaMetrics.Property.DEVICE, AudioSystem.getDeviceName(type))
6269                 .set(MediaMetrics.Property.NAME, name)
6270                 .set(MediaMetrics.Property.STATE,
6271                         state == CONNECTION_STATE_CONNECTED ? "connected" : "disconnected")
6272                 .record();
6273         mDeviceBroker.setWiredDeviceConnectionState(type, state, address, name, caller);
6274     }
6275 
6276     /**
6277      * @hide
6278      * The states that can be used with AudioService.setBluetoothHearingAidDeviceConnectionState()
6279      * and AudioService.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent()
6280      */
6281     @IntDef({
6282             BluetoothProfile.STATE_DISCONNECTED,
6283             BluetoothProfile.STATE_CONNECTED,
6284     })
6285     @Retention(RetentionPolicy.SOURCE)
6286     public @interface BtProfileConnectionState {}
6287 
6288     /**
6289      * See AudioManager.setBluetoothHearingAidDeviceConnectionState()
6290      */
setBluetoothHearingAidDeviceConnectionState( @onNull BluetoothDevice device, @BtProfileConnectionState int state, boolean suppressNoisyIntent, int musicDevice)6291     public void setBluetoothHearingAidDeviceConnectionState(
6292             @NonNull BluetoothDevice device, @BtProfileConnectionState int state,
6293             boolean suppressNoisyIntent, int musicDevice)
6294     {
6295         if (device == null) {
6296             throw new IllegalArgumentException("Illegal null device");
6297         }
6298         if (state != BluetoothProfile.STATE_CONNECTED
6299                 && state != BluetoothProfile.STATE_DISCONNECTED) {
6300             throw new IllegalArgumentException("Illegal BluetoothProfile state for device "
6301                     + " (dis)connection, got " + state);
6302         }
6303         mDeviceBroker.postBluetoothHearingAidDeviceConnectionState(
6304                 device, state, suppressNoisyIntent, musicDevice, "AudioService");
6305     }
6306 
6307     /**
6308      * See AudioManager.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent()
6309      */
setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent( @onNull BluetoothDevice device, @BtProfileConnectionState int state, int profile, boolean suppressNoisyIntent, int a2dpVolume)6310     public void setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
6311             @NonNull BluetoothDevice device, @BtProfileConnectionState int state,
6312             int profile, boolean suppressNoisyIntent, int a2dpVolume) {
6313         if (device == null) {
6314             throw new IllegalArgumentException("Illegal null device");
6315         }
6316         if (state != BluetoothProfile.STATE_CONNECTED
6317                 && state != BluetoothProfile.STATE_DISCONNECTED) {
6318             throw new IllegalArgumentException("Illegal BluetoothProfile state for device "
6319                     + " (dis)connection, got " + state);
6320         }
6321 
6322         AudioDeviceBroker.BtDeviceConnectionInfo info =
6323                 new AudioDeviceBroker.BtDeviceConnectionInfo(device, state,
6324                         profile, suppressNoisyIntent, a2dpVolume);
6325         sendMsg(mAudioHandler, MSG_SET_A2DP_DEV_CONNECTION_STATE, SENDMSG_QUEUE,
6326                 0 /*arg1*/, 0 /*arg2*/,
6327                 /*obj*/ info, 0 /*delay*/);
6328     }
6329 
6330     /** only public for mocking/spying, do not call outside of AudioService */
6331     @VisibleForTesting
setMusicMute(boolean mute)6332     public void setMusicMute(boolean mute) {
6333         mStreamStates[AudioSystem.STREAM_MUSIC].muteInternally(mute);
6334     }
6335 
6336     /**
6337      * See AudioManager.handleBluetoothA2dpDeviceConfigChange()
6338      * @param device
6339      */
handleBluetoothA2dpDeviceConfigChange(BluetoothDevice device)6340     public void handleBluetoothA2dpDeviceConfigChange(BluetoothDevice device)
6341     {
6342         if (device == null) {
6343             throw new IllegalArgumentException("Illegal null device");
6344         }
6345         sendMsg(mAudioHandler, MSG_A2DP_DEV_CONFIG_CHANGE, SENDMSG_QUEUE, 0, 0,
6346                 /*obj*/ device, /*delay*/ 0);
6347     }
6348 
6349     private static final Set<Integer> DEVICE_MEDIA_UNMUTED_ON_PLUG_SET;
6350     static {
6351         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET = new HashSet<>();
6352         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADSET);
6353         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE);
6354         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_LINE);
6355         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_A2DP_SET);
6356         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.addAll(AudioSystem.DEVICE_OUT_ALL_USB_SET);
6357         DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.add(AudioSystem.DEVICE_OUT_HDMI);
6358     }
6359 
6360     /** only public for mocking/spying, do not call outside of AudioService */
6361     @VisibleForTesting
postAccessoryPlugMediaUnmute(int newDevice)6362     public void postAccessoryPlugMediaUnmute(int newDevice) {
6363         sendMsg(mAudioHandler, MSG_ACCESSORY_PLUG_MEDIA_UNMUTE, SENDMSG_QUEUE,
6364                 newDevice, 0, null, 0);
6365     }
6366 
onAccessoryPlugMediaUnmute(int newDevice)6367     private void onAccessoryPlugMediaUnmute(int newDevice) {
6368         if (DEBUG_VOL) {
6369             Log.i(TAG, String.format("onAccessoryPlugMediaUnmute newDevice=%d [%s]",
6370                     newDevice, AudioSystem.getOutputDeviceName(newDevice)));
6371         }
6372 
6373         if (mNm.getZenMode() != Settings.Global.ZEN_MODE_NO_INTERRUPTIONS
6374                 && !isStreamMutedByRingerOrZenMode(AudioSystem.STREAM_MUSIC)
6375                 && DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.contains(newDevice)
6376                 && mStreamStates[AudioSystem.STREAM_MUSIC].mIsMuted
6377                 && mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(newDevice) != 0
6378                 && (newDevice & mAudioSystem.getDevicesForStream(AudioSystem.STREAM_MUSIC)) != 0) {
6379             if (DEBUG_VOL) {
6380                 Log.i(TAG, String.format("onAccessoryPlugMediaUnmute unmuting device=%d [%s]",
6381                         newDevice, AudioSystem.getOutputDeviceName(newDevice)));
6382             }
6383             mStreamStates[AudioSystem.STREAM_MUSIC].mute(false);
6384         }
6385     }
6386 
6387     /**
6388      * See AudioManager.hasHapticChannels(Context, Uri).
6389      */
hasHapticChannels(Uri uri)6390     public boolean hasHapticChannels(Uri uri) {
6391         return AudioManager.hasHapticChannelsImpl(mContext, uri);
6392     }
6393 
6394     ///////////////////////////////////////////////////////////////////////////
6395     // Inner classes
6396     ///////////////////////////////////////////////////////////////////////////
6397     /**
6398      * Key is the AudioManager VolumeGroupId
6399      * Value is the VolumeGroupState
6400      */
6401     private static final SparseArray<VolumeGroupState> sVolumeGroupStates = new SparseArray<>();
6402 
initVolumeGroupStates()6403     private void initVolumeGroupStates() {
6404         for (final AudioVolumeGroup avg : getAudioVolumeGroups()) {
6405             try {
6406                 // if no valid attributes, this volume group is not controllable, throw exception
6407                 ensureValidAttributes(avg);
6408             } catch (IllegalArgumentException e) {
6409                 // Volume Groups without attributes are not controllable through set/get volume
6410                 // using attributes. Do not append them.
6411                 if (DEBUG_VOL) {
6412                     Log.d(TAG, "volume group " + avg.name() + " for internal policy needs");
6413                 }
6414                 continue;
6415             }
6416             sVolumeGroupStates.append(avg.getId(), new VolumeGroupState(avg));
6417         }
6418         for (int i = 0; i < sVolumeGroupStates.size(); i++) {
6419             final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
6420             vgs.applyAllVolumes();
6421         }
6422     }
6423 
ensureValidAttributes(AudioVolumeGroup avg)6424     private void ensureValidAttributes(AudioVolumeGroup avg) {
6425         boolean hasAtLeastOneValidAudioAttributes = avg.getAudioAttributes().stream()
6426                 .anyMatch(aa -> !aa.equals(AudioProductStrategy.sDefaultAttributes));
6427         if (!hasAtLeastOneValidAudioAttributes) {
6428             throw new IllegalArgumentException("Volume Group " + avg.name()
6429                     + " has no valid audio attributes");
6430         }
6431     }
6432 
readVolumeGroupsSettings()6433     private void readVolumeGroupsSettings() {
6434         if (DEBUG_VOL) {
6435             Log.v(TAG, "readVolumeGroupsSettings");
6436         }
6437         for (int i = 0; i < sVolumeGroupStates.size(); i++) {
6438             final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
6439             vgs.readSettings();
6440             vgs.applyAllVolumes();
6441         }
6442     }
6443 
6444     // Called upon crash of AudioServer
restoreVolumeGroups()6445     private void restoreVolumeGroups() {
6446         if (DEBUG_VOL) {
6447             Log.v(TAG, "restoreVolumeGroups");
6448         }
6449         for (int i = 0; i < sVolumeGroupStates.size(); i++) {
6450             final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
6451             vgs.applyAllVolumes();
6452         }
6453     }
6454 
dumpVolumeGroups(PrintWriter pw)6455     private void dumpVolumeGroups(PrintWriter pw) {
6456         pw.println("\nVolume Groups (device: index)");
6457         for (int i = 0; i < sVolumeGroupStates.size(); i++) {
6458             final VolumeGroupState vgs = sVolumeGroupStates.valueAt(i);
6459             vgs.dump(pw);
6460             pw.println("");
6461         }
6462     }
6463 
6464     // NOTE: Locking order for synchronized objects related to volume management:
6465     //  1     mSettingsLock
6466     //  2       VolumeGroupState.class
6467     private class VolumeGroupState {
6468         private final AudioVolumeGroup mAudioVolumeGroup;
6469         private final SparseIntArray mIndexMap = new SparseIntArray(8);
6470         private int mIndexMin;
6471         private int mIndexMax;
6472         private int mLegacyStreamType = AudioSystem.STREAM_DEFAULT;
6473         private int mPublicStreamType = AudioSystem.STREAM_MUSIC;
6474         private AudioAttributes mAudioAttributes = AudioProductStrategy.sDefaultAttributes;
6475 
6476         // No API in AudioSystem to get a device from strategy or from attributes.
6477         // Need a valid public stream type to use current API getDeviceForStream
getDeviceForVolume()6478         private int getDeviceForVolume() {
6479             return getDeviceForStream(mPublicStreamType);
6480         }
6481 
VolumeGroupState(AudioVolumeGroup avg)6482         private VolumeGroupState(AudioVolumeGroup avg) {
6483             mAudioVolumeGroup = avg;
6484             if (DEBUG_VOL) {
6485                 Log.v(TAG, "VolumeGroupState for " + avg.toString());
6486             }
6487             for (final AudioAttributes aa : avg.getAudioAttributes()) {
6488                 if (!aa.equals(AudioProductStrategy.sDefaultAttributes)) {
6489                     mAudioAttributes = aa;
6490                     break;
6491                 }
6492             }
6493             final int[] streamTypes = mAudioVolumeGroup.getLegacyStreamTypes();
6494             if (streamTypes.length != 0) {
6495                 // Uses already initialized MIN / MAX if a stream type is attached to group
6496                 mLegacyStreamType = streamTypes[0];
6497                 for (final int streamType : streamTypes) {
6498                     if (streamType != AudioSystem.STREAM_DEFAULT
6499                             && streamType < AudioSystem.getNumStreamTypes()) {
6500                         mPublicStreamType = streamType;
6501                         break;
6502                     }
6503                 }
6504                 mIndexMin = MIN_STREAM_VOLUME[mPublicStreamType];
6505                 mIndexMax = MAX_STREAM_VOLUME[mPublicStreamType];
6506             } else if (!avg.getAudioAttributes().isEmpty()) {
6507                 mIndexMin = AudioSystem.getMinVolumeIndexForAttributes(mAudioAttributes);
6508                 mIndexMax = AudioSystem.getMaxVolumeIndexForAttributes(mAudioAttributes);
6509             } else {
6510                 Log.e(TAG, "volume group: " + mAudioVolumeGroup.name()
6511                         + " has neither valid attributes nor valid stream types assigned");
6512                 return;
6513             }
6514             // Load volume indexes from data base
6515             readSettings();
6516         }
6517 
getLegacyStreamTypes()6518         public @NonNull int[] getLegacyStreamTypes() {
6519             return mAudioVolumeGroup.getLegacyStreamTypes();
6520         }
6521 
name()6522         public String name() {
6523             return mAudioVolumeGroup.name();
6524         }
6525 
getVolumeIndex()6526         public int getVolumeIndex() {
6527             return getIndex(getDeviceForVolume());
6528         }
6529 
setVolumeIndex(int index, int flags)6530         public void setVolumeIndex(int index, int flags) {
6531             if (mUseFixedVolume) {
6532                 return;
6533             }
6534             setVolumeIndex(index, getDeviceForVolume(), flags);
6535         }
6536 
setVolumeIndex(int index, int device, int flags)6537         private void setVolumeIndex(int index, int device, int flags) {
6538             // Set the volume index
6539             setVolumeIndexInt(index, device, flags);
6540 
6541             // Update local cache
6542             mIndexMap.put(device, index);
6543 
6544             // update data base - post a persist volume group msg
6545             sendMsg(mAudioHandler,
6546                     MSG_PERSIST_VOLUME_GROUP,
6547                     SENDMSG_QUEUE,
6548                     device,
6549                     0,
6550                     this,
6551                     PERSIST_DELAY);
6552         }
6553 
setVolumeIndexInt(int index, int device, int flags)6554         private void setVolumeIndexInt(int index, int device, int flags) {
6555             // Reflect mute state of corresponding stream by forcing index to 0 if muted
6556             // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted.
6557             // This allows RX path muting by the audio HAL only when explicitly muted but not when
6558             // index is just set to 0 to repect BT requirements
6559             if (mStreamStates[mPublicStreamType].isFullyMuted()) {
6560                 index = 0;
6561             } else if (mPublicStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0) {
6562                 index = 1;
6563             }
6564             // Set the volume index
6565             AudioSystem.setVolumeIndexForAttributes(mAudioAttributes, index, device);
6566         }
6567 
getIndex(int device)6568         public int getIndex(int device) {
6569             synchronized (VolumeGroupState.class) {
6570                 int index = mIndexMap.get(device, -1);
6571                 // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
6572                 return (index != -1) ? index : mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT);
6573             }
6574         }
6575 
hasIndexForDevice(int device)6576         public boolean hasIndexForDevice(int device) {
6577             synchronized (VolumeGroupState.class) {
6578                 return (mIndexMap.get(device, -1) != -1);
6579             }
6580         }
6581 
getMaxIndex()6582         public int getMaxIndex() {
6583             return mIndexMax;
6584         }
6585 
getMinIndex()6586         public int getMinIndex() {
6587             return mIndexMin;
6588         }
6589 
isValidLegacyStreamType()6590         private boolean isValidLegacyStreamType() {
6591             return (mLegacyStreamType != AudioSystem.STREAM_DEFAULT)
6592                     && (mLegacyStreamType < mStreamStates.length);
6593         }
6594 
applyAllVolumes()6595         public void applyAllVolumes() {
6596             synchronized (VolumeGroupState.class) {
6597                 int deviceForStream = AudioSystem.DEVICE_NONE;
6598                 int volumeIndexForStream = 0;
6599                 if (isValidLegacyStreamType()) {
6600                     // Prevent to apply settings twice when group is associated to public stream
6601                     deviceForStream = getDeviceForStream(mLegacyStreamType);
6602                     volumeIndexForStream = getStreamVolume(mLegacyStreamType);
6603                 }
6604                 // apply device specific volumes first
6605                 int index;
6606                 for (int i = 0; i < mIndexMap.size(); i++) {
6607                     final int device = mIndexMap.keyAt(i);
6608                     if (device != AudioSystem.DEVICE_OUT_DEFAULT) {
6609                         index = mIndexMap.valueAt(i);
6610                         if (device == deviceForStream && volumeIndexForStream == index) {
6611                             continue;
6612                         }
6613                         if (DEBUG_VOL) {
6614                             Log.v(TAG, "applyAllVolumes: restore index " + index + " for group "
6615                                     + mAudioVolumeGroup.name() + " and device "
6616                                     + AudioSystem.getOutputDeviceName(device));
6617                         }
6618                         setVolumeIndexInt(index, device, 0 /*flags*/);
6619                     }
6620                 }
6621                 // apply default volume last: by convention , default device volume will be used
6622                 // by audio policy manager if no explicit volume is present for a given device type
6623                 index = getIndex(AudioSystem.DEVICE_OUT_DEFAULT);
6624                 if (DEBUG_VOL) {
6625                     Log.v(TAG, "applyAllVolumes: restore default device index " + index
6626                             + " for group " + mAudioVolumeGroup.name());
6627                 }
6628                 if (isValidLegacyStreamType()) {
6629                     int defaultStreamIndex = (mStreamStates[mLegacyStreamType]
6630                             .getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5) / 10;
6631                     if (defaultStreamIndex == index) {
6632                         return;
6633                     }
6634                 }
6635                 setVolumeIndexInt(index, AudioSystem.DEVICE_OUT_DEFAULT, 0 /*flags*/);
6636             }
6637         }
6638 
persistVolumeGroup(int device)6639         private void persistVolumeGroup(int device) {
6640             if (mUseFixedVolume) {
6641                 return;
6642             }
6643             if (DEBUG_VOL) {
6644                 Log.v(TAG, "persistVolumeGroup: storing index " + getIndex(device) + " for group "
6645                         + mAudioVolumeGroup.name()
6646                         + ", device " + AudioSystem.getOutputDeviceName(device)
6647                         + " and User=" + ActivityManager.getCurrentUser());
6648             }
6649             boolean success = Settings.System.putIntForUser(mContentResolver,
6650                     getSettingNameForDevice(device),
6651                     getIndex(device),
6652                     UserHandle.USER_CURRENT);
6653             if (!success) {
6654                 Log.e(TAG, "persistVolumeGroup failed for group " +  mAudioVolumeGroup.name());
6655             }
6656         }
6657 
readSettings()6658         public void readSettings() {
6659             synchronized (VolumeGroupState.class) {
6660                 // First clear previously loaded (previous user?) settings
6661                 mIndexMap.clear();
6662                 // force maximum volume on all streams if fixed volume property is set
6663                 if (mUseFixedVolume) {
6664                     mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
6665                     return;
6666                 }
6667                 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
6668                     // retrieve current volume for device
6669                     // if no volume stored for current volume group and device, use default volume
6670                     // if default device, continue otherwise
6671                     int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT)
6672                             ? AudioSystem.DEFAULT_STREAM_VOLUME[mPublicStreamType] : -1;
6673                     int index;
6674                     String name = getSettingNameForDevice(device);
6675                     index = Settings.System.getIntForUser(
6676                             mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT);
6677                     if (index == -1) {
6678                         continue;
6679                     }
6680                     if (mPublicStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED
6681                             && mCameraSoundForced) {
6682                         index = mIndexMax;
6683                     }
6684                     if (DEBUG_VOL) {
6685                         Log.v(TAG, "readSettings: found stored index " + getValidIndex(index)
6686                                  + " for group " + mAudioVolumeGroup.name() + ", device: " + name
6687                                  + ", User=" + ActivityManager.getCurrentUser());
6688                     }
6689                     mIndexMap.put(device, getValidIndex(index));
6690                 }
6691             }
6692         }
6693 
getValidIndex(int index)6694         private int getValidIndex(int index) {
6695             if (index < mIndexMin) {
6696                 return mIndexMin;
6697             } else if (mUseFixedVolume || index > mIndexMax) {
6698                 return mIndexMax;
6699             }
6700             return index;
6701         }
6702 
getSettingNameForDevice(int device)6703         public @NonNull String getSettingNameForDevice(int device) {
6704             final String suffix = AudioSystem.getOutputDeviceName(device);
6705             if (suffix.isEmpty()) {
6706                 return mAudioVolumeGroup.name();
6707             }
6708             return mAudioVolumeGroup.name() + "_" + AudioSystem.getOutputDeviceName(device);
6709         }
6710 
dump(PrintWriter pw)6711         private void dump(PrintWriter pw) {
6712             pw.println("- VOLUME GROUP " + mAudioVolumeGroup.name() + ":");
6713             pw.print("   Min: ");
6714             pw.println(mIndexMin);
6715             pw.print("   Max: ");
6716             pw.println(mIndexMax);
6717             pw.print("   Current: ");
6718             for (int i = 0; i < mIndexMap.size(); i++) {
6719                 if (i > 0) {
6720                     pw.print(", ");
6721                 }
6722                 final int device = mIndexMap.keyAt(i);
6723                 pw.print(Integer.toHexString(device));
6724                 final String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
6725                         : AudioSystem.getOutputDeviceName(device);
6726                 if (!deviceName.isEmpty()) {
6727                     pw.print(" (");
6728                     pw.print(deviceName);
6729                     pw.print(")");
6730                 }
6731                 pw.print(": ");
6732                 pw.print(mIndexMap.valueAt(i));
6733             }
6734             pw.println();
6735             pw.print("   Devices: ");
6736             int n = 0;
6737             final int devices = getDeviceForVolume();
6738             for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
6739                 if ((devices & device) == device) {
6740                     if (n++ > 0) {
6741                         pw.print(", ");
6742                     }
6743                     pw.print(AudioSystem.getOutputDeviceName(device));
6744                 }
6745             }
6746         }
6747     }
6748 
6749 
6750     // NOTE: Locking order for synchronized objects related to volume or ringer mode management:
6751     //  1 mScoclient OR mSafeMediaVolumeState
6752     //  2   mSetModeLock
6753     //  3     mSettingsLock
6754     //  4       VolumeStreamState.class
6755     private class VolumeStreamState {
6756         private final int mStreamType;
6757         private int mIndexMin;
6758         // min index when user doesn't have permission to change audio settings
6759         private int mIndexMinNoPerm;
6760         private int mIndexMax;
6761 
6762         private boolean mIsMuted;
6763         private boolean mIsMutedInternally;
6764         private String mVolumeIndexSettingName;
6765         private int mObservedDevices;
6766 
6767         private final SparseIntArray mIndexMap = new SparseIntArray(8) {
6768             @Override
6769             public void put(int key, int value) {
6770                 super.put(key, value);
6771                 record("put", key, value);
6772             }
6773             @Override
6774             public void setValueAt(int index, int value) {
6775                 super.setValueAt(index, value);
6776                 record("setValueAt", keyAt(index), value);
6777             }
6778 
6779             // Record all changes in the VolumeStreamState
6780             private void record(String event, int key, int value) {
6781                 final String device = key == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
6782                         : AudioSystem.getOutputDeviceName(key);
6783                 new MediaMetrics.Item(MediaMetrics.Name.AUDIO_VOLUME + MediaMetrics.SEPARATOR
6784                         + AudioSystem.streamToString(mStreamType)
6785                         + "." + device)
6786                         .set(MediaMetrics.Property.EVENT, event)
6787                         .set(MediaMetrics.Property.INDEX, value)
6788                         .set(MediaMetrics.Property.MIN_INDEX, mIndexMin)
6789                         .set(MediaMetrics.Property.MAX_INDEX, mIndexMax)
6790                         .record();
6791             }
6792         };
6793         private final Intent mVolumeChanged;
6794         private final Intent mStreamDevicesChanged;
6795 
VolumeStreamState(String settingName, int streamType)6796         private VolumeStreamState(String settingName, int streamType) {
6797             mVolumeIndexSettingName = settingName;
6798 
6799             mStreamType = streamType;
6800             mIndexMin = MIN_STREAM_VOLUME[streamType] * 10;
6801             mIndexMinNoPerm = mIndexMin; // may be overwritten later in updateNoPermMinIndex()
6802             mIndexMax = MAX_STREAM_VOLUME[streamType] * 10;
6803             final int status = AudioSystem.initStreamVolume(
6804                     streamType, mIndexMin / 10, mIndexMax / 10);
6805             if (status != AudioSystem.AUDIO_STATUS_OK) {
6806                 sLifecycleLogger.log(new AudioEventLogger.StringEvent(
6807                          "VSS() stream:" + streamType + " initStreamVolume=" + status)
6808                         .printLog(ALOGE, TAG));
6809                 sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_NOOP, 0, 0,
6810                         "VSS()" /*obj*/, 2 * INDICATE_SYSTEM_READY_RETRY_DELAY_MS);
6811             }
6812 
6813             readSettings();
6814             mVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION);
6815             mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
6816             mStreamDevicesChanged = new Intent(AudioManager.STREAM_DEVICES_CHANGED_ACTION);
6817             mStreamDevicesChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
6818         }
6819 
6820         /**
6821          * Update the minimum index that can be used without MODIFY_AUDIO_SETTINGS permission
6822          * @param index minimum index expressed in "UI units", i.e. no 10x factor
6823          */
updateNoPermMinIndex(int index)6824         public void updateNoPermMinIndex(int index) {
6825             mIndexMinNoPerm = index * 10;
6826             if (mIndexMinNoPerm < mIndexMin) {
6827                 Log.e(TAG, "Invalid mIndexMinNoPerm for stream " + mStreamType);
6828                 mIndexMinNoPerm = mIndexMin;
6829             }
6830         }
6831 
6832         @GuardedBy("VolumeStreamState.class")
observeDevicesForStream_syncVSS(boolean checkOthers)6833         public int observeDevicesForStream_syncVSS(boolean checkOthers) {
6834             if (!mSystemServer.isPrivileged()) {
6835                 return AudioSystem.DEVICE_NONE;
6836             }
6837             final int devices = mAudioSystem.getDevicesForStream(mStreamType);
6838             if (devices == mObservedDevices) {
6839                 return devices;
6840             }
6841             final int prevDevices = mObservedDevices;
6842             mObservedDevices = devices;
6843             if (checkOthers) {
6844                 // one stream's devices have changed, check the others
6845                 postObserveDevicesForAllStreams(mStreamType);
6846             }
6847             // log base stream changes to the event log
6848             if (mStreamVolumeAlias[mStreamType] == mStreamType) {
6849                 EventLogTags.writeStreamDevicesChanged(mStreamType, prevDevices, devices);
6850             }
6851             // send STREAM_DEVICES_CHANGED_ACTION on the message handler so it is scheduled after
6852             // the postObserveDevicesForStreams is handled
6853             sendMsg(mAudioHandler,
6854                     MSG_STREAM_DEVICES_CHANGED,
6855                     SENDMSG_QUEUE, prevDevices /*arg1*/, devices /*arg2*/,
6856                     // ok to send reference to this object, it is final
6857                     mStreamDevicesChanged /*obj*/, 0 /*delay*/);
6858             return devices;
6859         }
6860 
getSettingNameForDevice(int device)6861         public @Nullable String getSettingNameForDevice(int device) {
6862             if (!hasValidSettingsName()) {
6863                 return null;
6864             }
6865             final String suffix = AudioSystem.getOutputDeviceName(device);
6866             if (suffix.isEmpty()) {
6867                 return mVolumeIndexSettingName;
6868             }
6869             return mVolumeIndexSettingName + "_" + suffix;
6870         }
6871 
hasValidSettingsName()6872         private boolean hasValidSettingsName() {
6873             return (mVolumeIndexSettingName != null && !mVolumeIndexSettingName.isEmpty());
6874         }
6875 
readSettings()6876         public void readSettings() {
6877             synchronized (mSettingsLock) {
6878                 synchronized (VolumeStreamState.class) {
6879                     // force maximum volume on all streams if fixed volume property is set
6880                     if (mUseFixedVolume) {
6881                         mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, mIndexMax);
6882                         return;
6883                     }
6884                     // do not read system stream volume from settings: this stream is always aliased
6885                     // to another stream type and its volume is never persisted. Values in settings can
6886                     // only be stale values
6887                     if ((mStreamType == AudioSystem.STREAM_SYSTEM) ||
6888                             (mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED)) {
6889                         int index = 10 * AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType];
6890                         if (mCameraSoundForced) {
6891                             index = mIndexMax;
6892                         }
6893                         mIndexMap.put(AudioSystem.DEVICE_OUT_DEFAULT, index);
6894                         return;
6895                     }
6896                 }
6897             }
6898             synchronized (VolumeStreamState.class) {
6899                 for (int device : AudioSystem.DEVICE_OUT_ALL_SET) {
6900 
6901                     // retrieve current volume for device
6902                     // if no volume stored for current stream and device, use default volume if default
6903                     // device, continue otherwise
6904                     int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) ?
6905                             AudioSystem.DEFAULT_STREAM_VOLUME[mStreamType] : -1;
6906                     int index;
6907                     if (!hasValidSettingsName()) {
6908                         index = defaultIndex;
6909                     } else {
6910                         String name = getSettingNameForDevice(device);
6911                         index = Settings.System.getIntForUser(
6912                                 mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT);
6913                     }
6914                     if (index == -1) {
6915                         continue;
6916                     }
6917 
6918                     mIndexMap.put(device, getValidIndex(10 * index,
6919                             true /*hasModifyAudioSettings*/));
6920                 }
6921             }
6922         }
6923 
getAbsoluteVolumeIndex(int index)6924         private int getAbsoluteVolumeIndex(int index) {
6925             /* Special handling for Bluetooth Absolute Volume scenario
6926              * If we send full audio gain, some accessories are too loud even at its lowest
6927              * volume. We are not able to enumerate all such accessories, so here is the
6928              * workaround from phone side.
6929              * Pre-scale volume at lowest volume steps 1 2 and 3.
6930              * For volume step 0, set audio gain to 0 as some accessories won't mute on their end.
6931              */
6932             if (index == 0) {
6933                 // 0% for volume 0
6934                 index = 0;
6935             } else if (index > 0 && index <= 3) {
6936                 // Pre-scale for volume steps 1 2 and 3
6937                 index = (int) (mIndexMax * mPrescaleAbsoluteVolume[index - 1]) / 10;
6938             } else {
6939                 // otherwise, full gain
6940                 index = (mIndexMax + 5) / 10;
6941             }
6942             return index;
6943         }
6944 
setStreamVolumeIndex(int index, int device)6945         private void setStreamVolumeIndex(int index, int device) {
6946             // Only set audio policy BT SCO stream volume to 0 when the stream is actually muted.
6947             // This allows RX path muting by the audio HAL only when explicitly muted but not when
6948             // index is just set to 0 to repect BT requirements
6949             if (mStreamType == AudioSystem.STREAM_BLUETOOTH_SCO && index == 0
6950                     && !isFullyMuted()) {
6951                 index = 1;
6952             }
6953             AudioSystem.setStreamVolumeIndexAS(mStreamType, index, device);
6954         }
6955 
6956         // must be called while synchronized VolumeStreamState.class
applyDeviceVolume_syncVSS(int device)6957         /*package*/ void applyDeviceVolume_syncVSS(int device) {
6958             int index;
6959             if (isFullyMuted()) {
6960                 index = 0;
6961             } else if (AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
6962                     && mAvrcpAbsVolSupported) {
6963                 index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10);
6964             } else if (isFullVolumeDevice(device)) {
6965                 index = (mIndexMax + 5)/10;
6966             } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
6967                 index = (mIndexMax + 5)/10;
6968             } else {
6969                 index = (getIndex(device) + 5)/10;
6970             }
6971             setStreamVolumeIndex(index, device);
6972         }
6973 
applyAllVolumes()6974         public void applyAllVolumes() {
6975             synchronized (VolumeStreamState.class) {
6976                 // apply device specific volumes first
6977                 int index;
6978                 for (int i = 0; i < mIndexMap.size(); i++) {
6979                     final int device = mIndexMap.keyAt(i);
6980                     if (device != AudioSystem.DEVICE_OUT_DEFAULT) {
6981                         if (isFullyMuted()) {
6982                             index = 0;
6983                         } else if (AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)
6984                                 && mAvrcpAbsVolSupported) {
6985                             index = getAbsoluteVolumeIndex((getIndex(device) + 5)/10);
6986                         } else if (isFullVolumeDevice(device)) {
6987                             index = (mIndexMax + 5)/10;
6988                         } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
6989                             index = (mIndexMax + 5)/10;
6990                         } else {
6991                             index = (mIndexMap.valueAt(i) + 5)/10;
6992                         }
6993                         setStreamVolumeIndex(index, device);
6994                     }
6995                 }
6996                 // apply default volume last: by convention , default device volume will be used
6997                 // by audio policy manager if no explicit volume is present for a given device type
6998                 if (isFullyMuted()) {
6999                     index = 0;
7000                 } else {
7001                     index = (getIndex(AudioSystem.DEVICE_OUT_DEFAULT) + 5)/10;
7002                 }
7003                 setStreamVolumeIndex(index, AudioSystem.DEVICE_OUT_DEFAULT);
7004             }
7005         }
7006 
adjustIndex(int deltaIndex, int device, String caller, boolean hasModifyAudioSettings)7007         public boolean adjustIndex(int deltaIndex, int device, String caller,
7008                 boolean hasModifyAudioSettings) {
7009             return setIndex(getIndex(device) + deltaIndex, device, caller,
7010                     hasModifyAudioSettings);
7011         }
7012 
setIndex(int index, int device, String caller, boolean hasModifyAudioSettings)7013         public boolean setIndex(int index, int device, String caller,
7014                 boolean hasModifyAudioSettings) {
7015             boolean changed;
7016             int oldIndex;
7017             synchronized (mSettingsLock) {
7018                 synchronized (VolumeStreamState.class) {
7019                     oldIndex = getIndex(device);
7020                     index = getValidIndex(index, hasModifyAudioSettings);
7021                     if ((mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED) && mCameraSoundForced) {
7022                         index = mIndexMax;
7023                     }
7024                     mIndexMap.put(device, index);
7025 
7026                     changed = oldIndex != index;
7027                     // Apply change to all streams using this one as alias if:
7028                     // - the index actually changed OR
7029                     // - there is no volume index stored for this device on alias stream.
7030                     // If changing volume of current device, also change volume of current
7031                     // device on aliased stream
7032                     final boolean isCurrentDevice = (device == getDeviceForStream(mStreamType));
7033                     final int numStreamTypes = AudioSystem.getNumStreamTypes();
7034                     for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
7035                         final VolumeStreamState aliasStreamState = mStreamStates[streamType];
7036                         if (streamType != mStreamType &&
7037                                 mStreamVolumeAlias[streamType] == mStreamType &&
7038                                 (changed || !aliasStreamState.hasIndexForDevice(device))) {
7039                             final int scaledIndex = rescaleIndex(index, mStreamType, streamType);
7040                             aliasStreamState.setIndex(scaledIndex, device, caller,
7041                                     hasModifyAudioSettings);
7042                             if (isCurrentDevice) {
7043                                 aliasStreamState.setIndex(scaledIndex,
7044                                         getDeviceForStream(streamType), caller,
7045                                         hasModifyAudioSettings);
7046                             }
7047                         }
7048                     }
7049                     // Mirror changes in SPEAKER ringtone volume on SCO when
7050                     if (changed && mStreamType == AudioSystem.STREAM_RING
7051                             && device == AudioSystem.DEVICE_OUT_SPEAKER) {
7052                         for (int i = 0; i < mIndexMap.size(); i++) {
7053                             int otherDevice = mIndexMap.keyAt(i);
7054                             if (AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(otherDevice)) {
7055                                 mIndexMap.put(otherDevice, index);
7056                             }
7057                         }
7058                     }
7059                 }
7060             }
7061             if (changed) {
7062                 oldIndex = (oldIndex + 5) / 10;
7063                 index = (index + 5) / 10;
7064                 // log base stream changes to the event log
7065                 if (mStreamVolumeAlias[mStreamType] == mStreamType) {
7066                     if (caller == null) {
7067                         Log.w(TAG, "No caller for volume_changed event", new Throwable());
7068                     }
7069                     EventLogTags.writeVolumeChanged(mStreamType, oldIndex, index, mIndexMax / 10,
7070                             caller);
7071                 }
7072                 // fire changed intents for all streams
7073                 if (index != oldIndex) {
7074                     mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index);
7075                     mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex);
7076                     mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS,
7077                             mStreamVolumeAlias[mStreamType]);
7078                     sendBroadcastToAll(mVolumeChanged);
7079                 }
7080             }
7081             return changed;
7082         }
7083 
getIndex(int device)7084         public int getIndex(int device) {
7085             synchronized (VolumeStreamState.class) {
7086                 int index = mIndexMap.get(device, -1);
7087                 if (index == -1) {
7088                     // there is always an entry for AudioSystem.DEVICE_OUT_DEFAULT
7089                     index = mIndexMap.get(AudioSystem.DEVICE_OUT_DEFAULT);
7090                 }
7091                 return index;
7092             }
7093         }
7094 
hasIndexForDevice(int device)7095         public boolean hasIndexForDevice(int device) {
7096             synchronized (VolumeStreamState.class) {
7097                 return (mIndexMap.get(device, -1) != -1);
7098             }
7099         }
7100 
getMaxIndex()7101         public int getMaxIndex() {
7102             return mIndexMax;
7103         }
7104 
7105         /**
7106          * @return the lowest index regardless of permissions
7107          */
getMinIndex()7108         public int getMinIndex() {
7109             return mIndexMin;
7110         }
7111 
7112         /**
7113          * @param isPrivileged true if the caller is privileged and not subject to minimum
7114          *                     volume index thresholds
7115          * @return the lowest index that this caller can set or adjust to
7116          */
getMinIndex(boolean isPrivileged)7117         public int getMinIndex(boolean isPrivileged) {
7118             return isPrivileged ? mIndexMin : mIndexMinNoPerm;
7119         }
7120 
7121         /**
7122          * Copies all device/index pairs from the given VolumeStreamState after initializing
7123          * them with the volume for DEVICE_OUT_DEFAULT. No-op if the source VolumeStreamState
7124          * has the same stream type as this instance.
7125          * @param srcStream
7126          * @param caller
7127          */
7128         // must be sync'd on mSettingsLock before VolumeStreamState.class
7129         @GuardedBy("VolumeStreamState.class")
setAllIndexes(VolumeStreamState srcStream, String caller)7130         public void setAllIndexes(VolumeStreamState srcStream, String caller) {
7131             if (mStreamType == srcStream.mStreamType) {
7132                 return;
7133             }
7134             int srcStreamType = srcStream.getStreamType();
7135             // apply default device volume from source stream to all devices first in case
7136             // some devices are present in this stream state but not in source stream state
7137             int index = srcStream.getIndex(AudioSystem.DEVICE_OUT_DEFAULT);
7138             index = rescaleIndex(index, srcStreamType, mStreamType);
7139             for (int i = 0; i < mIndexMap.size(); i++) {
7140                 mIndexMap.put(mIndexMap.keyAt(i), index);
7141             }
7142             // Now apply actual volume for devices in source stream state
7143             SparseIntArray srcMap = srcStream.mIndexMap;
7144             for (int i = 0; i < srcMap.size(); i++) {
7145                 int device = srcMap.keyAt(i);
7146                 index = srcMap.valueAt(i);
7147                 index = rescaleIndex(index, srcStreamType, mStreamType);
7148 
7149                 setIndex(index, device, caller, true /*hasModifyAudioSettings*/);
7150             }
7151         }
7152 
7153         // must be sync'd on mSettingsLock before VolumeStreamState.class
7154         @GuardedBy("VolumeStreamState.class")
setAllIndexesToMax()7155         public void setAllIndexesToMax() {
7156             for (int i = 0; i < mIndexMap.size(); i++) {
7157                 mIndexMap.put(mIndexMap.keyAt(i), mIndexMax);
7158             }
7159         }
7160 
7161         /**
7162          * Mute/unmute the stream
7163          * @param state the new mute state
7164          * @return true if the mute state was changed
7165          */
mute(boolean state)7166         public boolean mute(boolean state) {
7167             boolean changed = false;
7168             synchronized (VolumeStreamState.class) {
7169                 if (state != mIsMuted) {
7170                     changed = true;
7171                     mIsMuted = state;
7172 
7173                     // Set the new mute volume. This propagates the values to
7174                     // the audio system, otherwise the volume won't be changed
7175                     // at the lower level.
7176                     sendMsg(mAudioHandler,
7177                             MSG_SET_ALL_VOLUMES,
7178                             SENDMSG_QUEUE,
7179                             0,
7180                             0,
7181                             this, 0);
7182                 }
7183             }
7184             if (changed) {
7185                 // Stream mute changed, fire the intent.
7186                 Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION);
7187                 intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType);
7188                 intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, state);
7189                 sendBroadcastToAll(intent);
7190             }
7191             return changed;
7192         }
7193 
7194         /**
7195          * Mute/unmute the stream by AudioService
7196          * @param state the new mute state
7197          * @return true if the mute state was changed
7198          */
muteInternally(boolean state)7199         public boolean muteInternally(boolean state) {
7200             boolean changed = false;
7201             synchronized (VolumeStreamState.class) {
7202                 if (state != mIsMutedInternally) {
7203                     changed = true;
7204                     mIsMutedInternally = state;
7205                     // mute immediately to avoid delay and preemption when using a message.
7206                     applyAllVolumes();
7207                 }
7208             }
7209             if (changed) {
7210                 sVolumeLogger.log(new VolumeEvent(
7211                         VolumeEvent.VOL_MUTE_STREAM_INT, mStreamType, state));
7212             }
7213             return changed;
7214         }
7215 
7216         @GuardedBy("VolumeStreamState.class")
isFullyMuted()7217         public boolean isFullyMuted() {
7218             return mIsMuted || mIsMutedInternally;
7219         }
7220 
getStreamType()7221         public int getStreamType() {
7222             return mStreamType;
7223         }
7224 
checkFixedVolumeDevices()7225         public void checkFixedVolumeDevices() {
7226             synchronized (VolumeStreamState.class) {
7227                 // ignore settings for fixed volume devices: volume should always be at max or 0
7228                 if (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_MUSIC) {
7229                     for (int i = 0; i < mIndexMap.size(); i++) {
7230                         int device = mIndexMap.keyAt(i);
7231                         int index = mIndexMap.valueAt(i);
7232                         if (isFullVolumeDevice(device)
7233                                 || (isFixedVolumeDevice(device) && index != 0)) {
7234                             mIndexMap.put(device, mIndexMax);
7235                         }
7236                         applyDeviceVolume_syncVSS(device);
7237                     }
7238                 }
7239             }
7240         }
7241 
getValidIndex(int index, boolean hasModifyAudioSettings)7242         private int getValidIndex(int index, boolean hasModifyAudioSettings) {
7243             final int indexMin = hasModifyAudioSettings ? mIndexMin : mIndexMinNoPerm;
7244             if (index < indexMin) {
7245                 return indexMin;
7246             } else if (mUseFixedVolume || index > mIndexMax) {
7247                 return mIndexMax;
7248             }
7249 
7250             return index;
7251         }
7252 
dump(PrintWriter pw)7253         private void dump(PrintWriter pw) {
7254             pw.print("   Muted: ");
7255             pw.println(mIsMuted);
7256             pw.print("   Muted Internally: ");
7257             pw.println(mIsMutedInternally);
7258             pw.print("   Min: ");
7259             pw.print((mIndexMin + 5) / 10);
7260             if (mIndexMin != mIndexMinNoPerm) {
7261                 pw.print(" w/o perm:");
7262                 pw.println((mIndexMinNoPerm + 5) / 10);
7263             } else {
7264                 pw.println();
7265             }
7266             pw.print("   Max: ");
7267             pw.println((mIndexMax + 5) / 10);
7268             pw.print("   streamVolume:"); pw.println(getStreamVolume(mStreamType));
7269             pw.print("   Current: ");
7270             for (int i = 0; i < mIndexMap.size(); i++) {
7271                 if (i > 0) {
7272                     pw.print(", ");
7273                 }
7274                 final int device = mIndexMap.keyAt(i);
7275                 pw.print(Integer.toHexString(device));
7276                 final String deviceName = device == AudioSystem.DEVICE_OUT_DEFAULT ? "default"
7277                         : AudioSystem.getOutputDeviceName(device);
7278                 if (!deviceName.isEmpty()) {
7279                     pw.print(" (");
7280                     pw.print(deviceName);
7281                     pw.print(")");
7282                 }
7283                 pw.print(": ");
7284                 final int index = (mIndexMap.valueAt(i) + 5) / 10;
7285                 pw.print(index);
7286             }
7287             pw.println();
7288             pw.print("   Devices: ");
7289             final int devices = getDevicesForStreamInt(mStreamType);
7290             int device, i = 0, n = 0;
7291             // iterate all devices from 1 to DEVICE_OUT_DEFAULT exclusive
7292             // (the default device is not returned by getDevicesForStreamInt)
7293             while ((device = 1 << i) != AudioSystem.DEVICE_OUT_DEFAULT) {
7294                 if ((devices & device) != 0) {
7295                     if (n++ > 0) {
7296                         pw.print(", ");
7297                     }
7298                     pw.print(AudioSystem.getOutputDeviceName(device));
7299                 }
7300                 i++;
7301             }
7302         }
7303     }
7304 
7305     /** Thread that handles native AudioSystem control. */
7306     private class AudioSystemThread extends Thread {
AudioSystemThread()7307         AudioSystemThread() {
7308             super("AudioService");
7309         }
7310 
7311         @Override
run()7312         public void run() {
7313             // Set this thread up so the handler will work on it
7314             Looper.prepare();
7315 
7316             synchronized(AudioService.this) {
7317                 mAudioHandler = new AudioHandler();
7318 
7319                 // Notify that the handler has been created
7320                 AudioService.this.notify();
7321             }
7322 
7323             // Listen for volume change requests that are set by VolumePanel
7324             Looper.loop();
7325         }
7326     }
7327 
7328     private static final class DeviceVolumeUpdate {
7329         final int mStreamType;
7330         final int mDevice;
7331         final @NonNull String mCaller;
7332         private static final int NO_NEW_INDEX = -2049;
7333         private final int mVssVolIndex;
7334 
7335         // Constructor with volume index, meant to cause this volume to be set and applied for the
7336         // given stream type on the given device
DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller)7337         DeviceVolumeUpdate(int streamType, int vssVolIndex, int device, @NonNull String caller) {
7338             mStreamType = streamType;
7339             mVssVolIndex = vssVolIndex;
7340             mDevice = device;
7341             mCaller = caller;
7342         }
7343 
7344         // Constructor with no volume index, meant to cause re-apply of volume for the given
7345         // stream type on the given device
DeviceVolumeUpdate(int streamType, int device, @NonNull String caller)7346         DeviceVolumeUpdate(int streamType, int device, @NonNull String caller) {
7347             mStreamType = streamType;
7348             mVssVolIndex = NO_NEW_INDEX;
7349             mDevice = device;
7350             mCaller = caller;
7351         }
7352 
hasVolumeIndex()7353         boolean hasVolumeIndex() {
7354             return mVssVolIndex != NO_NEW_INDEX;
7355         }
7356 
getVolumeIndex()7357         int getVolumeIndex() throws IllegalStateException {
7358             Preconditions.checkState(mVssVolIndex != NO_NEW_INDEX);
7359             return mVssVolIndex;
7360         }
7361     }
7362 
7363     /** only public for mocking/spying, do not call outside of AudioService */
7364     @VisibleForTesting
postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device, String caller)7365     public void postSetVolumeIndexOnDevice(int streamType, int vssVolIndex, int device,
7366                                                 String caller) {
7367         sendMsg(mAudioHandler,
7368                 MSG_SET_DEVICE_STREAM_VOLUME,
7369                 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/,
7370                 new DeviceVolumeUpdate(streamType, vssVolIndex, device, caller),
7371                 0 /*delay*/);
7372     }
7373 
postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller)7374     /*package*/ void postApplyVolumeOnDevice(int streamType, int device, @NonNull String caller) {
7375         sendMsg(mAudioHandler,
7376                 MSG_SET_DEVICE_STREAM_VOLUME,
7377                 SENDMSG_QUEUE, 0 /*arg1*/, 0 /*arg2*/,
7378                 new DeviceVolumeUpdate(streamType, device, caller),
7379                 0 /*delay*/);
7380     }
7381 
onSetVolumeIndexOnDevice(@onNull DeviceVolumeUpdate update)7382     private void onSetVolumeIndexOnDevice(@NonNull DeviceVolumeUpdate update) {
7383         final VolumeStreamState streamState = mStreamStates[update.mStreamType];
7384         if (update.hasVolumeIndex()) {
7385             int index = update.getVolumeIndex();
7386             if (!checkSafeMediaVolume(update.mStreamType, index, update.mDevice)) {
7387                 index = safeMediaVolumeIndex(update.mDevice);
7388             }
7389             streamState.setIndex(index, update.mDevice, update.mCaller,
7390                     // trusted as index is always validated before message is posted
7391                     true /*hasModifyAudioSettings*/);
7392             sVolumeLogger.log(new AudioEventLogger.StringEvent(update.mCaller + " dev:0x"
7393                     + Integer.toHexString(update.mDevice) + " volIdx:" + index));
7394         } else {
7395             sVolumeLogger.log(new AudioEventLogger.StringEvent(update.mCaller
7396                     + " update vol on dev:0x" + Integer.toHexString(update.mDevice)));
7397         }
7398         setDeviceVolume(streamState, update.mDevice);
7399     }
7400 
setDeviceVolume(VolumeStreamState streamState, int device)7401     /*package*/ void setDeviceVolume(VolumeStreamState streamState, int device) {
7402 
7403         synchronized (VolumeStreamState.class) {
7404             // Apply volume
7405             streamState.applyDeviceVolume_syncVSS(device);
7406 
7407             // Apply change to all streams using this one as alias
7408             int numStreamTypes = AudioSystem.getNumStreamTypes();
7409             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
7410                 if (streamType != streamState.mStreamType &&
7411                         mStreamVolumeAlias[streamType] == streamState.mStreamType) {
7412                     // Make sure volume is also maxed out on A2DP device for aliased stream
7413                     // that may have a different device selected
7414                     int streamDevice = getDeviceForStream(streamType);
7415                     if ((device != streamDevice) && mAvrcpAbsVolSupported
7416                             && AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(device)) {
7417                         mStreamStates[streamType].applyDeviceVolume_syncVSS(device);
7418                     }
7419                     mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice);
7420                 }
7421             }
7422         }
7423         // Post a persist volume msg
7424         sendMsg(mAudioHandler,
7425                 MSG_PERSIST_VOLUME,
7426                 SENDMSG_QUEUE,
7427                 device,
7428                 0,
7429                 streamState,
7430                 PERSIST_DELAY);
7431 
7432     }
7433 
7434     /** Handles internal volume messages in separate volume thread. */
7435     private class AudioHandler extends Handler {
7436 
setAllVolumes(VolumeStreamState streamState)7437         private void setAllVolumes(VolumeStreamState streamState) {
7438 
7439             // Apply volume
7440             streamState.applyAllVolumes();
7441 
7442             // Apply change to all streams using this one as alias
7443             int numStreamTypes = AudioSystem.getNumStreamTypes();
7444             for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
7445                 if (streamType != streamState.mStreamType &&
7446                         mStreamVolumeAlias[streamType] == streamState.mStreamType) {
7447                     mStreamStates[streamType].applyAllVolumes();
7448                 }
7449             }
7450         }
7451 
persistVolume(VolumeStreamState streamState, int device)7452         private void persistVolume(VolumeStreamState streamState, int device) {
7453             if (mUseFixedVolume) {
7454                 return;
7455             }
7456             if (mIsSingleVolume && (streamState.mStreamType != AudioSystem.STREAM_MUSIC)) {
7457                 return;
7458             }
7459             if (streamState.hasValidSettingsName()) {
7460                 System.putIntForUser(mContentResolver,
7461                         streamState.getSettingNameForDevice(device),
7462                         (streamState.getIndex(device) + 5)/ 10,
7463                         UserHandle.USER_CURRENT);
7464             }
7465         }
7466 
persistRingerMode(int ringerMode)7467         private void persistRingerMode(int ringerMode) {
7468             if (mUseFixedVolume) {
7469                 return;
7470             }
7471             Settings.Global.putInt(mContentResolver, Settings.Global.MODE_RINGER, ringerMode);
7472         }
7473 
onPersistSafeVolumeState(int state)7474         private void onPersistSafeVolumeState(int state) {
7475             Settings.Global.putInt(mContentResolver,
7476                     Settings.Global.AUDIO_SAFE_VOLUME_STATE,
7477                     state);
7478         }
7479 
onNotifyVolumeEvent(@onNull IAudioPolicyCallback apc, @AudioManager.VolumeAdjustment int direction)7480         private void onNotifyVolumeEvent(@NonNull IAudioPolicyCallback apc,
7481                 @AudioManager.VolumeAdjustment int direction) {
7482             try {
7483                 apc.notifyVolumeAdjust(direction);
7484             } catch(Exception e) {
7485                 // nothing we can do about this. Do not log error, too much potential for spam
7486             }
7487         }
7488 
7489         @Override
handleMessage(Message msg)7490         public void handleMessage(Message msg) {
7491             switch (msg.what) {
7492 
7493                 case MSG_SET_DEVICE_VOLUME:
7494                     setDeviceVolume((VolumeStreamState) msg.obj, msg.arg1);
7495                     break;
7496 
7497                 case MSG_SET_ALL_VOLUMES:
7498                     setAllVolumes((VolumeStreamState) msg.obj);
7499                     break;
7500 
7501                 case MSG_PERSIST_VOLUME:
7502                     persistVolume((VolumeStreamState) msg.obj, msg.arg1);
7503                     break;
7504 
7505                 case MSG_PERSIST_VOLUME_GROUP:
7506                     final VolumeGroupState vgs = (VolumeGroupState) msg.obj;
7507                     vgs.persistVolumeGroup(msg.arg1);
7508                     break;
7509 
7510                 case MSG_PERSIST_RINGER_MODE:
7511                     // note that the value persisted is the current ringer mode, not the
7512                     // value of ringer mode as of the time the request was made to persist
7513                     persistRingerMode(getRingerModeInternal());
7514                     break;
7515 
7516                 case MSG_AUDIO_SERVER_DIED:
7517                     onAudioServerDied();
7518                     break;
7519 
7520                 case MSG_DISPATCH_AUDIO_SERVER_STATE:
7521                     onDispatchAudioServerStateChange(msg.arg1 == 1);
7522                     break;
7523 
7524                 case MSG_UNLOAD_SOUND_EFFECTS:
7525                     mSfxHelper.unloadSoundEffects();
7526                     break;
7527 
7528                 case MSG_LOAD_SOUND_EFFECTS:
7529                 {
7530                     LoadSoundEffectReply reply = (LoadSoundEffectReply) msg.obj;
7531                     if (mSystemReady) {
7532                         mSfxHelper.loadSoundEffects(reply);
7533                     } else {
7534                         Log.w(TAG, "[schedule]loadSoundEffects() called before boot complete");
7535                         if (reply != null) {
7536                             reply.run(false);
7537                         }
7538                     }
7539                 }
7540                     break;
7541 
7542                 case MSG_PLAY_SOUND_EFFECT:
7543                     mSfxHelper.playSoundEffect(msg.arg1, msg.arg2);
7544                     break;
7545 
7546                 case MSG_SET_FORCE_USE:
7547                 {
7548                     final String eventSource = (String) msg.obj;
7549                     final int useCase = msg.arg1;
7550                     final int config = msg.arg2;
7551                     if (useCase == AudioSystem.FOR_MEDIA) {
7552                         Log.wtf(TAG, "Invalid force use FOR_MEDIA in AudioService from "
7553                                 + eventSource);
7554                         break;
7555                     }
7556                     new MediaMetrics.Item(MediaMetrics.Name.AUDIO_FORCE_USE
7557                             + MediaMetrics.SEPARATOR + AudioSystem.forceUseUsageToString(useCase))
7558                             .set(MediaMetrics.Property.EVENT, "setForceUse")
7559                             .set(MediaMetrics.Property.FORCE_USE_DUE_TO, eventSource)
7560                             .set(MediaMetrics.Property.FORCE_USE_MODE,
7561                                     AudioSystem.forceUseConfigToString(config))
7562                             .record();
7563                     sForceUseLogger.log(
7564                             new AudioServiceEvents.ForceUseEvent(useCase, config, eventSource));
7565                     mAudioSystem.setForceUse(useCase, config);
7566                 }
7567                     break;
7568 
7569                 case MSG_DISABLE_AUDIO_FOR_UID:
7570                     mPlaybackMonitor.disableAudioForUid( msg.arg1 == 1 /* disable */,
7571                             msg.arg2 /* uid */);
7572                     mAudioEventWakeLock.release();
7573                     break;
7574 
7575                 case MSG_INIT_STREAMS_VOLUMES:
7576                     onInitStreamsAndVolumes();
7577                     mAudioEventWakeLock.release();
7578                     break;
7579 
7580                 case MSG_INIT_SPATIALIZER:
7581                     mSpatializerHelper.init(/*effectExpected*/ mHasSpatializerEffect);
7582                     if (mHasSpatializerEffect) {
7583                         mSpatializerHelper.setFeatureEnabled(isSpatialAudioEnabled());
7584                         monitorRoutingChanges(true);
7585                     }
7586                     mAudioEventWakeLock.release();
7587                     break;
7588 
7589                 case MSG_INIT_HEADTRACKING_SENSORS:
7590                     mSpatializerHelper.onInitSensors();
7591                     break;
7592 
7593                 case MSG_CHECK_MUSIC_ACTIVE:
7594                     onCheckMusicActive((String) msg.obj);
7595                     break;
7596 
7597                 case MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED:
7598                 case MSG_CONFIGURE_SAFE_MEDIA_VOLUME:
7599                     onConfigureSafeVolume((msg.what == MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED),
7600                             (String) msg.obj);
7601                     break;
7602                 case MSG_PERSIST_SAFE_VOLUME_STATE:
7603                     onPersistSafeVolumeState(msg.arg1);
7604                     break;
7605 
7606                 case MSG_SYSTEM_READY:
7607                     onSystemReady();
7608                     break;
7609 
7610                 case MSG_INDICATE_SYSTEM_READY:
7611                     onIndicateSystemReady();
7612                     break;
7613 
7614                 case MSG_ACCESSORY_PLUG_MEDIA_UNMUTE:
7615                     onAccessoryPlugMediaUnmute(msg.arg1);
7616                     break;
7617 
7618                 case MSG_PERSIST_MUSIC_ACTIVE_MS:
7619                     final int musicActiveMs = msg.arg1;
7620                     Settings.Secure.putIntForUser(mContentResolver,
7621                             Settings.Secure.UNSAFE_VOLUME_MUSIC_ACTIVE_MS, musicActiveMs,
7622                             UserHandle.USER_CURRENT);
7623                     break;
7624 
7625                 case MSG_UNMUTE_STREAM:
7626                     onUnmuteStream(msg.arg1, msg.arg2);
7627                     break;
7628 
7629                 case MSG_DYN_POLICY_MIX_STATE_UPDATE:
7630                     onDynPolicyMixStateUpdate((String) msg.obj, msg.arg1);
7631                     break;
7632 
7633                 case MSG_NOTIFY_VOL_EVENT:
7634                     onNotifyVolumeEvent((IAudioPolicyCallback) msg.obj, msg.arg1);
7635                     break;
7636 
7637                 case MSG_ENABLE_SURROUND_FORMATS:
7638                     onEnableSurroundFormats((ArrayList<Integer>) msg.obj);
7639                     break;
7640 
7641                 case MSG_UPDATE_RINGER_MODE:
7642                     onUpdateRingerModeServiceInt();
7643                     break;
7644 
7645                 case MSG_SET_DEVICE_STREAM_VOLUME:
7646                     onSetVolumeIndexOnDevice((DeviceVolumeUpdate) msg.obj);
7647                     break;
7648 
7649                 case MSG_OBSERVE_DEVICES_FOR_ALL_STREAMS:
7650                     onObserveDevicesForAllStreams(/*skipStream*/ msg.arg1);
7651                     break;
7652 
7653                 case MSG_HDMI_VOLUME_CHECK:
7654                     onCheckVolumeCecOnHdmiConnection(msg.arg1, (String) msg.obj);
7655                     break;
7656 
7657                 case MSG_PLAYBACK_CONFIG_CHANGE:
7658                     onPlaybackConfigChange((List<AudioPlaybackConfiguration>) msg.obj);
7659                     break;
7660                 case MSG_RECORDING_CONFIG_CHANGE:
7661                     onRecordingConfigChange((List<AudioRecordingConfiguration>) msg.obj);
7662                     break;
7663 
7664                 case MSG_BROADCAST_MICROPHONE_MUTE:
7665                     mSystemServer.sendMicrophoneMuteChangedIntent();
7666                     break;
7667 
7668                 case MSG_CHECK_MODE_FOR_UID:
7669                     synchronized (mDeviceBroker.mSetModeLock) {
7670                         if (msg.obj == null) {
7671                             break;
7672                         }
7673                         // Update active playback/recording for apps requesting IN_COMMUNICATION
7674                         // mode after a grace period following the mode change
7675                         SetModeDeathHandler h = (SetModeDeathHandler) msg.obj;
7676                         if (mSetModeDeathHandlers.indexOf(h) < 0) {
7677                             break;
7678                         }
7679                         boolean wasActive = h.isActive();
7680                         h.setPlaybackActive(mPlaybackMonitor.isPlaybackActiveForUid(h.getUid()));
7681                         h.setRecordingActive(mRecordMonitor.isRecordingActiveForUid(h.getUid()));
7682                         if (wasActive != h.isActive()) {
7683                             onUpdateAudioMode(AudioSystem.MODE_CURRENT, android.os.Process.myPid(),
7684                                     mContext.getPackageName(), false /*force*/);
7685                         }
7686                     }
7687                     break;
7688 
7689                 case MSG_STREAM_DEVICES_CHANGED:
7690                     sendBroadcastToAll(((Intent) msg.obj)
7691                             .putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_DEVICES, msg.arg1)
7692                             .putExtra(AudioManager.EXTRA_VOLUME_STREAM_DEVICES, msg.arg2));
7693                     break;
7694 
7695                 case MSG_UPDATE_VOLUME_STATES_FOR_DEVICE:
7696                     onUpdateVolumeStatesForAudioDevice(msg.arg1, (String) msg.obj);
7697                     break;
7698 
7699                 case MSG_REINIT_VOLUMES:
7700                     onReinitVolumes((String) msg.obj);
7701                     break;
7702 
7703                 case MSG_UPDATE_A11Y_SERVICE_UIDS:
7704                     onUpdateAccessibilityServiceUids();
7705                     break;
7706 
7707                 case MSG_UPDATE_AUDIO_MODE:
7708                     synchronized (mDeviceBroker.mSetModeLock) {
7709                         onUpdateAudioMode(msg.arg1, msg.arg2, (String) msg.obj, false /*force*/);
7710                     }
7711                     break;
7712 
7713                 case MSG_SET_A2DP_DEV_CONNECTION_STATE:
7714                     mDeviceBroker.queueBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
7715                             (AudioDeviceBroker.BtDeviceConnectionInfo) msg.obj);
7716                     break;
7717 
7718                 case MSG_A2DP_DEV_CONFIG_CHANGE:
7719                     mDeviceBroker.postBluetoothA2dpDeviceConfigChange((BluetoothDevice) msg.obj);
7720                     break;
7721 
7722                 case MSG_DISPATCH_AUDIO_MODE:
7723                     dispatchMode(msg.arg1);
7724                     break;
7725 
7726                 case MSG_ROUTING_UPDATED:
7727                     mSpatializerHelper.onRoutingUpdated();
7728                     break;
7729 
7730                 case MSG_PERSIST_SPATIAL_AUDIO_ENABLED:
7731                     onPersistSpatialAudioEnabled(msg.arg1 == 1);
7732                     break;
7733             }
7734         }
7735     }
7736 
7737     private class SettingsObserver extends ContentObserver {
7738 
SettingsObserver()7739         SettingsObserver() {
7740             super(new Handler());
7741             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
7742                     Settings.Global.ZEN_MODE), false, this);
7743             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
7744                     Settings.Global.ZEN_MODE_CONFIG_ETAG), false, this);
7745             mContentResolver.registerContentObserver(Settings.System.getUriFor(
7746                 Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this);
7747             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
7748                 Settings.Global.DOCK_AUDIO_MEDIA_ENABLED), false, this);
7749             mContentResolver.registerContentObserver(Settings.System.getUriFor(
7750                     Settings.System.MASTER_MONO), false, this);
7751             mContentResolver.registerContentObserver(Settings.System.getUriFor(
7752                     Settings.System.MASTER_BALANCE), false, this);
7753 
7754             mEncodedSurroundMode = Settings.Global.getInt(
7755                     mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT,
7756                     Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
7757             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
7758                     Settings.Global.ENCODED_SURROUND_OUTPUT), false, this);
7759             mEnabledSurroundFormats = Settings.Global.getString(
7760                     mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS);
7761             mContentResolver.registerContentObserver(Settings.Global.getUriFor(
7762                     Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS), false, this);
7763 
7764             mContentResolver.registerContentObserver(Settings.Secure.getUriFor(
7765                     Settings.Secure.VOICE_INTERACTION_SERVICE), false, this);
7766         }
7767 
7768         @Override
onChange(boolean selfChange)7769         public void onChange(boolean selfChange) {
7770             super.onChange(selfChange);
7771             // FIXME This synchronized is not necessary if mSettingsLock only protects mRingerMode.
7772             //       However there appear to be some missing locks around mRingerAndZenModeMutedStreams
7773             //       and mRingerModeAffectedStreams, so will leave this synchronized for now.
7774             //       mRingerAndZenModeMutedStreams and mMuteAffectedStreams are safe (only accessed once).
7775             synchronized (mSettingsLock) {
7776                 if (updateRingerAndZenModeAffectedStreams()) {
7777                     /*
7778                      * Ensure all stream types that should be affected by ringer mode
7779                      * are in the proper state.
7780                      */
7781                     setRingerModeInt(getRingerModeInternal(), false);
7782                 }
7783                 readDockAudioSettings(mContentResolver);
7784                 updateMasterMono(mContentResolver);
7785                 updateMasterBalance(mContentResolver);
7786                 updateEncodedSurroundOutput();
7787                 sendEnabledSurroundFormats(mContentResolver, mSurroundModeChanged);
7788                 updateAssistantUId(false);
7789             }
7790         }
7791 
updateEncodedSurroundOutput()7792         private void updateEncodedSurroundOutput() {
7793             int newSurroundMode = Settings.Global.getInt(
7794                 mContentResolver, Settings.Global.ENCODED_SURROUND_OUTPUT,
7795                 Settings.Global.ENCODED_SURROUND_OUTPUT_AUTO);
7796             // Did it change?
7797             if (mEncodedSurroundMode != newSurroundMode) {
7798                 // Send to AudioPolicyManager
7799                 sendEncodedSurroundMode(newSurroundMode, "SettingsObserver");
7800                 mDeviceBroker.toggleHdmiIfConnected_Async();
7801                 mEncodedSurroundMode = newSurroundMode;
7802                 mSurroundModeChanged = true;
7803             } else {
7804                 mSurroundModeChanged = false;
7805             }
7806         }
7807     }
7808 
avrcpSupportsAbsoluteVolume(String address, boolean support)7809     public void avrcpSupportsAbsoluteVolume(String address, boolean support) {
7810         // address is not used for now, but may be used when multiple a2dp devices are supported
7811         sVolumeLogger.log(new AudioEventLogger.StringEvent("avrcpSupportsAbsoluteVolume addr="
7812                 + address + " support=" + support));
7813         mDeviceBroker.setAvrcpAbsoluteVolumeSupported(support);
7814         setAvrcpAbsoluteVolumeSupported(support);
7815     }
7816 
setAvrcpAbsoluteVolumeSupported(boolean support)7817     /*package*/ void setAvrcpAbsoluteVolumeSupported(boolean support) {
7818         mAvrcpAbsVolSupported = support;
7819         sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE,
7820                     AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0,
7821                     mStreamStates[AudioSystem.STREAM_MUSIC], 0);
7822     }
7823 
7824     /**
7825      * @return true if there is currently a registered dynamic mixing policy that affects media
7826      * and is not a render + loopback policy
7827      */
7828     // only public for mocking/spying
7829     @VisibleForTesting
hasMediaDynamicPolicy()7830     public boolean hasMediaDynamicPolicy() {
7831         synchronized (mAudioPolicies) {
7832             if (mAudioPolicies.isEmpty()) {
7833                 return false;
7834             }
7835             final Collection<AudioPolicyProxy> appColl = mAudioPolicies.values();
7836             for (AudioPolicyProxy app : appColl) {
7837                 if (app.hasMixAffectingUsage(AudioAttributes.USAGE_MEDIA,
7838                         AudioMix.ROUTE_FLAG_LOOP_BACK_RENDER)) {
7839                     return true;
7840                 }
7841             }
7842             return false;
7843         }
7844     }
7845 
7846     /** only public for mocking/spying, do not call outside of AudioService */
7847     @VisibleForTesting
checkMusicActive(int deviceType, String caller)7848     public void checkMusicActive(int deviceType, String caller) {
7849         if (mSafeMediaVolumeDevices.contains(deviceType)) {
7850             sendMsg(mAudioHandler,
7851                     MSG_CHECK_MUSIC_ACTIVE,
7852                     SENDMSG_REPLACE,
7853                     0,
7854                     0,
7855                     caller,
7856                     MUSIC_ACTIVE_POLL_PERIOD_MS);
7857         }
7858     }
7859 
7860     /**
7861      * Receiver for misc intent broadcasts the Phone app cares about.
7862      */
7863     private class AudioServiceBroadcastReceiver extends BroadcastReceiver {
7864         @Override
onReceive(Context context, Intent intent)7865         public void onReceive(Context context, Intent intent) {
7866             final String action = intent.getAction();
7867             int outDevice;
7868             int inDevice;
7869             int state;
7870 
7871             if (action.equals(Intent.ACTION_DOCK_EVENT)) {
7872                 int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
7873                         Intent.EXTRA_DOCK_STATE_UNDOCKED);
7874                 int config;
7875                 switch (dockState) {
7876                     case Intent.EXTRA_DOCK_STATE_DESK:
7877                         config = AudioSystem.FORCE_BT_DESK_DOCK;
7878                         break;
7879                     case Intent.EXTRA_DOCK_STATE_CAR:
7880                         config = AudioSystem.FORCE_BT_CAR_DOCK;
7881                         break;
7882                     case Intent.EXTRA_DOCK_STATE_LE_DESK:
7883                         config = AudioSystem.FORCE_ANALOG_DOCK;
7884                         break;
7885                     case Intent.EXTRA_DOCK_STATE_HE_DESK:
7886                         config = AudioSystem.FORCE_DIGITAL_DOCK;
7887                         break;
7888                     case Intent.EXTRA_DOCK_STATE_UNDOCKED:
7889                     default:
7890                         config = AudioSystem.FORCE_NONE;
7891                 }
7892                 // Low end docks have a menu to enable or disable audio
7893                 // (see mDockAudioMediaEnabled)
7894                 if (!((dockState == Intent.EXTRA_DOCK_STATE_LE_DESK)
7895                         || ((dockState == Intent.EXTRA_DOCK_STATE_UNDOCKED)
7896                                 && (mDockState == Intent.EXTRA_DOCK_STATE_LE_DESK)))) {
7897                     mDeviceBroker.setForceUse_Async(AudioSystem.FOR_DOCK, config,
7898                             "ACTION_DOCK_EVENT intent");
7899                 }
7900                 mDockState = dockState;
7901             } else if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED)
7902                     || action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
7903                 mDeviceBroker.receiveBtEvent(intent);
7904             } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
7905                 if (mMonitorRotation) {
7906                     RotationHelper.enable();
7907                 }
7908                 AudioSystem.setParameters("screen_state=on");
7909             } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
7910                 if (mMonitorRotation) {
7911                     //reduce wakeups (save current) by only listening when display is on
7912                     RotationHelper.disable();
7913                 }
7914                 AudioSystem.setParameters("screen_state=off");
7915             } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
7916                 handleConfigurationChanged(context);
7917             } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
7918                 if (mUserSwitchedReceived) {
7919                     // attempt to stop music playback for background user except on first user
7920                     // switch (i.e. first boot)
7921                     mDeviceBroker.postBroadcastBecomingNoisy();
7922                 }
7923                 mUserSwitchedReceived = true;
7924                 // the current audio focus owner is no longer valid
7925                 mMediaFocusControl.discardAudioFocusOwner();
7926 
7927                 if (mSupportsMicPrivacyToggle) {
7928                     mMicMuteFromPrivacyToggle = mSensorPrivacyManagerInternal
7929                             .isSensorPrivacyEnabled(getCurrentUserId(),
7930                                     SensorPrivacyManager.Sensors.MICROPHONE);
7931                     setMicrophoneMuteNoCallerCheck(getCurrentUserId());
7932                 }
7933 
7934                 // load volume settings for new user
7935                 readAudioSettings(true /*userSwitch*/);
7936                 // preserve STREAM_MUSIC volume from one user to the next.
7937                 sendMsg(mAudioHandler,
7938                         MSG_SET_ALL_VOLUMES,
7939                         SENDMSG_QUEUE,
7940                         0,
7941                         0,
7942                         mStreamStates[AudioSystem.STREAM_MUSIC], 0);
7943             } else if (action.equals(Intent.ACTION_USER_BACKGROUND)) {
7944                 // Disable audio recording for the background user/profile
7945                 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
7946                 if (userId >= 0) {
7947                     // TODO Kill recording streams instead of killing processes holding permission
7948                     UserInfo userInfo = UserManagerService.getInstance().getUserInfo(userId);
7949                     killBackgroundUserProcessesWithRecordAudioPermission(userInfo);
7950                 }
7951                 UserManagerService.getInstance().setUserRestriction(
7952                         UserManager.DISALLOW_RECORD_AUDIO, true, userId);
7953             } else if (action.equals(Intent.ACTION_USER_FOREGROUND)) {
7954                 // Enable audio recording for foreground user/profile
7955                 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
7956                 UserManagerService.getInstance().setUserRestriction(
7957                         UserManager.DISALLOW_RECORD_AUDIO, false, userId);
7958             } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
7959                 state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
7960                 if (state == BluetoothAdapter.STATE_OFF ||
7961                         state == BluetoothAdapter.STATE_TURNING_OFF) {
7962                     mDeviceBroker.disconnectAllBluetoothProfiles();
7963                 }
7964             } else if (action.equals(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION) ||
7965                     action.equals(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION)) {
7966                 handleAudioEffectBroadcast(context, intent);
7967             } else if (action.equals(Intent.ACTION_PACKAGES_SUSPENDED)) {
7968                 final int[] suspendedUids = intent.getIntArrayExtra(Intent.EXTRA_CHANGED_UID_LIST);
7969                 final String[] suspendedPackages =
7970                         intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
7971                 if (suspendedPackages == null || suspendedUids == null
7972                         || suspendedPackages.length != suspendedUids.length) {
7973                     return;
7974                 }
7975                 for (int i = 0; i < suspendedUids.length; i++) {
7976                     if (!TextUtils.isEmpty(suspendedPackages[i])) {
7977                         mMediaFocusControl.noFocusForSuspendedApp(
7978                                 suspendedPackages[i], suspendedUids[i]);
7979                     }
7980                 }
7981             }
7982         }
7983     } // end class AudioServiceBroadcastReceiver
7984 
7985     private class AudioServiceUserRestrictionsListener implements UserRestrictionsListener {
7986 
7987         @Override
onUserRestrictionsChanged(int userId, Bundle newRestrictions, Bundle prevRestrictions)7988         public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
7989                 Bundle prevRestrictions) {
7990             // Update mic mute state.
7991             {
7992                 final boolean wasRestricted =
7993                         prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE);
7994                 final boolean isRestricted =
7995                         newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_MICROPHONE);
7996                 if (wasRestricted != isRestricted) {
7997                     mMicMuteFromRestrictions = isRestricted;
7998                     setMicrophoneMuteNoCallerCheck(userId);
7999                 }
8000             }
8001 
8002             // Update speaker mute state.
8003             {
8004                 final boolean wasRestricted =
8005                         prevRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME)
8006                                 || prevRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE);
8007                 final boolean isRestricted =
8008                         newRestrictions.getBoolean(UserManager.DISALLOW_ADJUST_VOLUME)
8009                                 || newRestrictions.getBoolean(UserManager.DISALLOW_UNMUTE_DEVICE);
8010                 if (wasRestricted != isRestricted) {
8011                     setMasterMuteInternalNoCallerCheck(isRestricted, /* flags =*/ 0, userId);
8012                 }
8013             }
8014         }
8015     } // end class AudioServiceUserRestrictionsListener
8016 
handleAudioEffectBroadcast(Context context, Intent intent)8017     private void handleAudioEffectBroadcast(Context context, Intent intent) {
8018         String target = intent.getPackage();
8019         if (target != null) {
8020             Log.w(TAG, "effect broadcast already targeted to " + target);
8021             return;
8022         }
8023         intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
8024         // TODO this should target a user-selected panel
8025         List<ResolveInfo> ril = context.getPackageManager().queryBroadcastReceivers(
8026                 intent, 0 /* flags */);
8027         if (ril != null && ril.size() != 0) {
8028             ResolveInfo ri = ril.get(0);
8029             if (ri != null && ri.activityInfo != null && ri.activityInfo.packageName != null) {
8030                 intent.setPackage(ri.activityInfo.packageName);
8031                 context.sendBroadcastAsUser(intent, UserHandle.ALL);
8032                 return;
8033             }
8034         }
8035         Log.w(TAG, "couldn't find receiver package for effect intent");
8036     }
8037 
killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser)8038     private void killBackgroundUserProcessesWithRecordAudioPermission(UserInfo oldUser) {
8039         PackageManager pm = mContext.getPackageManager();
8040         // Find the home activity of the user. It should not be killed to avoid expensive restart,
8041         // when the user switches back. For managed profiles, we should kill all recording apps
8042         ComponentName homeActivityName = null;
8043         if (!oldUser.isManagedProfile()) {
8044             homeActivityName = LocalServices.getService(
8045                     ActivityTaskManagerInternal.class).getHomeActivityForUser(oldUser.id);
8046         }
8047         final String[] permissions = { Manifest.permission.RECORD_AUDIO };
8048         List<PackageInfo> packages;
8049         try {
8050             packages = AppGlobals.getPackageManager()
8051                     .getPackagesHoldingPermissions(permissions, 0, oldUser.id).getList();
8052         } catch (RemoteException e) {
8053             throw new AndroidRuntimeException(e);
8054         }
8055         for (int j = packages.size() - 1; j >= 0; j--) {
8056             PackageInfo pkg = packages.get(j);
8057             // Skip system processes
8058             if (UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID) {
8059                 continue;
8060             }
8061             // Skip packages that have permission to interact across users
8062             if (pm.checkPermission(Manifest.permission.INTERACT_ACROSS_USERS, pkg.packageName)
8063                     == PackageManager.PERMISSION_GRANTED) {
8064                 continue;
8065             }
8066             if (homeActivityName != null
8067                     && pkg.packageName.equals(homeActivityName.getPackageName())
8068                     && pkg.applicationInfo.isSystemApp()) {
8069                 continue;
8070             }
8071             try {
8072                 final int uid = pkg.applicationInfo.uid;
8073                 ActivityManager.getService().killUid(UserHandle.getAppId(uid),
8074                         UserHandle.getUserId(uid),
8075                         "killBackgroundUserProcessesWithAudioRecordPermission");
8076             } catch (RemoteException e) {
8077                 Log.w(TAG, "Error calling killUid", e);
8078             }
8079         }
8080     }
8081 
8082 
8083     //==========================================================================================
8084     // Audio Focus
8085     //==========================================================================================
8086     /**
8087      * Returns whether a focus request is eligible to force ducking.
8088      * Will return true if:
8089      * - the AudioAttributes have a usage of USAGE_ASSISTANCE_ACCESSIBILITY,
8090      * - the focus request is AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK,
8091      * - the associated Bundle has KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING set to true,
8092      * - the uid of the requester is a known accessibility service or root.
8093      * @param aa AudioAttributes of the focus request
8094      * @param uid uid of the focus requester
8095      * @return true if ducking is to be forced
8096      */
forceFocusDuckingForAccessibility(@ullable AudioAttributes aa, int request, int uid)8097     private boolean forceFocusDuckingForAccessibility(@Nullable AudioAttributes aa,
8098             int request, int uid) {
8099         if (aa == null || aa.getUsage() != AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY
8100                 || request != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) {
8101             return false;
8102         }
8103         final Bundle extraInfo = aa.getBundle();
8104         if (extraInfo == null ||
8105                 !extraInfo.getBoolean(AudioFocusRequest.KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING)) {
8106             return false;
8107         }
8108         if (uid == 0) {
8109             return true;
8110         }
8111         synchronized (mAccessibilityServiceUidsLock) {
8112             if (mAccessibilityServiceUids != null) {
8113                 int callingUid = Binder.getCallingUid();
8114                 for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
8115                     if (mAccessibilityServiceUids[i] == callingUid) {
8116                         return true;
8117                     }
8118                 }
8119             }
8120         }
8121         return false;
8122     }
8123 
isSupportedSystemUsage(@udioAttributes.AttributeUsage int usage)8124     private boolean isSupportedSystemUsage(@AudioAttributes.AttributeUsage int usage) {
8125         synchronized (mSupportedSystemUsagesLock) {
8126             for (int i = 0; i < mSupportedSystemUsages.length; i++) {
8127                 if (mSupportedSystemUsages[i] == usage) {
8128                     return true;
8129                 }
8130             }
8131             return false;
8132         }
8133     }
8134 
validateAudioAttributesUsage(@onNull AudioAttributes audioAttributes)8135     private void validateAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) {
8136         @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage();
8137         if (AudioAttributes.isSystemUsage(usage)) {
8138             if (callerHasPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)) {
8139                 if (!isSupportedSystemUsage(usage)) {
8140                     throw new IllegalArgumentException(
8141                             "Unsupported usage " + AudioAttributes.usageToString(usage));
8142                 }
8143             } else {
8144                 throw new SecurityException("Missing MODIFY_AUDIO_ROUTING permission");
8145             }
8146         }
8147     }
8148 
isValidAudioAttributesUsage(@onNull AudioAttributes audioAttributes)8149     private boolean isValidAudioAttributesUsage(@NonNull AudioAttributes audioAttributes) {
8150         @AudioAttributes.AttributeUsage int usage = audioAttributes.getSystemUsage();
8151         if (AudioAttributes.isSystemUsage(usage)) {
8152             return callerHasPermission(Manifest.permission.MODIFY_AUDIO_ROUTING)
8153                     && isSupportedSystemUsage(usage);
8154         }
8155         return true;
8156     }
8157 
requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb, IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags, IAudioPolicyCallback pcb, int sdk)8158     public int requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb,
8159             IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags,
8160             IAudioPolicyCallback pcb, int sdk) {
8161         final int uid = Binder.getCallingUid();
8162         MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus")
8163                 .setUid(uid)
8164                 //.putInt("durationHint", durationHint)
8165                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName)
8166                 .set(MediaMetrics.Property.CLIENT_NAME, clientId)
8167                 .set(MediaMetrics.Property.EVENT, "requestAudioFocus")
8168                 .set(MediaMetrics.Property.FLAGS, flags);
8169 
8170         // permission checks
8171         if (aa != null && !isValidAudioAttributesUsage(aa)) {
8172             final String reason = "Request using unsupported usage";
8173             Log.w(TAG, reason);
8174             mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
8175                     .record();
8176             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
8177         }
8178         if ((flags & AudioManager.AUDIOFOCUS_FLAG_LOCK) == AudioManager.AUDIOFOCUS_FLAG_LOCK) {
8179             if (AudioSystem.IN_VOICE_COMM_FOCUS_ID.equals(clientId)) {
8180                 if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
8181                             android.Manifest.permission.MODIFY_PHONE_STATE)) {
8182                     final String reason = "Invalid permission to (un)lock audio focus";
8183                     Log.e(TAG, reason, new Exception());
8184                     mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
8185                             .record();
8186                     return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
8187                 }
8188             } else {
8189                 // only a registered audio policy can be used to lock focus
8190                 synchronized (mAudioPolicies) {
8191                     if (!mAudioPolicies.containsKey(pcb.asBinder())) {
8192                         final String reason =
8193                                 "Invalid unregistered AudioPolicy to (un)lock audio focus";
8194                         Log.e(TAG, reason);
8195                         mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
8196                                 .record();
8197                         return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
8198                     }
8199                 }
8200             }
8201         }
8202 
8203         if (callingPackageName == null || clientId == null || aa == null) {
8204             final String reason = "Invalid null parameter to request audio focus";
8205             Log.e(TAG, reason);
8206             mmi.set(MediaMetrics.Property.EARLY_RETURN, reason)
8207                     .record();
8208             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
8209         }
8210         mmi.record();
8211         return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd,
8212                 clientId, callingPackageName, flags, sdk,
8213                 forceFocusDuckingForAccessibility(aa, durationHint, uid), -1 /*testUid, ignored*/);
8214     }
8215 
8216     /** see {@link AudioManager#requestAudioFocusForTest(AudioFocusRequest, String, int, int)} */
requestAudioFocusForTest(AudioAttributes aa, int durationHint, IBinder cb, IAudioFocusDispatcher fd, String clientId, String callingPackageName, int fakeUid, int sdk)8217     public int requestAudioFocusForTest(AudioAttributes aa, int durationHint, IBinder cb,
8218             IAudioFocusDispatcher fd, String clientId, String callingPackageName,
8219             int fakeUid, int sdk) {
8220         if (!enforceQueryAudioStateForTest("focus request")) {
8221             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
8222         }
8223         if (callingPackageName == null || clientId == null || aa == null) {
8224             final String reason = "Invalid null parameter to request audio focus";
8225             Log.e(TAG, reason);
8226             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
8227         }
8228         return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd,
8229                 clientId, callingPackageName, AudioManager.AUDIOFOCUS_FLAG_TEST,
8230                 sdk, false /*forceDuck*/, fakeUid);
8231     }
8232 
abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)8233     public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa,
8234             String callingPackageName) {
8235         MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "focus")
8236                 .set(MediaMetrics.Property.CALLING_PACKAGE, callingPackageName)
8237                 .set(MediaMetrics.Property.CLIENT_NAME, clientId)
8238                 .set(MediaMetrics.Property.EVENT, "abandonAudioFocus");
8239 
8240         if (aa != null && !isValidAudioAttributesUsage(aa)) {
8241             Log.w(TAG, "Request using unsupported usage.");
8242             mmi.set(MediaMetrics.Property.EARLY_RETURN, "unsupported usage").record();
8243 
8244             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
8245         }
8246         mmi.record();
8247         return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName);
8248     }
8249 
8250     /** see {@link AudioManager#abandonAudioFocusForTest(AudioFocusRequest, String)} */
abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId, AudioAttributes aa, String callingPackageName)8251     public int abandonAudioFocusForTest(IAudioFocusDispatcher fd, String clientId,
8252             AudioAttributes aa, String callingPackageName) {
8253         if (!enforceQueryAudioStateForTest("focus abandon")) {
8254             return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
8255         }
8256         return mMediaFocusControl.abandonAudioFocus(fd, clientId, aa, callingPackageName);
8257     }
8258 
unregisterAudioFocusClient(String clientId)8259     public void unregisterAudioFocusClient(String clientId) {
8260         new MediaMetrics.Item(mMetricsId + "focus")
8261                 .set(MediaMetrics.Property.CLIENT_NAME, clientId)
8262                 .set(MediaMetrics.Property.EVENT, "unregisterAudioFocusClient")
8263                 .record();
8264         mMediaFocusControl.unregisterAudioFocusClient(clientId);
8265     }
8266 
getCurrentAudioFocus()8267     public int getCurrentAudioFocus() {
8268         return mMediaFocusControl.getCurrentAudioFocus();
8269     }
8270 
getFocusRampTimeMs(int focusGain, AudioAttributes attr)8271     public int getFocusRampTimeMs(int focusGain, AudioAttributes attr) {
8272         return mMediaFocusControl.getFocusRampTimeMs(focusGain, attr);
8273     }
8274 
8275     /** only public for mocking/spying, do not call outside of AudioService */
8276     @VisibleForTesting
hasAudioFocusUsers()8277     public boolean hasAudioFocusUsers() {
8278         return mMediaFocusControl.hasAudioFocusUsers();
8279     }
8280 
8281     /** see {@link AudioManager#getFadeOutDurationOnFocusLossMillis(AudioAttributes)} */
getFadeOutDurationOnFocusLossMillis(AudioAttributes aa)8282     public long getFadeOutDurationOnFocusLossMillis(AudioAttributes aa) {
8283         if (!enforceQueryAudioStateForTest("fade out duration")) {
8284             return 0;
8285         }
8286         return mMediaFocusControl.getFadeOutDurationOnFocusLossMillis(aa);
8287     }
8288 
enforceQueryAudioStateForTest(String mssg)8289     private boolean enforceQueryAudioStateForTest(String mssg) {
8290         if (PackageManager.PERMISSION_GRANTED != mContext.checkCallingOrSelfPermission(
8291                 Manifest.permission.QUERY_AUDIO_STATE)) {
8292             final String reason = "Doesn't have QUERY_AUDIO_STATE permission for "
8293                     + mssg + " test API";
8294             Log.e(TAG, reason, new Exception());
8295             return false;
8296         }
8297         return true;
8298     }
8299 
8300     //==========================================================================================
8301     private final @NonNull SpatializerHelper mSpatializerHelper;
8302     /**
8303      * Initialized from property ro.audio.spatializer_enabled
8304      * Should only be 1 when the device ships with a Spatializer effect
8305      */
8306     private final boolean mHasSpatializerEffect;
8307     /**
8308      * Default value for the spatial audio feature
8309      */
8310     private static final boolean SPATIAL_AUDIO_ENABLED_DEFAULT = true;
8311 
8312     /**
8313      * persist in user settings whether the feature is enabled.
8314      * Can change when {@link Spatializer#setEnabled(boolean)} is called and successfully
8315      * changes the state of the feature
8316      * @param featureEnabled
8317      */
persistSpatialAudioEnabled(boolean featureEnabled)8318     void persistSpatialAudioEnabled(boolean featureEnabled) {
8319         sendMsg(mAudioHandler,
8320                 MSG_PERSIST_SPATIAL_AUDIO_ENABLED,
8321                 SENDMSG_REPLACE, featureEnabled ? 1 : 0, 0, null,
8322                 /*delay ms*/ 100);
8323     }
8324 
onPersistSpatialAudioEnabled(boolean enabled)8325     void onPersistSpatialAudioEnabled(boolean enabled) {
8326         Settings.Secure.putIntForUser(mContentResolver,
8327                 Settings.Secure.SPATIAL_AUDIO_ENABLED, enabled ? 1 : 0,
8328                 UserHandle.USER_CURRENT);
8329     }
8330 
isSpatialAudioEnabled()8331     boolean isSpatialAudioEnabled() {
8332         return Settings.Secure.getIntForUser(mContentResolver,
8333                 Settings.Secure.SPATIAL_AUDIO_ENABLED, SPATIAL_AUDIO_ENABLED_DEFAULT ? 1 : 0,
8334                 UserHandle.USER_CURRENT) == 1;
8335     }
8336 
enforceModifyDefaultAudioEffectsPermission()8337     private void enforceModifyDefaultAudioEffectsPermission() {
8338         if (mContext.checkCallingOrSelfPermission(
8339                 android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
8340                 != PackageManager.PERMISSION_GRANTED) {
8341             throw new SecurityException("Missing MODIFY_DEFAULT_AUDIO_EFFECTS permission");
8342         }
8343     }
8344 
8345     /**
8346      * Returns the immersive audio level that the platform is capable of
8347      * @see Spatializer#getImmersiveAudioLevel()
8348      */
getSpatializerImmersiveAudioLevel()8349     public int getSpatializerImmersiveAudioLevel() {
8350         return mSpatializerHelper.getCapableImmersiveAudioLevel();
8351     }
8352 
8353     /** @see Spatializer#isEnabled() */
isSpatializerEnabled()8354     public boolean isSpatializerEnabled() {
8355         return mSpatializerHelper.isEnabled();
8356     }
8357 
8358     /** @see Spatializer#isAvailable() */
isSpatializerAvailable()8359     public boolean isSpatializerAvailable() {
8360         return mSpatializerHelper.isAvailable();
8361     }
8362 
8363     /** @see Spatializer#setSpatializerEnabled(boolean) */
setSpatializerEnabled(boolean enabled)8364     public void setSpatializerEnabled(boolean enabled) {
8365         enforceModifyDefaultAudioEffectsPermission();
8366         mSpatializerHelper.setFeatureEnabled(enabled);
8367     }
8368 
8369     /** @see Spatializer#canBeSpatialized() */
canBeSpatialized( @onNull AudioAttributes attributes, @NonNull AudioFormat format)8370     public boolean canBeSpatialized(
8371             @NonNull AudioAttributes attributes, @NonNull AudioFormat format) {
8372         Objects.requireNonNull(attributes);
8373         Objects.requireNonNull(format);
8374         return mSpatializerHelper.canBeSpatialized(attributes, format);
8375     }
8376 
8377     /** @see Spatializer.SpatializerInfoDispatcherStub */
registerSpatializerCallback( @onNull ISpatializerCallback cb)8378     public void registerSpatializerCallback(
8379             @NonNull ISpatializerCallback cb) {
8380         Objects.requireNonNull(cb);
8381         mSpatializerHelper.registerStateCallback(cb);
8382     }
8383 
8384     /** @see Spatializer.SpatializerInfoDispatcherStub */
unregisterSpatializerCallback( @onNull ISpatializerCallback cb)8385     public void unregisterSpatializerCallback(
8386             @NonNull ISpatializerCallback cb) {
8387         Objects.requireNonNull(cb);
8388         mSpatializerHelper.unregisterStateCallback(cb);
8389     }
8390 
8391     /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */
registerSpatializerHeadTrackingCallback( @onNull ISpatializerHeadTrackingModeCallback cb)8392     public void registerSpatializerHeadTrackingCallback(
8393             @NonNull ISpatializerHeadTrackingModeCallback cb) {
8394         enforceModifyDefaultAudioEffectsPermission();
8395         Objects.requireNonNull(cb);
8396         mSpatializerHelper.registerHeadTrackingModeCallback(cb);
8397     }
8398 
8399     /** @see Spatializer#SpatializerHeadTrackingDispatcherStub */
unregisterSpatializerHeadTrackingCallback( @onNull ISpatializerHeadTrackingModeCallback cb)8400     public void unregisterSpatializerHeadTrackingCallback(
8401             @NonNull ISpatializerHeadTrackingModeCallback cb) {
8402         enforceModifyDefaultAudioEffectsPermission();
8403         Objects.requireNonNull(cb);
8404         mSpatializerHelper.unregisterHeadTrackingModeCallback(cb);
8405     }
8406 
8407     /** @see Spatializer#setOnHeadToSoundstagePoseUpdatedListener */
registerHeadToSoundstagePoseCallback( @onNull ISpatializerHeadToSoundStagePoseCallback cb)8408     public void registerHeadToSoundstagePoseCallback(
8409             @NonNull ISpatializerHeadToSoundStagePoseCallback cb) {
8410         enforceModifyDefaultAudioEffectsPermission();
8411         Objects.requireNonNull(cb);
8412         mSpatializerHelper.registerHeadToSoundstagePoseCallback(cb);
8413     }
8414 
8415     /** @see Spatializer#clearOnHeadToSoundstagePoseUpdatedListener */
unregisterHeadToSoundstagePoseCallback( @onNull ISpatializerHeadToSoundStagePoseCallback cb)8416     public void unregisterHeadToSoundstagePoseCallback(
8417             @NonNull ISpatializerHeadToSoundStagePoseCallback cb) {
8418         enforceModifyDefaultAudioEffectsPermission();
8419         Objects.requireNonNull(cb);
8420         mSpatializerHelper.unregisterHeadToSoundstagePoseCallback(cb);
8421     }
8422 
8423     /** @see Spatializer#getSpatializerCompatibleAudioDevices() */
getSpatializerCompatibleAudioDevices()8424     public @NonNull List<AudioDeviceAttributes> getSpatializerCompatibleAudioDevices() {
8425         enforceModifyDefaultAudioEffectsPermission();
8426         return mSpatializerHelper.getCompatibleAudioDevices();
8427     }
8428 
8429     /** @see Spatializer#addSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */
addSpatializerCompatibleAudioDevice(@onNull AudioDeviceAttributes ada)8430     public void addSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
8431         enforceModifyDefaultAudioEffectsPermission();
8432         Objects.requireNonNull(ada);
8433         mSpatializerHelper.addCompatibleAudioDevice(ada);
8434     }
8435 
8436     /** @see Spatializer#removeSpatializerCompatibleAudioDevice(AudioDeviceAttributes) */
removeSpatializerCompatibleAudioDevice(@onNull AudioDeviceAttributes ada)8437     public void removeSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
8438         enforceModifyDefaultAudioEffectsPermission();
8439         Objects.requireNonNull(ada);
8440         mSpatializerHelper.removeCompatibleAudioDevice(ada);
8441     }
8442 
8443     /** @see Spatializer#getSupportedHeadTrackingModes() */
getSupportedHeadTrackingModes()8444     public int[] getSupportedHeadTrackingModes() {
8445         enforceModifyDefaultAudioEffectsPermission();
8446         return mSpatializerHelper.getSupportedHeadTrackingModes();
8447     }
8448 
8449     /** @see Spatializer#getHeadTrackingMode() */
getActualHeadTrackingMode()8450     public int getActualHeadTrackingMode() {
8451         enforceModifyDefaultAudioEffectsPermission();
8452         return mSpatializerHelper.getActualHeadTrackingMode();
8453     }
8454 
8455     /** @see Spatializer#getDesiredHeadTrackingMode() */
getDesiredHeadTrackingMode()8456     public int getDesiredHeadTrackingMode() {
8457         enforceModifyDefaultAudioEffectsPermission();
8458         return mSpatializerHelper.getDesiredHeadTrackingMode();
8459     }
8460 
8461     /** @see Spatializer#setGlobalTransform */
setSpatializerGlobalTransform(@onNull float[] transform)8462     public void setSpatializerGlobalTransform(@NonNull float[] transform) {
8463         enforceModifyDefaultAudioEffectsPermission();
8464         Objects.requireNonNull(transform);
8465         mSpatializerHelper.setGlobalTransform(transform);
8466     }
8467 
8468     /** @see Spatializer#recenterHeadTracker() */
recenterHeadTracker()8469     public void recenterHeadTracker() {
8470         enforceModifyDefaultAudioEffectsPermission();
8471         mSpatializerHelper.recenterHeadTracker();
8472     }
8473 
8474     /** @see Spatializer#setDesiredHeadTrackingMode */
setDesiredHeadTrackingMode(@patializer.HeadTrackingModeSet int mode)8475     public void setDesiredHeadTrackingMode(@Spatializer.HeadTrackingModeSet int mode) {
8476         enforceModifyDefaultAudioEffectsPermission();
8477         switch(mode) {
8478             case Spatializer.HEAD_TRACKING_MODE_DISABLED:
8479             case Spatializer.HEAD_TRACKING_MODE_RELATIVE_WORLD:
8480             case Spatializer.HEAD_TRACKING_MODE_RELATIVE_DEVICE:
8481                 break;
8482             default:
8483                 return;
8484         }
8485         mSpatializerHelper.setDesiredHeadTrackingMode(mode);
8486     }
8487 
8488     /** @see Spatializer#setEffectParameter */
setSpatializerParameter(int key, @NonNull byte[] value)8489     public void setSpatializerParameter(int key, @NonNull byte[] value) {
8490         enforceModifyDefaultAudioEffectsPermission();
8491         Objects.requireNonNull(value);
8492         mSpatializerHelper.setEffectParameter(key, value);
8493     }
8494 
8495     /** @see Spatializer#getEffectParameter */
getSpatializerParameter(int key, @NonNull byte[] value)8496     public void getSpatializerParameter(int key, @NonNull byte[] value) {
8497         enforceModifyDefaultAudioEffectsPermission();
8498         Objects.requireNonNull(value);
8499         mSpatializerHelper.getEffectParameter(key, value);
8500     }
8501 
8502     /** @see Spatializer#getOutput */
getSpatializerOutput()8503     public int getSpatializerOutput() {
8504         enforceModifyDefaultAudioEffectsPermission();
8505         return mSpatializerHelper.getOutput();
8506     }
8507 
8508     /** @see Spatializer#setOnSpatializerOutputChangedListener */
registerSpatializerOutputCallback(ISpatializerOutputCallback cb)8509     public void registerSpatializerOutputCallback(ISpatializerOutputCallback cb) {
8510         enforceModifyDefaultAudioEffectsPermission();
8511         Objects.requireNonNull(cb);
8512         mSpatializerHelper.registerSpatializerOutputCallback(cb);
8513     }
8514 
8515     /** @see Spatializer#clearOnSpatializerOutputChangedListener */
unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb)8516     public void unregisterSpatializerOutputCallback(ISpatializerOutputCallback cb) {
8517         enforceModifyDefaultAudioEffectsPermission();
8518         Objects.requireNonNull(cb);
8519         mSpatializerHelper.unregisterSpatializerOutputCallback(cb);
8520     }
8521 
8522     /**
8523      * post a message to schedule init/release of head tracking sensors
8524      * whether to initialize or release sensors is based on the state of spatializer
8525      */
postInitSpatializerHeadTrackingSensors()8526     void postInitSpatializerHeadTrackingSensors() {
8527         sendMsg(mAudioHandler,
8528                 MSG_INIT_HEADTRACKING_SENSORS,
8529                 SENDMSG_REPLACE,
8530                 /*arg1*/ 0, /*arg2*/ 0, TAG, /*delay*/ 0);
8531     }
8532 
8533     //==========================================================================================
readCameraSoundForced()8534     private boolean readCameraSoundForced() {
8535         return SystemProperties.getBoolean("audio.camerasound.force", false) ||
8536                 mContext.getResources().getBoolean(
8537                         com.android.internal.R.bool.config_camera_sound_forced);
8538     }
8539 
8540     //==========================================================================================
8541     // Device orientation
8542     //==========================================================================================
8543     /**
8544      * Handles device configuration changes that may map to a change in rotation.
8545      * Monitoring rotation is optional, and is defined by the definition and value
8546      * of the "ro.audio.monitorRotation" system property.
8547      */
handleConfigurationChanged(Context context)8548     private void handleConfigurationChanged(Context context) {
8549         try {
8550             // reading new configuration "safely" (i.e. under try catch) in case anything
8551             // goes wrong.
8552             Configuration config = context.getResources().getConfiguration();
8553             sendMsg(mAudioHandler,
8554                     MSG_CONFIGURE_SAFE_MEDIA_VOLUME,
8555                     SENDMSG_REPLACE,
8556                     0,
8557                     0,
8558                     TAG,
8559                     0);
8560 
8561             boolean cameraSoundForced = readCameraSoundForced();
8562             synchronized (mSettingsLock) {
8563                 final boolean cameraSoundForcedChanged = (cameraSoundForced != mCameraSoundForced);
8564                 mCameraSoundForced = cameraSoundForced;
8565                 if (cameraSoundForcedChanged) {
8566                     if (!mIsSingleVolume) {
8567                         synchronized (VolumeStreamState.class) {
8568                             VolumeStreamState s = mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED];
8569                             if (cameraSoundForced) {
8570                                 s.setAllIndexesToMax();
8571                                 mRingerModeAffectedStreams &=
8572                                         ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
8573                             } else {
8574                                 s.setAllIndexes(mStreamStates[AudioSystem.STREAM_SYSTEM], TAG);
8575                                 mRingerModeAffectedStreams |=
8576                                         (1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
8577                             }
8578                         }
8579                         // take new state into account for streams muted by ringer mode
8580                         setRingerModeInt(getRingerModeInternal(), false);
8581                     }
8582                     mDeviceBroker.setForceUse_Async(AudioSystem.FOR_SYSTEM,
8583                             cameraSoundForced ?
8584                                     AudioSystem.FORCE_SYSTEM_ENFORCED : AudioSystem.FORCE_NONE,
8585                             "handleConfigurationChanged");
8586                     sendMsg(mAudioHandler,
8587                             MSG_SET_ALL_VOLUMES,
8588                             SENDMSG_QUEUE,
8589                             0,
8590                             0,
8591                             mStreamStates[AudioSystem.STREAM_SYSTEM_ENFORCED], 0);
8592 
8593                 }
8594             }
8595             mVolumeController.setLayoutDirection(config.getLayoutDirection());
8596         } catch (Exception e) {
8597             Log.e(TAG, "Error handling configuration change: ", e);
8598         }
8599     }
8600 
8601     @Override
setRingtonePlayer(IRingtonePlayer player)8602     public void setRingtonePlayer(IRingtonePlayer player) {
8603         mContext.enforceCallingOrSelfPermission(REMOTE_AUDIO_PLAYBACK, null);
8604         mRingtonePlayer = player;
8605     }
8606 
8607     @Override
getRingtonePlayer()8608     public IRingtonePlayer getRingtonePlayer() {
8609         return mRingtonePlayer;
8610     }
8611 
8612     @Override
startWatchingRoutes(IAudioRoutesObserver observer)8613     public AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) {
8614         return mDeviceBroker.startWatchingRoutes(observer);
8615     }
8616 
8617 
8618     //==========================================================================================
8619     // Safe media volume management.
8620     // MUSIC stream volume level is limited when headphones are connected according to safety
8621     // regulation. When the user attempts to raise the volume above the limit, a warning is
8622     // displayed and the user has to acknowlegde before the volume is actually changed.
8623     // The volume index corresponding to the limit is stored in config_safe_media_volume_index
8624     // property. Platforms with a different limit must set this property accordingly in their
8625     // overlay.
8626     //==========================================================================================
8627 
8628     // mSafeMediaVolumeState indicates whether the media volume is limited over headphones.
8629     // It is SAFE_MEDIA_VOLUME_NOT_CONFIGURED at boot time until a network service is connected
8630     // or the configure time is elapsed. It is then set to SAFE_MEDIA_VOLUME_ACTIVE or
8631     // SAFE_MEDIA_VOLUME_DISABLED according to country option. If not SAFE_MEDIA_VOLUME_DISABLED, it
8632     // can be set to SAFE_MEDIA_VOLUME_INACTIVE by calling AudioService.disableSafeMediaVolume()
8633     // (when user opts out).
8634     private static final int SAFE_MEDIA_VOLUME_NOT_CONFIGURED = 0;
8635     private static final int SAFE_MEDIA_VOLUME_DISABLED = 1;
8636     private static final int SAFE_MEDIA_VOLUME_INACTIVE = 2;  // confirmed
8637     private static final int SAFE_MEDIA_VOLUME_ACTIVE = 3;  // unconfirmed
8638     private int mSafeMediaVolumeState;
8639     private final Object mSafeMediaVolumeStateLock = new Object();
8640 
8641     private int mMcc = 0;
8642     // mSafeMediaVolumeIndex is the cached value of config_safe_media_volume_index property
8643     private int mSafeMediaVolumeIndex;
8644     // mSafeUsbMediaVolumeDbfs is the cached value of the config_safe_media_volume_usb_mB
8645     // property, divided by 100.0.
8646     private float mSafeUsbMediaVolumeDbfs;
8647     // mSafeUsbMediaVolumeIndex is used for USB Headsets and is the music volume UI index
8648     // corresponding to a gain of mSafeUsbMediaVolumeDbfs (defaulting to -37dB) in audio
8649     // flinger mixer.
8650     // We remove -22 dBs from the theoretical -15dB to account for the EQ + bass boost
8651     // amplification when both effects are on with all band gains at maximum.
8652     // This level corresponds to a loudness of 85 dB SPL for the warning to be displayed when
8653     // the headset is compliant to EN 60950 with a max loudness of 100dB SPL.
8654     private int mSafeUsbMediaVolumeIndex;
8655     // mSafeMediaVolumeDevices lists the devices for which safe media volume is enforced,
8656     /*package*/ final Set<Integer> mSafeMediaVolumeDevices = new HashSet<>(
8657             Arrays.asList(AudioSystem.DEVICE_OUT_WIRED_HEADSET,
8658                     AudioSystem.DEVICE_OUT_WIRED_HEADPHONE, AudioSystem.DEVICE_OUT_USB_HEADSET));
8659     // mMusicActiveMs is the cumulative time of music activity since safe volume was disabled.
8660     // When this time reaches UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX, the safe media volume is re-enabled
8661     // automatically. mMusicActiveMs is rounded to a multiple of MUSIC_ACTIVE_POLL_PERIOD_MS.
8662     private int mMusicActiveMs;
8663     private static final int UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX = (20 * 3600 * 1000); // 20 hours
8664     private static final int MUSIC_ACTIVE_POLL_PERIOD_MS = 60000;  // 1 minute polling interval
8665     private static final int SAFE_VOLUME_CONFIGURE_TIMEOUT_MS = 30000;  // 30s after boot completed
8666     // check playback or record activity every 6 seconds for UIDs owning mode IN_COMMUNICATION
8667     private static final int CHECK_MODE_FOR_UID_PERIOD_MS = 6000;
8668 
safeMediaVolumeIndex(int device)8669     private int safeMediaVolumeIndex(int device) {
8670         if (!mSafeMediaVolumeDevices.contains(device)) {
8671             return MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC];
8672         }
8673         if (device == AudioSystem.DEVICE_OUT_USB_HEADSET) {
8674             return mSafeUsbMediaVolumeIndex;
8675         } else {
8676             return mSafeMediaVolumeIndex;
8677         }
8678     }
8679 
setSafeMediaVolumeEnabled(boolean on, String caller)8680     private void setSafeMediaVolumeEnabled(boolean on, String caller) {
8681         synchronized (mSafeMediaVolumeStateLock) {
8682             if ((mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_NOT_CONFIGURED) &&
8683                     (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_DISABLED)) {
8684                 if (on && (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE)) {
8685                     mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE;
8686                     enforceSafeMediaVolume(caller);
8687                 } else if (!on && (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE)) {
8688                     mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_INACTIVE;
8689                     mMusicActiveMs = 1;  // nonzero = confirmed
8690                     saveMusicActiveMs();
8691                     sendMsg(mAudioHandler,
8692                             MSG_CHECK_MUSIC_ACTIVE,
8693                             SENDMSG_REPLACE,
8694                             0,
8695                             0,
8696                             caller,
8697                             MUSIC_ACTIVE_POLL_PERIOD_MS);
8698                 }
8699             }
8700         }
8701     }
8702 
enforceSafeMediaVolume(String caller)8703     private void enforceSafeMediaVolume(String caller) {
8704         VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC];
8705         Set<Integer> devices = mSafeMediaVolumeDevices;
8706 
8707         for (int device : devices) {
8708             int index = streamState.getIndex(device);
8709             if (index > safeMediaVolumeIndex(device)) {
8710                 streamState.setIndex(safeMediaVolumeIndex(device), device, caller,
8711                             true /*hasModifyAudioSettings*/);
8712                 sendMsg(mAudioHandler,
8713                         MSG_SET_DEVICE_VOLUME,
8714                         SENDMSG_QUEUE,
8715                         device,
8716                         0,
8717                         streamState,
8718                         0);
8719             }
8720         }
8721     }
8722 
checkSafeMediaVolume(int streamType, int index, int device)8723     private boolean checkSafeMediaVolume(int streamType, int index, int device) {
8724         synchronized (mSafeMediaVolumeStateLock) {
8725             if ((mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE)
8726                     && (mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC)
8727                     && (mSafeMediaVolumeDevices.contains(device))
8728                     && (index > safeMediaVolumeIndex(device))) {
8729                 return false;
8730             }
8731             return true;
8732         }
8733     }
8734 
8735     @Override
disableSafeMediaVolume(String callingPackage)8736     public void disableSafeMediaVolume(String callingPackage) {
8737         enforceVolumeController("disable the safe media volume");
8738         synchronized (mSafeMediaVolumeStateLock) {
8739             setSafeMediaVolumeEnabled(false, callingPackage);
8740             if (mPendingVolumeCommand != null) {
8741                 onSetStreamVolume(mPendingVolumeCommand.mStreamType,
8742                                   mPendingVolumeCommand.mIndex,
8743                                   mPendingVolumeCommand.mFlags,
8744                                   mPendingVolumeCommand.mDevice,
8745                                   callingPackage, true /*hasModifyAudioSettings*/);
8746                 mPendingVolumeCommand = null;
8747             }
8748         }
8749     }
8750 
8751     //==========================================================================================
8752     // Hdmi CEC:
8753     // - System audio mode:
8754     //     If Hdmi Cec's system audio mode is on, audio service should send the volume change
8755     //     to HdmiControlService so that the audio receiver can handle it.
8756     // - CEC sink:
8757     //     OUT_HDMI becomes a "full volume device", i.e. output is always at maximum level
8758     //     and volume changes won't be taken into account on this device. Volume adjustments
8759     //     are transformed into key events for the HDMI playback client.
8760     //==========================================================================================
8761 
8762     @GuardedBy("mHdmiClientLock")
updateHdmiCecSinkLocked(boolean hdmiCecSink)8763     private void updateHdmiCecSinkLocked(boolean hdmiCecSink) {
8764         if (!hasDeviceVolumeBehavior(AudioSystem.DEVICE_OUT_HDMI)) {
8765             if (hdmiCecSink) {
8766                 if (DEBUG_VOL) {
8767                     Log.d(TAG, "CEC sink: setting HDMI as full vol device");
8768                 }
8769                 addAudioSystemDeviceOutToFullVolumeDevices(AudioSystem.DEVICE_OUT_HDMI);
8770             } else {
8771                 if (DEBUG_VOL) {
8772                     Log.d(TAG, "TV, no CEC: setting HDMI as regular vol device");
8773                 }
8774                 // Android TV devices without CEC service apply software volume on
8775                 // HDMI output
8776                 removeAudioSystemDeviceOutFromFullVolumeDevices(AudioSystem.DEVICE_OUT_HDMI);
8777             }
8778             postUpdateVolumeStatesForAudioDevice(AudioSystem.DEVICE_OUT_HDMI,
8779                     "HdmiPlaybackClient.DisplayStatusCallback");
8780         }
8781     }
8782 
8783     private class MyHdmiControlStatusChangeListenerCallback
8784             implements HdmiControlManager.HdmiControlStatusChangeListener {
onStatusChange(@dmiControlManager.HdmiCecControl int isCecEnabled, boolean isCecAvailable)8785         public void onStatusChange(@HdmiControlManager.HdmiCecControl int isCecEnabled,
8786                 boolean isCecAvailable) {
8787             synchronized (mHdmiClientLock) {
8788                 if (mHdmiManager == null) return;
8789                 boolean cecEnabled = isCecEnabled == HdmiControlManager.HDMI_CEC_CONTROL_ENABLED;
8790                 updateHdmiCecSinkLocked(cecEnabled ? isCecAvailable : false);
8791             }
8792         }
8793     };
8794 
8795     private class MyHdmiCecVolumeControlFeatureListener
8796             implements HdmiControlManager.HdmiCecVolumeControlFeatureListener {
onHdmiCecVolumeControlFeature( @dmiControlManager.VolumeControl int hdmiCecVolumeControl)8797         public void onHdmiCecVolumeControlFeature(
8798                 @HdmiControlManager.VolumeControl int hdmiCecVolumeControl) {
8799             synchronized (mHdmiClientLock) {
8800                 if (mHdmiManager == null) return;
8801                 mHdmiCecVolumeControlEnabled =
8802                         hdmiCecVolumeControl == HdmiControlManager.VOLUME_CONTROL_ENABLED;
8803             }
8804         }
8805     };
8806 
8807     private final Object mHdmiClientLock = new Object();
8808 
8809     // If HDMI-CEC system audio is supported
8810     // Note that for CEC volume commands mHdmiCecVolumeControlEnabled will play a role on volume
8811     // commands
8812     private boolean mHdmiSystemAudioSupported = false;
8813     // Set only when device is tv.
8814     @GuardedBy("mHdmiClientLock")
8815     private HdmiTvClient mHdmiTvClient;
8816     // true if the device has system feature PackageManager.FEATURE_LEANBACK.
8817     // cached HdmiControlManager interface
8818     @GuardedBy("mHdmiClientLock")
8819     private HdmiControlManager mHdmiManager;
8820     // Set only when device is a set-top box.
8821     @GuardedBy("mHdmiClientLock")
8822     private HdmiPlaybackClient mHdmiPlaybackClient;
8823     // Set only when device is an audio system.
8824     @GuardedBy("mHdmiClientLock")
8825     private HdmiAudioSystemClient mHdmiAudioSystemClient;
8826     // True when volume control over HDMI CEC is used when CEC is enabled (meaningless otherwise)
8827     @GuardedBy("mHdmiClientLock")
8828     private boolean mHdmiCecVolumeControlEnabled;
8829 
8830     private MyHdmiControlStatusChangeListenerCallback mHdmiControlStatusChangeListenerCallback =
8831             new MyHdmiControlStatusChangeListenerCallback();
8832 
8833     private MyHdmiCecVolumeControlFeatureListener mMyHdmiCecVolumeControlFeatureListener =
8834             new MyHdmiCecVolumeControlFeatureListener();
8835 
8836     @Override
setHdmiSystemAudioSupported(boolean on)8837     public int setHdmiSystemAudioSupported(boolean on) {
8838         int device = AudioSystem.DEVICE_NONE;
8839         synchronized (mHdmiClientLock) {
8840             if (mHdmiManager != null) {
8841                 if (mHdmiTvClient == null && mHdmiAudioSystemClient == null) {
8842                     Log.w(TAG, "Only Hdmi-Cec enabled TV or audio system device supports"
8843                             + "system audio mode.");
8844                     return device;
8845                 }
8846                 if (mHdmiSystemAudioSupported != on) {
8847                     mHdmiSystemAudioSupported = on;
8848                     final int config = on ? AudioSystem.FORCE_HDMI_SYSTEM_AUDIO_ENFORCED :
8849                         AudioSystem.FORCE_NONE;
8850                     mDeviceBroker.setForceUse_Async(AudioSystem.FOR_HDMI_SYSTEM_AUDIO, config,
8851                             "setHdmiSystemAudioSupported");
8852                 }
8853                 device = getDevicesForStreamInt(AudioSystem.STREAM_MUSIC);
8854             }
8855         }
8856         return device;
8857     }
8858 
8859     @Override
isHdmiSystemAudioSupported()8860     public boolean isHdmiSystemAudioSupported() {
8861         return mHdmiSystemAudioSupported;
8862     }
8863 
8864     //==========================================================================================
8865     // Accessibility
8866 
initA11yMonitoring()8867     private void initA11yMonitoring() {
8868         final AccessibilityManager accessibilityManager =
8869                 (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
8870         updateDefaultStreamOverrideDelay(accessibilityManager.isTouchExplorationEnabled());
8871         updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive());
8872         accessibilityManager.addTouchExplorationStateChangeListener(this, null);
8873         accessibilityManager.addAccessibilityServicesStateChangeListener(this, null);
8874     }
8875 
8876     //---------------------------------------------------------------------------------
8877     // A11y: taking touch exploration into account for selecting the default
8878     //   stream override timeout when adjusting volume
8879     //---------------------------------------------------------------------------------
8880 
8881     // - STREAM_NOTIFICATION on tablets during this period after a notification stopped
8882     // - STREAM_RING on phones during this period after a notification stopped
8883     // - STREAM_MUSIC otherwise
8884 
8885     private static final int DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS = 0;
8886     private static final int TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS = 1000;
8887 
8888     private static int sStreamOverrideDelayMs;
8889 
8890     @Override
onTouchExplorationStateChanged(boolean enabled)8891     public void onTouchExplorationStateChanged(boolean enabled) {
8892         updateDefaultStreamOverrideDelay(enabled);
8893     }
8894 
updateDefaultStreamOverrideDelay(boolean touchExploreEnabled)8895     private void updateDefaultStreamOverrideDelay(boolean touchExploreEnabled) {
8896         if (touchExploreEnabled) {
8897             sStreamOverrideDelayMs = TOUCH_EXPLORE_STREAM_TYPE_OVERRIDE_DELAY_MS;
8898         } else {
8899             sStreamOverrideDelayMs = DEFAULT_STREAM_TYPE_OVERRIDE_DELAY_MS;
8900         }
8901         if (DEBUG_VOL) Log.d(TAG, "Touch exploration enabled=" + touchExploreEnabled
8902                 + " stream override delay is now " + sStreamOverrideDelayMs + " ms");
8903     }
8904 
8905     //---------------------------------------------------------------------------------
8906     // A11y: taking a11y state into account for the handling of a11y prompts volume
8907     //---------------------------------------------------------------------------------
8908 
8909     private static boolean sIndependentA11yVolume = false;
8910 
8911     // implementation of AccessibilityServicesStateChangeListener
8912     @Override
onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager)8913     public void onAccessibilityServicesStateChanged(AccessibilityManager accessibilityManager) {
8914         updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive());
8915     }
8916 
updateA11yVolumeAlias(boolean a11VolEnabled)8917     private void updateA11yVolumeAlias(boolean a11VolEnabled) {
8918         if (DEBUG_VOL) Log.d(TAG, "Accessibility volume enabled = " + a11VolEnabled);
8919         if (sIndependentA11yVolume != a11VolEnabled) {
8920             sIndependentA11yVolume = a11VolEnabled;
8921             // update the volume mapping scheme
8922             updateStreamVolumeAlias(true /*updateVolumes*/, TAG);
8923             // update the volume controller behavior
8924             mVolumeController.setA11yMode(sIndependentA11yVolume ?
8925                     VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME :
8926                         VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME);
8927             mVolumeController.postVolumeChanged(AudioManager.STREAM_ACCESSIBILITY, 0);
8928         }
8929     }
8930 
8931     //==========================================================================================
8932     // Camera shutter sound policy.
8933     // config_camera_sound_forced configuration option in config.xml defines if the camera shutter
8934     // sound is forced (sound even if the device is in silent mode) or not. This option is false by
8935     // default and can be overridden by country specific overlay in values-mccXXX/config.xml.
8936     //==========================================================================================
8937 
8938     // cached value of com.android.internal.R.bool.config_camera_sound_forced
8939     @GuardedBy("mSettingsLock")
8940     private boolean mCameraSoundForced;
8941 
8942     // called by android.hardware.Camera to populate CameraInfo.canDisableShutterSound
isCameraSoundForced()8943     public boolean isCameraSoundForced() {
8944         synchronized (mSettingsLock) {
8945             return mCameraSoundForced;
8946         }
8947     }
8948 
8949     //==========================================================================================
8950     // AudioService logging and dumpsys
8951     //==========================================================================================
8952     static final int LOG_NB_EVENTS_LIFECYCLE = 20;
8953     static final int LOG_NB_EVENTS_PHONE_STATE = 20;
8954     static final int LOG_NB_EVENTS_DEVICE_CONNECTION = 30;
8955     static final int LOG_NB_EVENTS_FORCE_USE = 20;
8956     static final int LOG_NB_EVENTS_VOLUME = 40;
8957     static final int LOG_NB_EVENTS_DYN_POLICY = 10;
8958 
8959     static final AudioEventLogger sLifecycleLogger = new AudioEventLogger(LOG_NB_EVENTS_LIFECYCLE,
8960             "audio services lifecycle");
8961 
8962     final private AudioEventLogger mModeLogger = new AudioEventLogger(LOG_NB_EVENTS_PHONE_STATE,
8963             "phone state (logged after successful call to AudioSystem.setPhoneState(int, int))");
8964 
8965     // logs for wired + A2DP device connections:
8966     // - wired: logged before onSetWiredDeviceConnectionState() is executed
8967     // - A2DP: logged at reception of method call
8968     /*package*/ static final AudioEventLogger sDeviceLogger = new AudioEventLogger(
8969             LOG_NB_EVENTS_DEVICE_CONNECTION, "wired/A2DP/hearing aid device connection");
8970 
8971     static final AudioEventLogger sForceUseLogger = new AudioEventLogger(
8972             LOG_NB_EVENTS_FORCE_USE,
8973             "force use (logged before setForceUse() is executed)");
8974 
8975     static final AudioEventLogger sVolumeLogger = new AudioEventLogger(LOG_NB_EVENTS_VOLUME,
8976             "volume changes (logged when command received by AudioService)");
8977 
8978     final private AudioEventLogger mDynPolicyLogger = new AudioEventLogger(LOG_NB_EVENTS_DYN_POLICY,
8979             "dynamic policy events (logged when command received by AudioService)");
8980 
8981     private static final String[] RINGER_MODE_NAMES = new String[] {
8982             "SILENT",
8983             "VIBRATE",
8984             "NORMAL"
8985     };
8986 
dumpRingerMode(PrintWriter pw)8987     private void dumpRingerMode(PrintWriter pw) {
8988         pw.println("\nRinger mode: ");
8989         pw.println("- mode (internal) = " + RINGER_MODE_NAMES[mRingerMode]);
8990         pw.println("- mode (external) = " + RINGER_MODE_NAMES[mRingerModeExternal]);
8991         pw.println("- zen mode:" + Settings.Global.zenModeToString(mNm.getZenMode()));
8992         dumpRingerModeStreams(pw, "affected", mRingerModeAffectedStreams);
8993         dumpRingerModeStreams(pw, "muted", mRingerAndZenModeMutedStreams);
8994         pw.print("- delegate = "); pw.println(mRingerModeDelegate);
8995     }
8996 
dumpRingerModeStreams(PrintWriter pw, String type, int streams)8997     private void dumpRingerModeStreams(PrintWriter pw, String type, int streams) {
8998         pw.print("- ringer mode "); pw.print(type); pw.print(" streams = 0x");
8999         pw.print(Integer.toHexString(streams));
9000         if (streams != 0) {
9001             pw.print(" (");
9002             boolean first = true;
9003             for (int i = 0; i < AudioSystem.STREAM_NAMES.length; i++) {
9004                 final int stream = (1 << i);
9005                 if ((streams & stream) != 0) {
9006                     if (!first) pw.print(',');
9007                     pw.print(AudioSystem.STREAM_NAMES[i]);
9008                     streams &= ~stream;
9009                     first = false;
9010                 }
9011             }
9012             if (streams != 0) {
9013                 if (!first) pw.print(',');
9014                 pw.print(streams);
9015             }
9016             pw.print(')');
9017         }
9018         pw.println();
9019     }
9020 
dumpDeviceTypes(@onNull Set<Integer> deviceTypes)9021     private String dumpDeviceTypes(@NonNull Set<Integer> deviceTypes) {
9022         Iterator<Integer> it = deviceTypes.iterator();
9023         if (!it.hasNext()) {
9024             return "";
9025         }
9026         final StringBuilder sb = new StringBuilder();
9027         sb.append("0x" + Integer.toHexString(it.next()));
9028         while (it.hasNext()) {
9029             sb.append("," + "0x" + Integer.toHexString(it.next()));
9030         }
9031         return sb.toString();
9032     }
9033 
9034     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)9035     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
9036         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
9037 
9038         sLifecycleLogger.dump(pw);
9039         if (mAudioHandler != null) {
9040             pw.println("\nMessage handler (watch for unhandled messages):");
9041             mAudioHandler.dump(new PrintWriterPrinter(pw), "  ");
9042         } else {
9043             pw.println("\nMessage handler is null");
9044         }
9045         mMediaFocusControl.dump(pw);
9046         dumpStreamStates(pw);
9047         dumpVolumeGroups(pw);
9048         dumpRingerMode(pw);
9049         dumpAudioMode(pw);
9050         pw.println("\nAudio routes:");
9051         pw.print("  mMainType=0x"); pw.println(Integer.toHexString(
9052                 mDeviceBroker.getCurAudioRoutes().mainType));
9053         pw.print("  mBluetoothName="); pw.println(mDeviceBroker.getCurAudioRoutes().bluetoothName);
9054 
9055         pw.println("\nOther state:");
9056         pw.print("  mVolumeController="); pw.println(mVolumeController);
9057         pw.print("  mSafeMediaVolumeState=");
9058         pw.println(safeMediaVolumeStateToString(mSafeMediaVolumeState));
9059         pw.print("  mSafeMediaVolumeIndex="); pw.println(mSafeMediaVolumeIndex);
9060         pw.print("  mSafeUsbMediaVolumeIndex="); pw.println(mSafeUsbMediaVolumeIndex);
9061         pw.print("  mSafeUsbMediaVolumeDbfs="); pw.println(mSafeUsbMediaVolumeDbfs);
9062         pw.print("  sIndependentA11yVolume="); pw.println(sIndependentA11yVolume);
9063         pw.print("  mPendingVolumeCommand="); pw.println(mPendingVolumeCommand);
9064         pw.print("  mMusicActiveMs="); pw.println(mMusicActiveMs);
9065         pw.print("  mMcc="); pw.println(mMcc);
9066         pw.print("  mCameraSoundForced="); pw.println(mCameraSoundForced);
9067         pw.print("  mHasVibrator="); pw.println(mHasVibrator);
9068         pw.print("  mVolumePolicy="); pw.println(mVolumePolicy);
9069         pw.print("  mAvrcpAbsVolSupported="); pw.println(mAvrcpAbsVolSupported);
9070         pw.print("  mBtScoOnByApp="); pw.println(mBtScoOnByApp);
9071         pw.print("  mIsSingleVolume="); pw.println(mIsSingleVolume);
9072         pw.print("  mUseFixedVolume="); pw.println(mUseFixedVolume);
9073         pw.print("  mFixedVolumeDevices="); pw.println(dumpDeviceTypes(mFixedVolumeDevices));
9074         pw.print("  mFullVolumeDevices="); pw.println(dumpDeviceTypes(mFullVolumeDevices));
9075         pw.print("  mExtVolumeController="); pw.println(mExtVolumeController);
9076         pw.print("  mHdmiAudioSystemClient="); pw.println(mHdmiAudioSystemClient);
9077         pw.print("  mHdmiPlaybackClient="); pw.println(mHdmiPlaybackClient);
9078         pw.print("  mHdmiTvClient="); pw.println(mHdmiTvClient);
9079         pw.print("  mHdmiSystemAudioSupported="); pw.println(mHdmiSystemAudioSupported);
9080         pw.print("  mHdmiCecVolumeControlEnabled="); pw.println(mHdmiCecVolumeControlEnabled);
9081         pw.print("  mIsCallScreeningModeSupported="); pw.println(mIsCallScreeningModeSupported);
9082         pw.print("  mic mute FromSwitch=" + mMicMuteFromSwitch
9083                         + " FromRestrictions=" + mMicMuteFromRestrictions
9084                         + " FromApi=" + mMicMuteFromApi
9085                         + " from system=" + mMicMuteFromSystemCached);
9086         pw.print("\n  mAssistantUid="); pw.println(mAssistantUid);
9087         pw.print("  mCurrentImeUid="); pw.println(mCurrentImeUid);
9088         dumpAccessibilityServiceUids(pw);
9089 
9090         dumpAudioPolicies(pw);
9091         mDynPolicyLogger.dump(pw);
9092         mPlaybackMonitor.dump(pw);
9093         mRecordMonitor.dump(pw);
9094 
9095         pw.println("\nAudioDeviceBroker:");
9096         mDeviceBroker.dump(pw, "  ");
9097         pw.println("\nSoundEffects:");
9098         mSfxHelper.dump(pw, "  ");
9099 
9100         pw.println("\n");
9101         pw.println("\nEvent logs:");
9102         mModeLogger.dump(pw);
9103         pw.println("\n");
9104         sDeviceLogger.dump(pw);
9105         pw.println("\n");
9106         sForceUseLogger.dump(pw);
9107         pw.println("\n");
9108         sVolumeLogger.dump(pw);
9109         pw.println("\n");
9110         dumpSupportedSystemUsage(pw);
9111 
9112         pw.println("\n");
9113         pw.println("\nSpatial audio:");
9114         pw.println("mHasSpatializerEffect:" + mHasSpatializerEffect);
9115         pw.println("isSpatializerEnabled:" + isSpatializerEnabled());
9116         pw.println("isSpatialAudioEnabled:" + isSpatialAudioEnabled());
9117 
9118         mAudioSystem.dump(pw);
9119     }
9120 
dumpSupportedSystemUsage(PrintWriter pw)9121     private void dumpSupportedSystemUsage(PrintWriter pw) {
9122         pw.println("Supported System Usages:");
9123         synchronized (mSupportedSystemUsagesLock) {
9124             for (int i = 0; i < mSupportedSystemUsages.length; i++) {
9125                 pw.printf("\t%s\n", AudioAttributes.usageToString(mSupportedSystemUsages[i]));
9126             }
9127         }
9128     }
9129 
dumpAccessibilityServiceUids(PrintWriter pw)9130     private void dumpAccessibilityServiceUids(PrintWriter pw) {
9131         synchronized (mSupportedSystemUsagesLock) {
9132             if (mAccessibilityServiceUids != null && mAccessibilityServiceUids.length > 0) {
9133                 pw.println("  Accessibility service Uids:");
9134                 for (int uid : mAccessibilityServiceUids) {
9135                     pw.println("  - " + uid);
9136                 }
9137             } else {
9138                 pw.println("  No accessibility service Uids.");
9139             }
9140         }
9141     }
9142 
9143     /**
9144      * Audio Analytics ids.
9145      */
9146     private static final String mMetricsId = MediaMetrics.Name.AUDIO_SERVICE
9147             + MediaMetrics.SEPARATOR;
9148 
safeMediaVolumeStateToString(int state)9149     private static String safeMediaVolumeStateToString(int state) {
9150         switch(state) {
9151             case SAFE_MEDIA_VOLUME_NOT_CONFIGURED: return "SAFE_MEDIA_VOLUME_NOT_CONFIGURED";
9152             case SAFE_MEDIA_VOLUME_DISABLED: return "SAFE_MEDIA_VOLUME_DISABLED";
9153             case SAFE_MEDIA_VOLUME_INACTIVE: return "SAFE_MEDIA_VOLUME_INACTIVE";
9154             case SAFE_MEDIA_VOLUME_ACTIVE: return "SAFE_MEDIA_VOLUME_ACTIVE";
9155         }
9156         return null;
9157     }
9158 
9159     // Inform AudioFlinger of our device's low RAM attribute
readAndSetLowRamDevice()9160     private static void readAndSetLowRamDevice()
9161     {
9162         boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic();
9163         long totalMemory = 1024 * 1024 * 1024; // 1GB is the default if ActivityManager fails.
9164 
9165         try {
9166             final ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();
9167             ActivityManager.getService().getMemoryInfo(info);
9168             totalMemory = info.totalMem;
9169         } catch (RemoteException e) {
9170             Log.w(TAG, "Cannot obtain MemoryInfo from ActivityManager, assume low memory device");
9171             isLowRamDevice = true;
9172         }
9173 
9174         final int status = AudioSystem.setLowRamDevice(isLowRamDevice, totalMemory);
9175         if (status != 0) {
9176             Log.w(TAG, "AudioFlinger informed of device's low RAM attribute; status " + status);
9177         }
9178     }
9179 
enforceVolumeController(String action)9180     private void enforceVolumeController(String action) {
9181         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR_SERVICE,
9182                 "Only SystemUI can " + action);
9183     }
9184 
9185     @Override
setVolumeController(final IVolumeController controller)9186     public void setVolumeController(final IVolumeController controller) {
9187         enforceVolumeController("set the volume controller");
9188 
9189         // return early if things are not actually changing
9190         if (mVolumeController.isSameBinder(controller)) {
9191             return;
9192         }
9193 
9194         // dismiss the old volume controller
9195         mVolumeController.postDismiss();
9196         if (controller != null) {
9197             // we are about to register a new controller, listen for its death
9198             try {
9199                 controller.asBinder().linkToDeath(new DeathRecipient() {
9200                     @Override
9201                     public void binderDied() {
9202                         if (mVolumeController.isSameBinder(controller)) {
9203                             Log.w(TAG, "Current remote volume controller died, unregistering");
9204                             setVolumeController(null);
9205                         }
9206                     }
9207                 }, 0);
9208             } catch (RemoteException e) {
9209                 // noop
9210             }
9211         }
9212         mVolumeController.setController(controller);
9213         if (DEBUG_VOL) Log.d(TAG, "Volume controller: " + mVolumeController);
9214     }
9215 
9216     @Override
notifyVolumeControllerVisible(final IVolumeController controller, boolean visible)9217     public void notifyVolumeControllerVisible(final IVolumeController controller, boolean visible) {
9218         enforceVolumeController("notify about volume controller visibility");
9219 
9220         // return early if the controller is not current
9221         if (!mVolumeController.isSameBinder(controller)) {
9222             return;
9223         }
9224 
9225         mVolumeController.setVisible(visible);
9226         if (DEBUG_VOL) Log.d(TAG, "Volume controller visible: " + visible);
9227     }
9228 
9229     @Override
setVolumePolicy(VolumePolicy policy)9230     public void setVolumePolicy(VolumePolicy policy) {
9231         enforceVolumeController("set volume policy");
9232         if (policy != null && !policy.equals(mVolumePolicy)) {
9233             mVolumePolicy = policy;
9234             if (DEBUG_VOL) Log.d(TAG, "Volume policy changed: " + mVolumePolicy);
9235         }
9236     }
9237 
9238     public class VolumeController {
9239         private static final String TAG = "VolumeController";
9240 
9241         private IVolumeController mController;
9242         private boolean mVisible;
9243         private long mNextLongPress;
9244         private int mLongPressTimeout;
9245 
setController(IVolumeController controller)9246         public void setController(IVolumeController controller) {
9247             mController = controller;
9248             mVisible = false;
9249         }
9250 
loadSettings(ContentResolver cr)9251         public void loadSettings(ContentResolver cr) {
9252             mLongPressTimeout = Settings.Secure.getIntForUser(cr,
9253                     Settings.Secure.LONG_PRESS_TIMEOUT, 500, UserHandle.USER_CURRENT);
9254         }
9255 
suppressAdjustment(int resolvedStream, int flags, boolean isMute)9256         public boolean suppressAdjustment(int resolvedStream, int flags, boolean isMute) {
9257             if (isMute) {
9258                 return false;
9259             }
9260             boolean suppress = false;
9261             // Intended behavior:
9262             // 1/ if the stream is not the default UI stream, do not suppress (as it is not involved
9263             //    in bringing up the UI)
9264             // 2/ if the resolved and default stream is MUSIC, and media is playing, do not suppress
9265             // 3/ otherwise suppress the first adjustments that occur during the "long press
9266             //    timeout" interval. Note this is true regardless of whether this is a "real long
9267             //    press" (where the user keeps pressing on the volume button), or repeated single
9268             //    presses (here we don't know if we are in a real long press, or repeated fast
9269             //    button presses).
9270             //    Once the long press timeout occurs (mNextLongPress reset to 0), do not suppress.
9271             // Example: for a default and resolved stream of MUSIC, this allows modifying rapidly
9272             // the volume when media is playing (whether by long press or repeated individual
9273             // presses), or to bring up the volume UI when media is not playing, in order to make
9274             // another change (e.g. switch ringer modes) without changing media volume.
9275             if (resolvedStream == DEFAULT_VOL_STREAM_NO_PLAYBACK && mController != null) {
9276                 // never suppress media vol adjustement during media playback
9277                 if (resolvedStream == AudioSystem.STREAM_MUSIC
9278                         && mAudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, mLongPressTimeout))
9279                 {
9280                     // media is playing, adjust the volume right away
9281                     return false;
9282                 }
9283 
9284                 final long now = SystemClock.uptimeMillis();
9285                 if ((flags & AudioManager.FLAG_SHOW_UI) != 0 && !mVisible) {
9286                     // UI is not visible yet, adjustment is ignored
9287                     if (mNextLongPress < now) {
9288                         mNextLongPress = now + mLongPressTimeout;
9289                     }
9290                     suppress = true;
9291                 } else if (mNextLongPress > 0) {  // in a long-press
9292                     if (now > mNextLongPress) {
9293                         // long press triggered, no more suppression
9294                         mNextLongPress = 0;
9295                     } else {
9296                         // keep suppressing until the long press triggers
9297                         suppress = true;
9298                     }
9299                 }
9300             }
9301             return suppress;
9302         }
9303 
setVisible(boolean visible)9304         public void setVisible(boolean visible) {
9305             mVisible = visible;
9306         }
9307 
isSameBinder(IVolumeController controller)9308         public boolean isSameBinder(IVolumeController controller) {
9309             return Objects.equals(asBinder(), binder(controller));
9310         }
9311 
asBinder()9312         public IBinder asBinder() {
9313             return binder(mController);
9314         }
9315 
binder(IVolumeController controller)9316         private IBinder binder(IVolumeController controller) {
9317             return controller == null ? null : controller.asBinder();
9318         }
9319 
9320         @Override
toString()9321         public String toString() {
9322             return "VolumeController(" + asBinder() + ",mVisible=" + mVisible + ")";
9323         }
9324 
postDisplaySafeVolumeWarning(int flags)9325         public void postDisplaySafeVolumeWarning(int flags) {
9326             if (mController == null)
9327                 return;
9328             flags = flags | AudioManager.FLAG_SHOW_UI;
9329             try {
9330                 mController.displaySafeVolumeWarning(flags);
9331             } catch (RemoteException e) {
9332                 Log.w(TAG, "Error calling displaySafeVolumeWarning", e);
9333             }
9334         }
9335 
postVolumeChanged(int streamType, int flags)9336         public void postVolumeChanged(int streamType, int flags) {
9337             if (mController == null)
9338                 return;
9339             try {
9340                 mController.volumeChanged(streamType, flags);
9341             } catch (RemoteException e) {
9342                 Log.w(TAG, "Error calling volumeChanged", e);
9343             }
9344         }
9345 
postMasterMuteChanged(int flags)9346         public void postMasterMuteChanged(int flags) {
9347             if (mController == null)
9348                 return;
9349             try {
9350                 mController.masterMuteChanged(flags);
9351             } catch (RemoteException e) {
9352                 Log.w(TAG, "Error calling masterMuteChanged", e);
9353             }
9354         }
9355 
setLayoutDirection(int layoutDirection)9356         public void setLayoutDirection(int layoutDirection) {
9357             if (mController == null)
9358                 return;
9359             try {
9360                 mController.setLayoutDirection(layoutDirection);
9361             } catch (RemoteException e) {
9362                 Log.w(TAG, "Error calling setLayoutDirection", e);
9363             }
9364         }
9365 
postDismiss()9366         public void postDismiss() {
9367             if (mController == null)
9368                 return;
9369             try {
9370                 mController.dismiss();
9371             } catch (RemoteException e) {
9372                 Log.w(TAG, "Error calling dismiss", e);
9373             }
9374         }
9375 
setA11yMode(int a11yMode)9376         public void setA11yMode(int a11yMode) {
9377             if (mController == null)
9378                 return;
9379             try {
9380                 mController.setA11yMode(a11yMode);
9381             } catch (RemoteException e) {
9382                 Log.w(TAG, "Error calling setA11Mode", e);
9383             }
9384         }
9385     }
9386 
9387     /**
9388      * Interface for system components to get some extra functionality through
9389      * LocalServices.
9390      */
9391     final class AudioServiceInternal extends AudioManagerInternal {
9392         @Override
setRingerModeDelegate(RingerModeDelegate delegate)9393         public void setRingerModeDelegate(RingerModeDelegate delegate) {
9394             mRingerModeDelegate = delegate;
9395             if (mRingerModeDelegate != null) {
9396                 synchronized (mSettingsLock) {
9397                     updateRingerAndZenModeAffectedStreams();
9398                 }
9399                 setRingerModeInternal(getRingerModeInternal(), TAG + ".setRingerModeDelegate");
9400             }
9401         }
9402 
9403         @Override
getRingerModeInternal()9404         public int getRingerModeInternal() {
9405             return AudioService.this.getRingerModeInternal();
9406         }
9407 
9408         @Override
setRingerModeInternal(int ringerMode, String caller)9409         public void setRingerModeInternal(int ringerMode, String caller) {
9410             AudioService.this.setRingerModeInternal(ringerMode, caller);
9411         }
9412 
9413         @Override
silenceRingerModeInternal(String caller)9414         public void silenceRingerModeInternal(String caller) {
9415             AudioService.this.silenceRingerModeInternal(caller);
9416         }
9417 
9418         @Override
updateRingerModeAffectedStreamsInternal()9419         public void updateRingerModeAffectedStreamsInternal() {
9420             synchronized (mSettingsLock) {
9421                 if (updateRingerAndZenModeAffectedStreams()) {
9422                     setRingerModeInt(getRingerModeInternal(), false);
9423                 }
9424             }
9425         }
9426 
9427         @Override
setHotwordDetectionServiceUid(int uid)9428         public void setHotwordDetectionServiceUid(int uid) {
9429             synchronized (mHotwordDetectionServiceUidLock) {
9430                 if (mHotwordDetectionServiceUid != uid) {
9431                     mHotwordDetectionServiceUid = uid;
9432                     AudioSystem.setHotwordDetectionServiceUid(mHotwordDetectionServiceUid);
9433                 }
9434             }
9435         }
9436 
9437         @Override
setAccessibilityServiceUids(IntArray uids)9438         public void setAccessibilityServiceUids(IntArray uids) {
9439             synchronized (mAccessibilityServiceUidsLock) {
9440                 if (uids.size() == 0) {
9441                     mAccessibilityServiceUids = null;
9442                 } else {
9443                     boolean changed = (mAccessibilityServiceUids == null)
9444                             || (mAccessibilityServiceUids.length != uids.size());
9445                     if (!changed) {
9446                         for (int i = 0; i < mAccessibilityServiceUids.length; i++) {
9447                             if (uids.get(i) != mAccessibilityServiceUids[i]) {
9448                                 changed = true;
9449                                 break;
9450                             }
9451                         }
9452                     }
9453                     if (changed) {
9454                         mAccessibilityServiceUids = uids.toArray();
9455                     }
9456                 }
9457                 sendMsg(mAudioHandler, MSG_UPDATE_A11Y_SERVICE_UIDS, SENDMSG_REPLACE,
9458                         0, 0, null, 0);
9459             }
9460         }
9461 
9462         /**
9463          * {@inheritDoc}
9464          */
9465         @Override
setInputMethodServiceUid(int uid)9466         public void setInputMethodServiceUid(int uid) {
9467             synchronized (mInputMethodServiceUidLock) {
9468                 if (mInputMethodServiceUid != uid) {
9469                     mAudioSystem.setCurrentImeUid(uid);
9470                     mInputMethodServiceUid = uid;
9471                 }
9472             }
9473         }
9474     }
9475 
onUpdateAccessibilityServiceUids()9476     private void onUpdateAccessibilityServiceUids() {
9477         int[] accessibilityServiceUids;
9478         synchronized (mAccessibilityServiceUidsLock) {
9479             accessibilityServiceUids = mAccessibilityServiceUids;
9480         }
9481         AudioSystem.setA11yServicesUids(accessibilityServiceUids);
9482     }
9483 
9484     //==========================================================================================
9485     // Audio policy management
9486     //==========================================================================================
registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection)9487     public String registerAudioPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb,
9488             boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy,
9489             boolean isVolumeController, IMediaProjection projection) {
9490         AudioSystem.setDynamicPolicyCallback(mDynPolicyCallback);
9491 
9492         if (!isPolicyRegisterAllowed(policyConfig,
9493                                      isFocusPolicy || isTestFocusPolicy || hasFocusListener,
9494                                      isVolumeController,
9495                                      projection)) {
9496             Slog.w(TAG, "Permission denied to register audio policy for pid "
9497                     + Binder.getCallingPid() + " / uid " + Binder.getCallingUid()
9498                     + ", need MODIFY_AUDIO_ROUTING or MediaProjection that can project audio");
9499             return null;
9500         }
9501 
9502         String regId = null;
9503         synchronized (mAudioPolicies) {
9504             if (mAudioPolicies.containsKey(pcb.asBinder())) {
9505                 Slog.e(TAG, "Cannot re-register policy");
9506                 return null;
9507             }
9508             try {
9509                 AudioPolicyProxy app = new AudioPolicyProxy(policyConfig, pcb, hasFocusListener,
9510                         isFocusPolicy, isTestFocusPolicy, isVolumeController, projection);
9511                 pcb.asBinder().linkToDeath(app, 0/*flags*/);
9512 
9513                 // logging after registration so we have the registration id
9514                 mDynPolicyLogger.log((new AudioEventLogger.StringEvent("registerAudioPolicy for "
9515                         + pcb.asBinder() + " u/pid:" + Binder.getCallingUid() + "/"
9516                         + Binder.getCallingPid() + " with config:" + app.toCompactLogString()))
9517                         .printLog(TAG));
9518 
9519                 regId = app.getRegistrationId();
9520                 mAudioPolicies.put(pcb.asBinder(), app);
9521             } catch (RemoteException e) {
9522                 // audio policy owner has already died!
9523                 Slog.w(TAG, "Audio policy registration failed, could not link to " + pcb +
9524                         " binder death", e);
9525                 return null;
9526             } catch (IllegalStateException e) {
9527                 Slog.w(TAG, "Audio policy registration failed for binder " + pcb, e);
9528                 return null;
9529             }
9530         }
9531         return regId;
9532     }
9533 
9534     /**
9535      * Apps with MODIFY_AUDIO_ROUTING can register any policy.
9536      * Apps with an audio capable MediaProjection are allowed to register a RENDER|LOOPBACK policy
9537      * as those policy do not modify the audio routing.
9538      */
isPolicyRegisterAllowed(AudioPolicyConfig policyConfig, boolean hasFocusAccess, boolean isVolumeController, IMediaProjection projection)9539     private boolean isPolicyRegisterAllowed(AudioPolicyConfig policyConfig,
9540                                             boolean hasFocusAccess,
9541                                             boolean isVolumeController,
9542                                             IMediaProjection projection) {
9543 
9544         boolean requireValidProjection = false;
9545         boolean requireCaptureAudioOrMediaOutputPerm = false;
9546         boolean requireModifyRouting = false;
9547         ArrayList<AudioMix> voiceCommunicationCaptureMixes = null;
9548 
9549 
9550         if (hasFocusAccess || isVolumeController) {
9551             requireModifyRouting |= true;
9552         } else if (policyConfig.getMixes().isEmpty()) {
9553             // An empty policy could be used to lock the focus or add mixes later
9554             requireModifyRouting |= true;
9555         }
9556         for (AudioMix mix : policyConfig.getMixes()) {
9557             // If mix is requesting privileged capture
9558             if (mix.getRule().allowPrivilegedMediaPlaybackCapture()) {
9559                 // then its format must be low quality enough
9560                 String privilegedMediaCaptureError =
9561                         mix.canBeUsedForPrivilegedMediaCapture(mix.getFormat());
9562                 if (privilegedMediaCaptureError != null) {
9563                     Log.e(TAG, privilegedMediaCaptureError);
9564                     return false;
9565                 }
9566                 // and it must have CAPTURE_MEDIA_OUTPUT or CAPTURE_AUDIO_OUTPUT permission
9567                 requireCaptureAudioOrMediaOutputPerm |= true;
9568 
9569             }
9570             // If mix is trying to explicitly capture USAGE_VOICE_COMMUNICATION
9571             if (mix.containsMatchAttributeRuleForUsage(
9572                     AudioAttributes.USAGE_VOICE_COMMUNICATION)
9573                     && (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER)) {
9574                 // It must have CAPTURE_USAGE_VOICE_COMMUNICATION_OUTPUT permission
9575                 // Note that for UID, USERID or EXCLDUE rules, the capture will be silenced
9576                 // in AudioPolicyMix
9577                 if (voiceCommunicationCaptureMixes == null) {
9578                     voiceCommunicationCaptureMixes = new ArrayList<AudioMix>();
9579                 }
9580                 voiceCommunicationCaptureMixes.add(mix);
9581             }
9582 
9583             // If mix is RENDER|LOOPBACK, then an audio MediaProjection is enough
9584             // otherwise MODIFY_AUDIO_ROUTING permission is required
9585             if (mix.getRouteFlags() == mix.ROUTE_FLAG_LOOP_BACK_RENDER && projection != null) {
9586                 requireValidProjection |= true;
9587             } else {
9588                 requireModifyRouting |= true;
9589             }
9590         }
9591 
9592         if (requireCaptureAudioOrMediaOutputPerm
9593                 && !callerHasPermission(android.Manifest.permission.CAPTURE_MEDIA_OUTPUT)
9594                 && !callerHasPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT)) {
9595             Log.e(TAG, "Privileged audio capture requires CAPTURE_MEDIA_OUTPUT or "
9596                       + "CAPTURE_AUDIO_OUTPUT system permission");
9597             return false;
9598         }
9599 
9600         if (voiceCommunicationCaptureMixes != null && voiceCommunicationCaptureMixes.size() > 0) {
9601             if (!callerHasPermission(
9602                     android.Manifest.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT)) {
9603                 Log.e(TAG, "Audio capture for voice communication requires "
9604                         + "CAPTURE_VOICE_COMMUNICATION_OUTPUT system permission");
9605                 return false;
9606             }
9607 
9608             // If permission check succeeded, we set the flag in each of the mixing rules
9609             for (AudioMix mix : voiceCommunicationCaptureMixes) {
9610                 mix.getRule().setVoiceCommunicationCaptureAllowed(true);
9611             }
9612         }
9613 
9614         if (requireValidProjection && !canProjectAudio(projection)) {
9615             return false;
9616         }
9617 
9618         if (requireModifyRouting
9619                 && !callerHasPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)) {
9620             Log.e(TAG, "Can not capture audio without MODIFY_AUDIO_ROUTING");
9621             return false;
9622         }
9623 
9624         return true;
9625     }
9626 
callerHasPermission(String permission)9627     private boolean callerHasPermission(String permission) {
9628         return mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED;
9629     }
9630 
9631     /** @return true if projection is a valid MediaProjection that can project audio. */
canProjectAudio(IMediaProjection projection)9632     private boolean canProjectAudio(IMediaProjection projection) {
9633         if (projection == null) {
9634             Log.e(TAG, "MediaProjection is null");
9635             return false;
9636         }
9637 
9638         IMediaProjectionManager projectionService = getProjectionService();
9639         if (projectionService == null) {
9640             Log.e(TAG, "Can't get service IMediaProjectionManager");
9641             return false;
9642         }
9643 
9644         try {
9645             if (!projectionService.isValidMediaProjection(projection)) {
9646                 Log.w(TAG, "App passed invalid MediaProjection token");
9647                 return false;
9648             }
9649         } catch (RemoteException e) {
9650             Log.e(TAG, "Can't call .isValidMediaProjection() on IMediaProjectionManager"
9651                     + projectionService.asBinder(), e);
9652             return false;
9653         }
9654 
9655         try {
9656             if (!projection.canProjectAudio()) {
9657                 Log.w(TAG, "App passed MediaProjection that can not project audio");
9658                 return false;
9659             }
9660         } catch (RemoteException e) {
9661             Log.e(TAG, "Can't call .canProjectAudio() on valid IMediaProjection"
9662                     + projection.asBinder(), e);
9663             return false;
9664         }
9665 
9666         return true;
9667     }
9668 
getProjectionService()9669     private IMediaProjectionManager getProjectionService() {
9670         if (mProjectionService == null) {
9671             IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE);
9672             mProjectionService = IMediaProjectionManager.Stub.asInterface(b);
9673         }
9674         return mProjectionService;
9675     }
9676 
9677     /**
9678      * See {@link AudioManager#unregisterAudioPolicyAsync(AudioPolicy)}
9679      * Declared oneway
9680      * @param pcb nullable because on service interface
9681      */
unregisterAudioPolicyAsync(@ullable IAudioPolicyCallback pcb)9682     public void unregisterAudioPolicyAsync(@Nullable IAudioPolicyCallback pcb) {
9683         if (pcb == null) {
9684             return;
9685         }
9686         unregisterAudioPolicyInt(pcb, "unregisterAudioPolicyAsync");
9687     }
9688 
9689     /**
9690      * See {@link AudioManager#unregisterAudioPolicy(AudioPolicy)}
9691      * @param pcb nullable because on service interface
9692      */
unregisterAudioPolicy(@ullable IAudioPolicyCallback pcb)9693     public void unregisterAudioPolicy(@Nullable IAudioPolicyCallback pcb) {
9694         if (pcb == null) {
9695             return;
9696         }
9697         unregisterAudioPolicyInt(pcb, "unregisterAudioPolicy");
9698     }
9699 
9700 
unregisterAudioPolicyInt(@onNull IAudioPolicyCallback pcb, String operationName)9701     private void unregisterAudioPolicyInt(@NonNull IAudioPolicyCallback pcb, String operationName) {
9702         mDynPolicyLogger.log((new AudioEventLogger.StringEvent(operationName + " for "
9703                 + pcb.asBinder()).printLog(TAG)));
9704         synchronized (mAudioPolicies) {
9705             AudioPolicyProxy app = mAudioPolicies.remove(pcb.asBinder());
9706             if (app == null) {
9707                 Slog.w(TAG, "Trying to unregister unknown audio policy for pid "
9708                         + Binder.getCallingPid() + " / uid " + Binder.getCallingUid());
9709                 return;
9710             } else {
9711                 pcb.asBinder().unlinkToDeath(app, 0/*flags*/);
9712             }
9713             app.release();
9714         }
9715         // TODO implement clearing mix attribute matching info in native audio policy
9716     }
9717 
9718     /**
9719      * Checks whether caller has MODIFY_AUDIO_ROUTING permission, and the policy is registered.
9720      * @param errorMsg log warning if permission check failed.
9721      * @return null if the operation on the audio mixes should be cancelled.
9722      */
9723     @GuardedBy("mAudioPolicies")
checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg)9724     private AudioPolicyProxy checkUpdateForPolicy(IAudioPolicyCallback pcb, String errorMsg) {
9725         // permission check
9726         final boolean hasPermissionForPolicy =
9727                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
9728                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
9729         if (!hasPermissionForPolicy) {
9730             Slog.w(TAG, errorMsg + " for pid " +
9731                     + Binder.getCallingPid() + " / uid "
9732                     + Binder.getCallingUid() + ", need MODIFY_AUDIO_ROUTING");
9733             return null;
9734         }
9735         // policy registered?
9736         final AudioPolicyProxy app = mAudioPolicies.get(pcb.asBinder());
9737         if (app == null) {
9738             Slog.w(TAG, errorMsg + " for pid " +
9739                     + Binder.getCallingPid() + " / uid "
9740                     + Binder.getCallingUid() + ", unregistered policy");
9741             return null;
9742         }
9743         return app;
9744     }
9745 
addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)9746     public int addMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) {
9747         if (DEBUG_AP) { Log.d(TAG, "addMixForPolicy for " + pcb.asBinder()
9748                 + " with config:" + policyConfig); }
9749         synchronized (mAudioPolicies) {
9750             final AudioPolicyProxy app =
9751                     checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy");
9752             if (app == null){
9753                 return AudioManager.ERROR;
9754             }
9755             return app.addMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS
9756                 ? AudioManager.SUCCESS : AudioManager.ERROR;
9757         }
9758     }
9759 
removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb)9760     public int removeMixForPolicy(AudioPolicyConfig policyConfig, IAudioPolicyCallback pcb) {
9761         if (DEBUG_AP) { Log.d(TAG, "removeMixForPolicy for " + pcb.asBinder()
9762                 + " with config:" + policyConfig); }
9763         synchronized (mAudioPolicies) {
9764             final AudioPolicyProxy app =
9765                     checkUpdateForPolicy(pcb, "Cannot add AudioMix in audio policy");
9766             if (app == null) {
9767                 return AudioManager.ERROR;
9768             }
9769             return app.removeMixes(policyConfig.getMixes()) == AudioSystem.SUCCESS
9770                 ? AudioManager.SUCCESS : AudioManager.ERROR;
9771         }
9772     }
9773 
9774     /** see AudioPolicy.setUidDeviceAffinity() */
setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)9775     public int setUidDeviceAffinity(IAudioPolicyCallback pcb, int uid,
9776             @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) {
9777         if (DEBUG_AP) {
9778             Log.d(TAG, "setUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid);
9779         }
9780         synchronized (mAudioPolicies) {
9781             final AudioPolicyProxy app =
9782                     checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy");
9783             if (app == null) {
9784                 return AudioManager.ERROR;
9785             }
9786             if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) {
9787                 return AudioManager.ERROR;
9788             }
9789             return app.setUidDeviceAffinities(uid, deviceTypes, deviceAddresses);
9790         }
9791     }
9792 
9793     /** see AudioPolicy.setUserIdDeviceAffinity() */
setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId, @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses)9794     public int setUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId,
9795             @NonNull int[] deviceTypes, @NonNull String[] deviceAddresses) {
9796         if (DEBUG_AP) {
9797             Log.d(TAG, "setUserIdDeviceAffinity for " + pcb.asBinder() + " user:" + userId);
9798         }
9799 
9800         synchronized (mAudioPolicies) {
9801             final AudioPolicyProxy app =
9802                     checkUpdateForPolicy(pcb, "Cannot change device affinity in audio policy");
9803             if (app == null) {
9804                 return AudioManager.ERROR;
9805             }
9806             if (!app.hasMixRoutedToDevices(deviceTypes, deviceAddresses)) {
9807                 return AudioManager.ERROR;
9808             }
9809             return app.setUserIdDeviceAffinities(userId, deviceTypes, deviceAddresses);
9810         }
9811     }
9812 
9813     /** see AudioPolicy.removeUidDeviceAffinity() */
removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid)9814     public int removeUidDeviceAffinity(IAudioPolicyCallback pcb, int uid) {
9815         if (DEBUG_AP) {
9816             Log.d(TAG, "removeUidDeviceAffinity for " + pcb.asBinder() + " uid:" + uid);
9817         }
9818         synchronized (mAudioPolicies) {
9819             final AudioPolicyProxy app =
9820                     checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy");
9821             if (app == null) {
9822                 return AudioManager.ERROR;
9823             }
9824             return app.removeUidDeviceAffinities(uid);
9825         }
9826     }
9827 
9828     /** see AudioPolicy.removeUserIdDeviceAffinity() */
removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId)9829     public int removeUserIdDeviceAffinity(IAudioPolicyCallback pcb, int userId) {
9830         if (DEBUG_AP) {
9831             Log.d(TAG, "removeUserIdDeviceAffinity for " + pcb.asBinder()
9832                     + " userId:" + userId);
9833         }
9834         synchronized (mAudioPolicies) {
9835             final AudioPolicyProxy app =
9836                     checkUpdateForPolicy(pcb, "Cannot remove device affinity in audio policy");
9837             if (app == null) {
9838                 return AudioManager.ERROR;
9839             }
9840             return app.removeUserIdDeviceAffinities(userId);
9841         }
9842     }
9843 
setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb)9844     public int setFocusPropertiesForPolicy(int duckingBehavior, IAudioPolicyCallback pcb) {
9845         if (DEBUG_AP) Log.d(TAG, "setFocusPropertiesForPolicy() duck behavior=" + duckingBehavior
9846                 + " policy " +  pcb.asBinder());
9847         synchronized (mAudioPolicies) {
9848             final AudioPolicyProxy app =
9849                     checkUpdateForPolicy(pcb, "Cannot change audio policy focus properties");
9850             if (app == null){
9851                 return AudioManager.ERROR;
9852             }
9853             if (!mAudioPolicies.containsKey(pcb.asBinder())) {
9854                 Slog.e(TAG, "Cannot change audio policy focus properties, unregistered policy");
9855                 return AudioManager.ERROR;
9856             }
9857             if (duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) {
9858                 // is there already one policy managing ducking?
9859                 for (AudioPolicyProxy policy : mAudioPolicies.values()) {
9860                     if (policy.mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) {
9861                         Slog.e(TAG, "Cannot change audio policy ducking behavior, already handled");
9862                         return AudioManager.ERROR;
9863                     }
9864                 }
9865             }
9866             app.mFocusDuckBehavior = duckingBehavior;
9867             mMediaFocusControl.setDuckingInExtPolicyAvailable(
9868                     duckingBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY);
9869         }
9870         return AudioManager.SUCCESS;
9871     }
9872 
9873     /** see AudioManager.hasRegisteredDynamicPolicy */
hasRegisteredDynamicPolicy()9874     public boolean hasRegisteredDynamicPolicy() {
9875         synchronized (mAudioPolicies) {
9876             return !mAudioPolicies.isEmpty();
9877         }
9878     }
9879 
9880     private final Object mExtVolumeControllerLock = new Object();
9881     private IAudioPolicyCallback mExtVolumeController;
setExtVolumeController(IAudioPolicyCallback apc)9882     private void setExtVolumeController(IAudioPolicyCallback apc) {
9883         if (!mContext.getResources().getBoolean(
9884                 com.android.internal.R.bool.config_handleVolumeKeysInWindowManager)) {
9885             Log.e(TAG, "Cannot set external volume controller: device not set for volume keys" +
9886                     " handled in PhoneWindowManager");
9887             return;
9888         }
9889         synchronized (mExtVolumeControllerLock) {
9890             if (mExtVolumeController != null && !mExtVolumeController.asBinder().pingBinder()) {
9891                 Log.e(TAG, "Cannot set external volume controller: existing controller");
9892             }
9893             mExtVolumeController = apc;
9894         }
9895     }
9896 
dumpAudioPolicies(PrintWriter pw)9897     private void dumpAudioPolicies(PrintWriter pw) {
9898         pw.println("\nAudio policies:");
9899         synchronized (mAudioPolicies) {
9900             for (AudioPolicyProxy policy : mAudioPolicies.values()) {
9901                 pw.println(policy.toLogFriendlyString());
9902             }
9903         }
9904     }
9905 
9906     //======================
9907     // Audio policy callbacks from AudioSystem for dynamic policies
9908     //======================
9909     private final AudioSystem.DynamicPolicyCallback mDynPolicyCallback =
9910             new AudioSystem.DynamicPolicyCallback() {
9911         public void onDynamicPolicyMixStateUpdate(String regId, int state) {
9912             if (!TextUtils.isEmpty(regId)) {
9913                 sendMsg(mAudioHandler, MSG_DYN_POLICY_MIX_STATE_UPDATE, SENDMSG_QUEUE,
9914                         state /*arg1*/, 0 /*arg2 ignored*/, regId /*obj*/, 0 /*delay*/);
9915             }
9916         }
9917     };
9918 
onDynPolicyMixStateUpdate(String regId, int state)9919     private void onDynPolicyMixStateUpdate(String regId, int state) {
9920         if (DEBUG_AP) Log.d(TAG, "onDynamicPolicyMixStateUpdate("+ regId + ", " + state +")");
9921         synchronized (mAudioPolicies) {
9922             for (AudioPolicyProxy policy : mAudioPolicies.values()) {
9923                 for (AudioMix mix : policy.getMixes()) {
9924                     if (mix.getRegistration().equals(regId)) {
9925                         try {
9926                             policy.mPolicyCallback.notifyMixStateUpdate(regId, state);
9927                         } catch (RemoteException e) {
9928                             Log.e(TAG, "Can't call notifyMixStateUpdate() on IAudioPolicyCallback "
9929                                     + policy.mPolicyCallback.asBinder(), e);
9930                         }
9931                         return;
9932                     }
9933                 }
9934             }
9935         }
9936     }
9937 
9938     //======================
9939     // Audio policy callbacks from AudioSystem for recording configuration updates
9940     //======================
9941     private final RecordingActivityMonitor mRecordMonitor;
9942 
registerRecordingCallback(IRecordingConfigDispatcher rcdb)9943     public void registerRecordingCallback(IRecordingConfigDispatcher rcdb) {
9944         final boolean isPrivileged =
9945                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
9946                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
9947         mRecordMonitor.registerRecordingCallback(rcdb, isPrivileged);
9948     }
9949 
unregisterRecordingCallback(IRecordingConfigDispatcher rcdb)9950     public void unregisterRecordingCallback(IRecordingConfigDispatcher rcdb) {
9951         mRecordMonitor.unregisterRecordingCallback(rcdb);
9952     }
9953 
getActiveRecordingConfigurations()9954     public List<AudioRecordingConfiguration> getActiveRecordingConfigurations() {
9955         final boolean isPrivileged =
9956                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
9957                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
9958         return mRecordMonitor.getActiveRecordingConfigurations(isPrivileged);
9959     }
9960 
9961     //======================
9962     // Audio recording state notification from clients
9963     //======================
9964     /**
9965      * Track a recorder provided by the client
9966      */
trackRecorder(IBinder recorder)9967     public int trackRecorder(IBinder recorder) {
9968         return mRecordMonitor.trackRecorder(recorder);
9969     }
9970 
9971     /**
9972      * Receive an event from the client about a tracked recorder
9973      */
recorderEvent(int riid, int event)9974     public void recorderEvent(int riid, int event) {
9975         mRecordMonitor.recorderEvent(riid, event);
9976     }
9977 
9978     /**
9979      * Stop tracking the recorder
9980      */
releaseRecorder(int riid)9981     public void releaseRecorder(int riid) {
9982         mRecordMonitor.releaseRecorder(riid);
9983     }
9984 
disableRingtoneSync(final int userId)9985     public void disableRingtoneSync(final int userId) {
9986         final int callingUserId = UserHandle.getCallingUserId();
9987         if (callingUserId != userId) {
9988             mContext.enforceCallingOrSelfPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9989                     "disable sound settings syncing for another profile");
9990         }
9991         final long token = Binder.clearCallingIdentity();
9992         try {
9993             // Disable the sync setting so the profile uses its own sound settings.
9994             Settings.Secure.putIntForUser(mContentResolver, Settings.Secure.SYNC_PARENT_SOUNDS,
9995                     0 /* false */, userId);
9996         } finally {
9997             Binder.restoreCallingIdentity(token);
9998         }
9999     }
10000 
10001     //======================
10002     // Audio playback notification
10003     //======================
10004     private final PlaybackActivityMonitor mPlaybackMonitor;
10005 
registerPlaybackCallback(IPlaybackConfigDispatcher pcdb)10006     public void registerPlaybackCallback(IPlaybackConfigDispatcher pcdb) {
10007         final boolean isPrivileged =
10008                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
10009                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
10010         mPlaybackMonitor.registerPlaybackCallback(pcdb, isPrivileged);
10011     }
10012 
unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb)10013     public void unregisterPlaybackCallback(IPlaybackConfigDispatcher pcdb) {
10014         mPlaybackMonitor.unregisterPlaybackCallback(pcdb);
10015     }
10016 
getActivePlaybackConfigurations()10017     public List<AudioPlaybackConfiguration> getActivePlaybackConfigurations() {
10018         final boolean isPrivileged =
10019                 (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
10020                         android.Manifest.permission.MODIFY_AUDIO_ROUTING));
10021         return mPlaybackMonitor.getActivePlaybackConfigurations(isPrivileged);
10022     }
10023 
trackPlayer(PlayerBase.PlayerIdCard pic)10024     public int trackPlayer(PlayerBase.PlayerIdCard pic) {
10025         if (pic != null && pic.mAttributes != null) {
10026             validateAudioAttributesUsage(pic.mAttributes);
10027         }
10028         return mPlaybackMonitor.trackPlayer(pic);
10029     }
10030 
playerAttributes(int piid, AudioAttributes attr)10031     public void playerAttributes(int piid, AudioAttributes attr) {
10032         if (attr != null) {
10033             validateAudioAttributesUsage(attr);
10034         }
10035         mPlaybackMonitor.playerAttributes(piid, attr, Binder.getCallingUid());
10036     }
10037 
10038     /**
10039      * Update player session ID
10040      * @param piid Player id to update
10041      * @param sessionId The new audio session ID
10042      */
playerSessionId(int piid, int sessionId)10043     public void playerSessionId(int piid, int sessionId) {
10044         if (sessionId <= AudioSystem.AUDIO_SESSION_ALLOCATE) {
10045             throw new IllegalArgumentException("invalid session Id " + sessionId);
10046         }
10047         mPlaybackMonitor.playerSessionId(piid, sessionId, Binder.getCallingUid());
10048     }
10049 
10050     /**
10051      * Update player event
10052      * @param piid Player id to update
10053      * @param event The new player event
10054      * @param deviceId The new player device id
10055      */
playerEvent(int piid, int event, int deviceId)10056     public void playerEvent(int piid, int event, int deviceId) {
10057         mPlaybackMonitor.playerEvent(piid, event, deviceId, Binder.getCallingUid());
10058     }
10059 
playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio)10060     public void playerHasOpPlayAudio(int piid, boolean hasOpPlayAudio) {
10061         mPlaybackMonitor.playerHasOpPlayAudio(piid, hasOpPlayAudio, Binder.getCallingUid());
10062     }
10063 
releasePlayer(int piid)10064     public void releasePlayer(int piid) {
10065         mPlaybackMonitor.releasePlayer(piid, Binder.getCallingUid());
10066     }
10067 
10068     /**
10069      * Specifies whether the audio played by this app may or may not be captured by other apps or
10070      * the system.
10071      *
10072      * @param capturePolicy one of
10073      *     {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL},
10074      *     {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM},
10075      *     {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}.
10076      * @return AudioSystem.AUDIO_STATUS_OK if set allowed capture policy succeed.
10077      * @throws IllegalArgumentException if the argument is not a valid value.
10078      */
setAllowedCapturePolicy(int capturePolicy)10079     public int setAllowedCapturePolicy(int capturePolicy) {
10080         int callingUid = Binder.getCallingUid();
10081         int flags = AudioAttributes.capturePolicyToFlags(capturePolicy, 0x0);
10082         final long identity = Binder.clearCallingIdentity();
10083         synchronized (mPlaybackMonitor) {
10084             int result = mAudioSystem.setAllowedCapturePolicy(callingUid, flags);
10085             if (result == AudioSystem.AUDIO_STATUS_OK) {
10086                 mPlaybackMonitor.setAllowedCapturePolicy(callingUid, capturePolicy);
10087             }
10088             Binder.restoreCallingIdentity(identity);
10089             return result;
10090         }
10091     }
10092 
10093     /**
10094      * Return the capture policy.
10095      * @return the cached capture policy for the calling uid.
10096      */
getAllowedCapturePolicy()10097     public int getAllowedCapturePolicy() {
10098         int callingUid = Binder.getCallingUid();
10099         final long identity = Binder.clearCallingIdentity();
10100         int capturePolicy = mPlaybackMonitor.getAllowedCapturePolicy(callingUid);
10101         Binder.restoreCallingIdentity(identity);
10102         return capturePolicy;
10103     }
10104 
10105     //======================
10106     // Audio device management
10107     //======================
10108     private final AudioDeviceBroker mDeviceBroker;
10109 
10110     //======================
10111     // Audio policy proxy
10112     //======================
10113     private static final class AudioDeviceArray {
10114         final @NonNull int[] mDeviceTypes;
10115         final @NonNull String[] mDeviceAddresses;
AudioDeviceArray(@onNull int[] types, @NonNull String[] addresses)10116         AudioDeviceArray(@NonNull int[] types,  @NonNull String[] addresses) {
10117             mDeviceTypes = types;
10118             mDeviceAddresses = addresses;
10119         }
10120     }
10121 
10122     /**
10123      * This internal class inherits from AudioPolicyConfig, each instance contains all the
10124      * mixes of an AudioPolicy and their configurations.
10125      */
10126     public class AudioPolicyProxy extends AudioPolicyConfig implements IBinder.DeathRecipient {
10127         private static final String TAG = "AudioPolicyProxy";
10128         final IAudioPolicyCallback mPolicyCallback;
10129         final boolean mHasFocusListener;
10130         final boolean mIsVolumeController;
10131         final HashMap<Integer, AudioDeviceArray> mUidDeviceAffinities =
10132                 new HashMap<Integer, AudioDeviceArray>();
10133 
10134         final HashMap<Integer, AudioDeviceArray> mUserIdDeviceAffinities =
10135                 new HashMap<>();
10136 
10137         final IMediaProjection mProjection;
10138         private final class UnregisterOnStopCallback extends IMediaProjectionCallback.Stub {
onStop()10139             public void onStop() {
10140                 unregisterAudioPolicyAsync(mPolicyCallback);
10141             }
10142         };
10143         UnregisterOnStopCallback mProjectionCallback;
10144 
10145         /**
10146          * Audio focus ducking behavior for an audio policy.
10147          * This variable reflects the value that was successfully set in
10148          * {@link AudioService#setFocusPropertiesForPolicy(int, IAudioPolicyCallback)}. This
10149          * implies that a value of FOCUS_POLICY_DUCKING_IN_POLICY means the corresponding policy
10150          * is handling ducking for audio focus.
10151          */
10152         int mFocusDuckBehavior = AudioPolicy.FOCUS_POLICY_DUCKING_DEFAULT;
10153         boolean mIsFocusPolicy = false;
10154         boolean mIsTestFocusPolicy = false;
10155 
AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token, boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy, boolean isVolumeController, IMediaProjection projection)10156         AudioPolicyProxy(AudioPolicyConfig config, IAudioPolicyCallback token,
10157                 boolean hasFocusListener, boolean isFocusPolicy, boolean isTestFocusPolicy,
10158                 boolean isVolumeController, IMediaProjection projection) {
10159             super(config);
10160             setRegistration(new String(config.hashCode() + ":ap:" + mAudioPolicyCounter++));
10161             mPolicyCallback = token;
10162             mHasFocusListener = hasFocusListener;
10163             mIsVolumeController = isVolumeController;
10164             mProjection = projection;
10165             if (mHasFocusListener) {
10166                 mMediaFocusControl.addFocusFollower(mPolicyCallback);
10167                 // can only ever be true if there is a focus listener
10168                 if (isFocusPolicy) {
10169                     mIsFocusPolicy = true;
10170                     mIsTestFocusPolicy = isTestFocusPolicy;
10171                     mMediaFocusControl.setFocusPolicy(mPolicyCallback, mIsTestFocusPolicy);
10172                 }
10173             }
10174             if (mIsVolumeController) {
10175                 setExtVolumeController(mPolicyCallback);
10176             }
10177             if (mProjection != null) {
10178                 mProjectionCallback = new UnregisterOnStopCallback();
10179                 try {
10180                     mProjection.registerCallback(mProjectionCallback);
10181                 } catch (RemoteException e) {
10182                     release();
10183                     throw new IllegalStateException("MediaProjection callback registration failed, "
10184                             + "could not link to " + projection + " binder death", e);
10185                 }
10186             }
10187             int status = connectMixes();
10188             if (status != AudioSystem.SUCCESS) {
10189                 release();
10190                 throw new IllegalStateException("Could not connect mix, error: " + status);
10191             }
10192         }
10193 
binderDied()10194         public void binderDied() {
10195             mDynPolicyLogger.log((new AudioEventLogger.StringEvent("AudioPolicy "
10196                     + mPolicyCallback.asBinder() + " died").printLog(TAG)));
10197             release();
10198         }
10199 
getRegistrationId()10200         String getRegistrationId() {
10201             return getRegistration();
10202         }
10203 
release()10204         void release() {
10205             if (mIsFocusPolicy) {
10206                 mMediaFocusControl.unsetFocusPolicy(mPolicyCallback, mIsTestFocusPolicy);
10207             }
10208             if (mFocusDuckBehavior == AudioPolicy.FOCUS_POLICY_DUCKING_IN_POLICY) {
10209                 mMediaFocusControl.setDuckingInExtPolicyAvailable(false);
10210             }
10211             if (mHasFocusListener) {
10212                 mMediaFocusControl.removeFocusFollower(mPolicyCallback);
10213             }
10214             if (mProjectionCallback != null) {
10215                 try {
10216                     mProjection.unregisterCallback(mProjectionCallback);
10217                 } catch (RemoteException e) {
10218                     Log.e(TAG, "Fail to unregister Audiopolicy callback from MediaProjection");
10219                 }
10220             }
10221             if (mIsVolumeController) {
10222                 synchronized (mExtVolumeControllerLock) {
10223                     mExtVolumeController = null;
10224                 }
10225             }
10226             final long identity = Binder.clearCallingIdentity();
10227             mAudioSystem.registerPolicyMixes(mMixes, false);
10228             Binder.restoreCallingIdentity(identity);
10229             synchronized (mAudioPolicies) {
10230                 mAudioPolicies.remove(mPolicyCallback.asBinder());
10231             }
10232             try {
10233                 mPolicyCallback.notifyUnregistration();
10234             } catch (RemoteException e) { }
10235         }
10236 
hasMixAffectingUsage(int usage, int excludedFlags)10237         boolean hasMixAffectingUsage(int usage, int excludedFlags) {
10238             for (AudioMix mix : mMixes) {
10239                 if (mix.isAffectingUsage(usage)
10240                         && ((mix.getRouteFlags() & excludedFlags) != excludedFlags)) {
10241                     return true;
10242                 }
10243             }
10244             return false;
10245         }
10246 
10247         // Verify all the devices in the array are served by mixes defined in this policy
hasMixRoutedToDevices(@onNull int[] deviceTypes, @NonNull String[] deviceAddresses)10248         boolean hasMixRoutedToDevices(@NonNull int[] deviceTypes,
10249                 @NonNull String[] deviceAddresses) {
10250             for (int i = 0; i < deviceTypes.length; i++) {
10251                 boolean hasDevice = false;
10252                 for (AudioMix mix : mMixes) {
10253                     // this will check both that the mix has ROUTE_FLAG_RENDER and the device
10254                     // is reached by this mix
10255                     if (mix.isRoutedToDevice(deviceTypes[i], deviceAddresses[i])) {
10256                         hasDevice = true;
10257                         break;
10258                     }
10259                 }
10260                 if (!hasDevice) {
10261                     return false;
10262                 }
10263             }
10264             return true;
10265         }
10266 
addMixes(@onNull ArrayList<AudioMix> mixes)10267         int addMixes(@NonNull ArrayList<AudioMix> mixes) {
10268             // TODO optimize to not have to unregister the mixes already in place
10269             synchronized (mMixes) {
10270                 mAudioSystem.registerPolicyMixes(mMixes, false);
10271                 this.add(mixes);
10272                 return mAudioSystem.registerPolicyMixes(mMixes, true);
10273             }
10274         }
10275 
removeMixes(@onNull ArrayList<AudioMix> mixes)10276         int removeMixes(@NonNull ArrayList<AudioMix> mixes) {
10277             // TODO optimize to not have to unregister the mixes already in place
10278             synchronized (mMixes) {
10279                 mAudioSystem.registerPolicyMixes(mMixes, false);
10280                 this.remove(mixes);
10281                 return mAudioSystem.registerPolicyMixes(mMixes, true);
10282             }
10283         }
10284 
connectMixes()10285         @AudioSystem.AudioSystemError int connectMixes() {
10286             final long identity = Binder.clearCallingIdentity();
10287             int status = mAudioSystem.registerPolicyMixes(mMixes, true);
10288             Binder.restoreCallingIdentity(identity);
10289             return status;
10290         }
10291 
setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses)10292         int setUidDeviceAffinities(int uid, @NonNull int[] types, @NonNull String[] addresses) {
10293             final Integer Uid = new Integer(uid);
10294             if (mUidDeviceAffinities.remove(Uid) != null) {
10295                 if (removeUidDeviceAffinitiesFromSystem(uid) != AudioSystem.SUCCESS) {
10296                     Log.e(TAG, "AudioSystem. removeUidDeviceAffinities(" + uid + ") failed, "
10297                             + " cannot call AudioSystem.setUidDeviceAffinities");
10298                     return AudioManager.ERROR;
10299                 }
10300             }
10301             AudioDeviceArray deviceArray = new AudioDeviceArray(types, addresses);
10302             if (setUidDeviceAffinitiesOnSystem(uid, deviceArray) == AudioSystem.SUCCESS) {
10303                 mUidDeviceAffinities.put(Uid, deviceArray);
10304                 return AudioManager.SUCCESS;
10305             }
10306             Log.e(TAG, "AudioSystem. setUidDeviceAffinities(" + uid + ") failed");
10307             return AudioManager.ERROR;
10308         }
10309 
removeUidDeviceAffinities(int uid)10310         int removeUidDeviceAffinities(int uid) {
10311             if (mUidDeviceAffinities.remove(new Integer(uid)) != null) {
10312                 if (removeUidDeviceAffinitiesFromSystem(uid) == AudioSystem.SUCCESS) {
10313                     return AudioManager.SUCCESS;
10314                 }
10315             }
10316             Log.e(TAG, "AudioSystem. removeUidDeviceAffinities failed");
10317             return AudioManager.ERROR;
10318         }
10319 
removeUidDeviceAffinitiesFromSystem(int uid)10320         @AudioSystem.AudioSystemError private int removeUidDeviceAffinitiesFromSystem(int uid) {
10321             final long identity = Binder.clearCallingIdentity();
10322             try {
10323                 return mAudioSystem.removeUidDeviceAffinities(uid);
10324             } finally {
10325                 Binder.restoreCallingIdentity(identity);
10326             }
10327         }
10328 
setUidDeviceAffinitiesOnSystem(int uid, AudioDeviceArray deviceArray)10329         @AudioSystem.AudioSystemError private int setUidDeviceAffinitiesOnSystem(int uid,
10330                 AudioDeviceArray deviceArray) {
10331             final long identity = Binder.clearCallingIdentity();
10332             try {
10333                 return mAudioSystem.setUidDeviceAffinities(uid, deviceArray.mDeviceTypes,
10334                         deviceArray.mDeviceAddresses);
10335             } finally {
10336                 Binder.restoreCallingIdentity(identity);
10337             }
10338         }
10339 
setUserIdDeviceAffinities(int userId, @NonNull int[] types, @NonNull String[] addresses)10340         int setUserIdDeviceAffinities(int userId,
10341                 @NonNull int[] types, @NonNull String[] addresses) {
10342             final Integer UserId = new Integer(userId);
10343             if (mUserIdDeviceAffinities.remove(UserId) != null) {
10344                 if (removeUserIdDeviceAffinitiesFromSystem(userId) != AudioSystem.SUCCESS) {
10345                     Log.e(TAG, "AudioSystem. removeUserIdDeviceAffinities("
10346                             + UserId + ") failed, "
10347                             + " cannot call AudioSystem.setUserIdDeviceAffinities");
10348                     return AudioManager.ERROR;
10349                 }
10350             }
10351             AudioDeviceArray audioDeviceArray = new AudioDeviceArray(types, addresses);
10352             if (setUserIdDeviceAffinitiesOnSystem(userId, audioDeviceArray)
10353                     == AudioSystem.SUCCESS) {
10354                 mUserIdDeviceAffinities.put(UserId, audioDeviceArray);
10355                 return AudioManager.SUCCESS;
10356             }
10357             Log.e(TAG, "AudioSystem.setUserIdDeviceAffinities(" + userId + ") failed");
10358             return AudioManager.ERROR;
10359         }
10360 
removeUserIdDeviceAffinities(int userId)10361         int removeUserIdDeviceAffinities(int userId) {
10362             if (mUserIdDeviceAffinities.remove(new Integer(userId)) != null) {
10363                 if (removeUserIdDeviceAffinitiesFromSystem(userId) == AudioSystem.SUCCESS) {
10364                     return AudioManager.SUCCESS;
10365                 }
10366             }
10367             Log.e(TAG, "AudioSystem.removeUserIdDeviceAffinities failed");
10368             return AudioManager.ERROR;
10369         }
10370 
removeUserIdDeviceAffinitiesFromSystem( @serIdInt int userId)10371         @AudioSystem.AudioSystemError private int removeUserIdDeviceAffinitiesFromSystem(
10372                 @UserIdInt int userId) {
10373             final long identity = Binder.clearCallingIdentity();
10374             try {
10375                 return mAudioSystem.removeUserIdDeviceAffinities(userId);
10376             } finally {
10377                 Binder.restoreCallingIdentity(identity);
10378             }
10379         }
10380 
setUserIdDeviceAffinitiesOnSystem( @serIdInt int userId, AudioDeviceArray deviceArray)10381         @AudioSystem.AudioSystemError private int setUserIdDeviceAffinitiesOnSystem(
10382                 @UserIdInt int userId, AudioDeviceArray deviceArray) {
10383             final long identity = Binder.clearCallingIdentity();
10384             try {
10385                 return mAudioSystem.setUserIdDeviceAffinities(userId, deviceArray.mDeviceTypes,
10386                         deviceArray.mDeviceAddresses);
10387             } finally {
10388                 Binder.restoreCallingIdentity(identity);
10389             }
10390         }
10391 
setupDeviceAffinities()10392         @AudioSystem.AudioSystemError int setupDeviceAffinities() {
10393             for (Map.Entry<Integer, AudioDeviceArray> uidEntry : mUidDeviceAffinities.entrySet()) {
10394                 int uidStatus = removeUidDeviceAffinitiesFromSystem(uidEntry.getKey());
10395                 if (uidStatus != AudioSystem.SUCCESS) {
10396                     Log.e(TAG,
10397                             "setupDeviceAffinities failed to remove device affinity for uid "
10398                                     + uidEntry.getKey());
10399                     return uidStatus;
10400                 }
10401                 uidStatus = setUidDeviceAffinitiesOnSystem(uidEntry.getKey(), uidEntry.getValue());
10402                 if (uidStatus != AudioSystem.SUCCESS) {
10403                     Log.e(TAG,
10404                             "setupDeviceAffinities failed to set device affinity for uid "
10405                                     + uidEntry.getKey());
10406                     return uidStatus;
10407                 }
10408             }
10409 
10410             for (Map.Entry<Integer, AudioDeviceArray> userIdEntry :
10411                     mUserIdDeviceAffinities.entrySet()) {
10412                 int userIdStatus = removeUserIdDeviceAffinitiesFromSystem(userIdEntry.getKey());
10413                 if (userIdStatus != AudioSystem.SUCCESS) {
10414                     Log.e(TAG,
10415                             "setupDeviceAffinities failed to remove device affinity for userId "
10416                                     + userIdEntry.getKey());
10417                     return userIdStatus;
10418                 }
10419                 userIdStatus = setUserIdDeviceAffinitiesOnSystem(userIdEntry.getKey(),
10420                                 userIdEntry.getValue());
10421                 if (userIdStatus != AudioSystem.SUCCESS) {
10422                     Log.e(TAG,
10423                             "setupDeviceAffinities failed to set device affinity for userId "
10424                                     + userIdEntry.getKey());
10425                     return userIdStatus;
10426                 }
10427             }
10428             return AudioSystem.SUCCESS;
10429         }
10430 
10431         /** @return human readable debug informations summarizing the state of the object. */
toLogFriendlyString()10432         public String toLogFriendlyString() {
10433             String textDump = super.toLogFriendlyString();
10434             textDump += " Uid Device Affinities:\n";
10435             String spacer = "     ";
10436             textDump += logFriendlyAttributeDeviceArrayMap("Uid",
10437                     mUidDeviceAffinities, spacer);
10438             textDump += " UserId Device Affinities:\n";
10439             textDump += logFriendlyAttributeDeviceArrayMap("UserId",
10440                     mUserIdDeviceAffinities, spacer);
10441             textDump += " Proxy:\n";
10442             textDump += "   is focus policy= " + mIsFocusPolicy + "\n";
10443             if (mIsFocusPolicy) {
10444                 textDump += "     focus duck behaviour= " + mFocusDuckBehavior + "\n";
10445                 textDump += "     is test focus policy= " + mIsTestFocusPolicy + "\n";
10446                 textDump += "     has focus listener= " + mHasFocusListener  + "\n";
10447             }
10448             textDump += "   media projection= " + mProjection + "\n";
10449             return textDump;
10450         }
10451 
logFriendlyAttributeDeviceArrayMap(String attribute, Map<Integer, AudioDeviceArray> map, String spacer)10452         private String logFriendlyAttributeDeviceArrayMap(String attribute,
10453                 Map<Integer, AudioDeviceArray> map, String spacer) {
10454             final StringBuilder stringBuilder = new StringBuilder();
10455             for (Map.Entry<Integer, AudioDeviceArray> mapEntry : map.entrySet()) {
10456                 stringBuilder.append(spacer).append(attribute).append(": ")
10457                         .append(mapEntry.getKey()).append("\n");
10458                 AudioDeviceArray deviceArray = mapEntry.getValue();
10459                 String deviceSpacer = spacer + "   ";
10460                 for (int i = 0; i < deviceArray.mDeviceTypes.length; i++) {
10461                     stringBuilder.append(deviceSpacer).append("Type: 0x")
10462                             .append(Integer.toHexString(deviceArray.mDeviceTypes[i]))
10463                             .append(" Address: ").append(deviceArray.mDeviceAddresses[i])
10464                                     .append("\n");
10465                 }
10466             }
10467             return stringBuilder.toString();
10468         }
10469     };
10470 
10471     //======================
10472     // Audio policy: focus
10473     //======================
10474     /**  */
dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb)10475     public int dispatchFocusChange(AudioFocusInfo afi, int focusChange, IAudioPolicyCallback pcb) {
10476         if (afi == null) {
10477             throw new IllegalArgumentException("Illegal null AudioFocusInfo");
10478         }
10479         if (pcb == null) {
10480             throw new IllegalArgumentException("Illegal null AudioPolicy callback");
10481         }
10482         synchronized (mAudioPolicies) {
10483             if (!mAudioPolicies.containsKey(pcb.asBinder())) {
10484                 throw new IllegalStateException("Unregistered AudioPolicy for focus dispatch");
10485             }
10486             return mMediaFocusControl.dispatchFocusChange(afi, focusChange);
10487         }
10488     }
10489 
setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult, IAudioPolicyCallback pcb)10490     public void setFocusRequestResultFromExtPolicy(AudioFocusInfo afi, int requestResult,
10491             IAudioPolicyCallback pcb) {
10492         if (afi == null) {
10493             throw new IllegalArgumentException("Illegal null AudioFocusInfo");
10494         }
10495         if (pcb == null) {
10496             throw new IllegalArgumentException("Illegal null AudioPolicy callback");
10497         }
10498         synchronized (mAudioPolicies) {
10499             if (!mAudioPolicies.containsKey(pcb.asBinder())) {
10500                 throw new IllegalStateException("Unregistered AudioPolicy for external focus");
10501             }
10502             mMediaFocusControl.setFocusRequestResultFromExtPolicy(afi, requestResult);
10503         }
10504     }
10505 
10506 
10507     //======================
10508     // Audioserver state dispatch
10509     //======================
10510     private class AsdProxy implements IBinder.DeathRecipient {
10511         private final IAudioServerStateDispatcher mAsd;
10512 
AsdProxy(IAudioServerStateDispatcher asd)10513         AsdProxy(IAudioServerStateDispatcher asd) {
10514             mAsd = asd;
10515         }
10516 
binderDied()10517         public void binderDied() {
10518             synchronized (mAudioServerStateListeners) {
10519                 mAudioServerStateListeners.remove(mAsd.asBinder());
10520             }
10521         }
10522 
callback()10523         IAudioServerStateDispatcher callback() {
10524             return mAsd;
10525         }
10526     }
10527 
10528     private final HashMap<IBinder, AsdProxy> mAudioServerStateListeners =
10529             new HashMap<IBinder, AsdProxy>();
10530 
checkMonitorAudioServerStatePermission()10531     private void checkMonitorAudioServerStatePermission() {
10532         if (!(mContext.checkCallingOrSelfPermission(
10533                     android.Manifest.permission.MODIFY_PHONE_STATE) ==
10534                 PackageManager.PERMISSION_GRANTED ||
10535               mContext.checkCallingOrSelfPermission(
10536                     android.Manifest.permission.MODIFY_AUDIO_ROUTING) ==
10537                 PackageManager.PERMISSION_GRANTED)) {
10538             throw new SecurityException("Not allowed to monitor audioserver state");
10539         }
10540     }
10541 
registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd)10542     public void registerAudioServerStateDispatcher(IAudioServerStateDispatcher asd) {
10543         checkMonitorAudioServerStatePermission();
10544         synchronized (mAudioServerStateListeners) {
10545             if (mAudioServerStateListeners.containsKey(asd.asBinder())) {
10546                 Slog.w(TAG, "Cannot re-register audio server state dispatcher");
10547                 return;
10548             }
10549             AsdProxy asdp = new AsdProxy(asd);
10550             try {
10551                 asd.asBinder().linkToDeath(asdp, 0/*flags*/);
10552             } catch (RemoteException e) {
10553 
10554             }
10555             mAudioServerStateListeners.put(asd.asBinder(), asdp);
10556         }
10557     }
10558 
unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd)10559     public void unregisterAudioServerStateDispatcher(IAudioServerStateDispatcher asd) {
10560         checkMonitorAudioServerStatePermission();
10561         synchronized (mAudioServerStateListeners) {
10562             AsdProxy asdp = mAudioServerStateListeners.remove(asd.asBinder());
10563             if (asdp == null) {
10564                 Slog.w(TAG, "Trying to unregister unknown audioserver state dispatcher for pid "
10565                         + Binder.getCallingPid() + " / uid " + Binder.getCallingUid());
10566                 return;
10567             } else {
10568                 asd.asBinder().unlinkToDeath(asdp, 0/*flags*/);
10569             }
10570         }
10571     }
10572 
isAudioServerRunning()10573     public boolean isAudioServerRunning() {
10574         checkMonitorAudioServerStatePermission();
10575         return (AudioSystem.checkAudioFlinger() == AudioSystem.AUDIO_STATUS_OK);
10576     }
10577 
10578     //======================
10579     // Audio HAL process dump
10580     //======================
10581 
10582     private static final String AUDIO_HAL_SERVICE_PREFIX = "android.hardware.audio";
10583 
getAudioHalPids()10584     private Set<Integer> getAudioHalPids() {
10585         try {
10586             IServiceManager serviceManager = IServiceManager.getService();
10587             ArrayList<IServiceManager.InstanceDebugInfo> dump =
10588                     serviceManager.debugDump();
10589             HashSet<Integer> pids = new HashSet<>();
10590             for (IServiceManager.InstanceDebugInfo info : dump) {
10591                 if (info.pid != IServiceManager.PidConstant.NO_PID
10592                         && info.interfaceName != null
10593                         && info.interfaceName.startsWith(AUDIO_HAL_SERVICE_PREFIX)) {
10594                     pids.add(info.pid);
10595                 }
10596             }
10597             return pids;
10598         } catch (RemoteException e) {
10599             return new HashSet<Integer>();
10600         }
10601     }
10602 
updateAudioHalPids()10603     private void updateAudioHalPids() {
10604         Set<Integer> pidsSet = getAudioHalPids();
10605         if (pidsSet.isEmpty()) {
10606             Slog.w(TAG, "Could not retrieve audio HAL service pids");
10607             return;
10608         }
10609         int[] pidsArray = pidsSet.stream().mapToInt(Integer::intValue).toArray();
10610         AudioSystem.setAudioHalPids(pidsArray);
10611     }
10612 
10613     //======================
10614     // Multi Audio Focus
10615     //======================
setMultiAudioFocusEnabled(boolean enabled)10616     public void setMultiAudioFocusEnabled(boolean enabled) {
10617         enforceModifyAudioRoutingPermission();
10618         if (mMediaFocusControl != null) {
10619             boolean mafEnabled = mMediaFocusControl.getMultiAudioFocusEnabled();
10620             if (mafEnabled != enabled) {
10621                 mMediaFocusControl.updateMultiAudioFocus(enabled);
10622                 if (!enabled) {
10623                     mDeviceBroker.postBroadcastBecomingNoisy();
10624                 }
10625             }
10626         }
10627     }
10628 
10629     /**
10630      * @hide
10631      * Sets an additional audio output device delay in milliseconds.
10632      *
10633      * The additional output delay is a request to the output device to
10634      * delay audio presentation (generally with respect to video presentation for better
10635      * synchronization).
10636      * It may not be supported by all output devices,
10637      * and typically increases the audio latency by the amount of additional
10638      * audio delay requested.
10639      *
10640      * If additional audio delay is supported by an audio output device,
10641      * it is expected to be supported for all output streams (and configurations)
10642      * opened on that device.
10643      *
10644      * @param deviceType
10645      * @param address
10646      * @param delayMillis delay in milliseconds desired.  This should be in range of {@code 0}
10647      *     to the value returned by {@link #getMaxAdditionalOutputDeviceDelay()}.
10648      * @return true if successful, false if the device does not support output device delay
10649      *     or the delay is not in range of {@link #getMaxAdditionalOutputDeviceDelay()}.
10650      */
10651     @Override
10652     //@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
setAdditionalOutputDeviceDelay( @onNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis)10653     public boolean setAdditionalOutputDeviceDelay(
10654             @NonNull AudioDeviceAttributes device, @IntRange(from = 0) long delayMillis) {
10655         Objects.requireNonNull(device, "device must not be null");
10656         enforceModifyAudioRoutingPermission();
10657         final String getterKey = "additional_output_device_delay="
10658                 + device.getInternalType() + "," + device.getAddress(); // "getter" key as an id.
10659         final String setterKey = getterKey + "," + delayMillis;     // append the delay for setter
10660         return mRestorableParameters.setParameters(getterKey, setterKey)
10661                 == AudioSystem.AUDIO_STATUS_OK;
10662     }
10663 
10664     /**
10665      * @hide
10666      * Returns the current additional audio output device delay in milliseconds.
10667      *
10668      * @param deviceType
10669      * @param address
10670      * @return the additional output device delay. This is a non-negative number.
10671      *     {@code 0} is returned if unsupported.
10672      */
10673     @Override
10674     @IntRange(from = 0)
getAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)10675     public long getAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) {
10676         Objects.requireNonNull(device, "device must not be null");
10677         final String key = "additional_output_device_delay";
10678         final String reply = AudioSystem.getParameters(
10679                 key + "=" + device.getInternalType() + "," + device.getAddress());
10680         long delayMillis;
10681         try {
10682             delayMillis = Long.parseLong(reply.substring(key.length() + 1));
10683         } catch (NullPointerException e) {
10684             delayMillis = 0;
10685         }
10686         return delayMillis;
10687     }
10688 
10689     /**
10690      * @hide
10691      * Returns the maximum additional audio output device delay in milliseconds.
10692      *
10693      * @param deviceType
10694      * @param address
10695      * @return the maximum output device delay in milliseconds that can be set.
10696      *     This is a non-negative number
10697      *     representing the additional audio delay supported for the device.
10698      *     {@code 0} is returned if unsupported.
10699      */
10700     @Override
10701     @IntRange(from = 0)
getMaxAdditionalOutputDeviceDelay(@onNull AudioDeviceAttributes device)10702     public long getMaxAdditionalOutputDeviceDelay(@NonNull AudioDeviceAttributes device) {
10703         Objects.requireNonNull(device, "device must not be null");
10704         final String key = "max_additional_output_device_delay";
10705         final String reply = AudioSystem.getParameters(
10706                 key + "=" + device.getInternalType() + "," + device.getAddress());
10707         long delayMillis;
10708         try {
10709             delayMillis = Long.parseLong(reply.substring(key.length() + 1));
10710         } catch (NullPointerException e) {
10711             delayMillis = 0;
10712         }
10713         return delayMillis;
10714     }
10715 
10716     //======================
10717     // misc
10718     //======================
10719     private final HashMap<IBinder, AudioPolicyProxy> mAudioPolicies =
10720             new HashMap<IBinder, AudioPolicyProxy>();
10721     @GuardedBy("mAudioPolicies")
10722     private int mAudioPolicyCounter = 0;
10723 
10724     //======================
10725     // Helper functions for full and fixed volume device
10726     //======================
isFixedVolumeDevice(int deviceType)10727     private boolean isFixedVolumeDevice(int deviceType) {
10728         if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX
10729                 && mRecordMonitor.isLegacyRemoteSubmixActive()) {
10730             return false;
10731         }
10732         return mFixedVolumeDevices.contains(deviceType);
10733     }
10734 
isFullVolumeDevice(int deviceType)10735     private boolean isFullVolumeDevice(int deviceType) {
10736         if (deviceType == AudioSystem.DEVICE_OUT_REMOTE_SUBMIX
10737                 && mRecordMonitor.isLegacyRemoteSubmixActive()) {
10738             return false;
10739         }
10740         return mFullVolumeDevices.contains(deviceType);
10741     }
10742 
10743     //====================
10744     // Helper functions for {set,get}DeviceVolumeBehavior
10745     //====================
getSettingsNameForDeviceVolumeBehavior(int deviceType)10746     private static String getSettingsNameForDeviceVolumeBehavior(int deviceType) {
10747         return "AudioService_DeviceVolumeBehavior_" + AudioSystem.getOutputDeviceName(deviceType);
10748     }
10749 
persistDeviceVolumeBehavior(int deviceType, @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior)10750     private void persistDeviceVolumeBehavior(int deviceType,
10751             @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior) {
10752         if (DEBUG_VOL) {
10753             Log.d(TAG, "Persisting Volume Behavior for DeviceType: " + deviceType);
10754         }
10755         final long callingIdentity = Binder.clearCallingIdentity();
10756         try {
10757             System.putIntForUser(mContentResolver,
10758                     getSettingsNameForDeviceVolumeBehavior(deviceType),
10759                     deviceVolumeBehavior,
10760                     UserHandle.USER_CURRENT);
10761         } finally {
10762             Binder.restoreCallingIdentity(callingIdentity);
10763         }
10764     }
10765 
10766     @AudioManager.DeviceVolumeBehaviorState
retrieveStoredDeviceVolumeBehavior(int deviceType)10767     private int retrieveStoredDeviceVolumeBehavior(int deviceType) {
10768         return System.getIntForUser(mContentResolver,
10769                 getSettingsNameForDeviceVolumeBehavior(deviceType),
10770                 AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET,
10771                 UserHandle.USER_CURRENT);
10772     }
10773 
restoreDeviceVolumeBehavior()10774     private void restoreDeviceVolumeBehavior() {
10775         for (int deviceType : AudioSystem.DEVICE_OUT_ALL_SET) {
10776             if (DEBUG_VOL) {
10777                 Log.d(TAG, "Retrieving Volume Behavior for DeviceType: " + deviceType);
10778             }
10779             int deviceVolumeBehavior = retrieveStoredDeviceVolumeBehavior(deviceType);
10780             if (deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET) {
10781                 if (DEBUG_VOL) {
10782                     Log.d(TAG, "Skipping Setting Volume Behavior for DeviceType: " + deviceType);
10783                 }
10784                 continue;
10785             }
10786 
10787             setDeviceVolumeBehaviorInternal(deviceType, deviceVolumeBehavior,
10788                     "AudioService.restoreDeviceVolumeBehavior()");
10789         }
10790     }
10791 
10792     /**
10793      * @param audioSystemDeviceOut one of AudioSystem.DEVICE_OUT_*
10794      * @return whether {@code audioSystemDeviceOut} has previously been set to a specific volume
10795      * behavior
10796      */
hasDeviceVolumeBehavior( int audioSystemDeviceOut)10797     private boolean hasDeviceVolumeBehavior(
10798             int audioSystemDeviceOut) {
10799         return retrieveStoredDeviceVolumeBehavior(audioSystemDeviceOut)
10800                 != AudioManager.DEVICE_VOLUME_BEHAVIOR_UNSET;
10801     }
10802 
addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut)10803     private void addAudioSystemDeviceOutToFixedVolumeDevices(int audioSystemDeviceOut) {
10804         if (DEBUG_VOL) {
10805             Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
10806                     + " to mFixedVolumeDevices");
10807         }
10808         mFixedVolumeDevices.add(audioSystemDeviceOut);
10809     }
10810 
removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut)10811     private void removeAudioSystemDeviceOutFromFixedVolumeDevices(int audioSystemDeviceOut) {
10812         if (DEBUG_VOL) {
10813             Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
10814                     + " from mFixedVolumeDevices");
10815         }
10816         mFixedVolumeDevices.remove(audioSystemDeviceOut);
10817     }
10818 
addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut)10819     private void addAudioSystemDeviceOutToFullVolumeDevices(int audioSystemDeviceOut) {
10820         if (DEBUG_VOL) {
10821             Log.d(TAG, "Adding DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
10822                     + " to mFullVolumeDevices");
10823         }
10824         mFullVolumeDevices.add(audioSystemDeviceOut);
10825     }
10826 
removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut)10827     private void removeAudioSystemDeviceOutFromFullVolumeDevices(int audioSystemDeviceOut) {
10828         if (DEBUG_VOL) {
10829             Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
10830                     + " from mFullVolumeDevices");
10831         }
10832         mFullVolumeDevices.remove(audioSystemDeviceOut);
10833     }
10834 
10835     //====================
10836     // Helper functions for app ops
10837     //====================
10838     /**
10839      * Validates, and notes an app op for a given uid and package name.
10840      * Validation comes from exception catching: a security exception indicates the package
10841      * doesn't exist, an IAE indicates the uid and package don't match. The code only checks
10842      * if exception was thrown for robustness to code changes in op validation
10843      * @param op the app op to check
10844      * @param uid the uid of the caller
10845      * @param packageName the package to check
10846      * @return true if the origin of the call is valid (no uid / package mismatch) and the caller
10847      *      is allowed to perform the operation
10848      */
checkNoteAppOp(int op, int uid, String packageName)10849     private boolean checkNoteAppOp(int op, int uid, String packageName) {
10850         try {
10851             if (mAppOps.noteOp(op, uid, packageName) != AppOpsManager.MODE_ALLOWED) {
10852                 return false;
10853             }
10854         } catch (Exception e) {
10855             Log.e(TAG, "Error noting op:" + op + " on uid:" + uid + " for package:"
10856                     + packageName, e);
10857             return false;
10858         }
10859         return true;
10860     }
10861 }
10862